公司动态
09:SSL Strip 与 HSTS——最不需要证书的攻击和最优雅的反杀
大家好我是毛衣哥。上一期我们把 HTTP 扒光了这一期来看看加了锁的 HTTPS 又是怎么被一步步拧开的。准备好瓜子七步拆完。前八篇一直在聊装证书。但你可能没想到最开始的中间人攻击根本不需要证书。2009 年一个叫 Moxie Marlinspike 的安全研究员在 Black Hat 上演示了一种攻击——它不需要你安装任何证书不需要你点击任何确认只需要你在浏览器地址栏输入了dumpany.cn而不是 https://dumpany.cn。你猜结果怎么着他成功劫持了所有人的 HTTPS 连接。SSL Strip 的原理——你少打了一个 s我就赢了先说一个你现在可能知道但当时没人注意的问题你在浏览器地址栏输入dumpany.cn不带 https://的时候浏览器默认使用的是http://不是https://。浏览器发出了一个 HTTP GET 请求到 http://dumpany.cn。服务器收到后回复一个重定向HTTP/1.1 301 Moved Permanently Location: https://dumpany.cn/浏览器收到重定向然后才改用 HTTPS 重新请求。中间人在这一步做了什么正常流程 你 → 浏览器发出 http://dumpany.cn → 互联网 → dumpany.cn 服务器回复请用 https://dumpany.cn → 浏览器改用 HTTPS 重新请求 SSL Strip 流程 你 → 浏览器发出 http://dumpany.cn → 中间人没有转发给真正的服务器 → 中间人自己替你去请求 https://dumpany.cn拿到了真正的网页内容 → 中间人把 HTTPS 内容转成 HTTP发回给你的浏览器关键点你的浏览器跟中间人之间永远是HTTP明文。中间人跟真正的服务器之间是HTTPS加密。你在浏览器地址栏看到的http://dumpany.cn——不是https://。但绝大多数用户不会注意到这个。你的浏览器没有收到任何证书错误——因为根本没有 TLS 握手。你跟中间人之间是纯 HTTP不需要证书。而中间人从真正的服务器拿到的内容以 HTTP 明文形式转发给你——它可以看到、篡改、插入任何内容。这个攻击最狠的地方它不需要证书。不需要你装任何东西。只需要中间人抢在真正的服务器之前回复了你的 HTTP 请求。为什么 SSL Strip 能成功这么久两个原因原因一大多数网站在 SSL Strip 出现的时候不支持强制 HTTPS。你要不记得在地址栏输入https://服务器虽然会重定向你到 HTTPS但在重定向之前的那几毫秒里你是通过 HTTP 访问的——而中间人就抓住了这几毫秒。原因二用户不会注意到地址栏没有小锁。即使是今天你让 100 个人看自己的地址栏能准确说出当前页面用没用 HTTPS 的可能不到 10 个。HSTS 的出现——“我说了只走 HTTPS就不能走 HTTP”Marlinspike 的 SSL Strip 演示之后行业意识到需要一种机制来从根本上禁止 HTTP 访问。这就是 HSTSHTTP Strict Transport Security。原理服务器在第一次而且必须是第一次HTTPS 响应中添加一个响应头Strict-Transport-Security: max-age31536000; includeSubDomains; preload这个头告诉浏览器max-age31536000接下来这一年里这个域名强制走 HTTPS。如果用户用 HTTP 访问浏览器直接拒绝——不发出请求、不等待重定向、直接显示错误页。includeSubDomains所有子域名也一样。blog.dumpany.cn、api.dumpany.cn、cdn.dumpany.cn——全部强制 HTTPS。preload申请加入浏览器的 HSTS Preload List。HSTS 怎么防 SSL Strip用户在地址栏输入 dumpany.cn没打 https:// → 浏览器检查 HSTS 缓存dumpany.cn 在列表中之前访问过时存下来的 → 浏览器直接发出 HTTPS 请求不经过 HTTP → 中间人被绕过了因为中间人只能劫持 HTTP 请求不能劫持 HTTPS 请求除非装证书如果没有之前的 HTTPS 访问记录呢浏览器没有缓存 HSTS 规则——那第一次访问时还是会有 SSL Strip 的窗口。这就是HSTS Preload List要解决的问题。HSTS Preload List——出厂前就写死在浏览器里Google 维护了一个域名列表——HSTS Preload List。如果你的域名在这个列表里浏览器在第一次访问时就强制走 HTTPS——不需要等服务器发 HSTS 头。这个列表目前包含上万个域名包括google.com、github.com、twitter.com、facebook.com、paypal.com等主流网站。怎么加入这个列表你需要你的网站已经配置了 HTTPS你的服务器返回了完整的 HSTS 头max-age至少 31536000包含preload标记你的网站支持所有子域名的 HTTPS去https://hstspreload.org/提交申请一旦加入了就没有回头路。Google 说“加入 Preload List 是一个永久性的承诺。”这对防止 SSL Strip 的效果完美。对 Preload List 里的域名来说SSL Strip 完全无效。SSL Strip 的现代变种变种一降级到 TLS 1.0不是降级到 HTTP而是降级到低版本的 TLS。假设服务器支持 TLS 1.2但中间人把客户端的 ClientHello 中的版本从 1.2 改成 1.0。如果服务器妥协了还支持 1.0它们就使用 1.0 通信。TLS 1.3 的降级保护标记解决了这个问题。变种二SSL Strip over HSTS如果攻击者能在用户第一次访问之前就拦截——这不太现实但理论上是可能的。Preload List 就是要解决这个第一次的问题。SSL Strip 的历史意义2026 年的今天主流网站几乎全部使用 HTTPS大多数配置了 HSTS。SSL Strip 的黄金时代已经过去了。但 SSL Strip 的历史告诉我们一个更深刻的道理很多所谓的安全是在攻击者出现之后才被发明出来的。在被攻击之前大部分人觉得现在这样就够好了。HTTPS 有 37 个密码套件够好了。HTTP 到 HTTPS 的重定向够好了。用户自己输入https://够好了。Marlinspike 证明了不够好。HSTS 修复了它。下期预告第一卷完结篇三十年的攻防进化。从 1994 年的 SSL 1.0 到 2026 年的 ECH——这场猫鼠游戏是怎么打到今天这个局面的。DumpAny 怎么做SSL Strip 在 DumpAny 中不是默认行为——DumpAny 默认走完整的 MITM装证书的版本因为这才是对开发者最有用的模式你不仅要看到请求到了还要看到请求的具体内容。但理解 SSL Strip 的原理对 DumpAny 的开发很有帮助——它提醒我们在设计代理时要考虑用户不知道连接被降级了怎么办。DumpAny 会在代理日志中标注连接的安全级别。真正的服务器中间人用户浏览器真正的服务器中间人用户浏览器地址栏显示 http:// 而不是 https://没有小锁没有证书警告HTTP GET dumpany.cn用户没输 https://HTTPS GET dumpany.cn中间人替你去HTTPS Response加密的网页内容解密→转成HTTPHTTP Response明文中间人全看到有记录无记录用户输入 dumpany.cn浏览器检查HSTS缓存直接发 HTTPS 请求发 HTTP 请求服务器回复 HSTS 头max-age31536000浏览器记录一年内必须HTTPSSSL Strip 失败中间人无法降级 聊几句TLS 握手七步中你觉得最关键的是哪一步为什么你平时会去看 TLS 握手的细节吗还是在用工具一键搞定如果有一天互联网的 CA 体系崩塌了你觉得会发生什么你有没有遇到过证书相关的线上问题怎么排查的上面聊的这些在 DumpAny 里基本都帮你封装好了。装个证书、开个代理直接看请求明文——不用手动处理 TLS 握手、不用自己写协议解析器。官网 dumpany.com开源免费。