“Padding Oracle” ASP.NET Vulnerability Explanation
Yesterday (Sept 18), Microsoft have released a Security Advisory for a newly discovered vulnerability in ASP.NET applications. Following the advisory, Scott Guthrie has published a blog post regarding this vulnerability, detailing an eligible workaround for preventing the exploit.
However, according to the investigation I’ve done during the past couple of days, unfortunately, this workaround is far from being enough for plugging this security hole. In this post I’ll try to briefly (without boring you too much) explain what is this vulnerability about, why the workaround doesn’t work and what is the best way to prevent hacking your app.
At the end of the post, I’m providing a list of links, from which you can learn much more about the issue.
WTF is this “Padding Oracle” vulnerability?
To make the long story short, since encryption algorithms work on blocks of data (usually 8 or 16 bytes per block), the remaining bytes are “padded”. For example, a 5-letter word “TABLE”, will be padded with three bytes to become 8-byte block. I’ll skip the explanation on how exactly it is done – you can read here about that.
“Oracle” is a mechanism inside a cipher, capable of providing Valid or Invalid answer for a given ciphertext. Therefore, “Padding Oracle” is a mechanism, capable to answer, whether the padding of the provided cyphertext is valid or not. There is no relation whatsoever to the Oracle database or the Oracle company.
Again, without going too much into details, this simple Valid/Invalid answer allowed security researchers to create an algorithm, decrypting almost any cypertext encrypted in CBC-mode with PKSC#5 padding (bla…bla…bla…) without knowing the encryption passphrase. It is somewhat similar to brute-force attack, but with much less required checks, taking minutes to complete. The attacking application changes one byte in a cyphertext at a time and sending it to the oracle, asking “is it valid?” till the byte is decrypted.
How is this related to ASP.NET?
Ciphers (encryption algorithms), built in Microsoft in .NET framework, throw a System.Security.Cryptography.CryptographicException with a message “Padding is invalid and cannot be removed” in case of invalid padding. So this is our Oracle for padding!
Now, think of an application saving some encrypted sensitive data in a cookie. The attacker can read this cookie, containing a cyphertext, and play with its bytes sending simulated requests to a server with a modified cookie. The attacker can then analyze the response and to deduce which response means Valid, and which one is Invalid. Hopefully, now you’re beginning to understand the potential of this exploit. Either way, I’ll elaborate on it later.
Does the vulnerability exists only in ASP.NET?
Not at all! As a matter of fact, the vulnerability has first been discovered in JSF (Java Server Faces) framework. It also exists in Java, which throws exceptions on invalid padding.
How does the vulnerability affect me?
Using the vulnerability, the attacker may decrypt all the sensitive data, sent by ASP.NET application to a client, i.e., cookies, ViewState, URL strings, hidden fields etc. Then, the attacker may find your encryption passphrase, change the encrypted data and send the modified content back to the server. For example, the attacker may impersonate himself as a system administrator.
Scott, in his post, also mentions ability to download web.config files from the web site. I actually have no idea how it is possible using this exploit. I personally think it’s a mistake in the article. There is another mechanism preventing downloading *.config files.
How about Microsoft’s workaround?
(This is the most critical section of the post!)
Well, while the workaround contains a really valuable information, relevant for every system (as for not disclosing the real error), and it will prevent the automated tool released by the researchers to hack your system, it will, by far, NOT protect you from a potential attack!
How so? The workaround assumes that the potential attacker will look for an HTTP error response status (500), or for an error page containing a specific exception message. However, it is enough for attacker to recognize an abnormal, or just different system behavior on certain requests.
Let’s get back to our ASP.NET system that stores an encrypted sensitive information in a cookie. Each request, the system will probably decrypt this information and use it. In case the ciphertext in a cookie is invalid, an exception will be thrown, and the system may act according to one of the following scenarios:
- Return a 500 error response - very user unfriendly!
- Return a default ASP.NET YSOD exception page - extremely bad in production environment!
- Return a page stating only the exception’s message - also very bad!
- Return a constant page, stating there was an error, without providing details– a good practice, this is actually the Microsoft’s workaround
- “Swallow” the exception, and behave like the cookie does not exist. The response may be a redirect to another pager, or just a a slightly changed HTML (instead of user’s name, a “login” link) – This is the way ASP.NET Forms Authentication works.
Note that every one of the possible responses is different from the normal one. Even the last scenario I’ve described above, as clean as it is, still returns a distinctively different response. Therefore, an attacker can take advantage of it, and write a simple script that infers this abnormal behavior to an Invalid Oracle’s answer. It is that simple!
So what do we do now?
Unfortunately, this vulnerability is very complex to deal with, because the problem actually lies in encryption algorithms allowing this simple hack. I’m pretty confident, Microsoft will release some kind of patch long before others will, however, I’m not sure how good it will be and how long will it take.
Meanwhile, the best advise I can give you is: do not store any sensitive data on a client (cookies, ViewState, hidden fields, etc), even encrypted. The most important thing is not to store a currently logged in user name and rely on it on further requests (the thing that ASP.NET Forms Authentication does). Hackers can decrypt your cookie, find the encryption passphrase and encrypt back some other value, like “Administrator” (scary, ha?). What you can do instead is to store some bogus value in a cookie, like a GUID of the user name, or even better, a GUID of a session variable that keeps the user name.
It is also possible to implement a double encryption. The attackers can only decrypt the first level of encryption – the second is still unreachable. In this case, the second (the inner) level of encryption should be implemented as clean as possible, without returning any errors.
The new vulnerability is a harsh one. It basically allows a hacker to decrypt you sensitive data without knowing the encryption passphrase. It is not easy to protect your application against the exploit, however it is possible. For more information and for much deeper understanding of the issue, look ad the list of links bellow.
Practical Padding Oracle Attacks paper by Juliano Rizzo and Thai Duong
A great explanation about the Oracle Padding, including an implemented python script
Padding Oracle Exploit Tool (POET) – original tool used for JSF attacks
A video, demonstrating attacking a DotNetNuke site