CVE-2021-3156 — Baron Samedit
sudo 中的基于堆的缓冲区溢出 → 本地权限提升
ITSOLERA 网络安全部门 | 红队实习 2026
██████╗ █████╗ ██████╗ ██████╗ ███╗ ██╗ ███████╗ █████╗ ███╗ ███╗███████╗██████╗ ██╗████████╗
██╔══██╗██╔══██╗██╔══██╗██╔═══██╗████╗ ██║ ██╔════╝██╔══██╗████╗ ████║██╔════╝██╔══██╗██║╚══██╔══╝
██████╔╝███████║██████╔╝██║ ██║██╔██╗ ██║ ███████╗███████║██╔████╔██║█████╗ ██║ ██║██║ ██║
██╔══██╗██╔══██║██╔══██╗██║ ██║██║╚██╗██║ ╚════██║██╔══██║██║╚██╔╝██║██╔══╝ ██║ ██║██║ ██║
██████╔╝██║ ██║██║ ██║╚██████╔╝██║ ╚████║ ███████║██║ ██║██║ ╚═╝ ██║███████╗██████╔╝██║ ██║
╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═════╝ ╚═╝ ╚═╝
⚠️ 仅供教育 / 隔离实验室使用
所有测试必须在 Docker 实验室容器内进行。
切勿针对真实、生产或共享系统运行。
目录
- CVE 概述
- 此 CVE 的特殊之处
- 项目结构
- 团队交付物
- 快速开始
- 漏洞利用原理
- 漏洞金丝雀测试
- exploit.py 用法
- 实验室重置与快照
- 已修补与易受攻击版本对比
- 参考资料
CVE 概述
| 属性 | 值 |
|---|
| CVE ID | CVE-2021-3156 |
| 别名 | Baron Samedit |
| 类型 | 基于堆的缓冲区溢出 → 本地权限提升 |
| 组件 | sudo — Linux 权限工具(src/sudo.c 中的 set_cmnd()) |
| CVSS v3 评分 | 7.8 高危 |
| 向量 | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| 受影响版本 | sudo 1.8.2 – 1.8.31p2 及 1.9.0 – 1.9.5p1 |
| 已修复版本 | sudo 1.9.5p2(1.9 分支)/ sudo 1.8.32(1.8 分支) |
| 实验室目标版本 | Ubuntu 20.04 上的 sudo 1.8.31 |
| 补丁 KB / 公告 | SA: https://www.sudo.ws/security/advisories/unescape_overflow/ |
| 发现者 | Qualys 研究团队 |
| 披露时间 | 2021-01-26 |
| 在野时长(代码) | 约 2011-07-09(sudo 1.8.2)起 — 约 10 年未被发现 |
| 所需认证 | 仅需本地用户 — 无需任何 sudo 权限 |
此 CVE 的特殊之处
| 属性 | CVE-2021-3156 | 典型 sudo 本地权限提升 |
|---|
| 需要 sudoers 条目 | ❌ 否 | ✅ 是 |
| 需要 sudo 组成员资格 | ❌ 否 | ✅ 是 |
| 需要任何先前的 sudo 访问权 | ❌ 否 | ✅ 是 |
| 全新用户账户即可利用 | ✅ 是 | ❌ 否 |
| 利用权限系统 | ❌ 完全绕过 | ✅ 滥用 |
| 攻击面 | 参数解析器(认证前) | 权限检查 |
关键点:溢出发生在 set_cmnd() — 即解析参数的函数 — 该函数在 sudo 查询 /etc/sudoers 之前运行。一个 10 秒前创建、拥有零权限的账户即可利用此漏洞。
项目结构
CVE-2021-3156-Project/
│
├── README.md ← you are here
│
├── lab/ ← Member 1: Lab Environment
│ ├── Dockerfile ← Ubuntu 20.04 + sudo 1.8.31 (pinned)
│ ├── docker-compose.yml ← vulnerable target + patched reference
│ ├── evidence_helper.sh ← pre/post-exploit state capture
│ ├── SETUP.md ← step-by-step VM/Docker guide
│ └── config_notes.md ← CVE conditions & container details
│
├── exploit/ ← Member 2: Exploit Development
│ ├── exploit.py ← Python LPE framework + canary test
│ └── payloads.txt ← heap overflow research notes
│
├── docs/ ← Member 3: Research & Documentation
│ ├── root_cause_analysis.md ← set_cmnd() deep dive + off-by-one
│ ├── references.md ← all sources, PoCs, CWE mapping
│ └── mitigation.md ← sudo upgrade + hardening checklist
│
├── proof/ ← Member 4: Evidence Collection
│ ├── screenshots/ ← exploitation screenshots
│ └── terminal_logs.txt ← command output template + logs
│
└── report/
└── CVE-2021-3156_Report.docx ← Member 4: Final professional report
团队交付物
成员 1 — 实验室环境与 CVE 验证
| 文件 | 描述 |
|---|
lab/Dockerfile | Ubuntu 20.04,固定 sudo 1.8.31(易受攻击);已安装 Python 3;labuser 账户无任何 sudo 权限 |
lab/docker-compose.yml | 编排易受攻击的目标容器 + 已修补的 Ubuntu 22.04 参考容器 |
lab/evidence_helper.sh | Bash 脚本,用于在漏洞利用前后捕获系统状态(用户、sudo 版本、金丝雀) |
lab/SETUP.md | 分步指南:构建 → 启动 → 进入 → 验证 sudo 版本 → 运行金丝雀测试 → 快照 |
lab/config_notes.md | 解释为何无需错误配置、Docker 安全设置、凭据参考 |
成员 2 — 漏洞利用开发(PoC 脚本)
| 文件 | 描述 |
|---|
exploit/exploit.py | 完整的 Python 框架:check_platform()、check_sudo_version()、run_canary_test()、get_system_info() + 三个漏洞利用 TODO 存根(select_heap_strategy、build_overflow_argument、trigger_overflow_and_escalate),并附有 blasty/worawit PoC 的详细参考 |
exploit/payloads.txt | 堆溢出概念、COMPRESSION_TRANSFORM 等效(参数结构)、三种堆利用策略、失败尝试日志模板、检测特征 |
注意:按照道德准则,不包含可用的内核/堆漏洞利用代码。
exploit.py 中的 TODO 存根引用 https://github.com/blasty/CVE-2021-3156
和 https://github.com/worawit/CVE-2021-3156 作为权威公开 PoC,
供你的团队研究并集成。
成员 3 — 根因分析与研究
| 文件 | 描述 |
|---|
docs/root_cause_analysis.md | 详细内容:set_cmnd() 的大小计算与拷贝不匹配、含代码示例的 off-by-one 错误、补丁差异、漏洞利用链、CVSS 7.8 逐项指标、10 年时间线、受影响发行版分布表 |
docs/references.md | Qualys 公告、MITRE、NVD、sudo 项目、blasty PoC、worawit PoC、ExploitDB、GTFOBins、CWE 映射 |
docs/mitigation.md | apt-get install --only-upgrade sudo、验证金丝雀、AppArmor 加固、auditd 监控、加固表 |
成员 4 — 证据收集、报告与集成
| 文件 | 描述 |
|---|
proof/terminal_logs.txt | 证据收集模板(用实际实验室输出填写) |
proof/screenshots/ | 存放 7 张必需截图的目录 |
report/CVE-2021-3156_Report.docx | 12 个部分的专业报告:封面页、执行摘要、CVE 描述、根因分析、CVSS 细分、利用步骤、代码说明、证据清单、缓解措施、时间线、参考资料、免责声明 |
快速开始
1. 构建并启动实验室
cd CVE-2021-3156-Project/lab/
# Build the vulnerable image (downloads Ubuntu 20.04, pins sudo 1.8.31)
docker compose build
# Start both containers
docker compose up -d
# Confirm containers are running
docker compose ps
预期输出:
NAME STATUS
baron_samedit_target running
baron_samedit_patched running
2. 进入易受攻击的容器
docker exec -it baron_samedit_target bash
3. 确认漏洞条件
# Inside the container as labuser
whoami # Expected: labuser
id # Expected: uid=1000(labuser)...
sudo --version # Expected: Sudo version 1.8.31
sudo -l # Expected: Sorry, user labuser may not run sudo...
sudoedit -s '\' 2>&1 # Expected: NOT "usage:" → VULNERABLE
4. 复制并运行漏洞利用程序
# From host machine
docker cp exploit/exploit.py baron_samedit_target:/home/labuser/
# Inside container
python3 exploit.py --check-only # verify all prerequisites pass
python3 exploit.py --safe-mode # canary only, no exploitation
python3 exploit.py --cmd "id" # LPE → show root identity
python3 exploit.py --cmd "whoami /all" --output /tmp/proof.txt
5. 捕获证据
# Inside container — before exploit
~/evidence_helper.sh > /tmp/before.txt
# After exploit
~/evidence_helper.sh > /tmp/after.txt
# Copy to host
docker cp baron_samedit_target:/tmp/before.txt proof/terminal_logs_before.txt
docker cp baron_samedit_target:/tmp/after.txt proof/terminal_logs_after.txt
漏洞利用原理
Step 1: Run 'sudoedit -s <crafted_argument>'
↓
Step 2: sudo calls set_cmnd() to parse arguments in shell mode
↓
Step 3: set_cmnd() COUNTS bytes for the cmnd_args buffer (correct size)
↓
Step 4: set_cmnd() COPIES bytes — but reads 1 byte past the null
terminator of any argument ending with '\'
↓
Step 5: Off-by-one overflow writes 1 unexpected byte beyond cmnd_args
↓
Step 6: Heap grooming (environment variable layout manipulation) ensures
a valuable sudo struct sits adjacent to the overflowed buffer
↓
Step 7: The overflow byte corrupts a pointer in the adjacent struct
↓
Step 8: sudo follows the corrupted pointer → executes attacker-controlled
command (via SUDO_EDITOR) with root privileges
↓
Result: uid=0(root) — from a user with ZERO sudo permissions
根本原因一句话总结
size_calculation("A\") = 2 bytes ≠ copy("A\") = writes 3 bytes → overflow
漏洞金丝雀测试
确认是否存在 CVE-2021-3156 的最安全方式 — 无需进行漏洞利用:
sudoedit -s '\' 2>&1; echo "Exit: $?"