Datacon2025 互联网威胁分析参赛复盘
Datacon2025 如期而来,今年分为四个赛道,分别为 AI 安全、软件供应链安全、互联网威胁分析、口令安全。我们根据兴趣和经验,选择了互联网威胁分析赛道。本赛道是奇安信X实验室出题,比赛时间一周,需要完成“异常流量检测”和“僵尸网络协议逆向”两个赛题。在多位队友的强力带飞下,我们有幸拿到了该赛道的冠军,这篇博客对我所主要完成的部分进行分享和复盘,完整的 WP 可见 Datacon 社区的官方分享。
赛题回顾
赛题一
赛题一要求识别漏洞利用流量中的 CVE,训练集提供了4万条 HTTP 请求以及对应的 CVE 标注,测试集为13万条 HTTP 会话。总结下来有几个关键点:a) 需要对应到流量中存在的具体 CVE,可能为一或多个;b) 提供的流量样本只包含 HTTP 请求;c) 情报时效性要求较高,最近的 CVE 编号为2025年8月公开的。
统计得到训练集样本 CVE 分布:
1 | 总样本数: 44983 |
赛题场景要求我们识别对应到具体 CVE,而学术界的方法主要是通过机器学习/深度学习模型的训练,来识别是否为恶意/属于哪种攻击,无法满足需求。因此,感觉工业界常用的规则匹配是需要着重考虑的点。
规则匹配方面,有诸多社区维护的 PoC 库或扫描器可供我们使用,例如 Goby、Nuclei、Fscan 等;知名的开源 IDS Suricata 也有官方和社区维护的不同规则库。整个赛题解题思路如下:
在本赛题中,我主要完成了 1) 设计 LLM Agent 来根据 PoC 自动化编写和验证 suricata 规则;2) 实现基于词汇表征的 URL 抽象和模板匹配;3) 寻找开源 Waf 来消除 FP。
本文着重分享前两个工作的思路。任务3是采用长亭雷池 Safeline ,借助它的攻击语义匹配能力,查找属于攻击但我们未能给出 CVE 标签的流量,然后进行一些半自动化的搜索和人工复核。
设计 LLM Agent 根据 PoC 自动化编写和验证 suricata 规则
Suricata 是一个开源的 IDS/IPS 系统,其主要基于规则签名对流量进行检测,处理性能高、社区规则较全。我们使用其官方的 ET-Open 规则集、从网络收集的其他数据集作为基础,经去重后共计6.2万条规则。
我们对这些规则做了一些预处理,以适配只有 HTTP request payload 的情况,具体包括:1) 筛选 alert http 的规则,得到2.7万条;2) 将规则签名头的IP宏去除,改为 alert http any any -> any any ,以检测所有源和目的IP;3) 确保包含 flow:established ,否则将无法正常检测数据集流量。为了使 suricata 正常检测流量,还需要将数据集中的 payload 组装为带三次握手的 TCP 报文。我们使用 python scapy 实现这一点。
然而,仅使用这些规则,只能匹配到训练集中113个 CVE 。因此我们采用 LLM Agent 的方式,对训练集的 CVE 样本进行 suricata 规则编写和验证。整体流程如下图所示:

提示词(基准)
1
2
3
4
5
6
7
8
9
10
11
12
13
14base_prompt = (
f"You are a senior cybersecurity expert specializing in Suricata rule authoring.\n"
f"Target vulnerability: {cve}.\n\n"
f"Below are HTTP payload samples associated with this CVE. Some represent different variants.\n"
f"Your task: Write one or MORE minimal Suricata rules to detect these variants.\n"
f"- Start each rule with: alert http any any -> any any\n"
f"- Include the CVE id {cve} in msg or reference so alerts are labeled with this CVE\n"
f"- Only include detection-relevant fields; avoid ttp or extra metadata\n"
f"- Output ALL rules inside a single triple-backtick code block, using 'suricata' as language.\n"
f"- One rule per line.\n"
f"- If necessary, use multiple rules to cover different patterns. Avoid overbroad patterns.\n\n"
f"Samples:\n{samples_block}\n\n"
f"Now output the rules only."
)提示词(反馈)
1
2
3
4
5
6
7feedback_prompt = (
base_prompt +
f"\n\nThe following pcaps were not detected by your rules ({len(uncovered)} remaining). "
f"Review and ADD or ADJUST rules as needed. Re-output the full set of rules.\n"
f"Current rules:\n```suricata\n{prev_rules_block}\n```\n" +
(f"Additional missed payloads for reference:\n{missed_block}" if missed_block else "")
)
对于每种 CVE,由于可能有多种利用特征,因此我们允许大模型提供多个规则。

最终,我们成功对训练数据集构建了351个CVE匹配规则,共计551条规则。

采用 Claude-sonnet-4.5 作为LLM后端。在训练集上测试,获得了流量级别检测率 (检测出的条数 / 总条数) = 0.3785 (8527/22527)。
基于词汇表征的 URL 抽象和模板匹配
URL 路由特征是匹配 CVE 的关键特征。尤其是在缺少 HTTP 响应内容的情况下,特征几乎只有 URL 和请求 Payload。
然而,直接使用 PoC 中提供的 URL 匹配数据集中的 URL 有两个关键缺陷:
- 一是变量完全嵌入在 URL 中,例如纯数字ID、UUID 这样的出现频率极低的字符串,直接匹配会导致大量失配。
- 二是存在 URL 编码、大小写不统一、以及末尾斜杠等归一化问题,导致简单的字符串比对完全失效。
面对海量的 WAF 告警日志,传统的基于正则(Regex)的规则维护成本过高且极易遗漏。我们需要一种能够自动学习 URL 结构,例如将 /api/v1/user/10086/profile 和 /api/v1/user/admin/profile 识别为同一类模式的算法。
为此,我们设计并实现了一种算法,想了想可以称之为:“两阶段词汇表征与模板化”算法。该方法的动机是:一个 URL 片段是“静态路由”还是“动态变量”,应由它在全局流量中出现的频率(稀有度)决定。
Phase 1: 词汇表构建
第一阶段需要遍历全量数据集,对 URL Path 按斜杠进行分词,构建一个全局的Token 词频表。引语义稀有度的概念:
高频词: 如 api, login, v1, user。这些词在成千上万条日志中重复出现,它们大概率是业务系统的固定路由结构。
低频词: 如 10086, a1b2-c3d4, admin_token_xyz。这些词往往只出现在极少数的请求中,具有极高的特异性,大概率是动态变量。
Phase 2: 模板生成
在第二阶段,我们再次遍历日志,利用 Phase 1 生成的词表对 URL 进行重构:
静态保留: 如果当前 Token 在词汇表中属于“高频词”或“语义关键词”,予以保留,维持其路由语义。
变量抹平: 如果当前 Token 是“低频词”,或者符合特定的高熵特征(如 UUID、Hash),则将其替换为统一的占位符。设计的占位符有:
{NUM}、{UUID}、{HASH}、{FILE_VAR}、{VAR}。
实施构建
使用 Github 上一个比较全面的 POC 库:https://github.com/eeeeeeeeee-code/POC
为经过处理后,在测试集上拿到了3926条 path 模板:

赛题二
初探
根据提供的僵尸网络样本(ELF)与部分数据包(Pcap),分析出 C&C 通讯协议格式, 并实现一个可以跟踪 C&C 服务器下发指令的跟踪程序。
这道题我们一开始理解错了题意,以为是我们只需要逆向出协议然后写一个抓包程序,挂到赛题环境中,然后 C&C 服务器就会定时(根据题目描述来看有5个 checkpoint)给我们发送指令。

经过咨询出题人后我们纠正了思路,按僵尸网络追踪的现实应用场景来说,是需要自己模拟一个样本(C2 客户端),与 C2 服务器主动建立连接,然后抓取其下发的攻击指令。
这道题组里的二进制大佬 @Wings 很快找到了思路,发现大部分样本的框架一致(框架一),仅有 6 个 ELF 是另一种框架(框架二)。不同样本基本上只是握手时使用的 magic number 不一样,少数还含有加密密钥或者 crc 校验。

随后 @Wings 写了一套极为完整、符合大模型提示工程的 Agent 提示词模板,通过调用 IDA MCP 和 fs MCP 来自动化寻找握手所需的参数。但由于最先尝试的 LLM 底座不太行(GPT-5),导致存在大量失败,而赛题一我的方法也基本到了性能瓶颈,就根据他的指导,协助他手工逆向了一些样本。
随后我们尝试了 Claude 模型作为底座,发现 Claude-4.5-sonnet 可以较好的遵循指令并完成任务。
转机
@Wings 想到,我们已经使用样本来发送上线消息和处理握手协议,于是想到可以让命令协议也通过样本来处理,这样能够保证通信协议是完全正确的。也就是将样本进行无害化处理后,patch 掉最后执行攻击指令的函数,将攻击参数外传出来。
对网络侧、ELF侧的数据进行交叉验证,以排查潜在的解析遗漏或者错误。验证方案如下:
- 获取ELF侧指令,以(quantized_ts, duration, target)为 key 存入缓存。由于网络侧指令往往迟于 ELF 侧指令到达,因此 quantized_ts 为 ts 向下取整到最近的 2 秒的值。
- 网络指令到达后,延迟1.5s处理。检查是否有匹配的 ELF 侧指令,若有,则检查所有字段是否匹配。若无,则表示 ELF 侧指令缺失。
- 若延迟后依然未收到网络指令,则表示网络侧指令缺失。
经过交叉验证后,最终完善了全部的协议解析。

Datacon2025 互联网威胁分析参赛复盘