调试方式

首先从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. MybatisPlus——入门案例

    MyBatisPlus MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发.提高效率 开发方式 基于MyBatis使用MyBatisPlus 基于Sprin ...

  2. linux tracepoint增加

    引入tracepoint的背景 当需要获取内核的debug信息时,通常你会通过以下printk的方式打印信息: void trace_func() { //-- printk("输出信息&q ...

  3. iOS解决嵌套在ScrollView中的TableView滑动手势冲突问题

    在项目开发中用到了这种需求,顶部两个选项卡,底部列表有侧滑手势,布局是就不说了,遇到的问题是左滑的时候添加滑动手势效果.一直纠结了很久,后来想到可能是手势冲突的问题. 解决办法开启多手势代理即可,我是 ...

  4. vue.config.js 常用的属性

    // vue.config.js 文件是脚手架的配置文件 const { defineConfig } = require("@vue/cli-service"); module. ...

  5. token有⼀定的失效性,过期了该怎么做?

    token 失效分为主动失效和被动失效 主动失效 就是自己设置函数检查token是否失效了, 主要步骤 :1 1.在登录的时候记录存储token的时间, 2. 在request文件,设置一个函数,用来 ...

  6. apisix~kafka-logger插件

    作用 将http请求与响应的内容发到kafka的topic,以json的形式发送存储 配置相关 log_format为自定义配置字段,添加后,默认的请求响应消息将被覆盖 { "_meta&q ...

  7. 云原生爱好者周刊:Dapr 成为 CNCF 孵化项目

    云原生一周动态要闻: Dapr 加入 CNCF 孵化器 Knative 1.0 发布 Canonical 开始提供针对 Intel CPU 优化的 Ubuntu 图像 Longhorn 为 CNCF ...

  8. linux 基础(5)文件的打包和压缩

    文件的压缩是非常重要和常见的操作. 在 Windows 下,zip 和 rar 经常使用的压缩软件,框选一堆文件,右键用 WinRAR 就可以完成压缩.不过在 linux 下通常不这么做.一是因为 l ...

  9. A星、Floyod、Bellman-Ford

    A 星算法 A 星和 Dijkstra 算法唯一区别在于堆中排序的依据.distance 数组仍然保存实际代价,预估代价只影响堆的弹出顺序. Dijkstra 根据源点到当前点的实际代价进行排序. A ...

  10. 黑神话:悟空电脑太卡?配置不够?ToDesk云电脑入门新手教程

    许多玩家在玩<黑神话:悟空>时会遭遇硬件配置不足导致的游戏卡顿.画面不流畅等问题. 其实这个难题很好解决,用ToDesk云电脑即可迎刃而解.即使你的本地电脑配置不高,也能享受到流畅的游戏体 ...