Can you spot the vulnerability?

ossl110d

This code was introduced in OpenSSL 1.1.0d, which was released a couple of days ago. This is in the server SSL code, ssl/statem/statem_srvr.c, ssl_bytes_to_cipher_list()), and can easily be reached remotely. Can you spot the vulnerability? (read ahead for the answer)

So there is a loop, and within that loop we have an ‘if’ statement, that tests a number of conditions. If any of those conditions fail, OPENSSL_free(raw) is called. But raw isn’t the address that was allocated; raw is increment every loop. Hence, there is a remote invalid free vulnerability.. But not quite. None of those checks in the ‘if’ statement can actually fail; earlier on in the function, there is a check that verifies that the packet contains at least 1 byte, so PACKET_get_1 cannot fail. Furthermore, earlier in the function it is verified that the packet length is a multiple of 3, hence PACKET_copy_bytes and PACKET_forward cannot fail.

Nonetheless OpenSSL has acknowledged that the OPENSSL_free line needs a rewrite: https://github.com/openssl/openssl/pull/2312

PS I’m not posting this to ridicule the OpenSSL project or their programming skills. I just like reading code and finding corner cases that impact security, which is an effort that ultimately works in everybody’s best interest, and I like to share what I find. Programming is a very difficult enterprise and everybody makes mistakes.

CVE-2017-3730: OpenSSL 1.1.0 remote client denial-of-service, affects servers as well (+ PoC)

somethingsfucky
Something’s fucky

I found this one completely by chance; I was messing around with the server’s Diffie-Hellman parameters (typical Saturday evening) and to my surprise it crashed the OpenSSL 1.1.0 client. Even for a project like OpenSSL, that doesn’t have the most stable foundation of code to work with (as evidenced by the amount of vulnerabilities that are released each year), remote and instant out-of-the-box crashes of stable releases are relatively rare; many of its security-impacting bugs are either related to weak cryptography or library functions susceptible to crashes under specific conditions (very large parameters, memory duress, specific configurations).

The vulnerability comprises a remotely triggerable NULL pointer dereference in OpenSSL 1.1.0 clients using a Diffie-Hellman-based ciphersuite. If the server sends an invalid ‘P’ parameter (such as an even number), which per the constraints of the Diffie-Hellman procedure must be prime, the client code will refuse to process this parameter, leading to setting a certain variable to NULL. A subsequent operation assumes this variable to be a valid pointer, whereupon the NULL pointer dereference occurs.

ssl_cke_dhe2
The highlighted line 2261 in the right-hand screen is the culprit; it assumes that ckey is a valid pointer

By virtue of the fact that the OpenSSL 1.1.0 line of releases isn’t very widespread yet — the stable releases of major Linux distributions still ship OpenSSL 1.0.2 or derivatives — the potential for incapacitating a large amount of networked software is probably limited. On top of that, major browsers all ship with their own flavor TLS libraries that, as far as I know, are not vulnerable.

Exploitation of servers

However, the danger that the vulnerability poses isn’t strictly limited to crashing simple TLS-enabled client software like curl if their user happens to manually connect to a “malicious” server. Many web applications, for instance, are complex and cater to a wide range of needs, some of which entail that the server-side code initiates a HTTP to another server; WordPress pingbacks spring to mind. If the web application at hand would leverage OpenSSL as its TLS wrapper to connect to HTTPS:// URLs, this would in effect reverse the roles of adversary and victim (formerly server and client respectively) and the bug could be exploited to target servers (this must be remembered for when a bad OpenSSL or curl “client-only” vulnerability emerges).

Remotely crashing the Postfix MTA

In an effort to demonstrate servers’ vulnerability to client issues, I’ve managed to crash the Postfix mail-transfer agent remotely if it connects to a malicious SMTP server that’s offering a wrong DH parameter after STARTTLS.

postfix

I assume it is possible to cause a certain amount of service disruption on OpenSSL 1.1.0-enabled mail servers by signing up for a mailing list with an e-mail address whose domain name, or rather its MX record, is pointing to a malicious server.

Other well-known server software that can initiate secure outbound connections is probably vulnerable to some degree as well. Think of Exim, proftpd (with mod_tls, by issuing an FXP request), pingbacks, oEmbed and similar via blogging software, etc. Time constraints have prevented me from exploring these options.

A ready-to-use proof of concept Postfix crasher can be found in my Github repository for this vulnerability (see below).

Crashing clients as a man-in-the-middle

Network entities who are in the position to read and alter data of third parties, such as a SOCKS proxy server, a Tor exit node, or someone who has performed an ARP spoofing attack on a WiFi network, are capable of intercepting every or any plain HTTP request and responding to it with a HTTP redirect to a “malicious” HTTPS server that’s offering a corrupt Diffie-Hellman parameter.

OpenSSH can be instructed to operate as a proxy server, so what I did was change its source code so that it will recognize a known Diffie-Hellman P parameter in the data stream between the client and the server for which it relays in its role as a proxy server, and patch the value on the fly (by setting the rightmost bit of P to zero, making it an even number), leading to a client crash despite the server being “benevolent”!

However, it only works for pre-shared key modes and not for ciphersuites that rely on RSA for signing, because the OpenSSL client will terminate once it determines that the RSA signature doesn’t add up before reaching the vulnerable bit. It is nonetheless interesting to see that a data relay in the network is able to affect peer stability in this way.

Proof of concept code

Code can be found here: https://github.com/guidovranken/CVE-2017-3730

This repository also includes a patch that can be used to patch the latest version of ARM mbed TLS so that it will serve DH parameters that will crash OpenSSL.

openssh-patch
Part of the changes I applied to OpenSSH so that it will patch Diffie-Hellman parameters on the fly.

Source code auditing

I’ve found many security defects in open source software. If there is open-source software written in C that you use and you would like to see reviewed for security problems for a fee, feel free to contact me.

Most open source software has never been seriously scrutinized for vulnerabilities, and even the most prominent of applications such as OpenSSL, OpenSSH, Apache, Tor, web browsers and so forth continue to exhibit problems.

As soon as a C application’s complexity is such that it can perform non-trivial tasks, it quickly becomes impossible to intuit all of its corner cases. The source code needs to be subjected to a focused review, an undertaking that requires its own particular set of tricks, tools, strategies, creativity and experience.

You may also contact me to review your private or proprietary C code. I almost always find problems in a given source code tree.

guidovranken at gmail