VNCTF2021 PWN LittleRedFlower
因为过几天vnctf2022就要来了,所以看看2021的题目希望能在比赛当中做出题目。
题目信息
题目整理
libc版本为2.30.so
直接泄露了libc,
在vul1函数中可以任意地址写一字节
输入offest可以任意写8字节
申请堆块大小在0xFFF到0x2000之间
在申请的堆块上写入数据
题目开启了沙盒,禁用了execve,那么只能是利用orw来获取flag了
好像说比赛给了HINT
打TCACHE_MAX_BINS
解题思路()
题目提示打TCACHE_MAX_BINS,类别global_max_fast,应该是改写tache的最大size;如果改写成功,那我们就可以通过调试来确定tcache取出堆块时的偏移,然后通过任意写8字节将申请的堆块改写为我们想要的位置, 并且在下一次申请的时候取出修改,通过 setcontext 来达到 SROP。
怎么修改TCACHE_MAX_BINS
通过搜索源代码发现,这是一个宏定义,所以无法直接修改
1 | # define TCACHE_MAX_BINS 64 |
继续搜索发现,在源代码中,该宏定义又被赋值给其他变量
1 | #if USE_TCACHE |
经过GDB动调发现,最后会进入如下的流程
1 |
|
而在上述流程中,对idx和TCACHE_MAX_BINS的比较被替换成了tc_idx和mp_.tcache_ bins的比较,如此一来,我们可以更该 mp_.tcache_bins达到目的。
而后当进入了tcache_get()函数中时,如下
libc-2.29.so
1 | tcache_get (size_t tc_idx) |
libc-2.30.so
1 | tcache_get (size_t tc_idx) |
libc-2.31.so
1 | tcache_get (size_t tc_idx) |
很明显,在libc-31.so和libc-2.31版本里已经优化了tcache_get,直接将assert函数去掉了。
所以,我们只需要修改 mp_.tcache_bins 的值即可,我们可以利用任意写一字节来修改最高位为 0xFF 。
伪造Tcache的count
经过修改TCACHE_MAX_BINS为0xff;这样的话tcache_bins的结构体会扩大,不再仅仅是0x290;这样一来我们首先要做的就是确定tcache_bins的idx;这里大概是有两种方法
方法一
- 直接gdb动调;
方法二,计算
查看glibc源码发现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* int_free also calls request2size, be careful to not pad twice. */
size_t tbytes;
if (!checked_request2size (bytes, &tbytes))
{
__set_errno (ENOMEM);
return NULL;
}
size_t tc_idx = csize2tidx (tbytes); #这个位置根据申请堆块的大小计算idx
MAYBE_INIT_TCACHE ();
DIAG_PUSH_NEEDS_COMMENT;
if (tc_idx < mp_.tcache_bins
&& tcache
&& tcache->counts[tc_idx] > 0)
{
return tcache_get (tc_idx);
}
DIAG_POP_NEEDS_COMMENT;csize2tidx定义如下
1
# define csize2tidx(x) (((x) - MINSIZE + MALLOC_ALIGNMENT - 1) / MALLOC_ALIGNMENT)
其中MINSIZE定义如下
1
2#define MINSIZE (unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
而其中MALLOC_ALIGN_MASK定义如下
1
2#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
而MALLOC_ALIGNMENT定义如下
1
2
3#define MALLOC_ALIGNMENT (2 * SIZE_SZ < __alignof__ (long double) \
? __alignof__ (long double) : 2 * SIZE_SZ)这里应该是计算出idx的大小,最后再通过计算算出next的位置。我还没有试过,待验证。
最后通过__free_hook来执行SROP
因为libc-2.30.so没有源码不好调试,所以改成了libc-2.31.so
exp(参考wjh师傅修改的)
1 | from pwn import * |
本地打通截图
参考文章
- 本文标题:LittleRedFlower
- 本文作者:LOLOLO
- 创建时间:2022-02-09 13:21:21
- 本文链接:https://lololo-pwn.github.io/2022/02/09/LittleRedFlower/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!