type
status
date
slug
summary
tags
category
icon
password
book
这道题直到最后也没做出来,但是还是恶补了不少的东西,学会了不少heap中的关于tcache的用法
tcache是在libc2.26中新加的机制,是用于来进行缓存机制的获取,然后在glibc2.31中,heap获得了加强,包括在tcache中也是
libc变化
glibc2.31之前
fastbin和tcache bin中,对于double free攻击都没有验证,同时在heap中对于fd指针的存储是明文存储。
tcache中甚至是直接没有对于double free的检测,你可以直接连续两次进行free
此时tcache的结构体是如下:
glibc2.31之后
tcache bin的结构体中加入了key,用于对double free进行验证,逻辑大概是检测
tcache_entry *entries[TCACHE_MAX_BINS]
中的一个链表中有没有我们想要加入的那个chunk,如果有就会被检测出来,所以是不能进行将相同的两个chunk放进同一条链表的glibc2.32之后
引入了safe-linking,safe-linking这里有介绍:
glibc2.35之后
hook函数全部消失,不能被使用
泄露libc地址
我在这个题中是使用unsorted bin来泄露main_arena的地址的
因为unsorted bin的链表头部是指着main_arena+0x60的地方的(不过不同的版本这个间距不一样到时候要单独看看)
而main_arena这个结构体也是存储在libc.so.6中的,也就是说和libc函数的间距是恒定的,只要有了这个返回值,就可以进行libc的所有地址的泄露了
Alloc to Stack
由于这道题使用的是2.35版本的libc,同时开启了
FULL RERLO
版本,所以我们没有办法改动got表,这样就导致我们只能考虑其他办法,通过t1d师傅的指导,发现可以使用在栈地址中进行更改。也就是alloc to stack思路
这道题具有一个很明显的UAF,我们可以通过这个UAF,利用它自带的edit函数直接修改heap中的地址。
所以我们的思路就是直接通过这个UAF来修改tcache bin的链表,达到可以进行将栈中的部分内存放进的效果
流程很简单:
- free一个chunk,由于UAF的存在我们可以修改这个chunk的fd指针,同时由于safe-linking的存在,我们在使用fd指针的时候是
fd^(addr>>12)
,对其进行异或后再将其放入chunk中。此时就可以看出我们的bin链表已经被变化了
- malloc一个相同大小的chunk,这样我们之前修改的那个地址就会被我们获取到,也就是说我们有了一个在栈中的chunk指针,这样通过这个指针就达成了修改栈内容的目的。
存在疑问
- 这个main函数没有正常的回退方式,也就是说没有办法直接更改ret地址达成ROP的效果
- 不知道为什么获取chunk的时候,栈中的结构并没有chunk头,这可能是malloc函数中出现的什么问题,很疑惑这一点,希望到时候看看wp怎么写
- 更改栈中chunk时会导致canary的问题,不知道是不是要先获取到cancary,然后再填入
- 希望wp教教我
Tld师傅版本
学习了一下tld师傅给我的exp,收获良多
- 不需要连续释放7个chunk来进入unsorted bin,只需要对一个不低于0x420(在我的电脑上是这个大小,一般就按着0x500来吧)大小的chunk进行释放,就会放入unsorted bin中,再对此进行fd指针,也就是main_area的获取(main_area的地址就在libc.so中)
- 可以按照不同大小的chunk来释放进入tcache bin中,方便操作,这样比弄7个节点方便多了
- 通过tcache poisoning,可以将environ的地址写进chunk中,直接将这个environ当作一个数组的指针管理
- 只有在bin中的时候才会进行safe-linking,chunk被重新malloc之后会进行异或解密
- call指令的时候会直接把ret压栈,所以不是非得需要rbp进行固定的,像是fgets中的这个_IO_getline函数,这个函数就不弄rbp、不涉及canary,可以直接覆盖