Currently, the hearttbleed vulnerability of OpenSSL has been widely known: in OpenSSL, one of the most popular TLS implementations, the lack of a boundary check results in millions (or more) the Web server exposes various sensitive information in the memory. this will expose the login certificate, authentication cookie and website traffic to attackers. but can it be used to obtain the private key of the site? After obtaining the private key of the site, you can crack the previously recorded traffic that has not achieved the perfect forward confidentiality, and then conduct man-in-the-middle attacks in future TLS sessions.
This is a more serious consequence of the painstaking effort vulnerability. I decided to try it. the result proves that this conjecture is correct. after several days of research, I was able to extract the private key from a testing Nginx server. I will use my technology to solve CloudFlare Challenge later. together with several other security researchers, we independently prove that RSA private keys are indeed at risk. next we will introduce in detail how the private key is extracted and why this attack is possible.
Note: CloudFlare Challenge is a Challenge initiated by cloudflare.com: they steal private keys from their nginx server (OpenSSL with the heartbleed vulnerability installed.
OpenSSL TLS heartbeat read remote information leakage (CVE-2014-0160)
Severe OpenSSL bug allows attackers to read 64 KB of memory, fixed in half an hour in Debian
OpenSSL "heartbleed" Security Vulnerability
Provides FTP + SSL/TLS authentication through OpenSSL and implements secure data transmission.
OpenSSL Heartbleed vulnerability upgrade method
How to extract the Private Key
Readers who are not familiar with RSA can find out here. for the sake of simplicity, a large number (2048 bits) N is obtained by multiplying two randomly generated large prime numbers p and q. N will be made public, but p and q won't. find p or q to calculate the private key. A common attack method is to break down N, but this is very difficult. however, vulnerabilities like hearttbleed make the attack much easier: Because the Web server needs to save the private key in the memory to sign the TLS handshake protocol, p and q must be in the memory and we can try to use the network package of heartbleed to get them. the problem is simply how to find them from the returned data. this is also very simple, because we know that the length of p and q is 1024 bits (128 bytes), and OpenSSL represents data in small byte order in memory. A brutal method is to treat each 128 consecutive bytes in the heartbleed packet as a small byte order value and test whether the value can be divisible by N. This method is sufficient to detect potential vulnerabilities. this is also a solution to CloudFlare challenge.
Coppersmith Improvement
However, this is different from our solution for Cold-starting memory image attacks. There have been many studies on recovering RSA through some messages. The most famous is a paper from Coppersmith, which describes how to use related messages or fill in insufficient messages, and break down some messages to attack with the help of the lattice simplification algorithm. Through the Coppersmith attack, you only need to know the upper or lower part of P, and N can be effectively decomposed by reason. Based on this, compared with the 128 bytes required for brute-force cracking, we only need 64 bytes in the upper or lower part to calculate the key. In practice, the limitation of Coppersmith is the computing overhead (but it is much better than the natural decomposition), assuming that 77 bytes (60%) are known ), we can quickly sort out the potential keys of the "painstaking efforts" package.
In retrospect, I have collected more than 10000 packets (64 kB each) with 242 private key residues suitable for the Coppersmith attack. Thanks to Sage (although I later found that Sage has implemented the Coppersmith attack), its comprehensive computer algebra makes it easier to implement the Coppersmith attack.
Can we do better? You have used the openssl ras-text-in server. key command to view the RSA private key. You will find that there are more than two prime factor p and q. In fact, they are designed to optimize the pre-calculated value of Chinese Remainder Theorem. If some of them are missing, they can also be deduced by p. How does OpenSSL use p and q's mongomery representations for fast product? They also acknowledge the variation of Coppersmith so that local bitwise is also useful. With this in mind, we began to search for collected packages on my test server. However, the data set does not even find a separate part (larger than 16 bytes ). How is this possible?
Note: All my labs andCloudFlare challengeThe target is a single-threaded Nginx. It is also possible on a multi-threaded web server to observe more leaks.
Why does it only expose p?
When "painstaking efforts" first appeared, some people argued that RSA private keys would not leak. after all, they will only be loaded when the Web server is started, so they are located in a low memory address. as the heap memory grows upwards, the allocated buffer memory leaked by "painstaking efforts" cannot access these private keys. this is the same as the value pre-calculated by CRT, but I do not know why p is indeed leaked. if we assume that this debate is correct, the question becomes: Why is p leaked?
In addition, OpenSSL clears all used temporary BigNum. to reduce the overhead caused by Dynamic Allocation of temporary values, OpenSSL provides a stack-operated BigNum pool --- BN_CTX. once it is used, its context will be destroyed and all allocated buffers will be cleared (scrubbed ). this means that no temporary data is available in the memory after the "painstaking effort" data packet is created (assuming it is a single thread), because BN_CTX has been released for a long time.
I will not block you with the pain I 've experienced when I found out the cause, so I will give the answer below:
When a BigNum is extended to a larger buffer, its original buffer is not set to 0 before it is released. the control flow path chain that causes p leakage becomes more subtle. during the TLS handshake initialization, the server key exchange is signed with the private key. the CRT signature executes modulo once.POperation, which causesP<BN_BITS2 results are stored in temporary variables allocated from the BN_CTX pool. in the subsequent CRT error injection check, this temporary variable is reused as val [0] (remember that BN_CTX operations are similar to stack operations ). an interesting fact is that the temporary variable being reassigned only sets its minimum memory to 0, soP<BN_BITS2 is not damaged (its minimum memory itself is 0 ).Val [0]Receive the value of Montgomery-ced CED immediately, but because the initial buffer is insufficient to store the new value, it will expand, so p is released to the idle heap space and will be used again. this occurs every time a TLS handshake occurs, and it will be leaked.
It is difficult to find out which BigNum will be extended and cause static leakage. I used a tool to perform some experiments on OpenSSL. the results show that an upgraded version of p Montgomery indicates that it will also be released at the leak point, but this only happens in the first RSA Power Operation initialized by the context of Montgomery. it will always exist in a low-memory address, and I cannot find it in the captured packets.
The above leakage bug has already been notified to the OpenSSL team. Although it is a little scary, it is not a security bug strictly, because OpenSSL never thought of preventing leakage of sensitive information on the stack during design.
Rubin XuHe is a PhD student at Cambridge University in the computer lab security group. His thesis is about mobile security and he is also interested in cryptography. he is one of the four who successfully cracked CloudFlare Challenge. this blog post was first published onLight Blue Touchpaper blog.Rubin XuThanksJoseph BonneauSuggestions and proofreaders for this article.
For more information about Heartbleed, click here.
Heartbleed: click here
This article permanently updates the link address: