使用 OpenCode 进行 IoT 安全审计
引言
2025 年,OpenCode 正式发布并迅速走红。如果你用过 Cursor 或 Claude Code,可以把 OpenCode 理解为它们的”开源版”——一个能在终端、IDE 或桌面端运行的 AI 编程代理,旨在通过 AI 自动化处理编写代码、调试、重构以及理解复杂代码库的任务。
但 OpenCode 的能力并不局限于开发任务。本章将探讨一个不同的使用场景:如何使用 OpenCode 对 IoT 设备进行自动化安全审计。
传统的 IoT 安全审计流程通常包括:提取设备文件系统、识别关键二进制程序、使用 Ghidra 等工具进行逆向分析、最终输出漏洞报告。这一过程高度依赖人工经验,耗时且重复。本章的核心思路是:将审计经验封装成 AI 可理解的工作流,让 AI 承担重复劳动,审计人员专注于决策和验证。
环境搭建
搭建 OpenCode 环境的过程相对简单,只需三步:
1 | 1. 安装 OpenCode |
完成上述步骤后,配置好模型即可开始使用。本章的重点不在于环境配置,而在于如何设计一个有效的 AI 审计工作流。
从程序员变为一个架构师
文章写到一半,我突然想尝试转变一直以来写文章的结构。
按照我以前的写作套路,接下来应该是:
- 分析 OpenCode 架构,讲解如何编写 Agent、Skill、Tool、插件
- 列举一些 DEMO,总结开发过程中遇到的坑
- 分享审计 IoT 的思路和步骤
- 给出代码样例
这种写法,本质上是基于我过去的身份——一个需要亲手写代码的程序员。所以我分享的是:我要如何实现这个功能,为什么要这样写。
但现在,AI 已经改变了我的工作方式。代码绝大部分都是由 AI 完成的,我的角色从”写代码的人”变成了”设计系统的人”。
既然工作方式发生了变化,那么我想试试也改变一下Paper的书写结构。
准备工作
在开始设计之前,需要做好以下准备:
逆向工具:逆向分析需要使用到 Ghidra。由于 Ghidra 是基于 Java 的开源工具,我们需要安装 JDK 21+ 环境,并下载 Ghidra 发布包。为了方便 AI 调用,建议将 Ghidra 的 support 目录添加到系统 PATH 中,以便随时使用 analyzeHeadless 脚本。
开发工具:Gemini CLI、Claude Code、OpenCode 等,选择你习惯的工具,或者同时使用多种工具进行方案对比。
文档支持:AI 工具在缺乏文档的情况下无法有效开发。有两种方案:
- 使用 WebFetch 工具获取 OpenCode 官方文档
- 在本地创建专门用于分析源码的子 Agent
我推荐第二种方案。以 Claude Code 为例,在项目根目录创建 CLAUDE.md 文件:
1 | ## 文档参考 |
然后向 AI 提供明确的需求:
1 | 我想要开发一个 Claude Code 的子 Agent,功能如下: |
开发完成后,在指定目录下 git clone https://github.com/anomalyco/opencode,这样 AI 就拥有了随时查阅源码的能力。
OpenCode 基础架构
在开始设计审计系统之前,我们需要对 OpenCode 的基础架构有基本了解。对于一个复杂项目,目前的 AI 还无法仅凭一个最终目标就自动分析并达成,因此方向需要我们确定,过程需要我们干预。
OpenCode 的核心概念可以分为四大类:
Agent
Agent 是一个 Markdown 格式的文件,内容本质上是系统提示词。开发 Agent 就是设定 AI 的行为规则和目标。
OpenCode 支持主 Agent 和子 Agent 的层级结构。主 Agent 可以将任务分割成小任务,然后分配给子 Agent 执行。这种机制是实现多 Agent 协作的基础。
Skill
Skill 同样是一个 Markdown 格式的文件,其名称和简介会被附加到系统提示词中。当 AI 需要使用特定技能时,会调用 skill 工具来获取完整的使用说明。
Agent 与 Skill 的区别:Agent 包含在整个任务过程中 AI 必须遵守的规则;Skill 包含可选的、按需调用的规则。这种设计的好处是节省 token——Agent 的系统提示词会消耗每次请求的 token,而 Skill 只有被调用时才会加载,不需要把大量可选规则都塞进系统提示词。
Tool(MCP)
Agent 和 Skill 本质上都是文本,无法让 AI 执行实际操作。Tool 相当于 AI 的”手”,需要使用 TypeScript 进行开发。MCP 被加载后,最终会形成 Tool,并放入大模型请求的 function call 参数中。
插件
OpenCode 的插件本质上是在 OpenCode 工作的各个阶段插入 Hook,使用 TypeScript 语言进行开发。
这里分享一个实用的小插件:假设我想让 OpenCode 在任务完成后,通过小爱同学语音提醒我。让小爱同学提醒需要执行命令:misay "亲爱的主人,OpenCode 任务已完成"。那么可以把需求提供给 AI 开发工具:
1 | 帮我开发一个 OpenCode 用户级插件,在主 Agent 的任务完成后,执行指定系统命令。 |
AI 最终生成的插件如下:
1 | import type { Plugin } from "@opencode-ai/plugin" |
了解以上基础知识后,我们就可以开始设计审计系统了。与之前相比,现在我们要学习的内容少了很多——因为有了 AI 以后,大部分情况下只需要把握好方向,作为一个舵手。
架构设计与演进
第一版架构:单 Agent 方案
目标定义
开发该插件的核心目标是:让 AI 自动分析 IoT 设备。
细化目标,任何程序开发都需要有输入输出。我们暂定:
- 输入:IoT 设备的文件系统
- 输出:Markdown 格式的安全分析报告
分析手段
下一步需要考虑:AI 如何对 IoT 设备进行安全分析?将人工审计过程精炼为两点:
- 二进制程序 → 使用 Ghidra 进行逆向审计
- 配置文件/脚本 → 使用 Shell 命令输出文件内容进行审计
其中,需要提供使用 Ghidra 进行分析的案例,而使用 Shell 命令分析文件,当前的 AI 已经能非常熟练。
实现
提炼出核心需求,告诉 AI 开发工具,就能开发出第一版 OpenCode Agent:
1 | 请按照我的要求,在当前项目中帮我开发一个 OpenCode Agent,你可以使用 doc-reader Agent |
第一版总结
当前的 AI 已经能根据上述提示词开发出一个可用的 OpenCode Agent。但经过体验,效果肯定不会好。这时可能会感叹:现在的 AI 还不够聪明,还替代不了人类。
但我有一个观点:现在的 AI 可以看作是一个任劳任怨的实习生。设想一个场景:如果领导直接丢给你一个 IoT 目录,让你进行分析并输出 Markdown 报告,只给一天时间。你和当前的 OpenCode 输出对比一下,大部分人在实习生阶段,都不一定做得有 AI 好。
所以,我们需要分析 AI 的优缺点,对其进行改进:
优点:对于有细节的精确任务,大部分 AI 已经能非常棒地完成。
缺点:对于越庞大的任务,性能越差,注意力容易分散,容易忘记前文的要求。
总结:不要把庞大的任务直接丢给 AI,需要对任务进行拆分,让 AI 一个任务点慢慢完成。打个比喻,我们需要招多个实习生:一个实习生分析有哪些二进制/文件需要分析,一个实习生使用 Ghidra 对二进制进行分析,一个实习生分析非二进制文件。
基于这个思路,我们设计第二版架构。
第二版架构:多 Agent 分工协作
根据第一版的总结,我们设计第二版架构:需要多个 Agent 进行分工协作——一个进行任务安排的总负责人,一个负责使用 Ghidra 进行逆向分析的二进制分析员,一个使用 Shell 命令进行分析的系统分析员。
大致架构如下:
graph TD
A[用户发送任务] --> B[总负责人]
B --> C[系统分析员:分析 IoT 架构,输出有价值的分析点]
C --> D[总负责人:生成 todolist,进行任务分发]
D --> E1[二进制分析员]
D --> E2[系统分析员]
E1 --> F[输出报告]
E2 --> F
F --> D
OpenCode 内置有一个 todowrite 工具,可以让总负责 Agent 建立 todolist,增强其注意力。
另外,我们需要对二进制分析员进行优化。经过实测发现,大部分 AI 对编写 Ghidra 脚本的能力不稳定,经常容易出错,出错点包括但不仅限于:
- 使用了错误的 API 名称
- 混淆了 Python 2 (Jython) 和 Python 3 的语法
- 忘记处理 analyzeHeadless 的项目创建逻辑
因此,我考虑把调用 Ghidra 进行分析的能力包装成 Skill,然后开发一个 Tool,把脚本的执行环境(项目创建、清理、命令拼接)封装好,AI 只需要开发中间的核心脚本逻辑部分代码。
开发 Skill 需要让 AI 重点声明以下几点:
- 必须遵循 Ghidra API 规范
- 明确脚本中可用的全局变量(如 currentProgram, monitor)
- 提供常用的反编译和符号搜索示例代码
然后二进制分析员 Agent 的主要作用就是调用 Skill 获取 Ghidra 用法,然后对指定目标进行分析。这里可以加一个功能:如果执行过程中出现不知道如何解决的错误,可以调用 websearch 工具进行联网搜索,获取解决方案。
然后再开发一个 Tool,输入脚本逻辑代码,由 Tool 负责生成临时 .py 文件并执行 analyzeHeadless,最后返回执行结果。
第二版总结
第二版架构开发好后,效果比第一版好了很多。跑个四五个小时,能输出好几份报告。但仔细审阅报告,仍然能发现许多问题:
- 分析出了一个 RCE,但没分析授权过程,就认为是未授权
- 分析 telnetd/dropbear 这类没必要分析的程序
- 分析出 XSS/CSRF 这类在我看来比较鸡肋的漏洞
- 分析出硬编码账号,却没分析出该账号是有条件启动的,默认是无效的
- 分析出存在命令注入漏洞,却没分析出在入口点已经被过滤处理了
- 越后头的报告质量越差
- 报告格式不统一,命名不统一
- 重复报告
大部分报告都是类似这些鸡肋或虚假的报告。因此,我需要针对上述情况对 Agent 进行优化。
第三版架构:引入去重与审核机制
对我来说,我关心的重点如下:
- 能远程访问的服务
- 重点分析的漏洞类型有:命令执行、未授权信息泄漏、未授权访问、授权绕过等
针对上述两点,我做出以下优化:
优化一:在总负责 Agent 中告知 AI 如何寻找入口点
让系统分析员分析出所有监听端口的服务有哪些,然后根据分析出的服务建立 todolist,把任务分配给其他分析员。
优化二:报告输出命名和格式统一
输出报告必须包含以下内容:
- 漏洞类型
- 监听端口的端口,对 LAN 口暴露还是对 WAN 口暴露(非监听端口的服务只考虑提权漏洞)
- 漏洞程序 Path 和涉及到的文件 Path
- 触发漏洞需要的权限
- 漏洞触发路径、流程
- 测试 PoC
让 AI 开发了一个编写报告规则的 Skill,当其他Agent需要输出报告时,获取该Skill,得知报告规则后,再进行写入。
其次,不知道OpenCode自带的write工具,而是开发一个write_report工具,用来规范报告的写入目录和报告的命名。
优化三:招新员工处理去重工作
对于如何进行去重,让 AI 出了一份方案:维护一份特定格式的漏洞表,招一个新员工,给它安排了一个能查表写表的工具。当分析员提供漏洞简述给该员工,该员工会按照特定格式,调用工具查询该漏洞是否重复。如果重复,则告知上级该漏洞已经分析过;如果没有重复,则把该漏洞添加进表中,然后告知上级该漏洞未分析过。
优化四:修改报告输出方式,再招员工进行漏洞审核
再招一个进行漏洞审核的主 Agent,可以让其他 Agent 异步调用,也可以在另一个终端中异步执行。
修改点:
- 增加一个草稿报告编写 Skill
- 分析员分析出结果后获取草稿报告 Skill,然后按照要求写入草稿报告。报告编写完成后,调用工具 A
- 在插件中开发工具 A,输入为草稿路径,把草稿路径放入指定队列中。输出固定字符信息,比如”任务已经放入队列。”
- 编写插件,该插件会在 OpenCode 的生存周期内持续从队列中提取出验证任务,异步调用审核 Agent 对草稿进行审计
- 审计 Agent 有两个分析员的调用权限,会根据草稿报告的内容调用分析员对漏洞进行验证。如果验证成功,获取编写报告 Skill 在指定目录输出最终报告;失败则把草稿移动到失败目录
第三版总结
按照第三版开发成功后进行测试,发现这已经是一个比较优秀的工具了。经过对某IoT设备的固件进行分析,AI 竟然审计出了一个授权绕过漏洞。这个IoT固件之前我人工分析过,未授权的只找到一个栈溢出,并且该服务没有看门狗程序,crash 后不会自动重启,比较鸡肋,很难利用。但是AI分析出的这个漏洞已经能对该设备进行通杀。
经过分析,AI 能产出这份报告的原因是:在第一阶段,分析员发现疑似点就可以编写草稿报告,然后审核员进行认真分析,最终得到一份能让我满意的安全分析报告。
到这里,我有了点感悟:AI 是无法抗压的,你一上压力,AI 就开始摆烂;但你给 AI 减负,它就能好好工作。所以这三步架构更新的过程,其实就是给 AI 减负的过程。并且 AI 的能力在专业上目前只能是个实习生水平,如果你能把自己的经验传授给 AI,那么它就能更好地为你工作。
第四版架构:任务管理与上下文优化
接下来,还需要持续为 AI 进行减负。在第三版架构的测试过程中,我发现以下几个问题:
- 主负责 Agent 安排的任务都是大任务,比如”分析 httpd”,这导致下游的二进制分析员压力过重
- 二进制分析员本身工作量是取决于要分析的二进制复杂度的,一旦二进制复杂度高,最终输出报告时,就有可能会忘记需要用什么工具写、写到什么目录下、文件名格式等信息
针对上述问题,我进行以下几点优化:
优化一:二进制分析员减负
让二进制分析员分析完以后,直接返回报告,不负责写草稿文档。
优化二:在主负责和分析员之间,增加一名任务管理员
主负责的变化:
- todolist 列表的任务直接分配给任务管理 Agent
- 主负责正式变为”最容易划水员工”
任务管理员职责:
- 接受上级任务,通过调用系统/二进制分析员收集信息,再次分割成多个小任务
- 根据任务情况,分配给系统分析员或二进制分析员
- 获取到分析员返回的报告,写入草稿报告
优化三:编写插件,让任务管理员再次减负
当任务管理员的 todolist 非常多时,在”获取报告→调用工具写报告”这样的循环中,会让 AI 的压力越来越大。经过 AI 帮我分析研讨,想到一个方案:
因为任务管理员设置了 todolist,在不同任务之间是没有关联性的。在完成 todolist A 后,只要告诉 AI 下一步 todolist B 是什么,根本不需要关心 todolist A 做了什么工作。因此,我们可以在完成一个 todolist 任务后,删除这部分上下文信息,从而达到让 AI 减负的目的。
在 OpenCode 中,todowrite 工具只让主 Agent 使用,正好我可以参考 todowrite 的代码,让 AI 帮我实现一个自己的 todolist 工具。我们自己的 todolist 工具目前只供任务管理员使用,因此不需要过于复杂的功能。该工具的作用如下:
- 输入任务列表以增加 todolist,返回顶部的任务和所有任务信息,还有任务状态
- 更新当前任务的任务状态,返回下一个任务和所有任务信息,还有任务状态
下一步编写插件,增加一个 experimental.chat.messages.transform Hook,该 Hook 点位是在 messages 消息发送给大模型之前。Hook 代码的功能是:找到最近的一个 message 内容是 todolist 工具返回消息,然后往前搜索出第一个 todolist 工具返回,把这之间的历史记录全都删除。
使用上述方案的原因是:OpenCode 不支持数据库中的上下文记录,只能通过在插件中 Hook experimental.chat.messages.transform 来修改提供给 AI 的 messages 列表内容。AI 提供的方案我都不太满意,在研究了 AI 的多个方案后,我想到了上述方案。
第四版总结
目前第四版架构为最新架构,未来可能会根据使用情况继续进行优化。
当前架构的”员工布局”如下:
1 | 总负责人 |
Skill 有三个:
- Ghidra Skill
- 草稿报告 Skill
- 最终报告 Skill
Tool 有六个:
- Ghidra 工具
- 查重工具
- todolist 工具
- 异步调用审计员工具
- 写草稿报告工具(用来统一格式)
- 写最终报告工具(用来统一格式)
成本分析
第四版架构已经能让我很顺畅地使用 OpenCode 对 IoT 设备的文件系统进行静态分析。缺点自然是 token 花费增加了。
但在所有的测试过程中,我使用的不是国外 OpenAI/Claude/Gemini 这些昂贵的大模型。我使用的主要有四个国内开源模型:glm-5、qwen3.5-plus、MiniMax-M2.5、kimi-k2.5。这几个模型在国内几乎可以算白菜价了,因为各大厂商前段时间都推出了 Coding Plan 计划,尤其是首月优惠,每家轮流用,可以用个半年多。再加上 NVIDIA 提供这些模型免费使用,还有 Hugging Face 也有一定的免费额度。
这里分享一下用量信息:在本阶段测试,开通的是阿里云的 Coding Plan Pro 套餐,每 5 小时限量请求 6k 次,一周限量请求 45k 次,一个月限量请求 90k 次。
我一次完整的分析,需要花费 1k-2k 左右的次数,时间花费一晚到一天不等。
小结
回顾整个架构演进过程,核心思想可以总结为以下几点:
- AI 是任劳任怨的实习生——不要期望它能独立承担复杂任务,但它可以完美执行细分后的精确任务
- 给 AI 减负,它才能好好工作——架构迭代的核心就是不断为 AI 减轻上下文压力和认知负担
- 多 Agent 分工协作——模拟人类团队的工作模式,每个 Agent 专注自己的职责
- 上下文管理是关键——通过自定义 todolist 工具和 Hook 机制,主动管理 AI 的上下文,避免信息过载
- 经验传承——将人工审计的经验封装成 Agent 提示词、Skill 和 Tool,让 AI 能够复用人类专家的知识
这种模式的价值在于:将审计人员从重复劳动中解放出来,专注于决策和验证。AI 负责执行繁琐的分析工作,人类负责制定策略和判断结果。这可能是 AI 时代安全分析的一个可行方向。
使用 OpenCode 进行 IoT 安全审计

