mit einem Klick
probe-audit
修改回落机制、伪装方案状态机、协议识别、连接处理代码后触发。
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Menü
修改回落机制、伪装方案状态机、协议识别、连接处理代码后触发。
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Basierend auf der SOC-Berufsklassifikation
写入新模块文档、重构模块、或用户要求分析模块时触发。
Bug 修复或对接问题排查确认有效后,将经验记录到知识库。
修改 PMR 分配器、内存池配置、热路径容器、对象生命周期管理代码后触发。
编写或修改性能基准测试、分析 benchmark 结果、优化热路径性能时触发。
新增或修改 enable_shared_from_this 类、co_spawn 调用、shared_ptr 捕获的 lambda、co_await 后的成员访问时触发。
新增或修改原子操作、异步定时器、无锁通道、跨线程状态同步、CAS 竞争相关代码时触发。
| name | probe-audit |
| description | 修改回落机制、伪装方案状态机、协议识别、连接处理代码后触发。 |
在修改涉及回落(Fallback)机制、伪装方案状态机、协议识别、连接处理代码后,必须对变更部分执行以下审计清单。审查系统通过发送各种探测报文(重放、乱码、半截请求、跨协议握手、大规模并发)来验证服务端是否为代理服务器。
审查系统的主动探测分为三个阶段:
核心原则:服务端必须对每字节输入都有定义的标准输出。任何"未定义行为"都会暴露代理身份。
审查系统使用多种探针,每种有不同目的和检测逻辑。防御方必须理解每种探针的预期行为,确保响应不暴露代理特征:
| 探针目的 | 探针类型 | 预期观察 |
|---|---|---|
| 存在性确认 | 重放合法握手包 | 响应是否等于标准 TLS/Web 响应? |
| 协议识别 | 跨协议握手(SSH/HTTP/SOCKS5 到 443) | 是否暴露非 TLS 行为? |
| 认证探测 | 构造认证包(密码 hash/UUID) | 响应长度/时间是否因认证成功/失败而不同? |
| 密钥空间探测 | 逐字节变异(256 个变体) | 响应差异是否泄漏密钥信息? |
| 资源压力 | 大量并发 + 半开连接 | 降级行为是否暴露代理? |
| 时序分析 | 精确测量认证路径响应时间 | 时间差是否暴露认证逻辑? |
| 重放确认 | 数小时/数天后重放捕获的包 | 响应是否与首次连接不同? |
防御要点:
重放攻击防御的完整审计见
replay-audit技能
连接处理采用多方案管道架构,按优先级依次尝试已注册的伪装方案:
polluted 标志 — 如果数据已被修改到无法恢复,直接返回错误而非回卷审计时需关注:快照回卷是否完整、方案间状态是否泄漏、polluted 标志是否正确传播。
| 检查项 | 说明 |
|---|---|
| 首包窥探(Peek) | 是否在解密后对首包进行快速校验(长度、版本、认证)?校验失败必须回落 |
| 回落目标合法性 | 回落目标是否为真实的、工业级 Web 服务器?不得回落到空白页或自签名证书服务 |
| 回落转发完整性 | 回落转发时是否将原始数据完整传递给回落目标?不得丢弃或修改任何字节 |
| 连接不断开 | 校验失败时是否保持 TCP 连接并转发给回落目标?直接断开(RST)或黑洞不响应都会暴露代理 |
| 内存分配平稳 | 处理探针时是否避免异常的内存分配峰值?探针导致的 OOM 会间接暴露代理 |
| 回落目标可达性 | 回落目标是否始终可达?如果回落目标偶尔不可达,探针会收到不同响应,行为不一致暴露代理 |
| 检查项 | 说明 |
|---|---|
| HTTP 探针响应 | 探针发送 HTTP 请求时,服务端是否返回标准 HTTP 响应(如 400 Bad Request)?不得返回代理协议特有的错误格式 |
| 乱码探针响应 | 收到随机二进制数据时,服务端是否表现得与标准 Web 服务器一致? |
| 半截请求响应 | 收到不完整的 TLS 记录或 HTTP 请求时,服务端是否等待超时而非立即断开? |
| 错误响应格式 | 所有错误响应是否使用标准格式?不得包含代理软件特有的 header 或 body |
| 响应延迟一致性 | 同一类型的探针是否总是返回相同延迟的响应?如果有时快有时慢(依赖内部状态),延迟差异可能暴露内部逻辑 |
| 检查项 | 说明 |
|---|---|
| SSH 握手探测 | 审查系统会向 443 端口发送 SSH-2.0-OpenSSH 握手。服务端是否按标准 TLS 行为处理(TLS Alert 或忽略)?不得返回 SSH 错误或挂起 |
| 明文 HTTP 探测 | 向 443 端口发送 GET / HTTP/1.1。服务端是否在 TLS 层拒绝(返回 TLS Alert)而非在应用层处理? |
| SOCKS5 探测 | 向 443 端口发送 SOCKS5 握手头 \x05\x01\x00。服务端是否不返回 SOCKS5 响应? |
| 协议状态机隔离 | 同一端口上的不同协议处理器是否完全隔离?一个协议的解析错误不得影响另一个协议的状态 |
| 非 TLS 数据处理 | 在期望 TLS 握手的端口上收到非 TLS 数据时,是否发送标准 TLS Alert 后优雅关闭? |
| 检查项 | 说明 |
|---|---|
| 认证成功/失败时间差 | 认证成功路径和认证失败(回落)路径的响应时间是否接近?如果失败路径明显更快(直接回落 vs 建立代理连接),时间差可被测量 |
| 回落开销隐藏 | 回落到 dest 的连接建立开销是否被掩盖?可以在回落前添加随机延迟来抹平时间差异 |
| 密钥交换时间 | 不同认证阶段的处理时间是否一致?如果某种认证失败比其他失败更快,时间差暴露认证逻辑 |
| 错误响应时间 | 各种错误响应(400/403/404/407)的延迟是否与标准 Web 服务器的延迟一致? |
回落的正确性可以通过四个形式化属性来定义。任何回落实现都必须同时满足这四个属性:
不可区分性(Indistinguishability):对于任意输入 x,服务端响应必须在计算上与真实 Web 服务器的响应不可区分 — 包括响应内容和响应时间。这是最核心的安全目标。不可区分性必须覆盖所有可能的探针类型,而非仅针对已知探针类型。
完备性(Completeness):对于任意输入 x,服务端始终有一条定义好的响应路径。不存在"未处理"的输入。任何意外的输入格式、意外的长度、意外的协议标记都必须有明确的回落路径。如果存在未覆盖的输入,审查系统可以通过遍历来发现未定义行为,从而暴露代理。
状态无关性(State independence):回落行为不得依赖于先前的探测历史。如果第一次探测影响了第二次探测的响应行为,审查系统可以通过串行探测来推断内部状态机的存在。例如:如果第一个探针触发了某种内部缓存或错误状态,使得第二个不同类型的探针收到不同的响应,两个探针的响应矛盾就会暴露代理。每次连接的回落行为必须是独立的、无状态的。
资源公平性(Resource fairness):探针处理的资源消耗必须与正常请求一致。如果探针触发了异常的 CPU/内存消耗(例如正则回溯、超长缓冲区分配),审查系统可以通过资源压力探测来确认目标为代理(标准 Web 服务器在负载下的降级行为是已知的和可预测的)。
审查系统的探测不是单次行为,而是多阶段协调攻击。单一探针的防御是不够的 — 所有探针响应在联合分析时也必须一致。
典型的多阶段探测流程:
关键洞察:单次探针防御是不够的。当审查系统将多次探针的响应联合分析时,不同探针之间的矛盾会暴露代理身份。
典型的矛盾暴露场景:
Server: nginx),但 TLS 探针触发 OpenSSL 风格的 Alert — 矛盾暴露"声称 Nginx 但后端是 OpenSSL"防御要求:
所有探针类型的响应必须在内容和格式上相互一致(模拟同一个 Web 服务器)
所有探针的 TLS 指纹必须一致(同一个 TLS 库的实现特征)
所有探针的响应时间分布必须一致(与正常请求无明显差异)
大规模并发下,降级行为必须与真实 Web 服务器一致
TLS 1.2 降级路径合规:审查系统可能发送仅支持 TLS 1.2 的 ClientHello 来强制降级。降级后服务端的行为是否与标准 TLS 1.2 实现一致?降级路径的响应行为、密码套件选择、证书格式必须符合 TLS 1.2 规范,不得因降级而暴露非标准行为
| 检查项 | 说明 |
|---|---|
| 握手后 HMAC 验证 | TLS 通道建立后,第一个 application_data 记录是否携带 HMAC 签名?验证失败是否安全回落? |
| 验证时序 | HMAC 验证是否在数据传递给后端代理引擎之前完成?先传递后验证会暴露侧信道 |
| 常量时间比较 | HMAC 验证是否使用常量时间比较函数?非常量时间比较会通过响应时间差异泄漏 HMAC 值的信息 |
| 检查项 | 说明 |
|---|---|
| 前置代理架构 | 是否将工业级反向代理(CDN/Nginx/Caddy)置于代理核心之前?直接暴露代理核心会增加攻击面 |
| L7 路由验证 | 是否通过 HTTP 层的 Authorization header 进行第七层路由?仅匹配的请求才转发给代理引擎 |
| 默认页面 | 未匹配的请求是否返回合法的默认网页?空白响应或 404 是可疑特征 |
| 检查项 | 说明 |
|---|---|
| 外层 TLS 合规 | 如果使用双 TLS 架构(外层正常 TLS + 内层加密隧道),外层 TLS 是否完全模拟标准 Web 服务器行为? |
| 内层隐藏 | 内层加密隧道是否对外层完全不可见?审查系统的探针只能触及外层 TLS |
| WebSocket+TLS | 如果使用 WebSocket 作为传输,是否正确实现 HTTP 升级握手?升级前的 HTTP 行为必须与标准 Web 服务器一致 |
| CDN 前置 | 如果通过 CDN 前置,CDN 是否正确处理所有探针?CDN 的响应行为(错误页面、超时)是否与直接部署一致? |
| 检查项 | 说明 |
|---|---|
| 连接数限制 | 是否有最大连接数限制?审查系统可能通过大量并发连接来探测服务器的资源管理行为 |
| 单连接内存限制 | 单个连接的内存使用是否有上限?畸形或超大请求是否被限制? |
| 全阶段超时保护 | 所有握手和认证阶段是否有合理的超时?无超时则探针可占用连接资源,同时大量半开连接可导致服务降级 |
| 半开连接清理 | 半开连接(如只发了 ClientHello 未完成握手)是否被及时清理?积累的半开连接会影响正常用户的响应时间,响应时间异常间接暴露代理 |
| 降级行为模拟 | 资源耗尽时的降级行为是否与标准 Web 服务器一致?突然拒绝所有连接 vs 优雅降级是可区分的 |
| 检查项 | 说明 |
|---|---|
| 未授权探针处理 | 无密钥的探针到达时,是否退化为透明 TCP 转发器? |
| 证书篡改隐蔽性 | 合法客户端的证书签名篡改是否精确?篡改范围不得超出原始签名字段 |
| dest 连接可靠性 | 回落建立的到真实网站的连接是否可靠?dest 不可达会导致探针无法获得合法响应 |
| 握手超时保护 | 握手是否有超时保护?无超时则探针可占用连接资源 |
| 转发透明性 | 透明转发时是否完全透传所有字节?包括 TCP 紧急数据和窗口更新 |
重放攻击防御的完整审计见
replay-audit技能,涵盖时间戳校验、Nonce 唯一性、AEAD 认证、选择密文攻击防御、延迟重放防御、响应行为分析等。
replay-audit 覆盖了本 skill 未深入探讨的重放攻击 nonce 记忆持久化、选择密文攻击 256 变体防御、多用户分区预言攻击维度leak-audit 覆盖了本 skill 未深入探讨的错误响应格式指纹、日志泄漏、部署规模追踪维度traffic-audit 覆盖了本 skill 未深入探讨的流量统计分析、包长分布、时间间隔模式、多会话关联分析维度dpi-audit 覆盖了本 skill 未深入探讨的 TLS 指纹一致性、ALPN 协商状态机、TCP/IP 栈指纹维度security-audit 提供了安全审计 skills 的编排指南,确定修改特定代码时应按何种顺序执行哪些审计// ❌ 认证失败直接断开 — 暴露代理行为
if (!authenticated)
{
transport_->close();
}
// ✅ 认证失败透明转发到真实网站
if (!authenticated)
{
co_await fallback_dest(session, inbound, raw_record);
}
// ❌ 非常量时间比较 — 侧信道泄露
if (memcmp(received_hash, expected_hash, hash_len) == 0) { ... }
// ✅ 常量时间比较
if (CRYPTO_memcmp(received_hash, expected_hash, hash_len) == 0) { ... }
// ❌ 回落转发丢弃原始数据
auto [ec, raw_record] = co_await read_tls_record(inbound);
co_await async_write(dest, net::buffer(raw_record.data(), partial_size));
// ✅ 完整转发所有原始数据
co_await async_write(dest, net::buffer(raw_record.data(), raw_record.size()));
// ❌ 跨协议探测暴露身份 — 443 端口返回 SSH 错误
if (data.starts_with("SSH-2.0"))
{
co_await send("Protocol mismatch\r\n");
}
// ✅ 跨协议探测按 TLS 标准处理
if (!looks_like_tls_record(data))
{
co_await send_tls_alert(alert_level::fatal, alert_description::handshake_failure);
}
// ❌ 时序侧信道 — 认证失败路径明显更快
if (!authenticated)
{
co_return; // 立即返回,无回落开销
}
// ✅ 认证失败路径与成功路径时间接近
if (!authenticated)
{
co_await fallback_dest(session, inbound, raw_record); // 有回落开销
}
// ❌ 未处理输入 — 违反完备性
// 未知协议版本号直接忽略,无回落
if (version != expected_v1 && version != expected_v2)
{
co_return; // 未定义行为,探针无法获得任何响应
}
// ✅ 所有输入都有明确回落路径 — 满足完备性
if (version != expected_v1 && version != expected_v2)
{
co_await fallback_dest(session, inbound, raw_record); // 任何未知输入都回落
}
// ❌ 状态依赖 — 第二次探针收到不同响应
// 全局计数器导致第一次和第二次探针行为不同
static std::int32_t probe_count = 0;
probe_count++;
if (probe_count > threshold)
{
close_immediately(); // 降级行为异常,暴露内部状态
}
// ✅ 每次连接独立处理 — 满足状态无关性
// 不依赖全局探针计数,每次连接的回落行为独立
co_await fallback_dest(session, inbound, raw_record);
// ❌ 多探针矛盾 — HTTP 探针返回 Nginx 错误但 TLS 层暴露 OpenSSL
// HTTP 处理器
send_http_400_with_header("Server: nginx");
// TLS Alert 处理器
send_openssl_style_tls_alert(); // 与 Nginx 的 TLS 指纹不一致
// ✅ 所有响应层使用一致的 Web 服务器身份
// 统一使用目标回落服务器的完整指纹(HTTP 头 + TLS 行为 + 证书链)
co_await transparent_forward_to_dest(session, inbound, raw_record);
// ❌ 资源耗尽降级异常 — 达到连接上限后直接 RST
if (active_conns >= max_conns)
{
socket.close(); // 突然断开,标准 Web 服务器不会这样
}
// ✅ 资源耗尽降级行为与标准 Web 服务器一致
if (active_conns >= max_conns)
{
co_await send_http_503(); // 标准服务不可用响应
co_await graceful_close();
}