1. CTF工控流量题为什么总在“最后一公里”卡住
工控流量题在 CTF 里属于那种“看起来不难、做起来很碎”的类型。你拿到一个 pcap 或 pcapng,里面可能是 S7Comm、Modbus、GOOSE、MQTT、COTP,甚至是一段 SSTV 音频。题目本身不会告诉你用哪个协议、哪个功能码、哪个字段,全靠你自己从流量里一点点还原。
我打过的工控题里,最常见的卡点不是“不会写脚本”,而是分析链路太长:Wireshark 看一遍、tshark 导一遍、pyshark 跑一遍、Audacity 看频谱、binwalk 拆文件、CyberChef 解码……每换一个工具,就要重新配一次 API Key 或者环境。尤其是现在很多人用 Cline、Claude Code 这类 AI 辅助工具来写解析脚本,Key 分散在好几个地方,改一次配置要翻半天。
这篇就聚焦一个具体场景:CTF 工控流量题从 pcap 抓包到协议还原的完整分析路径,重点解决多工具切换时 API Key 分散管理的问题。我会给出 TaoToken 统一 Key 的 settings.json 配置骨架、Cline 接入步骤,以及一次工控流量题的验证动作,帮你快速定位异常指令。
适合谁看:正在打 CTF 工控方向、需要频繁写 pyshark/tshark 脚本、同时用多个 AI 编码工具的选手。如果你只是偶尔做一道流量题,也可以看看配置骨架,后面遇到多工具协作时能直接套。
2. TaoToken 统一 Key 的前置准备
在讲配置之前,先说清楚为什么要用统一 Key。工控流量题的分析流程通常是这样的:
- 用 Wireshark 做初步过滤,确定协议类型
- 用 tshark 命令行导出特定字段
- 用 pyshark 写 Python 脚本批量提取功能码、寄存器值、payload
- 遇到编码数据,用 CyberChef 或本地脚本做 hex/base32/base64 解码
- 遇到音频,用 Audacity 看频谱或 SSTV 解码
这里面第 3 步和第 4 步最容易用到 AI 辅助。比如你不确定 S7Comm 的param_func字段怎么取,或者 Modbus 的response_time怎么过滤,直接让 AI 帮你写脚本比翻文档快得多。但如果你同时用 Cline、Claude Code、Continue 几个工具,每个都要单独配 Key,管理起来很烦。
TaoToken 的做法是提供一个统一的 API 入口,你只需要一个 Key,就能在多个工具里复用。官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api (注意 API 地址不加 UTM 参数)。
你需要先拿到 Key。进入控制台创建 API Key:
控制台地址:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
创建完 Key 之后,不要急着往代码里硬编码。工控流量题经常要跑多个脚本,硬编码容易泄露,也不方便切换。推荐的做法是写进 settings.json,让工具自己去读。
3. 可复制的 settings.json 配置骨架与 Cline 接入
3.1 settings.json 配置骨架
下面这个骨架可以直接复制,把your_api_key_here换成你实际的 Key。这个结构兼容大部分支持 OpenAI 格式的工具,包括 Cline、Continue、以及一些自定义脚本。
{ "taotoken": { "api_key": "your_api_key_here", "base_url": "https://taotoken.net/api", "default_model": "claude-sonnet-4-20250514", "timeout": 120, "max_retries": 3 }, "cline": { "provider": "openai", "apiKey": "your_api_key_here", "baseURL": "https://taotoken.net/api", "model": "claude-sonnet-4-20250514" }, "analysis": { "pcap_dir": "./captures", "output_dir": "./output", "default_encoding": "utf-8" } }几个参数说明:
| 字段 | 作用 | 建议值 |
|---|---|---|
| api_key | 统一 Key | 从控制台复制 |
| base_url | API 入口 | https://taotoken.net/api |
| default_model | 默认模型 | 按需选 |
| timeout | 超时秒数 | 工控脚本建议 120 |
| max_retries | 重试次数 | 3 |
注意:settings.json 不要提交到 Git。工控题经常要分享 writeup,Key 泄露了要重新生成。
3.2 Cline 接入步骤
Cline 是 VS Code 里的 AI 编码插件,写 pyshark 脚本很方便。接入 TaoToken 的步骤如下:
第一步,在 VS Code 里安装 Cline 插件,打开设置。
第二步,找到 Cline 的 API Provider 配置,选择OpenAI Compatible。
第三步,填入以下信息:
- Base URL:
https://taotoken.net/api - API Key: 你的 TaoToken Key
- Model: 按需填写,比如
claude-sonnet-4-20250514
第四步,保存后新建一个测试文件,输入一段注释,看 Cline 能不能正常补全。如果能补全,说明接入成功。
如果你用的是 Claude Code,接入方式类似,在配置里指定 API 地址和 Key 即可。具体文档可以参考:
接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
3.3 用统一 Key 跑一个 pyshark 脚本
配置好之后,你可以让 Cline 直接帮你写工控流量解析脚本。比如下面这个脚本,用来统计 S7Comm 的功能码分布:
# -*- coding: utf-8 -*- import pyshark def count_s7_func(pcap_path): captures = pyshark.FileCapture(pcap_path) func_codes = {} for c in captures: for pkt in c: if pkt.layer_name == "s7comm": if hasattr(pkt, "param_func"): func_code = pkt.param_func func_codes[func_code] = func_codes.get(func_code, 0) + 1 captures.close() return func_codes if __name__ == '__main__': result = count_s7_func("s702.pcapng") for code, count in sorted(result.items()): print(f"{code}: {count}")跑出来如果看到0x00000005出现次数异常多,基本可以判断是写入操作,接下来就重点分析 Write Var 的数据包。
4. 验证请求:一次工控流量题的完整分析动作
4.1 题目背景与初步过滤
假设你拿到一个 S7Comm 的 pcapng,题目说“某工程师发现设备异常,怀疑被攻击,请找出被篡改的数据包”。Flag 格式是flag{hex的data数据包后90位,字母为大写}。
第一步,用 Wireshark 打开,过滤s7comm。你会看到大量 Read Var 和 Write Var。正常运维场景下,Read 多 Write 少;如果 Write 异常多,说明有攻击者在批量写入。
第二步,用 tshark 快速统计功能码:
tshark -r s702.pcapng -Y "s7comm" -T fields -e s7comm.param.func | sort | uniq -c | sort -rn输出类似:
4016 0x00000005 3984 0x00000004 2 0x000000f00x05是 Write Var,出现 4016 次,明显异常。
4.2 提取写入数据
接下来用 pyshark 提取所有 Write Var 的resp_data:
# -*- coding: utf-8 -*- import pyshark def extract_write_data(pcap_path): captures = pyshark.FileCapture(pcap_path) data_list = [] for c in captures: for pkt in c: if pkt.layer_name == "s7comm" and hasattr(pkt, "param_func"): if pkt.param_func == '0x00000005': if hasattr(pkt, "resp_data"): data_list.append(pkt.resp_data) captures.close() return data_list if __name__ == '__main__': data = extract_write_data("s702.pcapng") result = ''.join(str(d) for d in data) print(result)跑完之后,你会得到一长串 hex 数据。题目要求取“data 数据包后 90 位”,所以直接切片:
flag_hex = result[-90:] print(flag_hex.upper())如果输出类似31312D31424535312D30584230203B56332E308240001505323B32383882410003000300A20000000072010000,那这就是 flag 的 hex 形式。转成 ASCII 就能看到可读字符串。
4.3 验证结果
把 hex 转 ASCII:
bytes.fromhex(flag_hex).decode('ascii', errors='ignore')如果看到类似11-1BE51-0XB0 ;V3.0...的内容,说明提取正确。题目要求提交 hex 形式,直接提交大写即可。
这一步的关键是:先用功能码统计定位异常,再用脚本批量提取,最后按题目要求切片。不要一上来就手动翻包,4000 多个包翻到天亮也翻不完。
5. 本篇常见错排查
5.1 pyshark 报错 “Layer not found”
工控协议字段名在不同版本的 Wireshark/pyshark 里可能不一样。比如 S7Comm 的param_func,有些版本是s7comm.param.func,有些是s7comm_param_func。排查方法:
for pkt in c: if pkt.layer_name == "s7comm": print(pkt.field_names)先打印所有字段名,再决定用哪个。
5.2 Modbus 功能码过滤不到
Modbus 的功能码字段是modbus.func_code,不是param_func。而且要注意区分请求和响应。如果你要提取写入成功的数据,需要加modbus.response_time > 0这个条件:
if pkt.layer_name == "modbus": if int(pkt.func_code) == 6 and float(pkt.response_time) > 0: payload = str(pkt.tcp.payload).replace(":", "")5.3 GOOSE 协议 appid 过滤
GOOSE 的 appid 字段是goose.appid。如果题目说“当 appid==8 时 Data 有变化”,直接过滤:
tshark -r goose.pcapng -Y "goose.appid == 8" -T fields -e goose.data提取出来的字符串可能是 base32 编码,解三次 base32 就能拿到 flag。
5.4 SSTV 音频题没有声音
SSTV 题需要虚拟声卡。如果你在虚拟机里跑,先确认声卡设备正常。播放 mp3 的同时用 SSTV 接收软件监听默认设备。Robot36 模式是常见模式,如果解不出来,试试其他模式。
5.5 API Key 配置后 Cline 不生效
检查三点:Base URL 是否带了/v1(TaoToken 的 API 地址是https://taotoken.net/api,不要自己加/v1);Key 是否有多余空格;模型名是否拼写正确。如果还不行,去控制台看请求日志:
API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
6. 把统一 Key 用进你的工控分析链路
工控流量题的分析链路很长,从 pcap 到协议还原,中间要换好几个工具。如果你每个工具都单独配 Key,改一次配置就要翻好几个文件。用 TaoToken 统一 Key 之后,settings.json 里维护一份,Cline、Claude Code、自定义脚本都从这里读,省事很多。
如果你主要做长期编码和 Agent 任务,可以看看 Coding Plan:
Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite
如果你只是想快速验证某个模型能不能解工控协议字段,直接用模型对话:
模型对话:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite
最后给一个实用技巧:工控题里遇到不确定的协议字段,先把 pcap 用 tshark 导出成 JSON,再让 AI 帮你分析字段结构。比手动翻 Wireshark 快得多。导出命令:
tshark -r target.pcapng -Y "s7comm" -T json > s7comm.json然后把这个 JSON 丢给 AI,问它“哪些字段可能是攻击者写入的数据”,通常能给你几个可验证的方向。