cve-2021-3156-sudo堆溢出简单分析
调试方式
首先从github下载代码
https://github.com/sudo-project/sudo/archive/SUDO_1_9_5p1.tar.gz
编译
tar xf sudo-SUDO_1_9_5p1.tar.gz
cd sudo-SUDO_1_9_5p1/
mkdir build
cd build/
../configure --enable-env-debug
make -j
sudo make install
调试
gdb --args sudoedit -s '\' `perl -e 'print "A" x 65536'`
gdb加载执行后进程会crash,这时候就可以对有漏洞的源码位置下断点,因为漏洞代码貌似是动态加载的,直接下断点下不到,crash之后就可以下了
断点命令
b ../../../plugins/sudoers/sudoers.c:964
b ../../../plugins/sudoers/sudoers.c:978
漏洞成因
调试用poc
sudoedit -s '\' 112233445566
漏洞位于 set_cmnd 函数中,关键代码如下
/* Alloc and build up user_args. */
for (size = 0, av = NewArgv + 1; *av; av++)
size += strlen(*av) + 1;
if (size == 0 || (user_args = malloc(size)) == NULL) {
if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) {
for (to = user_args, av = NewArgv + 1; (from = *av); av++) {
while (*from) {
if (from[0] == '\\' && !isspace((unsigned char)from[1])) // 关键逻辑!!!
from++;
*to++ = *from++;
}
*to++ = ' ';
}
*--to = '\0';
}
进入该函数时NewArgv的结构如下
NewArgv[0]: sudoedit
NewArgv[1]: \
NewArgv[2]: 112233445566
首先会计算 NewArgv 1~2
两个参数的长度 2 + 13 = 15
.
因此user_args
分配的内存大小为 15
字节。
然后会把 NewArgv 1~2
的数据拷贝到user_args
里面,拷贝过程中如果 from[0]
为 \
,且 from[1]
不是空格就会from++
。
if (from[0] == '\\' && !isspace((unsigned char)from[1])) // 关键逻辑!!!
from++;
所以在处理NewArgv[1]
时,from[0]
就是 \
,from[1]
为 \x00
,会通过这个判断让 from++
,然后后面会再次from++.
*to++ = *from++;
之后from就指向了NewArgv[1]
字符串\x00后面的一个字符,我们看看调试时NewArgv[1]
后面是什么
可以看到NewArgv[1] (0x5c 0x00)后面紧跟着的是NewArgv[2]( 0x31 0x31 ...),所以此时 from 执行的就是 NewArgv[2] 的开头
从而会再次进入while循环把NewArgv[2]
拷贝到user_args
然后处理NewArgv[2]
会再次把NewArgv[2]
拷贝到user_args
因此最终结果就是 NewArgv[2]
被拷贝了两次,实际的写入数据长度为26字节
这个漏洞是一个堆溢出,不过写的数据需要是非\x00,如果user_args
分配的内存比较小(比如15字节)的话,其后面是unsorted bin
,如果分配的比较大的话(使用原始的poc)其后面跟的是top chunk,感觉都不是很好利用。
感觉需要花一些时间捋一捋代码的逻辑,看看有没有什么其他的想法。
便于调试的脚本
写了些gdb插件的代码,可以用来查看堆布局里面的已释放块和未释放块的信息
https://github.com/hac425xxx/gdb-heap-trace
图中带 FREE_CHUNK
是处于释放状态的块
其他的是还没有释放的,展开chunk里面是这个块分配时的调用栈
对于没有释放块的调用栈可以通过让 gef
加载 heaptrace.py
的日志来实现
使用这个插件便于我们查看发送堆溢出时前后的堆块布局信息,以便找到合适溢出的堆对象。
参考链接
https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit