调试方式

首先从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. 揭秘JWT:从CTF实战到Web开发,使用JWT令牌验证

    揭秘JWT:从CTF实战到Web开发,使用JWT令牌验证 介绍 JWT(JSON Web Tokens)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在网络上安全地传输信息. ...

  2. el-table

    el-table-column 渲染的顺序不对,第一列被渲染到最后 el-table-column 必须作为 el-table 或 el-table-column 的直接子元素使用,如果不是将会导致标 ...

  3. Servlet——简介

    Servlet    快速入门   1.创建web项目,导入Servlet依赖坐标 <dependencies> <dependency> <groupId>jav ...

  4. IT男如何走上的自由职业之路。

    前言 在博客园的一篇文章<40岁大龄失业程序猿,未来该何去何从>,在下面留言,目前自己在做自由职业,很多人加好友咨询自由职业的事情,对IT行业自由职业比较感兴趣,问怎么能走上这条路,所以才 ...

  5. Project: Kill e

    接到上级任务,今天来暗杀 \(e\) 据说杀死 \(e\) 的方式就是把他算出来,好吧,现在我们还是来算一下 考虑使用如下代数式求解 \[e\ \text{site:baidu.com} \] 虽然我 ...

  6. [python] 基于PyOD库实现数据异常检测

    PyOD是一个全面且易于使用的Python库,专门用于检测多变量数据中的异常点或离群点.异常点是指那些与大多数数据点显著不同的数据,它们可能表示错误.噪声或潜在的有趣现象.无论是处理小规模项目还是大型 ...

  7. DNShell

    DNShell 一款基于DNS C2隧道的反弹shell工具. 支持 功能: 支持DNS-recordA-直连型 的C2隧道. 目标: Windows下基于Powershell的反弹. Linux下基 ...

  8. CSP-J2/S2 2023 游记

    可能早就应该发出来的游记. 2023-10-07 16:32. 前一天睡得比较晚,所以迟到了一点点. 上来先敲了个对拍,拍了一个 if a % 1000 = 0 then a++ 的 A + B,拍出 ...

  9. R语言经典统计分析

    经典统计分析包括了许多常用的统计方法和技术,用于数据的描述.推断和建模.本节将介绍经典统计分析方法(包括t检验.方差分析.卡方检验.线性回归)在R语言中的实现. 5.1.1  t检验 样本均值(sam ...

  10. 关系图谱后端不给指向性字段使用children

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...