2、TLS/SSL协议基础:握手、证书链、密码套件

好,我们正式进入加密接口渗透的核心地带。很多人一上来就对着加密流量抓包,结果全是乱码,心态直接崩了。别急,咱们先把这个协议底层的逻辑理清楚。

TLS/SSL,说白了就是给 HTTP 穿了一层「防窃听」和「防篡改」的铠甲。但铠甲也有缝隙,渗透测试的价值就在这儿。

TLS 1.2 完整握手与证书验证流程 客户端(Client) 服务端(Server) ① ClientHello:密码套件 + 随机数 ② ServerHello + 证书链 + ServerKeyExchange ③ 验证证书链 检查根CA、有效期、域名 ④ ClientKeyExchange(RSA/ECDHE) ⑤ 双方独立计算主密钥 ⑥ ChangeCipherSpec + Finished ⑦ ChangeCipherSpec + Finished ⑧ 应用数据加密传输 ⚠️ 高危点 证书未校验 / 降级攻击

2.1 握手过程:一次安全的「对暗号」

握手,其实就是客户端和服务端在正式聊天前,先互相确认身份、商量好加密方式、交换加密材料的过程。我见过不少开发同学把握手想得很复杂,其实核心就三个动作:打招呼、亮证件、算密钥。

咱们以最常见的 TLS 1.2 完整握手来拆解。为什么要先讲这个版本?因为新出的 TLS 1.3 虽然更快更安全,但生产环境里 TLS 1.2 仍然占了大头。你渗透测试碰到十个加密接口,至少有七个还在跑 1.2。

握手七步走

  1. ClientHello:客户端发请求,带上自己支持的 TLS 版本、密码套件列表、一个随机数,再外加一个 Session ID 留作重连用。
  2. ServerHello + 证书链:服务端从列表里选一个双方都认的密码套件,也回一个随机数,然后把自己的证书链一口气甩过来。嗯,这里要注意,如果服务端回复的是 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 这种带 ECDHE 的套件,后续还会多一步 ServerKeyExchange。
  3. 客户端验证证书链:客户端拿到证书后,会向上追溯,一直验到系统信任的根证书。中间有任何一环出问题——自签名、过期、域名对不上——握手直接中断。
  4. ClientKeyExchange:客户端生成一个预主密钥(Pre-Master Secret),用服务端的公钥加密后发过去。这一步在 ECDHE 密钥交换模式下,本质上是交换各自的 DH 参数,而不是直接传密钥。
  5. 双方算主密钥:两端利用随机数加上预主密钥,算出相同的主密钥。有意思的是,这个主密钥从来没有在网络上传输过。
  6. ChangeCipherSpec + Finished(客户端):客户端告诉服务端「后面的消息我要用密钥加密了」,然后发一条加密的 Finished 消息做验证。
  7. ChangeCipherSpec + Finished(服务端):服务端做相同操作。两边互相确认——嗯,安全通道正式建立。

渗透小贴士:我个人习惯在抓包时直接看 ClientHello 和 ServerHello 这两个报文。把这两个报文里的密码套件列表抓出来看一眼,基本就能判断这个接口是否存在弱加密或降级攻击的漏洞。

2.2 证书链:信任的传递与「信任」的漏洞

你想想看,网络对面那个自称是 api.example.com 的服务器,我凭什么相信它?凭的就是这张数字证书。证书链的信任模型,是层级担保的体系——根 CA 担保中间 CA,中间 CA 担保你的服务器证书。

这块在渗透测试中特别容易被忽略。很多公司图省事,内部接口直接用自签名证书,甚至有的连校验都不做。我前阵子还遇到一个客户,内网 API 网关的证书链配错了——根证书没带全,客户端直接弹了个 TRUST_ANCHOR_NOT_FOUND 的报错,整个业务挂了半天。

证书链验证的三个核心检查点:

  • 完整性:中间证书是否齐全?跳过中间证书直接签发,很多老旧客户端会拒绝。
  • 有效性:证书是否在有效期内?尤其是根证书的过期时间,一忘就是大事故。
  • 域名匹配:证书的 CN 或 SAN 字段是否匹配你访问的域名?

⚠️ 避坑指南:我曾经在渗透测试时碰到一个银行的移动端 APP,它对服务端证书的验证形同虚设——随便换一个代理工具的 CA 证书都能通过。你能想象吗?攻击者只要在咖啡店搭建一个钓鱼 Wi-Fi,用户的登录密码就直接送人了。所以,证书校验不是配了就完事,一定要验证「校验证书失败时服务端是否拒绝连接」。

2.3 密码套件:一把钥匙开一把锁

密码套件这个东西,很多人只知其名,不知其意。说白了,它就是一组密码算法的打包方案。一个典型的密码套件长这样:

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

别被这一长串吓到,拆开看就四个部分:

组件 作用 例子
密钥交换算法 如何安全地协商出共享密钥 ECDHE、RSA、DHE
身份验证算法 确认服务端身份 RSA(签名)、ECDSA
对称加密算法 实际加密通信数据的算法 AES_128_GCM、AES_256_CBC
HMAC / 伪随机函数 保证数据完整性和密钥派生 SHA256、SHA384

为什么渗透测试时要盯着密码套件看?因为这里面藏着很多「看似安全实际有坑」的东西。举个例子:TLS_RSA_WITH_AES_128_CBC_SHA,这玩意儿过去十年被爆出过 Padding Oracle 攻击、Lucky 13 攻击——我碰到过的很多老旧系统还在用。

渗透测试实战:在拦截了 TLS 握手包后,直接看 ServerHello 里的 CipherSuite 字段。如果发现服务端支持 TLS_RSA_WITH_AES_128_CBC_SHA 或 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,你就该留意了——RSA 密钥交换不具备前向安全性,一旦服务端私钥泄露,历史所有会话都能被解密。

我个人强烈建议在渗透测试报告中,把服务器的密码套件支持列表单独列出来。对比一下 OWASP 给出的推荐套件配置,看看有没有残存的老旧或弱密码套件。这是加密接口渗透最基础的检查项,但也是最能找出问题的地方。