分析 | CVE-2021-3156-sudo堆溢出高危漏洞
2021-01-28 18:58:00 Author: mp.weixin.qq.com(查看原文) 阅读量:164 收藏

本文为看雪论坛优秀文章

看雪论坛作者ID:暗香沉浮

编辑前言

Qualys的安全研究人员于1月13日发文称,攻击者无需知道用户密码即可成功利用此漏洞,在众多基于 Linux 的发行版本中获得最高的 root 权限。受影响的 Sudo 漏洞版本包括从 1.8.2 到 1.8.32p2 的经典版本,以及从 1.9.0 到 1.9.5p1 所有稳定版本。

调试方式

首先从github下载代码:
https://github.com/sudo-project/sudo/archive/SUDO_1_9_5p1.tar.gz

编译
tar xf sudo-SUDO_1_9_5p1.tar.gzcd sudo-SUDO_1_9_5p1/mkdir buildcd build/../configure --enable-env-debugmake -jsudo make install

调试(请以root方式执行gdb)
gdb --args sudoedit -s '\' `perl -e 'print "A" x 65536'`

gdb加载执行后进程会crash,这时候就可以对有漏洞的源码位置下断点,因为漏洞代码貌似是动态加载的,直接下断点下不到,crash之后就可以下了
 
断点命令
b ../../../plugins/sudoers/sudoers.c:964b ../../../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]: sudoeditNewArgv[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,感觉都不是很好利用。
 
感觉需要花一些时间捋一捋代码的逻辑,看看有没有什么其他的想法。
修改NewArgv[1]和NewArgv[2]的长度可以控制user_args堆块后面的空闲堆块的大小。
此外到达漏洞代码的poc构造过程也很精彩,这部分可以去发布漏洞的博客查看。

参考链接:

https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit

- End -

看雪ID:暗香沉浮

https://bbs.pediy.com/user-home-690974.htm

  *本文由看雪论坛 暗香沉浮 原创,转载请注明来自看雪社区。

# 往期推荐

公众号ID:ikanxue
官方微博:看雪安全
商务合作:[email protected]

球分享

球点赞

球在看

点击“阅读原文”,了解更多!


文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458380711&idx=1&sn=aef5ea72b0679e84196e2dd285d784dc&chksm=b180d92d86f7503bb9a75c62fcee83db7d6e38b95b96083d545f5c959d9ced856dff7c67d441#rd
如有侵权请联系:admin#unsafe.sh