首页
论坛
课程
招聘
[原创]看雪CTF2019Q2题目提交
2019-5-15 04:46 1097

[原创]看雪CTF2019Q2题目提交

2019-5-15 04:46
1097

0x00 概要

题目实现了一个多线程free的功能,这道题目关键点在于多线程所导致的uint8_t类型的整型溢出,进而导致double free。然后构造UAF泄漏Libc地址,再poison tcache写__free_hookgetshell

0x01 漏洞点

这题比上次那题还要简单,灵感来源于上architecture课教授slides里面的一个pseudocode,大概长这样

if (myThreadId() == 0)
    i = 0;
barrier();
// on each thread
while (true)
{
    local_i = FetchAndAdd(&i);
    if (local_i >= N) break; //integer overflow
    C[local_i] = 0.5*(A[local_i] + B[local_i]);
}
barrier();

然后我就在想这个如果FetchAndAdd函数能导致整型溢出的话,是否可以导致可利用的漏洞,于是就有了我这道题。

 

然后漏洞点在这里,代码跟上面的伪代码很像,只不过一些无关的东西删掉了。

void* free_thread(void* varg)
{
    thread_arg* arg = (thread_arg*)varg;
    uint8_t* i = &arg->iter;
    volatile size_t idx;
    while(true)
    {
        idx = __sync_fetch_and_add(i, 1);
        if (idx >= arg->bound) //整型溢出
            break;
        if (data[idx])
            free(data[idx]);
        else
            exit(-1);
    }
    return NULL;
}

bound的值很大的时候,比方说,删除范围254-255的时候,如果有两个线程,线程1freedata[254],线程2255 >= 255所以退出,而线程1这个时候__sync_fetch_and_add溢出到0,这个时候会把0到254的所有elements又free了一次,等于导致了double free。

0x02 利用

这里我稍微增加了一下难度,就是如果有空指针就会退出,所以得先把那些项都占满先。
然后注意,在线程中freechunk时会加到那个线程自己的tcache,然后线程退出时这些chunks会被放回fastbin或者unsortedbin而不是主线程的tcache。所以把index 0设置为unsortedbin大小可以直接leak libc的地址。

 

然后因为所有indeces都被占满了,这样就没有能用的index可以做poison了,所以得先把他们clear掉,但是在那之前得把最顶上的chunk(这时是index 1)先拿出来(所以data[254]==data[1]),方便到时候做poison利用。

 

然后用fastbin dup把0x70的fastbin污染了,创造出这种情况a -> b -> a,但这个时候tcache也是满的,这个时候malloc 4个tcache可以创造出这种情况a -> b -> &__free_hook,然后就可以写free hook执行system了。

 

不过有一点要注意,因为多线程,难免会有条件竞争,所以成功率并不是100%,不过也不低就是了。

 

环境libc2.27,md5=50390b2ae8aaa73c47745040f54e602f


第五届安全开发者峰会(SDC 2021)议题征集正式开启!

最后于 2019-6-24 18:22 被kanxue编辑 ,原因:
上传的附件:
收藏
点赞0
打赏
分享
最新回复 (1)
雪    币: 1818
活跃值: 活跃值 (5178)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2019-5-22 09:49
2
0
初步检查正常
游客
登录 | 注册 方可回帖
返回