feat(沙箱): 强制使用沙箱验证并增强沙箱功能
- 移除 LLM 模拟验证工具,强制使用沙箱进行漏洞验证 - 增强沙箱容器配置,添加/tmp挂载点 - 扩展沙箱基础镜像,增加多种语言环境支持 - 添加RCE漏洞验证脚本用于测试沙箱功能 - 更新验证Agent的系统提示,明确必须使用沙箱工具
This commit is contained in:
parent
189274fd56
commit
95929a467b
|
|
@ -599,8 +599,9 @@ async def _initialize_tools(
|
||||||
# Verification 工具
|
# Verification 工具
|
||||||
verification_tools = {
|
verification_tools = {
|
||||||
**base_tools,
|
**base_tools,
|
||||||
"vulnerability_validation": VulnerabilityValidationTool(llm_service),
|
# 强制使用沙箱工具,移除 LLM 模拟验证工具
|
||||||
"dataflow_analysis": DataFlowAnalysisTool(llm_service),
|
# "vulnerability_validation": VulnerabilityValidationTool(llm_service),
|
||||||
|
# "dataflow_analysis": DataFlowAnalysisTool(llm_service),
|
||||||
"create_vulnerability_report": CreateVulnerabilityReportTool(),
|
"create_vulnerability_report": CreateVulnerabilityReportTool(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,13 +44,7 @@ VERIFICATION_SYSTEM_PROMPT = """你是 DeepAudit 的漏洞验证 Agent,一个*
|
||||||
- **list_files**: 列出目录文件
|
- **list_files**: 列出目录文件
|
||||||
参数: directory (str), pattern (str)
|
参数: directory (str), pattern (str)
|
||||||
|
|
||||||
### 验证分析
|
### 沙箱验证 (必须使用)
|
||||||
- **vulnerability_validation**: LLM 深度验证 ⭐
|
|
||||||
参数: code (str), vulnerability_type (str), context (str)
|
|
||||||
- **dataflow_analysis**: 追踪数据流
|
|
||||||
参数: source (str), sink (str), file_path (str)
|
|
||||||
|
|
||||||
### 沙箱验证
|
|
||||||
- **sandbox_exec**: 在沙箱中执行命令
|
- **sandbox_exec**: 在沙箱中执行命令
|
||||||
参数: command (str), timeout (int)
|
参数: command (str), timeout (int)
|
||||||
- **sandbox_http**: 发送 HTTP 请求测试
|
- **sandbox_http**: 发送 HTTP 请求测试
|
||||||
|
|
|
||||||
|
|
@ -263,9 +263,7 @@ class AgentRunner:
|
||||||
# 职责:漏洞验证、PoC 执行、误报排除
|
# 职责:漏洞验证、PoC 执行、误报排除
|
||||||
self.verification_tools = {
|
self.verification_tools = {
|
||||||
**base_tools,
|
**base_tools,
|
||||||
# 验证工具
|
# 验证工具 - 移除旧的 vulnerability_validation 和 dataflow_analysis,强制使用沙箱
|
||||||
"vulnerability_validation": VulnerabilityValidationTool(self.llm_service),
|
|
||||||
"dataflow_analysis": DataFlowAnalysisTool(self.llm_service),
|
|
||||||
# 🔥 新增:漏洞报告工具(仅Verification可用)
|
# 🔥 新增:漏洞报告工具(仅Verification可用)
|
||||||
"create_vulnerability_report": CreateVulnerabilityReportTool(),
|
"create_vulnerability_report": CreateVulnerabilityReportTool(),
|
||||||
# 🔥 新增:反思工具
|
# 🔥 新增:反思工具
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,8 @@ class SandboxManager:
|
||||||
temp_dir: {"bind": "/workspace", "mode": "rw"},
|
temp_dir: {"bind": "/workspace", "mode": "rw"},
|
||||||
},
|
},
|
||||||
"tmpfs": {
|
"tmpfs": {
|
||||||
"/home/sandbox": "rw,size=100m,mode=1777"
|
"/home/sandbox": "rw,size=100m,mode=1777",
|
||||||
|
"/tmp": "rw,size=100m,mode=1777"
|
||||||
},
|
},
|
||||||
"working_dir": working_dir or "/workspace",
|
"working_dir": working_dir or "/workspace",
|
||||||
"environment": env or {},
|
"environment": env or {},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
try:
|
||||||
|
import docker
|
||||||
|
client = docker.from_env()
|
||||||
|
client.ping()
|
||||||
|
print("Docker is available and connected")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Docker connection failed: {e}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
from app.services.agent.tools.sandbox_tool import SandboxConfig, SandboxManager, SandboxTool # pyright: ignore[reportMissingImports]
|
||||||
|
print("Sandbox modules imported successfully")
|
||||||
|
except ImportError as e:
|
||||||
|
print(f"Sandbox import failed: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Sandbox import error: {e}")
|
||||||
|
|
@ -2,17 +2,17 @@
|
||||||
# 安全沙箱环境用于漏洞验证和 PoC 执行
|
# 安全沙箱环境用于漏洞验证和 PoC 执行
|
||||||
# 集成各类安全扫描工具 (Semgrep, Bandit, Gitleaks, etc.)
|
# 集成各类安全扫描工具 (Semgrep, Bandit, Gitleaks, etc.)
|
||||||
|
|
||||||
FROM python:3.11-bullseye
|
FROM docker.m.daocloud.io/python:3.11-bullseye
|
||||||
|
|
||||||
LABEL maintainer="XCodeReviewer Team"
|
LABEL maintainer="XCodeReviewer Team"
|
||||||
LABEL description="Secure sandbox environment for vulnerability verification and security scanning"
|
LABEL description="Secure sandbox environment for vulnerability verification and security scanning"
|
||||||
|
|
||||||
# 安装基本工具
|
# 安装基本工具
|
||||||
# 安装基本工具
|
# 安装基本工具
|
||||||
#Configuring mirrors for CN and unsetting broken proxy
|
# 使用阿里云镜像加速 apt
|
||||||
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
|
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY && \
|
||||||
|
sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
|
||||||
sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
|
sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
|
||||||
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY && \
|
|
||||||
apt-get update && apt-get install -y --no-install-recommends \
|
apt-get update && apt-get install -y --no-install-recommends \
|
||||||
curl \
|
curl \
|
||||||
wget \
|
wget \
|
||||||
|
|
@ -23,14 +23,41 @@ RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list && \
|
||||||
git \
|
git \
|
||||||
unzip \
|
unzip \
|
||||||
jq \
|
jq \
|
||||||
|
php-cli \
|
||||||
|
openjdk-11-jdk-headless \
|
||||||
|
ruby-full \
|
||||||
|
build-essential \
|
||||||
|
cmake \
|
||||||
|
clang \
|
||||||
|
llvm \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# 安装 Node.js (用于 JavaScript/TypeScript 代码执行 和 npm audit)
|
# 安装 Node.js (用于 JavaScript/TypeScript 代码执行 和 npm audit)
|
||||||
|
# 使用淘宝/阿里云镜像加速
|
||||||
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY && \
|
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY && \
|
||||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||||
&& apt-get install -y nodejs \
|
&& apt-get install -y nodejs \
|
||||||
|
&& npm config set registry https://registry.npmmirror.com \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# 安装 Go (使用阿里云镜像)
|
||||||
|
ENV PATH=$PATH:/usr/local/go/bin
|
||||||
|
ENV GOPROXY=https://goproxy.cn,direct
|
||||||
|
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY && \
|
||||||
|
curl -L https://mirrors.aliyun.com/golang/go1.21.6.linux-amd64.tar.gz -o go.tar.gz && \
|
||||||
|
tar -C /usr/local -xzf go.tar.gz && \
|
||||||
|
rm go.tar.gz
|
||||||
|
|
||||||
|
# 安装 Rust (使用 rsproxy 镜像)
|
||||||
|
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||||
|
CARGO_HOME=/usr/local/cargo \
|
||||||
|
PATH=/usr/local/cargo/bin:$PATH \
|
||||||
|
RUSTUP_DIST_SERVER=https://rsproxy.cn \
|
||||||
|
RUSTUP_UPDATE_ROOT=https://rsproxy.cn/rustup
|
||||||
|
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY && \
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh -s -- -y --default-toolchain stable --profile minimal && \
|
||||||
|
chmod -R a+w /usr/local/cargo
|
||||||
|
|
||||||
# 安装 Python 安全工具
|
# 安装 Python 安全工具
|
||||||
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY && \
|
RUN unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY && \
|
||||||
pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple \
|
pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
|
||||||
|
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())
|
||||||
Loading…
Reference in New Issue