ByteCTF2021 Bytezoom
Keyword: 智能指针
逆向分析
打比赛时候写的文档找不到了……从头做一遍吧
C++ 逆向分析起来很头大,肯定是要靠调试来分析的
结构
1 | 1.create --cat |
结构体如下
)
如果name长度小于8,就直接存放在结构体中,否则就另外申请一个chunk存放name,name_if_short
则存放name_size
。
看到这个结构体,第一反应可以类型混淆。
create
大量用到了shared_ptr
,他是一个类而非单纯一个指针
shared_ptr 主要的功能是,管理动态创建的对象的销毁。它的基本原理就是记录对象被引用的次数,当引用次数为 0 的时候,也就是最后一个指向某对象的共享指针析构的时候,共享指针的析构函数就把指向的内存区域释放掉。
我们只要申请同idx的chunk,原chunk就会因为引用次数变为0而被自动释放。
select
分别创建一个shared_ptr保存我们选择的cat和dog
我们写一个简单的demo,演示一下用同一个原始指针创建两个共享指针会造成什么后果
1 | //g++ test.cpp -o test |
可以看到,这两个指针的计数都是1,而且引起了double free,因为他们是独立创建的,指向同一个对象,但是计数并不互通,当程序结束时,他们各自将对象释放,造成了double free。
因此,即使我们通过create将对象释放了,select这里的共享指针仍旧指向原对象,造成了一个UAF。
change
cat可以改age,dog可以改name
思路
- UAF
- 类型混淆
首先利用select的uaf,得到一块dog的free的chunk,然后将这个chunk用cat申请到,申请到之后我们可以通过操控dog的age来改变cat的name的addr,从而泄露libc地址
然后再利用这个uaf,造成一个fastbin dup,攻击free_hook就可以了。
刚刚拿到以为是要打vtable,但其实只考察了shared_ptr这个点,其他的就当常规C pwn打。
1 | #! /usr/bin/python |