附:SNI攻击原理

SNI - Server Name Indication, TLS 握手时,客户端告诉服务器"我要访问哪个域名"的字段。

传统问题:

服务器 IP: 1.2.3.4
├── site-a.com (证书 A)
├── site-b.com (证书 B)
└── site-c.com (证书 C)

客户端连接 1.2.3.4 时:
服务器不知道该返回哪个证书

SNI 解决方案:

客户端 TLS ClientHello:
├── "我要访问 site-b.com"  ← SNI 字段
│
服务器收到后:
└── "好的,返回 site-b.com 的证书"

SNI攻击场景:

正常情况:
客户端 ──► SNI: google.com ──► 真正的 google.com

SNI 欺骗:
客户端 ──► SNI: google.com ──► 实际连接恶意服务器
          (防火墙看到 google.com,放行)
          (但实际流量去了攻击者服务器)

攻击手法是攻击者利用防火墙只检查 SNI 不验证证书的漏洞:

1. 攻击者控制 malware.com(IP: 1.2.3.4)
2. 客户端被感染,发起连接:
   - TCP 连接到 1.2.3.4
   - TLS ClientHello 中 SNI 设为 "google.com"
3. 防火墙检查 SNI = google.com → 放行
4. 实际流量去了恶意服务器 1.2.3.4

为什么能欺骗:

防火墙检查 是否被欺骗
只检查 SNI 容易被欺骗
检查 IP 黑名单 新 IP 无法检测
检查 SNI + 验证证书 无法欺骗

TLS 证书验证如何防御:

客户端 ClientHello
├── SNI: google.com
│
防火墙检查 ServerHello 中的证书
├── 证书 CN/SAN 是否匹配 google.com?
├── 证书是否由可信 CA 签发?
├── 证书是否过期?
│
如果不匹配 → 阻止连接

流程对比,无证书验证(易被攻击):

客户端 ──► SNI: google.com ──► 防火墙检查 SNI ──► 放行
                                    │
                              只看 SNI,不管证书
                                    │
                              实际连接恶意服务器 ✗

有证书验证(安全):

客户端 ──► SNI: google.com ──► 防火墙
                                │
                    ┌───────────┴───────────┐
                    │ 检查服务器返回的证书    │
                    │ CN/SAN = google.com?   │
                    │ CA 可信?               │
                    └───────────┬───────────┘
                                │
              ┌─────────────────┼─────────────────┐
              │                 │                 │
          证书匹配           证书不匹配        无效证书
          (真正的 Google)    (恶意服务器)      (自签/过期)
              │                 │                 │
              ▼                 ▼                 ▼
            放行              阻止              阻止