CVE-2021-3156 分析

发布: (2026年2月22日 GMT+8 13:54)
4 分钟阅读
原文: Dev.to

Source: Dev.to

背景

上周,我决定进一步学习漏洞利用和漏洞分析。我选择研究 CVE‑2021‑3156,这是一种 2021 年的 sudo 漏洞,早已被修补。复现该漏洞时遇到了若干困难:

  • 搭建一个使用 2021 年之前版本 sudo 的环境。
  • 确保二进制文件未被修补。
  • 触发堆溢出(由于 Docker 中堆布局的差异,我未能实现完整的代码执行)。

漏洞细节

CVE‑2021‑3156 是 基于堆的缓冲区溢出,出现在 sudo 中。该漏洞允许向已分配缓冲区之外写入数据,从而破坏堆上相邻的内存。

利用目标是 glibc 的名称服务切换(NSS)系统中的 service_user 结构体,该结构体包含用于用户和组查询的函数指针。通过溢出缓冲区,攻击者可以覆盖这些函数指针并将其重定向到攻击者控制的代码。

当 sudo 调用 NSS 函数(例如 getpwnam_r() 来查询用户信息)时,它会遵循被篡改的函数指针并执行攻击者的代码。由于 sudo 以 root 权限运行,注入的代码也继承了该权限,从而使攻击者能够获取 root shell。

利用设置

  1. 首次尝试使用虚拟机 – 我尝试在 UTM 虚拟化应用中运行 Ubuntu 18.04。较旧的 Ubuntu 镜像出现问题:安装过程频繁崩溃,甚至 live 镜像也无法启动。于是放弃了此方案。

  2. Docker 容器 – 我改用基于 Ubuntu 18.04 的 Docker 容器,在我的机器上成功运行。然而,当我尝试利用时,sudo 报告使用错误,表明二进制文件已被更新。检查二进制文件的时间戳发现它是 2023 年编译的——比修补时间晚了两年。

  3. 安装易受攻击的 sudo – 我在 Docker 实例内部下载了旧版本的 sudo,进行安装并从其所在位置运行。这样就能够使用易受攻击的 sudo 二进制触发一次内存访问错误。

尝试利用

我下载了公开的利用脚本并尝试获取 root 权限。脚本默认假设 sudo 二进制位于系统默认路径,因此多次失败。通过创建指向新安装 sudo 的符号链接,堆溢出尝试得以执行,但仍未能获得 root 权限。

在尝试了多种块大小后,利用仍未成功。我怀疑 Docker 对堆内存的布局与典型的 Ubuntu 安装有显著差异,这使得在该环境中实现利用更加困难。

0 浏览
Back to Blog

相关文章

阅读更多 »