第三章 - 重生之我是AI人:架构拆解LLM 怎么当黑客的大脑
Khan安全团队
2026年6月19日 21:07
广东
在小说阅读器读本章
去阅读
以下文章来源于威胁情报Z分析
,作者Gachong
威胁情报Z分析
.
国际网络安全威胁情报,地缘政治事件分析。
- 架构
第二章你跑通了,现在停下来想一下:Hati 整体怎么设计?为什么这样设计?
我把它拆成 3 层 + 2 个边界:
第 1 层:用户交互层
● Web UI:static/index.html(SPA,1815 行 HTML/JS,没用任何前端框架,纯 vanilla)
● REST API:api/main.py(798 行,FastAPI)
● WebSocket:api/websocket.py(流式推送,5175 字节)
为啥不用 React/Vue?因为整个 UI 只有 3 个页面:主页、报告页、设置页。Vanilla JS + 几个 fetch 调用就够了,引框架反而是负担。
第 2 层:智能调度层
● Orchestrator:agents/orchestrator.py(2986 行,整个项目最重文件)
● ChatAgent:agents/chat\_agent.py(1287 行,自然语言入口)
● Sub-agents:agents/recon\_agent.py / vuln\_agent.py / exploit\_agent.py / report\_agent.py
● RAG:rag/(153+277 行,向量检索)
● State:state/pentest\_state.py(584 行,LangGraph 状态定义)
关键点:这一层只做决策,不做执行。LLM 想想下一步干啥,然后调下面那层去真的发包。
第 3 层:工具执行层
● HexStrike MCP Server:54 个安全工具的 HTTP 包装(这里补充一点,hex完整是有124个工具的,我只注册了54个,因为越多占用硬盘空间也越多,ai也不一定会选择都用上)
● SSH 隧道:scripts/ssh\_tunnel.sh / .ps1
● Docker 容器:docker/Dockerfile.toolkit(可选,工具镜像)
关键点:这一层是真发包的地方。主机和 VM 之间通过 HTTP(明文)或 SSH 隧道(加密)通信。
- 三个核心组件
2.1 MiniMax LLM — 大脑
选 MiniMax 的理由:
● OpenAI 协议兼容,迁移成本低
● 国内访问稳定,不用魔法
● 价格友好(我们单次任务大概烧 0.5-1 元)
怎么接的?看 config/minimax\_config.py:29-60:
MINIMAX_API_KEY = os.getenv(\"MINIMAX_API_KEY\", \"\")MINIMAX_BASE_URL = \"https://api.minimax.chat/v1\"MINIMAX_MODEL = os.getenv(\"MINIMAX_MODEL\", \"MiniMax-M2.7\")
class MiniMaxLLM: def __init__(self, api_key, model, base_url): self.llm = ChatOpenAI( api_key=api_key, base_url=base_url, model=model, temperature=0.7, max_tokens=4096, )
LLM 配置(config/settings.py:25-27):
minimax_api_key: str = \"\"minimax_group_id: str = \"\"minimax_model: str = \"abab6.5s-chat\" # 兼容老字段
2.2 HexStrike MCP — 手和脚
MCP 是啥?Model Context Protocol,Anthropic 搞的一个标准协议,让 LLM 知道有哪些工具可以调。HexStrike 把 124 个渗透测试工具(nmap、nuclei、sqlmap、ffuf...) 全部包成 MCP 工具。但因为外存有限,我只用了54个做尝试。
我为啥不用 HexStrike 的\"原版\"?原版是给 Claude 桌面端用的,集成方式不一样。Hati 走的是自己包一层 HTTP 客户端(agents/recon\_agent.py 里的 HexStrikeClient),通过 HTTP API 调 Kali VM 上的 MCP Server。
54 个工具长啥样?看 hexstrike/hexstrike\_mcp.py,全是函数:
@mcp.tool()def nmap_scan(target: str, ports: str = \"1-65535\") -> dict: \"\"\"Nmap 端口扫描\"\"\" return subprocess_run([\"nmap\", \"-sV\", \"-p\", ports, target])
Hati 怎么用?看 agents/recon\_agent.py 的 HexStrikeClient:
class HexStrikeClient: def __init__(self, base_url=settings.hexstrike_server_url): self.base_url = base_url
def execute_command(self, command: str, category: str = \"general\"): return requests.post( f\"{self.base_url}/api/command\", json={\"command\": command, \"category\": category}, timeout=180 ).json()
2.3 RAG 知识库
RAG = Retrieval Augmented Generation。简单说:让 LLM 动手前先查\"参考书\"。
为啥需要?
● LLM 知识有截止日期,新出的 0day 不知道
● 真实 POC 有特异性,MySQL 注入和 PostgreSQL 注入语法不同
● LLM 凭记忆容易写出错的 payload
数据:poc/wpoc/ 下的 799 个文件。每个文件是一个产品的已知漏洞。
向量模型:all-MiniLM-L6-v2(Sentence Transformers 出的,90MB 不到,本地 CPU 跑得动)。
存储:ChromaDB,本地嵌入式,不用起服务。
完整路径:poc/wpoc/\*.md → scripts/build\_rag.py → ChromaDB → rag/query\_interface.py 检索
- 三个辅助系统
3.1 Redis 进度追踪
干啥:Web UI 实时显示\"现在在做什么\",这个信息从哪来?Redis。
配置(config/settings.py:30-33):
redis_host: str = \"localhost\"redis_port: int = 6379redis_db: int = 0redis_db_progress: int = 2 # 进度追踪专用 DB
实现:state/progress\_tracker.py。每次阶段切换都写一条进度到 Redis,WebSocket 从 Redis 读出来推给前端。
降级设计:Redis 挂了 → 内存兜底,Hati 不会因此崩。
3.2 WebSocket 流式推送
为啥要 WebSocket?HTTP 没法\"服务端主动推\",只能客户端轮询。渗透测试跑几分钟,前端轮询既慢又浪费。
接口:ws://localhost:8000/ws/{client\_id}
消息类型:
{type: \"progress\", content: \"正在扫描端口...\"}{type: \"ai_token\", content: \"我决定\"} // 流式 token{type: \"result\", data: {...}}{type: \"complete\", report_url: \"...\"}
实现:api/websocket.py(5175 字节,不长)。
3.3 Elasticsearch 审计日志
为啥要审计?每一次 LLM 决策、每一次工具调用、每一次漏洞发现,都要记下来。这是合规需要,不是技术需要。
配置(config/settings.py:36-37):
elasticsearch_host: str = \"localhost\"elasticsearch_port: int = 9200
索引:pentest-logs-YYYY.MM.DD
降级设计:ES 不可用 → 写本地 JSON。Windows 上特别有用 — Docker 起 ES 在 Windows 上慢得离谱。
实现:security/audit\_logger.py:48-65 的 ping() 检测,失败就 fallback。
- 状态机设计
为啥要状态机?因为渗透测试是一个多阶段、长周期的任务,不能像普通 HTTP 请求那样一次性返回。
7 个阶段(state/pentest\_state.py:14-25):
class PentestPhase(str, Enum): INIT = \"init\" # 初始化 RECON = \"recon\" # 信息收集 VULN_SCAN = \"vuln_scan\" # 漏洞扫描 EXPLOIT = \"exploit\" # 漏洞利用 POST_EXPLOIT = \"post_exploit\" REPORT = \"report\" # 报告生成 COMPLETE = \"complete\" ABORTED = \"aborted\" # 中止
任务状态(state/pentest\_state.py:29-38):
class TaskState(str, Enum): PENDING = \"pending\" RUNNING = \"running\" WAITING_APPROVAL = \"waiting_approval\" # 等待高危操作审批 APPROVED = \"approved\" REJECTED = \"rejected\" SUCCESS = \"success\" FAILED = \"failed\" CANCELLED = \"cancelled\"
LangGraph 状态结构(state/pentest\_state.py:145-180):几十个字段,从 task\_id 到 vulnerabilities 到 markdown\_content,统统塞在 PentestState 这个 TypedDict 里流转。
- 关键设计原则
最后总结一下整个项目的设计原则,也是我希望小伙伴们看其他模块时能带上的视角:
重生之我是AI人:让 AI 替我挖洞 — 从一次甲方任务聊起
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论