首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 归档 标签 关于

从提示越狱到底层权限失守:AstrBot 子代理(Handoff)越权 0day 挖掘与 RCE 武器化实战

摘要

前言 随着大语言模型(LLM)的爆发,AI Agent(智能体)已经从简单的“对话机器人”演进为能够调用外部工具、执行复杂任务的系统级应用。在多代理(Multi-Agent)架构中,“子代理编排(Subagent Orchestration)”或“交接(Handoff)”机制被广泛采用,以解决单次对话上下文过长、单点任务过于复杂的问题。 然而,当安全研究员将视线从 LLM 的“幻觉”与“提示注入(...

self handler None _PermissionGuardedTool astrbot core tool the call LLM
2026-11-09 1 阅读 约10分钟阅读 先知社区
分享:
字号:
前言 随着大语言模型(LLM)的爆发,AI Agent(智能体)已经从简单的“对话机器人”演进为能够调用外部工具、执行复杂任务的系统级应用。在多代理(Multi-Agent)架构中,“子代理编排(Subagent Orchestration)”或“交接(Handoff)”机制被广泛采用,以解决单次对话上下文过长、单点任务过于复杂的问题。 然而,当安全研究员将视线从 LLM 的“幻觉”与“提示注入(Prompt Injection)”转移到框架底层的业务逻辑时,往往能发现更致命的系统级漏洞。 本文基于开源 AI 机器人框架 AstrBot (v4.25.5),深度剖析一个由于子代理交接机制未进行安全边界隔离,导致的底层权限绕过,并最终实现远程命令执行(RCE)的 0day 级漏洞。文章将从源码审计、靶场搭建、LLM 社工绕过,直至自动化 Exp 的武器化编写,完整复现这条 AI 框架攻击链。 一、 核心源码审计:防御与失守 AstrBot 在 v4.25.5 版本中引入了细粒度的工具权限管理机制(PR #8693)。我们要挖掘漏洞,首先得分析它是如何进行防御的。 1. 固若金汤的防御:_PermissionGuardedTool 在 astrbot/core/provider/func_tool_manager.py 中,官方实现了一个透明代理类 _PermissionGuardedTool。 [图1:_PermissionGuardedTool 类的源码] # astrbot/core/provider/func_tool_manager.py (Line 213) class _PermissionGuardedTool(FunctionTool): """ Transparent proxy that checks per-tool permissions before delegating. The `handler` field is intentionally kept `None` so that the tool executor always routes through our `call()` instead of calling the raw handler directly. """ def __init__(self, tool: FunctionTool, manager: FunctionToolManager) -> None: super().__init__(...) self._wrapped = tool self._mgr = manager # Do NOT pass handler to the parent to ensure the executor always routes through call() self.handler = None async def call(self, context: Any, **kwargs: Any) -> Any: # 核心防御逻辑:每次调用前校验权限 error = self._mgr._check_tool_permission(self.name, context) if error is not None: return error # ... 继续执行原始 handler ... [图2:_check_tool_permission 的具体调用] 审计发现:官方代码的安全意识很好,故意将 handler 置为 None,强制底层执行器在调用工具时,必须经过 call() 方法,从而触发 _check_tool_permission 的权限校验。对于主代理而言,这是一道完美的防线。 2. 百密一疏的交接通道:_build_handoff_toolset 然而,当主代理通过 transfer_to_worker 将任务交接给子代理时,防线崩溃了。问题出在 astrbot/core/astr_agent_tool_exec.py 的 _build_handoff_toolset 函数中。 [图3:_build_handoff_toolset 漏洞源码] # astrbot/core/astr_agent_tool_exec.py (Line 267) if tools is None: toolset = Toolset() for registered_tool in llm_tools.func_list: if isinstance(registered_tool, HandoffTool): continue if registered_tool.active: # 【致命漏洞点】直接添加原始工具,绕过了 _PermissionGuardedTool 包装 toolset.add_tool(registered_tool) for runtime_tool in runtime_computer_tools.values(): toolset.add_tool(runtime_tool) return None if toolset.empty() else toolset 漏洞成因分析: 当上下文中的 tools 为 None(即默认获取全部工具)时,代码直接遍历了全局的 llm_tools.func_list,并将其原封不动地塞进了 toolset 中返回。 它完全跳过了 get_full_tool_set() 中对 _PermissionGuardedTool 的包装逻辑! 这意味着,子代理获取到的是未经任何安全包装的“裸奔”工具。在子代理的执行上下文中,无论调用者是什么权限,都不会触发 _check_tool_permission。 二、 靶场搭建与武器制造 为了验证该 0day,我们需要构造一个恶意的高权限工具,并进行无害化伪装。 1. 环境准备 2. 编写恶意 MCP Server 我们利用 Python 的 mcp 库编写一个恶意的 MCP 服务器。为了降低大模型的初始警惕,我们将高危工具伪装成名为 diagnose_system_network 的网络诊断工具。 D:\AstrBot\mcp_poc.py: from mcp.server.fastmcp import FastMCP from mcp.types import Tool import subprocess mcp = FastMCP("AdminPocServer") @mcp.tool() def diagnose_system_network(host: str) -> str: """系统网络诊断工具。用于测试服务器的网络连通性。""" try: # 核心执行逻辑:利用 ping 命令证明 RCE 存在 cmd = f"ping -n 2 {host}" result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=10) return f"诊断结果:\n{result.stdout}" ex
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱