[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"consumer-news-detail-937":3,"consumer-news-interaction-937":38,"consumer-news-related-937":41},{"detail":4,"item":34},{"card":5,"schemaVersion":21,"fields":22,"content":28},{"id":6,"kind":7,"targetType":8,"targetId":9,"subtype":7,"typeLabel":10,"title":11,"subtitle":12,"summary":13,"coverUrl":14,"badgeText":14,"href":15,"sourceName":12,"meta":16,"metrics":18,"tags":19,"resolved":20},"NEWS_ARTICLE:937","news","NEWS_ARTICLE",937,"资讯","实战攻防中SNI技术应用","博客园","SNI 是 TLS 协议里一个很基础的机制，但在攻防里它的意义很特殊——因为它是明文的。 一、SNI 是什么 SNI（Server Name Indication，服务器名称指示） 是 TLS 握手的扩展字段。客户端在建立 HTTPS 连接时，会在 ClientHello 里明文告诉服务器「我要访问","","\u002Fnews\u002F937",[17],"2026",{},[],true,"consumer-content-detail-v1",{"sourceName":12,"authorName":23,"summary":13,"description":13,"publishTime":24,"updateTime":25,"sourceUrl":26,"language":27},"菜就多练forever","2026-09-10T16:24","2026-09-11T15:21:59","https:\u002F\u002Fwww.cnblogs.com\u002FNBeveryday\u002Fp\u002F22923122\u002Fsni","中文",{"format":29,"policy":30,"normalized":20,"html":31,"text":32,"wordCount":33,"hasBody":20},"HTML","NEWS_CONTENT_V1","\u003Cp>SNI 是 TLS 协议里一个很基础的机制，但在攻防里它的意义很特殊——\u003Cstrong>因为它是明文的\u003C\u002Fstrong>。\u003C\u002Fp>\n\u003Ch2>一、SNI 是什么\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>SNI（Server Name Indication，服务器名称指示）\u003C\u002Fstrong> 是 TLS 握手的扩展字段。客户端在建立 HTTPS 连接时，会在 \u003Cstrong>ClientHello\u003C\u002Fstrong> 里\u003Cstrong>明文\u003C\u002Fstrong>告诉服务器「我要访问哪个域名」，这样一台服务器（同一个 IP）才能返回对应的证书，实现\u003Cstrong>一个 IP 托管多个 HTTPS 网站\u003C\u002Fstrong>。\u003C\u002Fp>\n\u003Cp>关键点：\u003Cstrong>SNI 在加密建立之前发送，是明文的\u003C\u002Fstrong>（除非用 ECH）。这正是它在攻防中重要的原因。\u003C\u002Fp>\n\u003Cpre>\u003Ccode>ClientHello\n  └── SNI: www.example.com   ← 明文可见\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>二、攻击方视角的应用场景\u003C\u002Fh2>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>场景\u003C\u002Fth>\n   \u003Cth>说明\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>流量识别与阻断\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>中间设备\u002F防火墙读取 SNI 明文，判断目标域名并封禁。这是很多企业网关、运营商做域名过滤的常用手段\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>资产测绘\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>用 SNI 反查：给一个 IP，发不同 SNI，观察返回的证书。可以\u003Cstrong>发现同一 IP 上隐藏的其他站点\u003C\u002Fstrong>，用于资产梳理\u002F攻击面发现\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>绕过 IP 封禁\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>目标封了 IP 但没做 SNI 校验时，用\u003Cstrong>域名+SNI 指向被封 IP\u003C\u002Fstrong> 仍可访问\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>域名前置（Domain Fronting）\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>用合法大站域名做 SNI，实际流量转发到目标，\u003Cstrong>隐藏真实通信目标\u003C\u002Fstrong>，常用于绕过审查\u002FC2 隐蔽通信\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>CDN 回源与真实 IP 探测\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>结合 SNI 与证书信息，判断站点是否挂在 CDN 后面，寻找回源 IP\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>证书信息搜集\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>SNI 对应的证书里常含域名、组织名，用于情报收集\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch2>三、防守方视角的应用场景\u003C\u002Fh2>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>场景\u003C\u002Fth>\n   \u003Cth>说明\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>流量审计\u002F出入站控制\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>基于 SNI 做域名白名单\u002F黑名单，管住内网出站访问\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>恶意 TLS 流量检测\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>检测异常 SNI（如 SNI 与证书不匹配、域名为 DGA 生成、SNI 为空或乱码）\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>CDN\u002F负载均衡\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>依据 SNI 分流到不同后端（这是正常业务用法）\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>威胁情报匹配\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>把 SNI 与情报库比对，识别 C2、钓鱼域名\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch2>四、值得注意的技术演进\u003C\u002Fh2>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>技术\u003C\u002Fth>\n   \u003Cth>作用\u003C\u002Fth>\n   \u003Cth>对攻防的影响\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>ESNI（已废弃）\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>早期尝试加密 SNI\u003C\u002Ftd>\n   \u003Ctd>被 ECH 取代\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>ECH（Encrypted Client Hello）\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>加密整个 ClientHello，包括 SNI\u003C\u002Ftd>\n   \u003Ctd>\u003Cstrong>让基于 SNI 的识别\u002F阻断失效\u003C\u002Fstrong>，是防守方检测能力的新挑战\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>SNI 为空\u002F伪装\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>客户端不发或发假 SNI\u003C\u002Ftd>\n   \u003Ctd>常用于绕过 SNI 过滤，但会与证书不匹配，容易被识别\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch2>一句话总结\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>SNI 是 TLS 握手里明文的「目标域名标签」\u003C\u002Fstrong>：\u003C\u002Fp>\n\u003Cul>\n \u003Cli>\u003Cstrong>攻击方\u003C\u002Fstrong>用它做资产测绘、流量混淆、绕封禁（域名前置最典型）；\u003C\u002Fli>\n \u003Cli>\u003Cstrong>防守方\u003C\u002Fstrong>用它做出站管控、流量审计、恶意域名识别；\u003C\u002Fli>\n \u003Cli>\u003Cstrong>ECH 的出现\u003C\u002Fstrong>正在让「靠 SNI 看流量」这套打法逐渐失效。\u003C\u002Fli>\n\u003C\u002Ful>\n检测异常 SNI 有什么特征，如何在zeek、wirshark或者SOC 态势产品上发现或者验证而已SNI流量\n\u003Cp>这是个偏防守侧的好问题。我按「\u003Cstrong>异常特征 → 各平台落地方法 → 验证思路\u003C\u002Fstrong>」三层来讲，尽量给可操作的规则而不是泛泛而谈。\u003C\u002Fp>\n\u003Ch2>一、异常 SNI 的特征清单\u003C\u002Fh2>\n\u003Ch3>1. 协议层异常（最容易落地检测）\u003C\u002Fh3>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>特征\u003C\u002Fth>\n   \u003Cth>说明\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>SNI 与证书 CN\u002FSAN 不匹配\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>最经典的异常信号。请求 \u003Ccode>a.com\u003C\u002Fcode> 但服务器返回 \u003Ccode>b.com\u003C\u002Fcode> 的证书\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>SNI 缺失（空）\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>现代浏览器几乎必发 SNI；空 SNI 常见于恶意工具、扫描器、老旧\u002F定制客户端\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>SNI 是 IP 字面量\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>正常客户端很少把 IP 当 SNI\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>SNI 与 HTTP Host 不一致\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>同一连接里 TLS 层和 HTTP 层目标不一致 → 疑似隧道\u002F代理\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>SNI 后跟不同的 SNI（同连接）\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>罕见，可能异常协商\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3>2. 内容层异常\u003C\u002Fh3>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>特征\u003C\u002Fth>\n   \u003Cth>说明\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>域名非标准格式\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>纯数字、随机字符串、超长域名、多级随机子域（DGA 特征）\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>使用免费\u002F可疑 TLD\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>\u003Ccode>.tk .ml .ga .cf .xyz .top\u003C\u002Fcode> 等高频出现在恶意外联\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>域名刚注册\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>结合 whois\u002F情报：注册时间 &lt; 30 天\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>命中威胁情报\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>SNI 落在 C2、钓鱼、矿池等情报库中\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>高频轮换\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>同一源 IP 短时间内访问大量不同 SNI（扫描\u002FDGA 行为）\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>时序\u002F长度异常\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>心跳式周期连接、固定大小包（C2 beacon 特征）\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3>3. 行为层异常\u003C\u002Fh3>\n\u003Cul>\n \u003Cli>单主机 \u003Cstrong>SNI 数量异常多\u003C\u002Fstrong>；\u003C\u002Fli>\n \u003Cli>非工作时间的固定周期外联；\u003C\u002Fli>\n \u003Cli>内网主机访问与业务无关的外部域名；\u003C\u002Fli>\n \u003Cli>同一 SNI 分辨率下的\u003Cstrong>证书频繁变化\u003C\u002Fstrong>。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Chr>\n\u003Ch2>二、Zeek 上怎么发现\u003C\u002Fh2>\n\u003Cp>Zeek 自带 \u003Ccode>ssl.log\u003C\u002Fcode>，里面有 \u003Ccode>server_name\u003C\u002Fcode>（SNI）、\u003Ccode>subject\u003C\u002Fcode>、\u003Ccode>issuer\u003C\u002Fcode>、\u003Ccode>validation_status\u003C\u002Fcode> 等字段，非常适合做检测。\u003C\u002Fp>\n\u003Cp>\u003Cstrong>关键字段\u003C\u002Fstrong>：\u003C\u002Fp>\n\u003Cul>\n \u003Cli>\u003Ccode>server_name\u003C\u002Fcode> — SNI\u003C\u002Fli>\n \u003Cli>\u003Ccode>subject\u003C\u002Fcode> \u002F \u003Ccode>issuer\u003C\u002Fcode> — 证书主体\u002F签发者\u003C\u002Fli>\n \u003Cli>\u003Ccode>validation_status\u003C\u002Fcode> — 含 \u003Ccode>certificate-unknown-authority\u003C\u002Fcode>、\u003Ccode>self signed certificate\u003C\u002Fcode> 等\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>实用检测思路\u003C\u002Fstrong>：\u003C\u002Fp>\n\u003Cpre>\u003Ccode># 1. 无 SNI 的 TLS 连接（可疑客户端）\nevent ssl_client_hello(c: connection, version: count, record_version: count,\n                        possible_ts: time, client_random: string,\n                        session_id: string, ciphers: index_vec,\n                        comp_methods: index_vec) {\n    if ( ! c$ssl?$server_name || c$ssl$server_name == \"\" )\n        print fmt(\"[No-SNI] %s -&gt; %s\", c$id$orig_h, c$id$resp_h);\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>更实用的做法是\u003Cstrong>用 Zeek 输出日志 + 集中分析\u003C\u002Fstrong>：\u003C\u002Fp>\n\u003Cul>\n \u003Cli>把 \u003Ccode>ssl.log\u003C\u002Fcode> 喂给 SIEM，做字段关联与情报匹配；\u003C\u002Fli>\n \u003Cli>用 \u003Ccode>conn.log\u003C\u002Fcode> 关联 \u003Ccode>ssl.log\u003C\u002Fcode>，看「同 SNI 的证书是否稳定」。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>验证方式\u003C\u002Fstrong>：\u003Ccode>zeek -r capture.pcap\u003C\u002Fcode> 重放流量，直接看 \u003Ccode>ssl.log\u003C\u002Fcode> 里的 \u003Ccode>server_name\u003C\u002Fcode> \u002F \u003Ccode>validation_status\u003C\u002Fcode>。\u003C\u002Fp>\n\u003Chr>\n\u003Ch2>三、Wireshark 上怎么发现\u003C\u002Fh2>\n\u003Ch3>显示过滤器（快速定位）\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># 只看含 SNI 的 ClientHello\ntls.handshake.extensions_server_name\n\n# 按具体 SNI 过滤\ntls.handshake.extensions_server_name == \"example.com\"\n\n# 无 SNI 的 ClientHello\ntls.handshake.type == 1 &amp;&amp; !tls.handshake.extensions_server_name\n\n# 找证书里的 CN（配合 SNI 对比）\ntls.handshake.type == 11\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>排查手法\u003C\u002Fh3>\n\u003Col>\n \u003Cli>\u003Ccode>tls.handshake.type == 1\u003C\u002Fcode> 抓 ClientHello → 展开 \u003Cstrong>Extension: server_name\u003C\u002Fstrong> 看明文 SNI；\u003C\u002Fli>\n \u003Cli>再找同连接的 \u003Cstrong>Certificate\u003C\u002Fstrong> 消息 → 看 CN\u002FSAN；\u003C\u002Fli>\n \u003Cli>\u003Cstrong>两者不一致\u003C\u002Fstrong>，即为强异常信号。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cblockquote>\n \u003Cp>小技巧：\u003Ccode>Statistics → Conversations\u003C\u002Fcode> 看 TLS 会话，再逐条跟到 SNI。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Chr>\n\u003Ch2>四、SOC \u002F 态势感知怎么落地\u003C\u002Fh2>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>能力\u003C\u002Fth>\n   \u003Cth>实现方式\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>日志接入\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>采集 Zeek \u003Ccode>ssl.log\u003C\u002Fcode>、防火墙\u002F代理日志、DNS 日志\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>关联分析\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>SNI ↔ DNS 查询 ↔ 证书 ↔ 源主机 多源关联（能大幅降误报）\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>情报匹配\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>SNI 与威胁情报（C2\u002F钓鱼\u002F矿池域名）实时比对\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>基线建模\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>建立「主机—SNI」正常基线，检测\u003Cstrong>从未出现过的新 SNI\u003C\u002Fstrong>、\u003Cstrong>异常时段外联\u003C\u002Fstrong>\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>规则告警\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>无 SNI、SNI\u002F证书不匹配、DGA 域名、可疑 TLD、高频轮换\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>可视化\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>SNI 频次 TOP、新出现域名趋势、主机外联拓扑\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>\u003Cstrong>推荐的降误报组合\u003C\u002Fstrong>（单看 SNI 误报很高，要叠加）：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>异常SNI  AND  (新域名 OR 命中情报 OR 无SNI OR 证书不匹配)  AND  内网主机发起\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Chr>\n\u003Ch2>五、验证用的实验方法（授权前提下）\u003C\u002Fh2>\n\u003Cp>要验证检测规则是否有效，可以在自己环境里做：\u003C\u002Fp>\n\u003Col>\n \u003Cli>\u003Cstrong>构造异常流量\u003C\u002Fstrong>： \n  \u003Cul>\n   \u003Cli>用 \u003Ccode>curl --resolve example.com:443:1.2.3.4 https:\u002F\u002Fexample.com\u002F\u003C\u002Fcode> 验证「SNI 与证书不匹配」；\u003C\u002Fli>\n   \u003Cli>用 \u003Ccode>openssl s_client -servername &lt;SNI&gt; -connect &lt;ip&gt;:443\u003C\u002Fcode> 指定任意 SNI，观察返回证书；\u003C\u002Fli>\n   \u003Cli>用 \u003Ccode>curl --no-alpn\u003C\u002Fcode> 或自定义客户端构造\u003Cstrong>空 SNI\u003C\u002Fstrong>。\u003C\u002Fli>\n  \u003C\u002Ful>\u003C\u002Fli>\n \u003Cli>\u003Cstrong>抓包验证\u003C\u002Fstrong>：Wireshark 确认 SNI 字段值，标记 pcap 作为测试样本。\u003C\u002Fli>\n \u003Cli>\u003Cstrong>回放检测\u003C\u002Fstrong>：\u003Ccode>zeek -r test.pcap\u003C\u002Fcode>，确认 \u003Ccode>ssl.log\u003C\u002Fcode> 抓出预期字段；再喂 SIEM 看规则是否触发。\u003C\u002Fli>\n \u003Cli>\u003Cstrong>误报评估\u003C\u002Fstrong>：用正常业务流量做基线，测量误报率后再调阈值。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cblockquote>\n \u003Cp>⚠️ 边界提醒：以上\u003Cstrong>验证方法只应在你自有或明确授权的环境中进行\u003C\u002Fstrong>。「指定任意 SNI 探测某 IP 返回证书」这类操作若指向未授权目标，属于越界探测。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Chr>\n\u003Ch2>六、必须知道的现实局限\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>ECH（Encrypted Client Hello）正在让 SNI 检测逐渐失效\u003C\u002Fstrong>——启用 ECH 后 SNI 被加密，网关只能看到外层 SNI（通常是 CDN 域名）。\u003C\u002Fp>\n\u003Cp>应对方向：\u003C\u002Fp>\n\u003Cul>\n \u003Cli>从 \u003Cstrong>SNI 检测\u003C\u002Fstrong>转向\u003Cstrong>证书\u002F指纹\u002F行为检测\u003C\u002Fstrong>（JA3\u002FJA4 指纹、连接时序、流量大小分布）；\u003C\u002Fli>\n \u003Cli>结合 \u003Cstrong>DNS 层\u003C\u002Fstrong>（DoH\u002FDoT 会让 DNS 也难见，需终端侧遥测）；\u003C\u002Fli>\n \u003Cli>加强\u003Cstrong>端点侧（EDR）\u003C\u002Fstrong>的可见性，弥补网络层盲区。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Chr>\n\u003Ch2>一句话总结\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>异常 SNI 的核心信号\u003C\u002Fstrong>是「无 SNI、SNI 与证书不匹配、域名字符串可疑、行为高频轮换」；\u003Cstrong>Zeek 看 \u003Ccode>ssl.log\u003C\u002Fcode>、Wireshark 用 \u003Ccode>tls.handshake.extensions_server_name\u003C\u002Fcode> 过滤器\u003C\u002Fstrong>即可快速发现，\u003Cstrong>SOC 上要叠加情报与基线才能把误报压下来\u003C\u002Fstrong>；而 \u003Cstrong>ECH 正让这条检测路径失效\u003C\u002Fstrong>，需要转向指纹与端点侧遥测。\u003C\u002Fp>\n异常 SNI 检测：Zeek 脚本 + Wireshark 过滤器清单\n\u003Cblockquote>\n \u003Cp>用途：在\u003Cstrong>自有或已授权\u003C\u002Fstrong>环境中，检测 TLS 握手阶段的异常 SNI 行为\u003Cbr>\n   适用：Zeek 5.x \u002F 6.x；Wireshark 3.6+\u003Cbr>\n   ⚠️ 仅限自有系统或明确授权的安全测试场景使用\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Chr>\n\u003Ch2>一、Zeek 脚本\u003C\u002Fh2>\n\u003Ch3>1.1 部署方式\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># 放到 Zeek 本地站点目录\nsudo cp snicheck.zeek \u002Fusr\u002Flocal\u002Fzeek\u002Fshare\u002Fzeek\u002Fsite\u002F\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>在 \u003Ccode>local.zeek\u003C\u002Fcode> 中加载：\u003C\u002Fp>\n\u003Cpre>\u003Ccode># \u002Fusr\u002Flocal\u002Fzeek\u002Fshare\u002Fzeek\u002Fsite\u002Flocal.zeek\n@load .\u002Fsnicheck\n\n# 务必定义本地网段，否则脚本不检测内网流量\nredef Site::local_nets += { 10.0.0.0\u002F8, 172.16.0.0\u002F12, 192.168.0.0\u002F16 };\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>或命令行直接跑：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>zeek -r capture.pcap site\u002Fsnicheck.zeek Site::local_nets=10.0.0.0\u002F8\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Chr>\n\u003Ch3>1.2 主脚本 \u003Ccode>snicheck.zeek\u003C\u002Fcode>\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>##! 异常 SNI 检测脚本\n##! 检测：无 SNI、可疑 TLD、DGA 特征、SNI\u002F证书不匹配、高频轮换\n##! 依赖：本机所抓 TLS 流量 + Site::local_nets 定义\n\nmodule SNICheck;\n\nexport {\n    redef enum Notice::Type += {\n        No_SNI,\n        SNI_Cert_Mismatch,\n        Suspicious_TLD,\n        DGA_Like_SNI,\n        SNI_High_Frequency,\n    };\n\n    ## ---- 可调参数 ----\n    # 可疑\u002F高频滥用 TLD\n    const suspicious_tlds: set[string] = {\n        \"tk\", \"ml\", \"ga\", \"cf\", \"gq\", \"xyz\", \"top\", \"buzz\",\n        \"click\", \"work\", \"loan\", \"review\", \"country\", \"stream\"\n    } &amp;redef;\n\n    # 同一源主机在窗口内访问的不同 SNI 数阈值（扫描\u002F轮换告警）\n    const sni_freq_threshold: count = 50 &amp;redef;\n    const sni_freq_window: interval = 5min &amp;redef;\n\n    # 无 SNI 白名单（内部服务、已知合法客户端）\n    const no_sni_whitelist: set[subnet] = {} &amp;redef;\n}\n\n# ---------- 辅助：DGA 特征判断 ----------\nfunction dga_like(name: string): bool\n    {\n    local parts = split_string(name, \u002F\\.\u002F);\n    if ( |parts| &lt; 2 )\n        return F;\n\n    local label = parts[|parts| - 2];   # 二级域名标签\n\n    # 条件1：标签过长\n    if ( |label| &gt;= 15 )\n        return T;\n\n    # 条件2：数字占比 &gt;= 40%\n    local digits = 0;\n    local letters = 0;\n    local i = 0;\n    local ch = \"\";\n    for ( i in label )\n        {\n        ch = label[i];\n        if ( ch in \"0123456789\" )\n            digits += 1;\n        else if ( ch in \"abcdefghijklmnopqrstuvwxyz\" )\n            letters += 1;\n        }\n\n    if ( digits + letters == 0 )\n        return F;\n    if ( digits * 100 \u002F (digits + letters) &gt;= 40 )\n        return T;\n\n    # 条件3：连续 5 个及以上辅音（随机串特征）\n    local cons = 0;\n    local vowels = \"aeiou\";\n    for ( i in label )\n        {\n        ch = label[i];\n        if ( ch !in vowels &amp;&amp; ch !in \"0123456789\" )\n            {\n            cons += 1;\n            if ( cons &gt;= 5 )\n                return T;\n            }\n        else\n            cons = 0;\n        }\n\n    return F;\n    }\n\n# ---------- 状态表：统计每源主机的 SNI 频次 ----------\nglobal sni_tracker: table[addr] of set[string] &amp;create_expire=sni_freq_window;\n\n# ---------- 检测 1：无 SNI ----------\n# 说明：ssl_client_hello 的签名在 Zeek 各版本间略有差异，\n#      这里使用最通用的 (c, version, record_version) 前三个参数写法。\nevent ssl_client_hello(c: connection, version: count, record_version: count)\n    {\n    local orig = c$id$orig_h;\n    local resp = c$id$resp_h;\n\n    # 仅关注内网发起的连接\n    if ( orig !in Site::local_nets )\n        return;\n\n    if ( orig in no_sni_whitelist )\n        return;\n\n    if ( ! c$ssl?$server_name || c$ssl$server_name == \"\" )\n        {\n        NOTICE([$note=No_SNI,\n                $conn=c,\n                $msg=fmt(\"TLS connection without SNI: %s -&gt; %s:%s\", orig, resp, c$id$resp_p),\n                $identifier=cat(orig, resp)]);\n        }\n    }\n\n# ---------- 检测 2\u002F3\u002F4：可疑 TLD、DGA、SNI\u002F证书不匹配 ----------\nevent ssl_established(c: connection)\n    {\n    if ( ! c$ssl?$server_name || c$ssl$server_name == \"\" )\n        return;\n\n    local sni = c$ssl$server_name;\n    local sni_lower = to_lower(sni);\n\n    # 2a. 可疑 TLD\n    local s_parts = split_string(sni_lower, \u002F\\.\u002F);\n    local tld = \"\";\n    if ( |s_parts| &gt;= 2 )\n        {\n        tld = s_parts[|s_parts| - 1];\n        if ( tld in suspicious_tlds )\n            NOTICE([$note=Suspicious_TLD,\n                    $conn=c,\n                    $msg=fmt(\"Suspicious TLD: SNI=%s\", sni),\n                    $identifier=cat(c$id$orig_h, sni)]);\n        }\n\n    # 2b. DGA 特征\n    if ( dga_like(sni_lower) )\n        NOTICE([$note=DGA_Like_SNI,\n                $conn=c,\n                $msg=fmt(\"DGA-like SNI: %s\", sni),\n                $identifier=cat(c$id$orig_h, sni)]);\n\n    # 2c. SNI 与证书主体不匹配\n    if ( c$ssl?$certificate &amp;&amp; c$ssl$certificate$subject != \"\" &amp;&amp;\n         sni_lower !in to_lower(c$ssl$certificate$subject) )\n        {\n        NOTICE([$note=SNI_Cert_Mismatch,\n                $conn=c,\n                $msg=fmt(\"SNI\u002Fcert mismatch: SNI=%s cert=%s\",\n                         sni, c$ssl$certificate$subject),\n                $identifier=cat(c$id$orig_h, sni)]);\n        }\n    }\n\n# ---------- 检测 5：高频 SNI（扫描 \u002F 轮换） ----------\nevent ssl_established(c: connection)\n    {\n    if ( ! c$ssl?$server_name || c$ssl$server_name == \"\" )\n        return;\n\n    local orig = c$id$orig_h;\n    if ( orig !in Site::local_nets )\n        return;\n\n    if ( orig !in sni_tracker )\n        sni_tracker[orig] = set();\n\n    add sni_tracker[orig][c$ssl$server_name];\n\n    if ( |sni_tracker[orig]| == sni_freq_threshold )\n        {\n        NOTICE([$note=SNI_High_Frequency,\n                $conn=c,\n                $msg=fmt(\"Source %s hit %d distinct SNIs within %s (possible scan\u002Frotation)\",\n                         orig, sni_freq_threshold, sni_freq_window),\n                $identifier=cat(orig)]);\n        }\n    }\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Chr>\n\u003Ch3>1.3 部署后验证\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># 1) 语法检查（-a 表示仅解析不执行）\nzeek -a site\u002Fsnicheck.zeek\n\n# 2) 回放 pcap（记得指定本地网段）\nzeek -r test.pcap site\u002Fsnicheck.zeek Site::local_nets=10.0.0.0\u002F8\n\n# 3) 查看告警\ncat notice.log | zeek-cut note msg id.orig_h id.resp_h\n\n# 4) 查看 SNI 明细（ssl.log 自带）\ncat ssl.log | zeek-cut id.orig_h id.resp_h server_name validation_status\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Chr>\n\u003Ch3>1.4 脚本要点说明（部署前必读）\u003C\u002Fh3>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>要点\u003C\u002Fth>\n   \u003Cth>说明\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>必须定义 \u003Ccode>Site::local_nets\u003C\u002Fcode>\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>否则 \u003Ccode>orig !in Site::local_nets\u003C\u002Fcode> 恒真，脚本不会报任何告警\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>\u003Ccode>ssl_client_hello\u003C\u002Fcode> 签名\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>各 Zeek 版本参数不同，脚本只取前三个参数（Zeek 支持按前缀匹配 event 签名）。若你的版本编译报参数错误，改为 \u003Ccode>event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec)\u003C\u002Fcode> 补齐\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>\u003Ccode>c$ssl?$certificate\u003C\u002Fcode>\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>证书字段并非所有连接都有，必须先判断存在性再访问，脚本已处理\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>\u003Ccode>&amp;create_expire\u003C\u002Fcode>\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>5 分钟窗口自动清理，避免状态表无限增长\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Cstrong>两个 \u003Ccode>ssl_established\u003C\u002Fcode>\u003C\u002Fstrong>\u003C\u002Ftd>\n   \u003Ctd>Zeek 允许多个同名 event handler，会依次执行；如需合并可自行整理为一个\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Chr>\n\u003Ch2>二、Wireshark 过滤器清单\u003C\u002Fh2>\n\u003Ch3>2.1 基础定位（含 SNI 的握手）\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># 只显示含 SNI 的 ClientHello\ntls.handshake.type == 1 &amp;&amp; tls.handshake.extensions_server_name\n\n# 所有 ClientHello（含无 SNI 的）\ntls.handshake.type == 1\n\n# 按具体 SNI 过滤\ntls.handshake.extensions_server_name == \"example.com\"\ntls.handshake.extensions_server_name contains \"example\"\n\n# 无 SNI 的 ClientHello（可疑客户端\u002F扫描器）\ntls.handshake.type == 1 &amp;&amp; !tls.handshake.extensions_server_name\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>2.2 证书与 SNI 对比排查\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># 显示证书消息（看 CN\u002FSAN）\ntls.handshake.type == 11\n\n# 证书里包含某个域名（与 SNI 对比）\ntls.handshake.certificate contains \"example.com\"\n\n# 只看 ServerHello + Certificate（快速看服务端返回）\ntls.handshake.type == 2 || tls.handshake.type == 11\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>2.3 按主机 \u002F IP 过滤\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># 某 IP 的所有 TLS\nip.addr == 10.0.0.5 &amp;&amp; tls\n\n# 某内网主机发起的 ClientHello\nip.src == 10.0.0.5 &amp;&amp; tls.handshake.type == 1\n\n# 排除某个已知合法的 SNI\ntls.handshake.type == 1 &amp;&amp; tls.handshake.extensions_server_name != \"internal.corp.com\"\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>2.4 结合时间 \u002F 流\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># 指定时间段的 ClientHello\nframe.time &gt;= \"2026-09-10 09:00:00\" &amp;&amp; frame.time &lt;= \"2026-09-10 18:00:00\" &amp;&amp; tls.handshake.type == 1\n\n# 按 TCP 流排查\ntcp.stream == 12 &amp;&amp; tls\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>2.5 快捷排查动作\u003C\u002Fh3>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>目的\u003C\u002Fth>\n   \u003Cth>操作\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>看 SNI 明文\u003C\u002Ftd>\n   \u003Ctd>抓 ClientHello → 展开 \u003Ccode>Extension: server_name\u003C\u002Fcode>\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>看证书 CN\u002FSAN\u003C\u002Ftd>\n   \u003Ctd>同连接 Certificate 消息 → 展开 \u003Ccode>signedCertificate\u003C\u002Fcode>\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>SNI 与证书比对\u003C\u002Ftd>\n   \u003Ctd>两条消息对照，域名不一致即异常\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>找无 SNI 连接\u003C\u002Ftd>\n   \u003Ctd>用 2.1 最后一条过滤器\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>批量看会话\u003C\u002Ftd>\n   \u003Ctd>\u003Ccode>Statistics → Conversations → TCP\u003C\u002Fcode>\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Ch3>2.6 导出可疑样本供 Zeek 回放\u003C\u002Fh3>\n\u003Cpre>\u003Ccode># 只保留无 SNI 的流，导出为 no_sni.pcap\ntls.handshake.type == 1 &amp;&amp; !tls.handshake.extensions_server_name\n# File → Export Specified Packets\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Chr>\n\u003Ch2>三、验证流程（仅限授权环境）\u003C\u002Fh2>\n\u003Cpre>\u003Ccode>① 构造测试流量\n   - 无 SNI：      用可关闭 SNI 的客户端\u002F自写 TLS 客户端发起连接\n   - SNI 不匹配：  curl --resolve example.com:443:&lt;目标IP&gt; https:\u002F\u002Fexample.com\u002F\n   - 自定义 SNI：  openssl s_client -servername &lt;任意SNI&gt; -connect &lt;ip&gt;:443\n\n② 抓包确认\n   - Wireshark 用 2.1 \u002F 2.2 过滤器确认字段值\n\n③ 检测回放\n   - zeek -r test.pcap site\u002Fsnicheck.zeek Site::local_nets=10.0.0.0\u002F8\n   - 检查 notice.log 是否产生对应告警\n\n④ 误报评估\n   - 用正常业务 pcap 回放，统计误报\n   - 调整 sni_freq_threshold、suspicious_tlds、no_sni_whitelist 后复测\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Chr>\n\u003Ch2>四、参数调优建议\u003C\u002Fh2>\n\u003Ctable>\n \u003Cthead>\n  \u003Ctr>\n   \u003Cth>参数\u003C\u002Fth>\n   \u003Cth>默认\u003C\u002Fth>\n   \u003Cth>调整建议\u003C\u002Fth>\n  \u003C\u002Ftr>\n \u003C\u002Fthead>\n \u003Ctbody>\n  \u003Ctr>\n   \u003Ctd>\u003Ccode>sni_freq_threshold\u003C\u002Fcode>\u003C\u002Ftd>\n   \u003Ctd>50 \u002F 5min\u003C\u002Ftd>\n   \u003Ctd>办公网调高至 100+；服务器区可调低\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Ccode>suspicious_tlds\u003C\u002Fcode>\u003C\u002Ftd>\n   \u003Ctd>常见滥用 TLD\u003C\u002Ftd>\n   \u003Ctd>按贵司业务裁剪，避免误伤\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>\u003Ccode>no_sni_whitelist\u003C\u002Fcode>\u003C\u002Ftd>\n   \u003Ctd>空\u003C\u002Ftd>\n   \u003Ctd>加入内网服务网段、已知无 SNI 的合法客户端\u003C\u002Ftd>\n  \u003C\u002Ftr>\n  \u003Ctr>\n   \u003Ctd>SNI\u002F证书不匹配\u003C\u002Ftd>\n   \u003Ctd>全量告警\u003C\u002Ftd>\n   \u003Ctd>CDN 场景误报高，建议加白名单域\u003C\u002Ftd>\n  \u003C\u002Ftr>\n \u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Chr>\n\u003Ch2>五、局限与演进（务必知悉）\u003C\u002Fh2>\n\u003Col>\n \u003Cli>\u003Cstrong>ECH（Encrypted Client Hello）\u003C\u002Fstrong> 生效后 SNI 被加密，本套检测基本失效——需转向 \u003Cstrong>JA3\u002FJA4 指纹、连接时序、流量分布、端点遥测（EDR）\u003C\u002Fstrong>。\u003C\u002Fli>\n \u003Cli>\u003Cstrong>DoH\u002FDoT\u003C\u002Fstrong> 会让 DNS 侧关联变难，需终端侧数据补充。\u003C\u002Fli>\n \u003Cli>\u003Cstrong>CDN 场景\u003C\u002Fstrong>下 SNI 与证书不匹配属正常（证书由 CDN 签发），需白名单降误报。\u003C\u002Fli>\n \u003Cli>单看 SNI 误报较高，\u003Cstrong>务必叠加情报、基线、行为多维关联\u003C\u002Fstrong>再告警。\u003C\u002Fli>\n \u003Cli>本脚本\u003Cstrong>未做 pcap 实测验证\u003C\u002Fstrong>（编写环境无 Zeek 运行时），首次部署请在测试环境用 \u003Ccode>zeek -a\u003C\u002Fcode> 校验语法并回放样本确认。\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Chr>","SNI 是 TLS 协议里一个很基础的机制，但在攻防里它的意义很特殊——因为它是明文的。 一、SNI 是什么 SNI（Server Name Indication，服务器名称指示） 是 TLS 握手的扩展字段。客户端在建立 HTTPS 连接时，会在 ClientHello 里明文告诉服务器「我要访问哪个域名」，这样一台服务器（同一个 IP）才能返回对应的证书，实现一个 IP 托管多个 HTTPS 网站。 关键点：SNI 在加密建立之前发送，是明文的（除非用 ECH）。这正是它在攻防中重要的原因。 ClientHello └── SNI: www.example.com ← 明文可见 二、攻击方视角的应用场景 场景 说明 流量识别与阻断 中间设备\u002F防火墙读取 SNI 明文，判断目标域名并封禁。这是很多企业网关、运营商做域名过滤的常用手段 资产测绘 用 SNI 反查：给一个 IP，发不同 SNI，观察返回的证书。可以发现同一 IP 上隐藏的其他站点，用于资产梳理\u002F攻击面发现 绕过 IP 封禁 目标封了 IP 但没做 SNI 校验时，用域名+SNI 指向被封 IP 仍可访问 域名前置（Domain Fronting） 用合法大站域名做 SNI，实际流量转发到目标，隐藏真实通信目标，常用于绕过审查\u002FC2 隐蔽通信 CDN 回源与真实 IP 探测 结合 SNI 与证书信息，判断站点是否挂在 CDN 后面，寻找回源 IP 证书信息搜集 SNI 对应的证书里常含域名、组织名，用于情报收集 三、防守方视角的应用场景 场景 说明 流量审计\u002F出入站控制 基于 SNI 做域名白名单\u002F黑名单，管住内网出站访问 恶意 TLS 流量检测 检测异常 SNI（如 SNI 与证书不匹配、域名为 DGA 生成、SNI 为空或乱码） CDN\u002F负载均衡 依据 SNI 分流到不同后端（这是正常业务用法） 威胁情报匹配 把 SNI 与情报库比对，识别 C2、钓鱼域名 四、值得注意的技术演进 技术 作用 对攻防的影响 ESNI（已废弃） 早期尝试加密 SNI 被 ECH 取代 ECH（Encrypted Client Hello） 加密整个 ClientHello，包括 SNI 让基于 SNI 的识别\u002F阻断失效，是防守方检测能力的新挑战 SNI 为空\u002F伪装 客户端不发或发假 SNI 常用于绕过 SNI 过滤，但会与证书不匹配，容易被识别 一句话总结 SNI 是 TLS 握手里明文的「目标域名标签」： 攻击方用它做资产测绘、流量混淆、绕封禁（域名前置最典型）； 防守方用它做出站管控、流量审计、恶意域名识别； ECH 的出现正在让「靠 SNI 看流量」这套打法逐渐失效。 检测异常 SNI 有什么特征，如何在zeek、wirshark或者SOC 态势产品上发现或者验证而已SNI流量 这是个偏防守侧的好问题。我按「异常特征 → 各平台落地方法 → 验证思路」三层来讲，尽量给可操作的规则而不是泛泛而谈。 一、异常 SNI 的特征清单 1. 协议层异常（最容易落地检测） 特征 说明 SNI 与证书 CN\u002FSAN 不匹配 最经典的异常信号。请求 a.com 但服务器返回 b.com 的证书 SNI 缺失（空） 现代浏览器几乎必发 SNI；空 SNI 常见于恶意工具、扫描器、老旧\u002F定制客户端 SNI 是 IP 字面量 正常客户端很少把 IP 当 SNI SNI 与 HTTP Host 不一致 同一连接里 TLS 层和 HTTP 层目标不一致 → 疑似隧道\u002F代理 SNI 后跟不同的 SNI（同连接） 罕见，可能异常协商 2. 内容层异常 特征 说明 域名非标准格式 纯数字、随机字符串、超长域名、多级随机子域（DGA 特征） 使用免费\u002F可疑 TLD .tk .ml .ga .cf .xyz .top 等高频出现在恶意外联 域名刚注册 结合 whois\u002F情报：注册时间 \u003C 30 天 命中威胁情报 SNI 落在 C2、钓鱼、矿池等情报库中 高频轮换 同一源 IP 短时间内访问大量不同 SNI（扫描\u002FDGA 行为） 时序\u002F长度异常 心跳式周期连接、固定大小包（C2 beacon 特征） 3. 行为层异常 单主机 SNI 数量异常多； 非工作时间的固定周期外联； 内网主机访问与业务无关的外部域名； 同一 SNI 分辨率下的证书频繁变化。 二、Zeek 上怎么发现 Zeek 自带 ssl.log，里面有 server_name（SNI）、subject、issuer、validation_status 等字段，非常适合做检测。 关键字段： server_name — SNI subject \u002F issuer — 证书主体\u002F签发者 validation_status — 含 certificate-unknown-authority、self signed certificate 等 实用检测思路： # 1. 无 SNI 的 TLS 连接（可疑客户端） event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) { if ( ! c$ssl?$server_name || c$ssl$server_name == \"\" ) print fmt(\"[No-SNI] %s -> %s\", c$id$orig_h, c$id$resp_h); } 更实用的做法是用 Zeek 输出日志 + 集中分析： 把 ssl.log 喂给 SIEM，做字段关联与情报匹配； 用 conn.log 关联 ssl.log，看「同 SNI 的证书是否稳定」。 验证方式：zeek -r capture.pcap 重放流量，直接看 ssl.log 里的 server_name \u002F validation_status。 三、Wireshark 上怎么发现 显示过滤器（快速定位） # 只看含 SNI 的 ClientHello tls.handshake.extensions_server_name # 按具体 SNI 过滤 tls.handshake.extensions_server_name == \"example.com\" # 无 SNI 的 ClientHello tls.handshake.type == 1 && !tls.handshake.extensions_server_name # 找证书里的 CN（配合 SNI 对比） tls.handshake.type == 11 排查手法 tls.handshake.type == 1 抓 ClientHello → 展开 Extension: server_name 看明文 SNI； 再找同连接的 Certificate 消息 → 看 CN\u002FSAN； 两者不一致，即为强异常信号。 小技巧：Statistics → Conversations 看 TLS 会话，再逐条跟到 SNI。 四、SOC \u002F 态势感知怎么落地 能力 实现方式 日志接入 采集 Zeek ssl.log、防火墙\u002F代理日志、DNS 日志 关联分析 SNI ↔ DNS 查询 ↔ 证书 ↔ 源主机 多源关联（能大幅降误报） 情报匹配 SNI 与威胁情报（C2\u002F钓鱼\u002F矿池域名）实时比对 基线建模 建立「主机—SNI」正常基线，检测从未出现过的新 SNI、异常时段外联 规则告警 无 SNI、SNI\u002F证书不匹配、DGA 域名、可疑 TLD、高频轮换 可视化 SNI 频次 TOP、新出现域名趋势、主机外联拓扑 推荐的降误报组合（单看 SNI 误报很高，要叠加）： 异常SNI AND (新域名 OR 命中情报 OR 无SNI OR 证书不匹配) AND 内网主机发起 五、验证用的实验方法（授权前提下） 要验证检测规则是否有效，可以在自己环境里做： 构造异常流量： 用 curl --resolve example.com:443:1.2.3.4 https:\u002F\u002Fexample.com\u002F 验证「SNI 与证书不匹配」； 用 openssl s_client -servername \u003CSNI> -connect \u003Cip>:443 指定任意 SNI，观察返回证书； 用 curl --no-alpn 或自定义客户端构造空 SNI。 抓包验证：Wireshark 确认 SNI 字段值，标记 pcap 作为测试样本。 回放检测：zeek -r test.pcap，确认 ssl.log 抓出预期字段；再喂 SIEM 看规则是否触发。 误报评估：用正常业务流量做基线，测量误报率后再调阈值。 ⚠️ 边界提醒：以上验证方法只应在你自有或明确授权的环境中进行。「指定任意 SNI 探测某 IP 返回证书」这类操作若指向未授权目标，属于越界探测。 六、必须知道的现实局限 ECH（Encrypted Client Hello）正在让 SNI 检测逐渐失效——启用 ECH 后 SNI 被加密，网关只能看到外层 SNI（通常是 CDN 域名）。 应对方向： 从 SNI 检测转向证书\u002F指纹\u002F行为检测（JA3\u002FJA4 指纹、连接时序、流量大小分布）； 结合 DNS 层（DoH\u002FDoT 会让 DNS 也难见，需终端侧遥测）； 加强端点侧（EDR）的可见性，弥补网络层盲区。 一句话总结 异常 SNI 的核心信号是「无 SNI、SNI 与证书不匹配、域名字符串可疑、行为高频轮换」；Zeek 看 ssl.log、Wireshark 用 tls.handshake.extensions_server_name 过滤器即可快速发现，SOC 上要叠加情报与基线才能把误报压下来；而 ECH 正让这条检测路径失效，需要转向指纹与端点侧遥测。 异常 SNI 检测：Zeek 脚本 + Wireshark 过滤器清单 用途：在自有或已授权环境中，检测 TLS 握手阶段的异常 SNI 行为 适用：Zeek 5.x \u002F 6.x；Wireshark 3.6+ ⚠️ 仅限自有系统或明确授权的安全测试场景使用 一、Zeek 脚本 1.1 部署方式 # 放到 Zeek 本地站点目录 sudo cp snicheck.zeek \u002Fusr\u002Flocal\u002Fzeek\u002Fshare\u002Fzeek\u002Fsite\u002F 在 local.zeek 中加载： # \u002Fusr\u002Flocal\u002Fzeek\u002Fshare\u002Fzeek\u002Fsite\u002Flocal.zeek @load .\u002Fsnicheck # 务必定义本地网段，否则脚本不检测内网流量 redef Site::local_nets += { 10.0.0.0\u002F8, 172.16.0.0\u002F12, 192.168.0.0\u002F16 }; 或命令行直接跑： zeek -r capture.pcap site\u002Fsnicheck.zeek Site::local_nets=10.0.0.0\u002F8 1.2 主脚本 snicheck.zeek ##! 异常 SNI 检测脚本 ##! 检测：无 SNI、可疑 TLD、DGA 特征、SNI\u002F证书不匹配、高频轮换 ##! 依赖：本机所抓 TLS 流量 + Site::local_nets 定义 module SNICheck; export { redef enum Notice::Type += { No_SNI, SNI_Cert_Mismatch, Suspicious_TLD, DGA_Like_SNI, SNI_High_Frequency, }; ## ---- 可调参数 ---- # 可疑\u002F高频滥用 TLD const suspicious_tlds: set[string] = { \"tk\", \"ml\", \"ga\", \"cf\", \"gq\", \"xyz\", \"top\", \"buzz\", \"click\", \"work\", \"loan\", \"review\", \"country\", \"stream\" } &redef; # 同一源主机在窗口内访问的不同 SNI 数阈值（扫描\u002F轮换告警） const sni_freq_threshold: count = 50 &redef; const sni_freq_window: interval = 5min &redef; # 无 SNI 白名单（内部服务、已知合法客户端） const no_sni_whitelist: set[subnet] = {} &redef; } # ---------- 辅助：DGA 特征判断 ---------- function dga_like(name: string): bool { local parts = split_string(name, \u002F\\.\u002F); if ( |parts| \u003C 2 ) return F; local label = parts[|parts| - 2]; # 二级域名标签 # 条件1：标签过长 if ( |label| >= 15 ) return T; # 条件2：数字占比 >= 40% local digits = 0; local letters = 0; local i = 0; local ch = \"\"; for ( i in label ) { ch = label[i]; if ( ch in \"0123456789\" ) digits += 1; else if ( ch in \"abcdefghijklmnopqrstuvwxyz\" ) letters += 1; } if ( digits + letters == 0 ) return F; if ( digits * 100 \u002F (digits + letters) >= 40 ) return T; # 条件3：连续 5 个及以上辅音（随机串特征） local cons = 0; local vowels = \"aeiou\"; for ( i in label ) { ch = label[i]; if ( ch !in vowels && ch !in \"0123456789\" ) { cons += 1; if ( cons >= 5 ) return T; } else cons = 0; } return F; } # ---------- 状态表：统计每源主机的 SNI 频次 ---------- global sni_tracker: table[addr] of set[string] &create_expire=sni_freq_window; # ---------- 检测 1：无 SNI ---------- # 说明：ssl_client_hello 的签名在 Zeek 各版本间略有差异， # 这里使用最通用的 (c, version, record_version) 前三个参数写法。 event ssl_client_hello(c: connection, version: count, record_version: count) { local orig = c$id$orig_h; local resp = c$id$resp_h; # 仅关注内网发起的连接 if ( orig !in Site::local_nets ) return; if ( orig in no_sni_whitelist ) return; if ( ! c$ssl?$server_name || c$ssl$server_name == \"\" ) { NOTICE([$note=No_SNI, $conn=c, $msg=fmt(\"TLS connection without SNI: %s -> %s:%s\", orig, resp, c$id$resp_p), $identifier=cat(orig, resp)]); } } # ---------- 检测 2\u002F3\u002F4：可疑 TLD、DGA、SNI\u002F证书不匹配 ---------- event ssl_established(c: connection) { if ( ! c$ssl?$server_name || c$ssl$server_name == \"\" ) return; local sni = c$ssl$server_name; local sni_lower = to_lower(sni); # 2a. 可疑 TLD local s_parts = split_string(sni_lower, \u002F\\.\u002F); local tld = \"\"; if ( |s_parts| >= 2 ) { tld = s_parts[|s_parts| - 1]; if ( tld in suspicious_tlds ) NOTICE([$note=Suspicious_TLD, $conn=c, $msg=fmt(\"Suspicious TLD: SNI=%s\", sni), $identifier=cat(c$id$orig_h, sni)]); } # 2b. DGA 特征 if ( dga_like(sni_lower) ) NOTICE([$note=DGA_Like_SNI, $conn=c, $msg=fmt(\"DGA-like SNI: %s\", sni), $identifier=cat(c$id$orig_h, sni)]); # 2c. SNI 与证书主体不匹配 if ( c$ssl?$certificate && c$ssl$certificate$subject != \"\" && sni_lower !in to_lower(c$ssl$certificate$subject) ) { NOTICE([$note=SNI_Cert_Mismatch, $conn=c, $msg=fmt(\"SNI\u002Fcert mismatch: SNI=%s cert=%s\", sni, c$ssl$certificate$subject), $identifier=cat(c$id$orig_h, sni)]); } } # ---------- 检测 5：高频 SNI（扫描 \u002F 轮换） ---------- event ssl_established(c: connection) { if ( ! c$ssl?$server_name || c$ssl$server_name == \"\" ) return; local orig = c$id$orig_h; if ( orig !in Site::local_nets ) return; if ( orig !in sni_tracker ) sni_tracker[orig] = set(); add sni_tracker[orig][c$ssl$server_name]; if ( |sni_tracker[orig]| == sni_freq_threshold ) { NOTICE([$note=SNI_High_Frequency, $conn=c, $msg=fmt(\"Source %s hit %d distinct SNIs within %s (possible scan\u002Frotation)\", orig, sni_freq_threshold, sni_freq_window), $identifier=cat(orig)]); } } 1.3 部署后验证 # 1) 语法检查（-a 表示仅解析不执行） zeek -a site\u002Fsnicheck.zeek # 2) 回放 pcap（记得指定本地网段） zeek -r test.pcap site\u002Fsnicheck.zeek Site::local_nets=10.0.0.0\u002F8 # 3) 查看告警 cat notice.log | zeek-cut note msg id.orig_h id.resp_h # 4) 查看 SNI 明细（ssl.log 自带） cat ssl.log | zeek-cut id.orig_h id.resp_h server_name validation_status 1.4 脚本要点说明（部署前必读） 要点 说明 必须定义 Site::local_nets 否则 orig !in Site::local_nets 恒真，脚本不会报任何告警 ssl_client_hello 签名 各 Zeek 版本参数不同，脚本只取前三个参数（Zeek 支持按前缀匹配 event 签名）。若你的版本编译报参数错误，改为 event ssl_client_hello(c: connection, version: count, record_version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec, comp_methods: index_vec) 补齐 c$ssl?$certificate 证书字段并非所有连接都有，必须先判断存在性再访问，脚本已处理 &create_expire 5 分钟窗口自动清理，避免状态表无限增长 两个 ssl_established Zeek 允许多个同名 event handler，会依次执行；如需合并可自行整理为一个 二、Wireshark 过滤器清单 2.1 基础定位（含 SNI 的握手） # 只显示含 SNI 的 ClientHello tls.handshake.type == 1 && tls.handshake.extensions_server_name # 所有 ClientHello（含无 SNI 的） tls.handshake.type == 1 # 按具体 SNI 过滤 tls.handshake.extensions_server_name == \"example.com\" tls.handshake.extensions_server_name contains \"example\" # 无 SNI 的 ClientHello（可疑客户端\u002F扫描器） tls.handshake.type == 1 && !tls.handshake.extensions_server_name 2.2 证书与 SNI 对比排查 # 显示证书消息（看 CN\u002FSAN） tls.handshake.type == 11 # 证书里包含某个域名（与 SNI 对比） tls.handshake.certificate contains \"example.com\" # 只看 ServerHello + Certificate（快速看服务端返回） tls.handshake.type == 2 || tls.handshake.type == 11 2.3 按主机 \u002F IP 过滤 # 某 IP 的所有 TLS ip.addr == 10.0.0.5 && tls # 某内网主机发起的 ClientHello ip.src == 10.0.0.5 && tls.handshake.type == 1 # 排除某个已知合法的 SNI tls.handshake.type == 1 && tls.handshake.extensions_server_name != \"internal.corp.com\" 2.4 结合时间 \u002F 流 # 指定时间段的 ClientHello frame.time >= \"2026-09-10 09:00:00\" && frame.time \u003C= \"2026-09-10 18:00:00\" && tls.handshake.type == 1 # 按 TCP 流排查 tcp.stream == 12 && tls 2.5 快捷排查动作 目的 操作 看 SNI 明文 抓 ClientHello → 展开 Extension: server_name 看证书 CN\u002FSAN 同连接 Certificate 消息 → 展开 signedCertificate SNI 与证书比对 两条消息对照，域名不一致即异常 找无 SNI 连接 用 2.1 最后一条过滤器 批量看会话 Statistics → Conversations → TCP 2.6 导出可疑样本供 Zeek 回放 # 只保留无 SNI 的流，导出为 no_sni.pcap tls.handshake.type == 1 && !tls.handshake.extensions_server_name # File → Export Specified Packets 三、验证流程（仅限授权环境） ① 构造测试流量 - 无 SNI： 用可关闭 SNI 的客户端\u002F自写 TLS 客户端发起连接 - SNI 不匹配： curl --resolve example.com:443:\u003C目标IP> https:\u002F\u002Fexample.com\u002F - 自定义 SNI： openssl s_client -servername \u003C任意SNI> -connect \u003Cip>:443 ② 抓包确认 - Wireshark 用 2.1 \u002F 2.2 过滤器确认字段值 ③ 检测回放 - zeek -r test.pcap site\u002Fsnicheck.zeek Site::local_nets=10.0.0.0\u002F8 - 检查 notice.log 是否产生对应告警 ④ 误报评估 - 用正常业务 pcap 回放，统计误报 - 调整 sni_freq_threshold、suspicious_tlds、no_sni_whitelist 后复测 四、参数调优建议 参数 默认 调整建议 sni_freq_threshold 50 \u002F 5min 办公网调高至 100+；服务器区可调低 suspicious_tlds 常见滥用 TLD 按贵司业务裁剪，避免误伤 no_sni_whitelist 空 加入内网服务网段、已知无 SNI 的合法客户端 SNI\u002F证书不匹配 全量告警 CDN 场景误报高，建议加白名单域 五、局限与演进（务必知悉） ECH（Encrypted Client Hello） 生效后 SNI 被加密，本套检测基本失效——需转向 JA3\u002FJA4 指纹、连接时序、流量分布、端点遥测（EDR）。 DoH\u002FDoT 会让 DNS 侧关联变难，需终端侧数据补充。 CDN 场景下 SNI 与证书不匹配属正常（证书由 CDN 签发），需白名单降误报。 单看 SNI 误报较高，务必叠加情报、基线、行为多维关联再告警。 本脚本未做 pcap 实测验证（编写环境无 Zeek 运行时），首次部署请在测试环境用 zeek -a 校验语法并回放样本确认。",9827,{"id":6,"kind":7,"title":11,"summary":13,"image":14,"href":15,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":37},"#2563eb","16 \u002F 10",[7,8],{"targetType":8,"targetId":9,"likedByMe":39,"likeCount":40,"commentCount":40,"contentLikeCount":40,"contentCommentCount":40,"sourceLikeCount":40,"sourceCommentCount":40},false,0,[42,51,57,63,72,79,85,92],{"id":43,"kind":7,"title":44,"summary":45,"image":46,"href":47,"meta":48,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":49},"NEWS_ARTICLE:927","HelloCrab - 短视频开源爬虫，仅供学习参考","HelloCrab 基于 Avalonia、Playwright、AI与 FFmpeg 的跨平台桌面采集器，支持9大平台，以及 Android、iOS、Browser 远程控制端。 Made By ChatGPT &amp; Vincent with ❤ 平台 是否接入 哔哩哔哩 ✅ 抖音 ✅ 快手","https:\u002F\u002Fwww.cnblogs.com\u002Fhupo376787\u002Fp\u002FScreenshot\u002FWindows.jpg","\u002Fnews\u002F927","2026 · 软件开发",[50],"软件开发",{"id":52,"kind":7,"title":53,"summary":54,"image":14,"href":55,"meta":48,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":56},"NEWS_ARTICLE:929",".NET 异常处理的\"暗门\"：代码里写满 catch，你依然能抓住它——从一个 AI Agent 运行时的源码说起","一个健壮的系统，必然到处都是有意的 catch；异常被消化不等于问题不存在。 观测与韧性，是一个硬币的两面——降级逻辑保证系统不崩，FirstChance 保证你能看见它为什么降级。","\u002Fnews\u002F929",[50],{"id":58,"kind":7,"title":59,"summary":60,"image":14,"href":61,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":62},"NEWS_ARTICLE:928","架构师化繁为简，执行者化简为繁","新手改三天，你改三行——反而是你显得更不重要。因为化繁为简做得越纯熟，产出看起来越小。这篇聊聊两种能力的辩证关系，以及为什么'看不见'的那部分工作，恰恰是最难的部分。","\u002Fnews\u002F928",[7,8],{"id":64,"kind":7,"title":65,"summary":66,"image":67,"href":68,"meta":69,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":70},"NEWS_ARTICLE:930","基于 vLLM+Nginx 构建负载均衡推理集群","企业内部私有环境部署大模型推理集群时，很容易遇到流量调度混乱、节点负载失衡、会话上下文丢失、接口缺少鉴权防护等一系列问题，单 vLLM 推理节点难以支撑并发请求。本文基于 Ubuntu 22.04 系统环境，搭建 Nginx + vLLM-Semantic-Router + vLLM-Router","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F1379525\u002F202609\u002F1379525-20260910165534385-2022408098.png","\u002Fnews\u002F930","2026 · 人工智能",[71],"人工智能",{"id":73,"kind":7,"title":74,"summary":75,"image":76,"href":77,"meta":69,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":78},"NEWS_ARTICLE:932","2026年AI编程工具大全，33个主流工具一次看懂","事情是这样的，前两天看到一张图，是某个社区官网的「支持的工具」清单，我数了数，整整31个AI编程工具。 两年前这份清单撑死5个，现在直接31个，而且我居然每一个都认识。。。 干脆整理成一篇，顺手把最近字节的TraeWork和豆包工作也补了进来，凑成33个。 今天给大家推荐一遍，每个工具说说它是干什么","https:\u002F\u002Fimage.kjdaohang.com\u002Fimg\u002F20260909210838518.png","\u002Fnews\u002F932",[71],{"id":80,"kind":7,"title":81,"summary":82,"image":14,"href":83,"meta":17,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":84},"NEWS_ARTICLE:931","SH 中文化样例数据使用手册","在数据库演示与 PoC 场景中，Oracle 自带的 SH 示例模式虽然经典，但英文维度数据往往让国内演示效果打折扣。笔者整理了一套方案：保留 SH 标准英文对象名，同时装载中文化维度数据，并按参数生成可复现的销售历史数据，方便个人测试与概念验证。 01 | 环境准备 使用前请确认满足以下条件： O","\u002Fnews\u002F931",[7,8],{"id":86,"kind":7,"title":87,"summary":88,"image":89,"href":90,"meta":48,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":91},"NEWS_ARTICLE:933","写给 C++ 工程师的 OpenClaw.NET 上手指南：用你熟悉的 C++ 思维，跑起一个生产级 AI Agent","它像一个「基于 boost.asio + REST 端点的常驻服务」——对外是 HTTP \u002F WebSocket \u002F 各 IM 的 webhook，对内跑着一个能调工具、读写记忆、跨渠道对话的 AI Agent——只不过协程不用你手写 promise_type，内存不用你管 new\u002Fdelete。","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F510\u002F202609\u002F510-20260905070811424-1837144874.jpg","\u002Fnews\u002F933",[50],{"id":93,"kind":7,"title":94,"summary":95,"image":96,"href":97,"meta":69,"badge":10,"author":12,"stats":-1,"accent":35,"coverRatio":36,"tags":98},"NEWS_ARTICLE:935","[Agent Memory \u002F 强化学习] MemPO源码学习笔记 ---（1）--- 总体","[Agent Memory \u002F 强化学习] MemPO源码学习笔记 （1） 总体 目录[Agent Memory \u002F 强化学习] MemPO源码学习笔记 （1） 总体0x00 概要0x01 基础 &amp; 背景1.1 用RL训练记忆系统的要点1.2 主要难点1.3 主要思路1.4 RL训练方案1.","https:\u002F\u002Fimg2024.cnblogs.com\u002Fblog\u002F1850883\u002F202609\u002F1850883-20260906190854637-986949885.jpg","\u002Fnews\u002F935",[71]]