前言

自ChatGPT问世以来,大语言模型发展以不可想象的速度发展,随时间流失,工业界也终于有了它的反应,智能体Agent应运而生,ClaudeCode、Cursor、Copilot、MiniMax、Trae、通义灵码等国内外各个产品被推出。

目前,各个垂直领域也闻风而动,安全领域也开始了定制化开发

  1. Shannon: 完全自主的AI工具,集成了NMAP和漏洞利用功能。

  2. WPeChatGPT: 基于与 ChatGPT 相同模型的 IDA 插件。

  3. IDA Pro MCP: 针对IDA开发的MCP服务。

  4. mcp-kali-server: Kali定制化MCP服务。

  5. Evasion SubAgents: 基于 Claude Code 的免杀技术研究与 Shellcode Loader 生成框架。

  6. red-run: Claude Code 的攻击性安全工具包。

  7. NexusAI: AI驱动的IDA Pro插件

  8. IDA Auto MCP: 无界面 IDA Pro MCP 服务器,让 AI 智能体自动打开、分析和查询多个二进制文件,无需手动操作 IDA GUI

  9. AI-Assisted Reverse Engineering with Ghidra: 逆向工具Ghidra的MCP服务

  10. METATRON: 基于Linux(Parrot OS)的本地LLM驱动的AI渗透测试助手

  11. DeepZero: DeepZero 是一个自动化、由人工智能驱动的框架,用于大规模发现 Windows 内核驱动中的零日漏洞。

  12. MCP Clients: 宝藏网站,里面可以搜集到各种不同的 mcp server

  13. MCP Server for WinDbg Crash Analysis: 一款模型上下文协议服务器,连接 AI 模型与 WinDbg,用于崩溃转储分析和远程调试。

  14. x64dbg MCP: 一台MCP服务器,可以桥接各种LLMS(Claude and Cursor testes)与x64dbg调试器,通过提示直接访问调试应用。

  15. ghidraMCP: ghidraMCP 是一个模型上下文协议服务器,允许大型语言模型自主逆向工程应用。它向MCP客户端展示了大量Ghidra核心功能的工具。

同样的,还有像腾讯安全众测智能渗透挑战赛,有很多项目可以参考


IDA Pro MCP

安装(这里权限问题,将插件安装到了C盘,不建议像我这样操作

D:\xx xx\IDA Professional 9.3\python-3.13.12>python -m pip install --no-build-isolation https://github.com/mrexodia/ida-pro-mcp/archive/refs/heads/main.zip
Collecting https://github.com/mrexodia/ida-pro-mcp/archive/refs/heads/main.zip
  Using cached https://github.com/mrexodia/ida-pro-mcp/archive/refs/heads/main.zip (1.5 MB)
  Preparing metadata (pyproject.toml) ... done
………………………………………………………………………………………………………………………………
Successfully installed ida-pro-mcp-2.0.0 idapro-0.0.7 tomli-w-1.2.0

D:\xx xx\IDA Professional 9.3\python-3.13.12>cd Scripts

D:\xx xx\IDA Professional 9.3\python-3.13.12\Scripts>ida-pro-mcp --install
Installed IDA Pro plugin (IDA restart required)
  loader: xx\AppData\Roaming\Hex-Rays\IDA Pro\plugins\ida_mcp.py
  package: xx\AppData\Roaming\Hex-Rays\IDA Pro\plugins\ida_mcp
[?25l[1mSelect transport mode:[0m
  (up/down: move, enter: confirm, esc: cancel)

  [36m>[0m Streamable HTTP (recommended)
    stdio
    SSE

同时ida需要手动启动MCP
在这里插入图片描述
查看配置,并将配置拷贝到客户端中(cursor、vscode插件cline、trae等)

D:\xx xx\IDA Professional 9.3\python-3.13.12\Scripts>ida-pro-mcp --config
[STDIO MCP CONFIGURATION]
{
  "mcpServers": {
    "ida-pro-mcp": {
      "command": "D:\\xx xx\\IDA Professional 9.3\\python-3.13.12\\python.exe",
      "args": [
        "D:\\xx xx\\IDA Professional 9.3\\python-3.13.12\\Lib\\site-packages\\ida_pro_mcp\\server.py",
        "--ida-rpc",
        "http://127.0.0.1:13337"
      ]
    }
  }
}
…………………………………………………………………………………………………………………………

这里使用vscode插件trae进行配置
在这里插入图片描述
开始分析,成功给出分析结果。体验可以节省大量时间
在这里插入图片描述


NexusAI

安装极其方便,默认即可
在这里插入图片描述
在窗口中,选择编辑 → NexusAI → 设置进行配置
在这里插入图片描述
然后快捷键Ctrl+Shift+K打开交互窗口(注:这里发现该交互窗口无AI回复,但实际上AI已完成操作,可从历史中查看日志,发现交互。但经过多轮测试,大概率是交互逻辑存在一些问题,未深入排查
在这里插入图片描述
实际体验有待提升(其实一般般,感觉不如IDA Pro MCP,不能说没用,但达不到好用


OpenClaw(题外话

龙虾,说实话,我感觉目前对我没有什么帮助(未来不知道,个人观点

但龙虾热的都快熟了,怎么也得亲自上手体验一番,才有自己的理解。

  1. 安装nodejs,默认选择最新版即可

在这里插入图片描述

  1. 安装git,默认即可

在这里插入图片描述

前提依赖安装完成

C:\Users\test>node -v
v24.14.1

C:\Users\test>git -v
git version 2.53.0.windows.2
  1. 安装openclaw

在这里插入图片描述

  1. 配置openclaw,配置时model、key、skill、bot全部建议跳过,后续慢慢配置即可

在这里插入图片描述
修改配置文件C:\Users\test\.openclaw\openclaw.json,补充以下信息(替换为自己的API key

  "models": {
    "providers": {
      "volcengine": {
        "baseUrl": "https://ark.cn-beijing.volces.com/api/v3",
        "apiKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "api": "openai-completions",
        "models": [
          {
            "id": "doubao-seed-2-0-pro-xxxxxx",
            "name": "Doubao-Seed-2.0-pro",
            "reasoning": true,
            "input": ["text"],
            "cost": {
              "input": 0.0032,
              "output": 0.016,
              "cacheRead": 0,
              "cacheWrite": 0
            },
            "contextWindow": 32768,
            "maxTokens": 4096
          } 
        ]
      }
    }
  },
  "agents": {
    "defaults": {
      "model": {
        "primary": "volcengine/doubao-seed-2-0-pro-xxxxxx"
      },
      "workspace": "C:\\Users\\test\\.openclaw\\workspace"
    }
  },
  1. 重启,执行openclaw gateway restart命令

在这里插入图片描述

CTF Web Agent

我们先来个简单的Agent练练手!

平时针对CTF竞赛中关于web题目,在之前,是通过拥有大量经验的专家来进行的。而大模型出来之后,所谓专家,则可以由LLM进行替代,假如我们替LLM装上一个简单的命令行终端,那么它就可以替代人类专家

数据集XBOW - 网络攻击工具熟练度基准测试,这个可以测试智能体的性能,或者使用BUUCTF等平台题目进行测试

配置沙箱

使用docker拉取镜像,给Agent提供沙箱用以执行命令

xxx@xxx:~$ docker pull ubuntu:24.04
24.04: Pulling from library/ubuntu
817807f3c64e: Pull complete
Digest: sha256:186072bba1b2f436cbb91ef2567abca677337cfc786c86e107d25b7072feef0c
Status: Downloaded newer image for ubuntu:24.04
docker.io/library/ubuntu:24.04
xxx@xxx:~$ docker pull kalilinux/kali-rolling
Using default tag: latest
latest: Pulling from kalilinux/kali-rolling
194d70789344: Pull complete
Digest: sha256:287cd5cfa409e258e9ec3661db4dff0bfbb45fc95734e82d3b270a0f749629ca
Status: Downloaded newer image for kalilinux/kali-rolling:latest
docker.io/kalilinux/kali-rolling:latest
xxx@xxx:~$ docker pull python:3.12-slim
3.12-slim: Pulling from library/python
ec781dee3f47: Pull complete
b1a20e2fae4c: Pull complete
a6d1911b36ac: Pull complete
e3c59d77c03e: Pull complete
Digest: sha256:3d5ed973e45820f5ba5e46bd065bd88b3a504ff0724d85980dcd05eab361fcf4
Status: Downloaded newer image for python:3.12-slim
docker.io/library/python:3.12-slim

欧克,首先我们配置kali的沙箱环境

xxx@xxx:~$ docker run -it --name my-kali -p 8888:8888 kalilinux/kali-rolling
┌──(root㉿6be6a794a792)-[/]
└─# apt update -y
Get:1 http://mirror.nyist.edu.cn/kali kali-rolling InRelease [34.0 kB]
Get:2 http://mirror.nyist.edu.cn/kali kali-rolling/non-free-firmware amd64 Packages [14.3 kB]
Get:3 http://mirror.nyist.edu.cn/kali kali-rolling/main amd64 Packages [21.0 MB]
Get:4 http://mirror.nyist.edu.cn/kali kali-rolling/contrib amd64 Packages [119 kB]
Get:5 http://mirror.nyist.edu.cn/kali kali-rolling/non-free amd64 Packages [186 kB]
Fetched 21.4 MB in 7s (3041 kB/s)
All packages are up to date.
……………………………………………………………………………………………………………………
自行安装工具
……………………………………………………………………………………………………………………

配置python沙盒环境

xxx@xxx:~$ docker run -it --name my-python -p 8889:8889 python:3.12-slim /bin/sh
root@e9f63784db96:/# pip install requests scapy beautifulsoup4 lxml pwntools pycryptodome flask
Requirement already satisfied: requests in /usr/local/lib/python3.12/site-packages (2.33.0)
Collecting scapy
  Downloading scapy-2.7.0-py3-none-any.whl.metadata (5.8 kB)
Collecting beautifulsoup4
  Downloading beautifulsoup4-4.14.3-py3-none-any.whl.metadata (3.8 kB)
……………………………………………………………………………………………………………………

编写程序

首先我们可以定义基类Agent

from core.config import Config
from abc import ABC, abstractmethod
from langchain.agents import create_agent
from langchain.agents.middleware import AgentMiddleware, AgentState, before_model, after_model
from langchain.tools import tool
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
from langgraph.runtime import Runtime
from typing import Any
from langchain.chat_models import init_chat_model
from langchain.agents.structured_output import ProviderStrategy
import os


LOG_FD = 1
# 日志记录(模型调用前)
@before_model
def log_before_model(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    name = "recv <- " + str(state["messages"][-1].name)
    first_message = name + ': ' + str(state["messages"][-1].content) + '\n'
    os.write(LOG_FD, first_message.encode('gb2312'))
    return None

# 日志记录(模型调用后)
@after_model()
def log_after_model(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    name = "send -> " + str(state["messages"][-2].name)
    last_message = name + ': ' + str(state["messages"][-1].content) + '\n'
    os.write(LOG_FD, last_message.encode('gb2312'))
    return None


class Agent(ABC):
    def __init__(self):
        self.config = Config()
        self.model_name = self.config.get('llm.default.model_name')
        self.api_key = self.config.get('llm.default.api_key')
        self.base_url = self.config.get('llm.default.base_url')
        self.middleware = [log_before_model, log_after_model]
        self.message = []
        self.tools = []
        self.max_step = 30
    

    def init_model(self):
        self.llm = init_chat_model(
            model_provider = "openai",
            model          = self.model_name,
            api_key        = self.api_key,
            base_url       = self.base_url,
        )

    def init_agent(self):
        if not hasattr(self, 'response_format'):
            self.response_format = None
        
        self.agent = create_agent(
            model           = self.llm,
            tools           = self.tools,
            middleware      = self.middleware,
            system_prompt   = SystemMessage(content=self.init_system_prompt()),
            response_format = self.response_format
        )

    def send(self) -> str:
        if not hasattr(self, 'agent'):
            self.init_agent()
        
        response = self.agent.invoke({"messages": self.message})
        return response['messages'][-1].content
    
    def run(self, task: str):
        self.message = []
        self.message.append(HumanMessage(content=task, name=self.name))
        content = self.send()
        return content

    @abstractmethod
    def init_system_prompt(self) -> str:
        """初始化系统提示"""
        pass

配置类Config

import yaml, os

class Config:
    def __init__(self, config_path=None):
        self.config_path = config_path or os.path.join(os.path.dirname(__file__), '../config.yml')
        self.config = self._load_config()
    
    def _load_config(self):
        with open(self.config_path, 'r', encoding='utf-8') as f:
            return yaml.safe_load(f)
    
    def get(self, key, default=None):
        keys = key.split('.')
        value = self.config
        for k in keys:
            if isinstance(value, dict) and k in value:
                value = value[k]
            else:
                return default
        return value

实际上一个demo是很容易实现的

from langchain_core.messages import HumanMessage
from core.tools.python_tool import run_python_command, run_system_command
from core.agent.main_agent import Agent

class CTFWebAgent(Agent):
    def __init__(self):
        super().__init__()
        self.name = 'CTFWebAgent'
        self.model_name = self.config.get('llm.ctf_web_agent.model_name') or self.model_name
        self.api_key = self.config.get('llm.ctf_web_agent.api_key') or self.api_key
        self.base_url = self.config.get('llm.ctf_web_agent.base_url') or self.base_url
        self.tools = self.tools + [run_python_command, run_system_command]
        self.init_model()
        self.init_agent()
       
    
    def init_system_prompt(self) -> str:
        system_prompt = """
你是一名专业的CTF Web安全自动化解题Agent,目标是高效完成CTF中的Web题目。请严格遵循以下步骤:

请按照以下逻辑执行解题操作:
1. 分析目标URL,识别可能的漏洞类型(如SQL注入、XSS、CSRF、文件包含、命令执行等)
2. 基于当前进度,生成下一步具体操作指令(包括Payload构造、工具调用、参数测试、代码审计目标等,直接使用提供的工具执行)
3. 若当前进度存在错误操作,给出修正后的操作方案

注意:
- 输出仅包含必要的操作指令,避免冗余
- 复杂漏洞分步骤给出可执行指令
- 每次操作前都需要先进行思考
- 工具执行后需要记录观察结果
- 基于观察结果调整后续策略
"""
        return system_prompt

工具实现

工具的实现,可谓是核心中的核心,它是智能体的双手。这里我们关于tool的实现,首先是沙箱kali中的server

import socket
import subprocess
import json
import threading


class KaliMCPServer:
    def __init__(self, host='0.0.0.0', port=8888):
        self.host = host
        self.port = port
        self.server_socket = None
        self.running = False
    
    def start(self): # 启动 MCP 服务器
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind((self.host, self.port))
        self.server_socket.listen(5)
        self.running = True
        print(f"Kali MCP Server start success, listen {self.host}:{self.port}")
        
        while self.running:
            try:
                client_socket, client_address = self.server_socket.accept()
                print(f"accept client {client_address}")
                # 为每个客户端创建一个线程处理
                client_thread = threading.Thread(
                    target=self.handle_client, 
                    args=(client_socket,)
                )
                client_thread.daemon = True
                client_thread.start()
            except socket.error as e:
                if not self.running:
                    break
                print(f"server error: {e}")
    
    def handle_client(self, client_socket): # 处理客户端连接
        try:
            # 接收客户端发送的命令
            data = client_socket.recv(1024)
            if not data:
                return
            
            try: # 解析命令
                request = json.loads(data.decode('utf-8'))
                command = request.get('command')
                if not command:
                    response = {
                        'success': False,
                        'message': 'missing command parameter'
                    }
                else:
                    result = self.execute_command(command)
                    response = {
                        'success': True,
                        'result': result
                    }
            except json.JSONDecodeError:
                response = {
                    'success': False,
                    'message': 'invalid JSON format'
                }
            except Exception as e:
                response = {
                    'success': False,
                    'message': f'handle command error: {str(e)}'
                }
            
            client_socket.sendall(json.dumps(response).encode('utf-8'))
        except socket.error as e:
            print(f"client error handle: {e}")
        finally:
            client_socket.close()
    
    def execute_command(self, command):
        try:
            result = subprocess.run(
                command, 
                shell=True, 
                capture_output=True, 
                text=True, 
                timeout=30
            )
            return {
                'stdout': result.stdout,
                'stderr': result.stderr,
                'returncode': result.returncode
            }
        except subprocess.TimeoutExpired:
            return {
                'stdout': '',
                'stderr': 'command execute timeout',
                'returncode': -1
            }
        except Exception as e:
            return {
                'stdout': '',
                'stderr': f'execute command error: {str(e)}',
                'returncode': -1
            }
    
    def stop(self): # 停止 MCP 服务器
        self.running = False
        if self.server_socket:
            self.server_socket.close()
        print("Kali MCP Server stop success")


if __name__ == "__main__":
    server = KaliMCPServer()
    try:
        server.start()
    except KeyboardInterrupt:
        server.stop()

对接到Agent的客户端

from langchain.tools import tool
import socket
import json


class KaliToolClient:
    def __init__(self, host='localhost', port=8888, timeout=30):
        self.host = host
        self.port = port
        self.timeout = timeout
    
    def execute_command(self, command):
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.settimeout(self.timeout)
                s.connect((self.host, self.port))

                request = json.dumps({'command': command})
                s.sendall(request.encode('utf-8'))

                response = b''
                while True:
                    data = s.recv(1024)
                    if not data:
                        break
                    response += data
                
                if not response:
                    return {'success': False, 'message': 'mcp server execute error!'}
                
                result = json.loads(response.decode('utf-8'))
                print(f"response: {result}")
                return result
                
        except Exception as e:
            return {'success': False, 'message': f'mcp server execute error: {str(e)}'}


kali_client = KaliToolClient()


@tool
def run_kali_command(command: str) -> str:
    """于 Kali Linux 中执行命令
    
    Args:
        command: 于 Kali Linux 中执行的命令
        
    Returns:
        str: 命令执行结果
    """
    result = kali_client.execute_command(command)
    
    if result.get('success'):
        command_result = result.get('result', {})
        stdout = command_result.get('stdout', '')
        stderr = command_result.get('stderr', '')
        output = stdout
        if stderr:
            output += stderr
        return output.strip()
    else:
        return result.get('message', 'mcp server execute error!')
    

@tool
def list_kali_command() -> None:
    """
    环境 Kali Linux 中额外可用的工具列表:
    1. fscan      内网扫描、端口扫描
    2. nuclei     自动化漏洞扫描
    3. sqlmap     SQL注入检测
    4. python3    Python执行环境
    5. nc         反弹shell、端口监听
    6. ffuf       目录爆破、FUZZ测试
    """
    pass

上面这种方法其实并不推荐,但也算是一种方案

同样的,我们也可以采用Kali官方MCP服务 mcp-kali-server对接到我们的智能体中,不过经过测试,好像这个并不完善

接下来,我们采用官方mcp库来编写python mcp server,这样就简单多了

#!/usr/bin/env python3
import subprocess
import asyncio
import argparse
from typing import Any, Literal

async def execute_command(command: str, is_system_command: bool = False) -> dict[str, Any]:
    """执行命令的内部函数"""
    try:
        if is_system_command:
            result = await asyncio.create_subprocess_shell(
                command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            try:
                stdout, stderr = await asyncio.wait_for(
                    result.communicate(),
                    timeout=30
                )
                return {
                    'stdout': stdout.decode('utf-8', errors='replace'),
                    'stderr': stderr.decode('utf-8', errors='replace'),
                    'returncode': result.returncode
                }
            except asyncio.TimeoutError:
                result.kill()
                await result.wait()
                return {
                    'stdout': '',
                    'stderr': 'command execute timeout',
                    'returncode': -1
                }
        else:
            result = await asyncio.create_subprocess_exec(
                'python', '-c', command,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            try:
                stdout, stderr = await asyncio.wait_for(
                    result.communicate(),
                    timeout=30
                )
                return {
                    'stdout': stdout.decode('utf-8', errors='replace'),
                    'stderr': stderr.decode('utf-8', errors='replace'),
                    'returncode': result.returncode
                }
            except asyncio.TimeoutError:
                result.kill()
                await result.wait()
                return {
                    'stdout': '',
                    'stderr': 'command execute timeout',
                    'returncode': -1
                }
    except Exception as e:
        return {
            'stdout': '',
            'stderr': f'execute command error: {str(e)}',
            'returncode': -1
        }
    
# ========== 启动 MCP 服务 ==========
def run_mcp_server(transport: Literal["stdio", "sse", "streamable-http"] = "stdio", host: str = "0.0.0.0", port: int = 8889):
    try:
        from mcp.server.fastmcp import FastMCP
        app = FastMCP("python-mcp-server", host=host, port=port)

        @app.tool()
        async def run_python_command(code: str) -> str:
            """于 Python 环境中执行 Python 代码

            Args:
                code: 要执行的 Python 代码
            Returns:
                str: 代码执行结果
            """
            result = await execute_command(code, is_system_command=False)
            return result['stdout'] + result['stderr']
        
        @app.tool()
        async def run_system_command(command: str) -> str:
            """于 Python 环境中执行系统命令

            Args:
                command: 要执行的系统命令
            Returns:
                str: 命令执行结果
            """
            result = await execute_command(command, is_system_command=True)
            return result['stdout'] + result['stderr']
        app.run(transport=transport)      
    except ImportError:
        print("Error: FastMCP create failed for MCP server")
        exit(1)

def main():
    """主函数"""
    parser = argparse.ArgumentParser(description="Python MCP Server")
    parser.add_argument(
        "--stdio",
        action="store_true",
        help="Run in stdio mode (default: HTTP/SSE mode)"
    )
    parser.add_argument(
        "--host",
        default="0.0.0.0",
        help="Host to listen on (HTTP/SSE mode only)"
    )
    parser.add_argument(
        "--port",
        type=int,
        default=8889,
        help="Port to listen on (HTTP/SSE mode only)"
    )

    args = parser.parse_args()
    if args.stdio:
        transport = "stdio"
    else:
        print(f"Starting Python MCP Server on http://{args.host}:{args.port}")
        transport = "streamable-http"
    try:
        run_mcp_server(transport=transport, host=args.host, port=args.port)
    except KeyboardInterrupt:
        print(f"Error: MCP server stopped by user")
        exit(0)

if __name__ == "__main__":
    main()

客户端也极其简单,这里给出了同步方案与异步方案

from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_core.tools import BaseTool
import asyncio
from typing import List, Tuple

async def get_python_tools_async(
    host: str = '172.28.154.126',
    port: int = 8889
) -> Tuple[List[BaseTool], MultiServerMCPClient]:
    client = MultiServerMCPClient({
        "python": {
            "transport": "http",
            "url": f"http://{host}:{port}/mcp"
        }
    })
    tools = await client.get_tools()
    return tools, client

def get_python_tools_sync(
    host: str = '172.28.154.126',
    port: int = 8889
) -> Tuple[List[BaseTool], MultiServerMCPClient]:
    return asyncio.run(get_python_tools_async(host, port))

sync_tools, sync_client = get_python_tools_sync()

if __name__ == "__main__":
    tools, client = asyncio.run(get_python_tools_async(port=9000))
    print(tools)

最终汇总,编写一个ctf web demo

from langchain_core.messages import HumanMessage
from core.tools.python_tool import sync_tools
from core.tools.kali_tool import run_kali_command, list_kali_command
from core.agent.main_agent import Agent

class CTFWebAgent(Agent):
    def __init__(self):
        super().__init__()
        self.name = 'CTFWebAgent'
        self.model_name = self.config.get('llm.ctf_web_agent.model_name') or self.model_name
        self.api_key = self.config.get('llm.ctf_web_agent.api_key') or self.api_key
        self.base_url = self.config.get('llm.ctf_web_agent.base_url') or self.base_url
        self.tools = self.tools + sync_tools + [run_kali_command, list_kali_command]
        self.init_model()
        self.init_agent()
    
    async def arun(self, task: str):
        self.message = []
        self.message.append(HumanMessage(content=task, name=self.name))
        response = await self.agent.ainvoke({"messages": self.message})
        return response['messages'][-1].content
    
    def init_system_prompt(self) -> str:
        system_prompt = """
你是一名专业的CTF Web安全自动化解题Agent,目标是高效完成CTF中的Web题目。请严格遵循以下步骤:

请按照以下逻辑执行解题操作:
1. 分析目标URL,识别可能的漏洞类型(如SQL注入、XSS、CSRF、文件包含、命令执行等)
2. 基于当前进度,生成下一步具体操作指令(包括Payload构造、工具调用、参数测试、代码审计目标等,直接使用提供的工具执行)
3. 若当前进度存在错误操作,给出修正后的操作方案

注意:
- 输出仅包含必要的操作指令,避免冗余
- 复杂漏洞分步骤给出可执行指令
- 每次操作前都需要先进行思考
- 工具执行后需要记录观察结果
- 基于观察结果调整后续策略
"""
        return system_prompt

这个demo可以通过一些单线条漏洞的测试,但是经过深入测试,发现在一些复杂组合场景中(比如渗透,像渗透则需要Multi-Agent来进行工作,且需要对细节进行适配),这种简单的架构仍然不行

不过这里就不再多编写了,可以在此基础上引入多智能体编排,重试机制等一些措施来提升能力

CTF Pwn Agent

同样的,这里给出关于针对Pwn环境的沙箱,通过MCP协议操控,服务端代码

#!/usr/bin/env python3
import subprocess
import asyncio
import argparse
from typing import Any, Literal

async def execute_command(command: str) -> dict[str, Any]:
    """执行命令的内部函数"""
    try:
        result = await asyncio.create_subprocess_shell(
            command,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        try:
            stdout, stderr = await asyncio.wait_for(
                result.communicate(),
                timeout=30
            )
            return {
                'stdout': stdout.decode('utf-8', errors='replace'),
                'stderr': stderr.decode('utf-8', errors='replace'),
                'returncode': result.returncode
            }
        except asyncio.TimeoutError:
            result.kill()
            await result.wait()
            return {
                'stdout': '',
                'stderr': 'command execute timeout',
                'returncode': -1
            }
    except Exception as e:
        return {
            'stdout': '',
            'stderr': f'execute command error: {str(e)}',
            'returncode': -1
        }

def interact_with_gdb():
    gdb_process = subprocess.Popen(
        ['gdb', '--interpreter=mi'],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        text=True
    )
    while True:
        output = gdb_process.stdout.readline()
        if not output:
            break
        if output.strip() == "(gdb)" or output.strip().startswith("$"):
            break
    return gdb_process

gdb_process = None
def execute_gdb_shell(user_input : str) -> str:
    global gdb_process
    if gdb_process is None:
        gdb_process = interact_with_gdb()
    try:
        if user_input.lower().strip() in ["quit", "exit", "q"]:
            gdb_process.stdin.write("quit\n")
            gdb_process.stdin.flush()
            buf_size = ""
            while True:
                output = gdb_process.stdout.readline()
                if not output:
                    break
                buf_size += output
            gdb_process.wait()
            gdb_process = None
            return buf_size.rstrip()
        
        gdb_process.stdin.write(user_input + "\n")
        gdb_process.stdin.flush()
        buf_size = ""
        while True:
            output = gdb_process.stdout.readline()
            if not output:
                break
            buf_size += output
            if output.strip() == "(gdb)" or output.strip().startswith("$"):
                break
        return buf_size.rstrip()
    except Exception as e:
        if gdb_process and gdb_process.poll() is None:
            gdb_process.terminate()
            gdb_process.wait()
        gdb_process = None
        return f"gdb error: {str(e)}"

# ========== 启动 MCP 服务 ==========

def run_mcp_server(transport: Literal["stdio", "sse", "streamable-http"] = "stdio", host: str = "0.0.0.0", port: int = 8890):
    try:
        from mcp.server.fastmcp import FastMCP
        app = FastMCP("ubuntu-mcp-server", host=host, port=port)

        @app.tool()
        async def run_ubuntu_command(command: str) -> str:
            """于 Ubuntu Linux 中执行命令

            Args:
                command: 于 Ubuntu Linux 中执行的命令
            Returns:
                str: 命令执行结果
            """
            result = await execute_command(command)
            return result['stdout'] + result['stderr']

        @app.tool()
        async def list_commands() -> None:
            """
            1. readelf
            2. checksec
            3. file
            4. objdump
            5. nc
            6. strings
            7. radare2
            """
            pass

        @app.tool()
        async def execute_gdb(command: str) -> str:
            """于交互式会话中执行 GDB 命令

            Args:
                command: GDB 命令
            Returns:
                str: GDB 命令执行结果
            """
            try:
                user_input = command# input("gdb> ")
                output = execute_gdb_shell(user_input)
                return output
            except Exception as e:
                return f"execute_gdb tool error: {str(e)}"

        app.run(transport=transport)
    except ImportError:
        print("Error: FastMCP create failed for MCP server")
        exit(1)

def main():
    """主函数"""
    parser = argparse.ArgumentParser(description="Ubuntu MCP Server")
    parser.add_argument(
        "--stdio",
        action="store_true",
        help="Run in stdio mode (default: HTTP/SSE mode)"
    )
    parser.add_argument(
        "--host",
        default="0.0.0.0",
        help="Host to listen on (HTTP/SSE mode only)"
    )
    parser.add_argument(
        "--port",
        type=int,
        default=8890,
        help="Port to listen on (HTTP/SSE mode only)"
    )

    args = parser.parse_args()
    if args.stdio:
        transport = "stdio"
    else:
        print(f"Starting Ubuntu MCP Server on http://{args.host}:{args.port}")
        transport = "streamable-http"
    try:
        run_mcp_server(transport=transport, host=args.host, port=args.port)
    except KeyboardInterrupt:
        print(f"Error: MCP server stopped by user")
        exit(0)


if __name__ == "__main__":
    main()

接下来就是客户端代码

from langchain.tools import tool
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_core.tools import BaseTool
import asyncio
from typing import List, Tuple

async def get_ubuntu_tools_async(
    host: str = 'localhost',
    port: int = 8890
) -> Tuple[List[BaseTool], MultiServerMCPClient]:
    client = MultiServerMCPClient({
        "ubuntu": {
            "transport": "http",
            "url": f"http://{host}:{port}/mcp"
        }
    })

    tools = await client.get_tools()
    return tools, client

def get_ubuntu_tools_sync(
    host: str = 'localhost',
    port: int = 8890
) -> Tuple[List[BaseTool], MultiServerMCPClient]:
    return asyncio.run(get_ubuntu_tools_async(host, port))

# 全局工具实例
sync_ubuntu_tools, sync_ubuntu_client = get_ubuntu_tools_sync()


if __name__ == "__main__":
    tools, client = asyncio.run(get_ubuntu_tools_async())
    print(tools)

以及我们定义的prompt

from langchain_core.messages import HumanMessage
from core.tools.python_tool import sync_tools
from core.tools.ubuntu_tool import sync_ubuntu_tools
from core.agent.main_agent import Agent
from langchain.agents.middleware import wrap_tool_call

@wrap_tool_call
async def log_tool_call(request, handler):
    tool_name, command = "", ""
    if hasattr(request, 'tool_call'):
        tool_name = request.tool_call["name"]
        if hasattr(request.tool_call, "args") and hasattr(request.tool_call["args"], "command"):
            command = request.tool_call["args"]["command"]
    print(f"tool name: {tool_name} , args: {command}", end=" ")
    res = await handler(request)
    print(f"return: {res.content[0]}")
    return res

class CTFPwnAgent(Agent):
    def __init__(self):
        super().__init__()
        self.name = 'CTFPwnAgent'
        self.model_name = self.config.get('llm.ctf_pwn_agent.model_name') or self.model_name
        self.api_key = self.config.get('llm.ctf_pwn_agent.api_key') or self.api_key
        self.base_url = self.config.get('llm.ctf_pwn_agent.base_url') or self.base_url
        self.tools = self.tools + sync_tools + sync_ubuntu_tools
        self.middleware = self.middleware + [log_tool_call]
        self.init_model()
        self.init_agent()

    async def arun(self, task: str):
        self.message = []
        self.message.append(HumanMessage(content=task, name=self.name))
        response = await self.agent.ainvoke({"messages": self.message})
        return response['messages'][-1].content       
    
    def init_system_prompt(self) -> str:
        system_prompt = """
你是一名专业的CTF Pwn题目安全自动化解题Agent,目标是高效完成CTF中的Pwn题目。请严格遵循以下步骤:

请按照以下逻辑执行Pwn题目解题操作:
1. 分析目标程序(如ELF、PE等二进制文件)或远程服务,识别可能的Pwn漏洞类型(如栈溢出、堆溢出、格式化字符串漏洞、UAF、ROP、ret2libc、ret2syscall、整数溢出、use-after-free、double free等)
2. 基于当前进度,生成下一步具体操作指令(包括Payload构造、工具调用(如checksec、gdb、pwntools、IDA Pro、Ghidra等)、参数测试、代码审计目标等,直接使用提供的工具执行)
3. 若当前进度存在错误操作,给出修正后的操作方案

注意:
- 输出仅包含必要的操作指令,避免冗余
- 复杂Pwn漏洞分步骤给出可执行指令
- 每次操作前都需要先进行思考
- 工具执行后需要记录相关观察结果
- 基于观察结果调整后续解题策略
"""
        return system_prompt

Driver Analyse Agent

安装ida auto mcp服务,作为我们的工具提供给智能体使用

C:\Users\xxx\Downloads\ida-auto-mcp>pip install -e .
Obtaining file:///C:/Users/xxx/Downloads/ida-auto-mcp
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Preparing editable metadata (pyproject.toml) ... done
Building wheels for collected packages: ida-auto-mcp
  Building editable for ida-auto-mcp (pyproject.toml) ... done
  Created wheel for ida-auto-mcp: filename=ida_auto_mcp-1.0.0-0.editable-py3-none-any.whl size=7640 sha256=a59aacbaac2a1bd09bcf056577102c28d807205a06a34d747a6e205daf1b6402
  Stored in directory: C:\Users\xxx\AppData\Local\Temp\pip-ephem-wheel-cache-qw4pgf3z\wheels\dc\72\ed\47b21cd68bffbd9ed9a1e64716d63aa4346e163a7a33f1d6eb
Successfully built ida-auto-mcp
Installing collected packages: ida-auto-mcp
Successfully installed ida-auto-mcp-1.0.0

安装ida python

C:\Users\xxx\Downloads\ida-auto-mcp>pip install "D:\Program Files\IDA Professional 9.3\idalib\python"
Processing d:\program files\ida professional 9.3\idalib\python
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: idapro
  Building wheel for idapro (pyproject.toml) ... done
  Created wheel for idapro: filename=idapro-0.0.2-py3-none-any.whl size=4290 sha256=0b967ddf3547ae16286bffd68933bf866114ec029e97b6fb4a3c84c177d9a6e3
  Stored in directory: C:\Users\xxx\AppData\Local\Temp\pip-ephem-wheel-cache-nyd8vj91\wheels\f5\ad\e4\6202892ab27edd68456d3b2765f625d3d08773be959ffa0d19
Successfully built idapro
Installing collected packages: idapro
  Attempting uninstall: idapro
    Found existing installation: idapro 0.0.2
    Uninstalling idapro-0.0.2:
      Successfully uninstalled idapro-0.0.2
Successfully installed idapro-0.0.2

启动mcp服务,正常启动

(py312) C:\Users\xxx\Downloads\ida-auto-mcp>python -m ida_auto_mcp --ida-dir "D:\Program Files\IDA Professional 9.3"

场景:

在已经搭建好的driver analyse自动化驱动分析平台(原理是通过符号执行判断漏洞位置)所生成的漏洞报告,通常需要人为验证判断,当大批量的驱动报告需要分析,我们采用LLM来辅助验证并给出poc,是一个正确的决定

后续我们可以将智能化拼接到自动化分析平台尾部,全流程无人为干预,这将节省人力成本,一次开发,终生受益

规划:

我们需要处理大批量的驱动文件和对应漏洞报告,最简单的方式是给执行体添加ida工具即可

这里的规划是,编排 -> 执行体 -> 汇总。简单的工作流,三个智能体足以(甚至一个智能体就够了,引入多智能体将不可避免的面对一个问题,重复性,最令人担心的是,这很可能是负向优化)

开发:

  1. 这里将ida auto mcp作为智能体的工具,这里需要注意,必须将transport设置为"http",设置为"stdio"因为其他插件冲突导致运行报错
# ========== IDA Auto Pro 客户端 ==========
class IdaAutoProClient:
    def __init__(self):
        self.shell = None
        self.client = None

    async def initialize(self):
        self.mcp_server_start()
        await asyncio.sleep(1)
        self.client = MultiServerMCPClient({
            "ida": {
                "transport": "http",
                "url": "http://127.0.0.1:8765/mcp"
            }
        })

    def mcp_server_start(self):
        python_path = r"python.exe path"
        self.shell = subprocess.Popen(
            [
                python_path,
                "-m", "ida_auto_mcp",
                "--transport", "http",
                "--port", "8765",
                "--ida-dir", r"IDA Professional 9.3 path"
            ],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )

    def mcp_server_stop(self):
        if self.shell:
            self.shell.terminate()
            self.shell.wait()

    async def get_tools(self):
        if not self.client:
            raise Exception("please await initialize() first")
        return await self.client.get_tools()

    async def close(self):
        if self.client:
            await self.client.aclose()
        self.mcp_server_stop()
  1. 接下来,编写ExecutionAgent智能体,用于分析单个任务。这里发现在极少数情况下,调用工具的参数会被污染导致整个程序崩溃,可以在tool_after_handle做具体限制
# ========== ExecutionAgent ==========
@before_model
def tool_before_handle(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    #print("tool_before_handle args:\n", state["messages"][-1].content)
    pass

@after_model
def tool_after_handle(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
    # print("tool_after_handle args:\n", state["messages"][-1].tool_calls)
    for tool_call in state["messages"][-1].tool_calls: # 处理函数调用
        pass

class ExecutionAgent(Agent):
    def __init__(self, tools: List[BaseTool] = None):
        super().__init__()
        self.name = "ExecutionAgent"
        self.tools = tools or []
        self.middleware.append(tool_before_handle)
        self.middleware.append(tool_after_handle)
        self.init_model()
        self.init_agent()
    
    async def run(self, task: str) -> str:
        self.message = []
        self.message.append(AIMessage(content=task, name=self.name))
        response = await self.agent.ainvoke({"messages": self.message})
        content = response['messages'][-1].content
        return content

    def init_system_prompt(self) -> str:
        """初始化系统提示"""
        return """
你是“驱动漏洞验证与POC开发专家”,核心目标是基于用户提供的驱动文件和漏洞报告,完成漏洞存在性验证、可利用性分析,并为可利用漏洞输出函数调用链条、函数伪代码摘要及最小化POC伪代码。

# 任务拆解:
1. **漏洞存在性验证**:使用IDA工具分析驱动文件,对照漏洞报告中的漏洞描述(如漏洞类型、涉及函数、触发条件等),判断漏洞是否真实存在。若不存在,直接排除该漏洞。
2. **可利用性分析**:针对存在的漏洞,评估是否具备实际利用条件(如是否存在权限限制绕过、是否能控制关键内存地址、是否无有效防护机制等)。若不可利用,排除该漏洞。
3. **可利用漏洞输出**:对通过前两步的漏洞,输出以下内容:
   - 函数调用链条:清晰列出从触发点到漏洞核心函数的调用路径(如`用户输入→IOCTL调用→驱动处理函数X→漏洞函数Y`)
   - 函数伪代码摘要:提炼漏洞核心函数的关键代码
   - 最小化POC伪代码:仅保留关键步骤(包括payload构造、API调用逻辑,重复性基础代码无需编写),示例框架如下
     ```c
     // POC伪代码示例
     HANDLE hDriver = CreateFileA("\\\\.\\TargetDriver", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
     char payload[0x1000]; // 构造溢出/越界等恶意payload
     memset(payload, 'A', sizeof(payload));
     DWORD bytesReturned;
     DeviceIoControl(hDriver, 0x12345678, payload, sizeof(payload), NULL, 0, &bytesReturned, NULL);
     CloseHandle(hDriver);
     ```

# 约束规则
- **必做**:所有分析需基于IDA对驱动文件的逆向结果,不可主观臆断;POC伪代码需聚焦核心利用逻辑,避免冗余
- **禁止**:不可虚构漏洞存在性或可利用性;不可输出与漏洞无关的函数或代码
- **注意**:如果不存在漏洞报告,则自行分析驱动文件,判断是否存在可利用漏洞

# 输入输出规范
- **输入**:需明确驱动文件路径、漏洞报告JSON文件路径
- **输出**:按“漏洞ID→存在性验证结果→可利用性分析→函数调用链条→伪代码摘要→POC伪代码”的结构组织,若无可利用漏洞,需明确说明“未发现可利用的驱动漏洞”。
"""
  1. 接下来,编写ReportAgent智能体,用于汇总所有任务结果,并给出报告
# ========== ReportAgent ==========
@tool
def write_mdown_report(path: str, report: str) -> str:
    """将Markdown格式的漏洞分析报告写入文件

    Args:
        path: 目标文件路径
        report: 漏洞分析报告内容
    Returns:
        str: 操作结果
    """
    with open(path, "w") as f:
        result = f.write(report)
        if result == len(report):
            return "success"
        else:
            return "failed"
    return "error"

class ReportAgent(Agent):
    def __init__(self):
        super().__init__()
        self.name = "ReportAgent"
        self.tools = [write_mdown_report]
        self.init_model()
        self.init_agent()
    
    def init_system_prompt(self) -> str:
        return """
# 角色设定
你是漏洞分析报告整理专家,核心职责是将所有漏洞分析内容整合为结构清晰、内容完整的Markdown格式报告。

# 核心规则
## 必做事项
1. 完整性检查:必须覆盖所有输入的Agent输出内容,不得遗漏任何漏洞ID及对应的分析信息
2. 结构化整合:严格按照“漏洞ID→存在性验证结果→可利用性分析→函数调用链条→伪代码摘要→POC伪代码”的固定顺序组织每个漏洞的信息
3. 异常处理:若某漏洞无可利用性,需在对应位置明确标注“未发现可利用的驱动漏洞”
4. 格式规范:输出必须为Markdown格式,使用二级标题(##)标注每个漏洞模块,子项使用三级标题(###)或列表呈现。

## 约束条件
1. 禁止篡改原始Agent输出的核心结论(如存在性验证结果、可利用性判断)
2. 禁止添加未经Agent输出确认的主观分析内容
3. 若多个Agent输出存在重复漏洞ID,需合并相同ID的信息,优先保留详细程度更高的分析内容
4. 若Agent输出格式混乱,需先梳理关键信息再按要求整合,不得直接复制杂乱内容。

# 输入处理
1. 读取顺序:按输入中Agent输出的先后顺序逐一处理每个漏洞条目
2. 异常处理:若某Agent输出缺少某字段(如无POC伪代码),使用pass占位,不中断整合流程。

# 执行流程
1. 信息提取:遍历所有Agent输出内容,按Agent分析驱动文件分组,提取每个对应的存在性验证结果、可利用性分析、函数调用链条、伪代码摘要、POC伪代码
2. 内容整合:对每个漏洞ID,按照“漏洞ID→存在性验证结果→可利用性分析→函数调用链条→伪代码摘要→POC伪代码”的结构拼接信息,若无可利用性则替换为指定说明
3. 格式优化:使用Markdown二级标题标注每个漏洞模块,子项用三级标题或有序列表呈现,确保层次清晰
4. 最终校验:检查是否所有Agent输出均已整合,格式是否符合要求,无遗漏或错误后输出报告

# 输出规范
1. 结构框架:
   - 报告标题:# 驱动名称:[驱动文件名]
   - 漏洞分析模块:## 漏洞ID: [具体ID]
     - ### 存在性验证结果:[具体结果]
     - ### 可利用性分析:[具体分析/未发现可利用的驱动漏洞]
     - ### 函数调用链条:[具体链条]
     - ### 伪代码摘要:[具体摘要]
     - ### POC伪代码:[具体代码/pass]
2. 标签使用:仅使用Markdown原生标签(标题、列表、代码块)
3. 语言风格:正式、客观,避免口语化表达
4. 字数限制:每个漏洞模块字数控制字数,POC伪代码可单独占块不受字数限制。
"""
  1. 接下来,编写OrchestrationAgent智能体,用于编排任务,下发给具体执行智能体
# ========== OrchestrationAgent ==========
@tool
def dir(path: str) -> str:
    """执行dir命令

    Args:
        path: 目标文件夹路径
    Returns:
        str: 命令执行结果
    """
    import subprocess
    result = subprocess.run(f"dir {path}", shell=True, capture_output=True, text=True)
    return result.stdout or result.stderr
class OrchestrationAgent(Agent):
    """编排Agent,统筹大局,管理多个任务"""
    
    def __init__(self):
        super().__init__()
        self.name = "OrchestrationAgent"
        self.tools = self.tools + [dir]
        self.init_model()
        self.init_agent()
    
    def init_system_prompt(self) -> str:
        """初始化系统提示"""
        return """
# 身份定位
你是**驱动-报告关联编排专员**,核心职责是读取目标文件夹内下的sys驱动文件与json报告文件,完成文件关联匹配后生成可执行的任务清单。

# 规则边界
## 必做动作
- 当检测到sys驱动与json报告文件名存在相同标识(如设备ID、版本号)时,必须建立一一对应关系

## 约束条件
- 禁止关联文件名无匹配标识的sys驱动与json报告
- 若文件夹内存在同一驱动的不同版本,仅保留最新修改时间的驱动文件,如example_1.sys与example_1.json,example_2.sys与example_2.json,仅保留较新版本的驱动文件与报告文件。

## 输出规范
需输出JSON格式,每项任务需包含以下2个键,且文件对统一按指定格式填写:
1. "sys":字符类型,驱动绝对路径+驱动名
2. "report":字符类型,报告绝对路径+报告名
示例:
[
    {
        "sys": "C/Windows/System32/drivers/example1.sys",
        "report": "C/Windows/System32/drivers/example1.json"
    },
    {
        "sys": "C/Windows/System32/drivers/etc/hiworld.sys",
        "report": "C/Windows/System32/drivers/etc/hiworld.json"
    }
]
"""
  1. 最终封装在DriverAnalyseAgent智能体中,这里构建了一个简单的图结构
# 定义状态结构
class SecurityAnalysisState(TypedDict):
    overall_task: str                # 总任务
    sub_tasks: List[str]             # 子任务列表
    execution_agent: ExecutionAgent  # 执行Agent
    task_results: List[str]          # 任务结果
    success: bool                    # 是否成功
    report: str                      # 生成的报告内容


# 定义节点函数
def decompose_task_node(state, orchestration_agent: OrchestrationAgent):
    """分解任务节点"""
    result =orchestration_agent.run(state["overall_task"])
    import ast
    state["sub_tasks"] = ast.literal_eval(result)
    return state

async def execute_task_node(state):
    """执行任务"""

    for task_info in state["sub_tasks"]:
        with open(task_info["report"], "r") as f:
            report = f.read()
        tmp_task = {
            "sys": task_info["sys"],
            "report": report
        }
        result = await state["execution_agent"].run(str(tmp_task))
        state["task_results"].append(result)
    return state

def generate_report_node(state, report_agent: ReportAgent):
    """生成报告节点"""
    state["report"] = report_agent.run(", ".join(state["task_results"]))
    return state


class DriverAnalyseAgent:
    """驱动分析Agent,整合编排、执行和报告功能"""
    
    def __init__(self):
        self.orchestration_agent = OrchestrationAgent()
        self.ida_tools = IdaAutoProClient()
        self.execution_agent = None
        self.report_agent = ReportAgent()

        
    
    async def initialize(self):
        await self.ida_tools.initialize()
        tools = await self.ida_tools.get_tools()
        self.execution_agent = ExecutionAgent(tools)

        self.graph = self._build_graph()

    def _build_graph(self):
        """构建LangGraph工作流"""
        from langgraph.graph import StateGraph, END
        workflow = StateGraph(SecurityAnalysisState) # 创建状态图
        
        # 添加节点
        workflow.add_node("decompose_task", lambda state: decompose_task_node(state, self.orchestration_agent))
        workflow.add_node("execute_task", execute_task_node)
        workflow.add_node("generate_report", lambda state: generate_report_node(state, self.report_agent))
        
        # 添加边
        workflow.set_entry_point("decompose_task") # workflow.add_edge(START, "decompose_task")
        workflow.add_edge("decompose_task", "execute_task")
        workflow.add_edge("execute_task", "generate_report")
        workflow.add_edge("generate_report", END)

        return workflow.compile() # 编译图
    
    async def run(self, task: str) -> Dict[str, Any]:
        """运行分析任务"""
        if not hasattr(self, "graph"):
            await self.initialize()
        try:
            # 初始化状态
            initial_state: SecurityAnalysisState = {
                "overall_task": task,
                "sub_tasks": [],
                "execution_agent": self.execution_agent,
                "task_results": [],
                "success": True,
                "report": ""
            }
            
            # 执行图
            result = await self.graph.ainvoke(initial_state)
            return result
        except Exception as e:
            return {
                "overall_task": task,
                "sub_tasks": [],
                "task_results": [],
                "success": False,
                "report": str(e)
            }
  1. 测试测试
async def main():
    d = DriverAnalyseAgent()
    await d.initialize()
    task = "C:\\work" # 该目录下是sys驱动文件,以及漏洞报告文件
    r = await d.run(task)
    print(r)


if __name__ == "__main__":
    asyncio.run(main())
  1. 补充

这里经过大量测试,发现有很大优化空间,举例说明

  • 自动化测试平台原理是通过符号执行获取漏洞,漏洞报告相当于Agent的先验知识,会导致Agent陷入先验知识中,需要纠偏
  • 提示词仍然有较大优化空间,如,可以加入分析驱动权限校验部分(这部分必须加入,否则我们将会得到很多无法利用的漏洞)

结语

上面还仅仅只是demo,还有很多需要我们去学习,尤其现在AI发展速度极快,所以更应该去追踪前沿的消息,实时跟踪更新自己的知识库。

虽然AI与人类的相遇,就像站台上火车越过的一瞬,但是在这一刻,仍然希望再多看两眼。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐