调试方式

首先从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

cve-2021-3156-sudo堆溢出简单分析的更多相关文章

  1. CVE-2012-1876:Internet Exporter MSHTML.DLL CaculateMinMax 堆溢出简单分析

    0x01 2012 Pwn2Own 黑客大赛 Pwn2Own 是世界上最著名的黑客大赛,意在激励白帽黑客们进行顶尖的安全研究.在 2012 年 Pwn2Own 大赛上,来自法国著名的安全团队 Vupe ...

  2. Linux 堆溢出原理分析

    堆溢出与堆的内存布局有关,要搞明白堆溢出,首先要清楚的是malloc()分配的堆内存布局是什么样子,free()操作后又变成什么样子. 解决第一个问题:通过malloc()分配的堆内存,如何布局? 上 ...

  3. CVE-2013-0077:Microsoft DirectShow quartz.dll m2p 文件堆溢出漏洞简单分析

    0x01 前言 2012 年 10 月 5 日,exploit-db 漏洞公布站点上发布了 QQplayer.exe 3.7.892 m2p quartz.dll Heap Pointer OverW ...

  4. linux下堆溢出unlink的一个简单例子及利用

    最近认真学习了下linux下堆的管理及堆溢出利用,做下笔记:作者作为初学者,如果有什么写的不对的地方而您又碰巧看到,欢迎指正. 本文用到的例子下载链接https://github.com/ctfs/w ...

  5. CVE-2010-2553:Microsoft Cinepak Codec CVDecompress 函数堆溢出漏洞调试分析

    0x01 前言 微软提供一个叫 Cinepak 的视频解码器,通过调用 iccvid.dll 这个动态链接库文件可以使用这个解码器:微软自带的 Windows Media Player(视频音频软件) ...

  6. CVE_2012_1876堆溢出分析

    首先用windbg附加进程ie页面内容进程,!gflag +hpa添加堆尾检查,.childdbg 1允许子进程调试,然后加载POC. POC: <html> <body> & ...

  7. 7.3.5 Tomcat堆溢出分析(1)

    实战Java虚拟机:JVM故障诊断与性能优化>第7章分析Java堆,本章主要介绍了Java堆的分析方法.首先,介绍了几种常见的Java内存溢出现象及解决思路.其次,探讨了java.lang.St ...

  8. Linux堆溢出漏洞利用之unlink

    Linux堆溢出漏洞利用之unlink 作者:走位@阿里聚安全 0 前言 之前我们深入了解了glibc malloc的运行机制(文章链接请看文末▼),下面就让我们开始真正的堆溢出漏洞利用学习吧.说实话 ...

  9. 《深入理解Java虚拟机》(六)堆内存使用分析,垃圾收集器 GC 日志解读

    堆内存使用分析,GC 日志解读 重要的东东 在Java中,对象实例都是在堆上创建.一些类信息,常量,静态变量等存储在方法区.堆和方法区都是线程共享的. GC机制是由JVM提供,用来清理需要清除的对象, ...

  10. 【转载】利用一个堆溢出漏洞实现 VMware 虚拟机逃逸

    1. 介绍 2017年3月,长亭安全研究实验室(Chaitin Security Research Lab)参加了 Pwn2Own 黑客大赛,我作为团队的一员,一直专注于 VMware Worksta ...

随机推荐

  1. MyBatis——简介

    MyBatis MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发 官网:https://mybatis.net.cn/ 持久层 负责将数据保存到数据库的那一层代码 javaEE 三层架 ...

  2. 使用.NET并行任务库(TPL)与并行Linq(PLINQ)充分利用多核性能

    前言 最近比较闲,(项目要转Java被分到架构组,边缘化人员,无所事事 哈哈哈哈) 记录一下前段时间用到的.NET框架下采用并行策略充分利用多核CPU进行优化的一个方法 起因是项目中有个结算的方法,需 ...

  3. request和response请求包中的各项解释

    Request Response

  4. Spring 之 RestTemplate VS WebClient 发送 HTTP请求

    WebClient 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifact ...

  5. nexus 部署与设置

    安装nexus df -h 先查看目录磁盘空间,我安装的版本占用了四个G 空间,目录文件空间不够导致启动失败 上传 nexus 压缩包,并解压 查询 8081 端口号是否被占用 sudo netsta ...

  6. 【官宣】2024 DTC数据技术嘉年华全议程发布:汇聚行业精英,共襄年度盛宴

    龙腾四海内,风云际会时.由墨天轮数据社区和中国数据库联盟(ACDU)主办的第十三届数据技术嘉年华 将于2024年4月12日至13日在北京新云南皇冠假日酒店盛大召开.本次大会的主题是"智能·云 ...

  7. 使用 Debugger 断点 如果打开了断点调试 就会跳转空白页面

    <!DOCTYPE html> <html> <header> <title>test</title> </header> &l ...

  8. computed 中的属性名和data的属性名可以相同吗?

    不可以,因为无论computed 中的属性名还是 data 又或者是props中的属性名,都会别挂载到组件实例上,所以名字都不允许重复  : ps:好比一个作用域里面不允许定义2个相同的变量名 :

  9. Nuxt.js 应用中的 modules:done 事件钩子详解

    title: Nuxt.js 应用中的 modules:done 事件钩子详解 date: 2024/10/16 updated: 2024/10/16 author: cmdragon excerp ...

  10. 分享一个很好用的代理转发工具:rinetd

    rinetd介绍: 安装与使用:https://zhuanlan.zhihu.com/p/530875131 注意事项: 1.如果发现配置中的端口在进程中没找到,那就是配置填写错误导致的,笔者就遇到过 ...