实现原理:TLS 漏洞探测
对应代码:
pkg/vulnscanner.go· 入口VulnerabilityScan(target)
scan-vulns 覆盖 11 个经典 TLS 漏洞。这一页讲每个漏洞怎么探测——核心是一句话:全部手搓 raw TLS 报文,不走 Go 标准库。
为什么手搓 raw 报文
所有探测共用:5 秒超时(net.DialTimeout 与 tls.DialWithDialer.Timeout)、InsecureSkipVerify、裸 TCP。CCS 的最终读取为 3 秒。
11 项漏洞完整表
| 名称 | CVE | 严重度 | check 函数 |
|---|---|---|---|
| Heartbleed | CVE-2014-0160 | Critical | checkHeartbleed |
| POODLE (SSLv3) | CVE-2014-3566 | High | checkPOODLE |
| ROBOT (Bleichenbacher) | CVE-2017-13098 | High | checkROBOT |
| CCS Injection | CVE-2014-0224 | High | checkCCSInjection |
| FREAK (Export Cipher) | CVE-2015-0204 | High | checkFREAK |
| Logjam (Export DHE) | CVE-2015-4000 | High | checkLogjam |
| Sweet32 | CVE-2016-2183 | Medium | checkSweet32 |
| BEAST | CVE-2011-3389 | Medium | checkBEAST |
| CRIME | CVE-2012-4929 | Medium | checkCRIME |
| Insecure Renegotiation | CVE-2009-3555 | Medium | checkRenegotiation |
| DROWN | CVE-2016-0800 | High | checkDROWN |
Heartbleed(CVE-2014-0160)
OpenSSL heartbeat 扩展没校验声明长度,会回吐内存。
ClientHello 关键字节(buildHeartbeatClientHello L253-326):
- 记录头:
0x16+0x03 0x01(TLS1.0 记录层)+ 2 字节长度 - 握手头:
0x01(ClientHello)+ 3 字节长度 - 版本:
0x03 0x03(TLS1.2) - Random:32 字节
byte(i+1)即 1..32 - Session ID:
0x00(空) - CipherSuites:
0x00 0x08(4 个):0xC02F, 0xC030, 0x009C, 0x009D - Compression:
0x01 0x00 - 扩展:heartbeat(
0x000F, mode=0x01) + SNI(0x0000)
判定:响应 buf[0]==0x18 且 n>4 且 BigEndian.Uint16(buf[3:5])>3 → vulnerable。
POODLE(CVE-2014-3566)
能协商 SSLv3 即漏。probeTLSVersion(addr, tls.VersionSSL30)(=0x0300)——握手成功就报漏。
ROBOT / Bleichenbacher(CVE-2017-13098)
ROBOT 只能标"潜在风险"
ROBOT 的最终判定需构造非法 PKCS#1 padding 报文观察服务器错误响应差异,Go 标准库做不到。cert-skills 只标"潜在风险"——这是诚实的边界,需用专用工具(如 robot-detect)做最终确认。
CCS Injection(CVE-2014-0224)
最终读取超时 3 秒。判定:err==nil && n>0 && buf[0]==0x14 → VULNERABLE。
FREAK / Logjam / Sweet32(受限套件集协商成功即漏)
| 漏洞 | 试探的套件 hex | 套件数 |
|---|---|---|
| FREAK(export RSA) | 0x0014 0x0018 0x0026 0x0029 0x0030 0x0033 0x0036 0x0062 | 8 |
| Logjam(export DHE) | 0x0014 0x0019 0x0030 0x0033 0x0036 0x0063 0x0066 | 7 |
| Sweet32(3DES/Blowfish) | 0xC012 0xC008 0x000A 0x001A 0x0016 | 5 |
BEAST(CVE-2011-3389)
CRIME(CVE-2012-4929)
DROWN(CVE-2016-0800)
原始 SSLv2 ClientHello:
- header
0x80 0x26(38 字节) - version
0x00 0x02 - 7 个 cipher spec(每个 3 字节:
0x010080..0x0700C0) - challenge 16 字节
0x01..0x10
判定:buf[0]&0x80 != 0 → vulnerable。
不安全重协商(CVE-2009-3555)
checkRenegotiation 查 ServerHello 扩展 0xff01(renegotiation_info)。parseServerHelloForExtension(L759-810)偏移:
共同模式总结
| 漏洞 | 探测核心 | 判漏信号 |
|---|---|---|
| Heartbleed | 畸形 Heartbeat | record 0x18 回吐 payload>3 |
| POODLE | 试 SSLv3 | 协商成功 |
| ROBOT | 试 RSA 静态套件 | 协商成功(潜在) |
| CCS | 偷发 CCS | 服务器回 0x14 |
| FREAK/Logjam | 试 export 套件 | 协商成功 |
| Sweet32 | 试 3DES/Blowfish | 协商成功 |
| BEAST | TLS1.0 + CBC | 均支持 |
| CRIME | 通告压缩 | compression_method 非 0 |
| DROWN | SSLv2 探测 | buf[0]&0x80 != 0 |
| 重协商 | 查 0xff01 扩展 | 缺失 |