{"id":120,"date":"2010-10-13T11:33:22","date_gmt":"2010-10-13T18:33:22","guid":{"rendered":"http:\/\/peterwong.net\/blog\/?p=120"},"modified":"2010-10-13T11:33:22","modified_gmt":"2010-10-13T18:33:22","slug":"yet-another-take-on-the-padding-oracle-exploit-against-asp-net","status":"publish","type":"post","link":"https:\/\/peterwong.net\/blog\/yet-another-take-on-the-padding-oracle-exploit-against-asp-net\/","title":{"rendered":"Yet Another Take on the Padding Oracle Exploit Against ASP.NET"},"content":{"rendered":"<p>Or an example Padding Oracle attack in 100 lines of C# code.<\/p>\n<p>This post has been in my outbox for weeks, since I did not want to make it generally available before the patches were released.&#160; Now that the patches are being pushed on Windows Update, and I also see that there are a couple of blog entries already providing the same details, I hope that making the source available would help developers understand how the exploit worked.<\/p>\n<p>There\u2019s been several web postings citing the vulnerability of ASP.NET, but few have tried to explain it.&#160; Here\u2019s my attempt to simplify it for you, dear reader, complete with C# code to perform the exploit on a padding oracle.&#160; There are two kinds of attacks that I\u2019ll be describing \u2013 the easier one is a decrypting attack, where the plaintext for encrypted data is obtained, and the more difficult one is an encrypting attack (where a forged encrypted request is sent).<\/p>\n<p>None of the information I present here is secret, and all the steps can be obtained by thoroughly understanding the public documents describing how an exploit is performed.&#160; None of the documents I\u2019ve read specifically exploits ASP.NET, but coupled with knowledge on how ASP.NET works (Reflector helps a lot), an exploit program can easily be crafted.&#160; The first and second documents are practically the same.&#160; The third document describes the attack in more practical terms.<\/p>\n<ul>\n<li><a title=\"http:\/\/usenix.org\/events\/woot10\/tech\/full_papers\/Rizzo.pdf\" href=\"http:\/\/usenix.org\/events\/woot10\/tech\/full_papers\/Rizzo.pdf\">http:\/\/usenix.org\/events\/woot10\/tech\/full_papers\/Rizzo.pdf<\/a> <\/li>\n<li><a title=\"https:\/\/media.blackhat.com\/bh-eu-10\/whitepapers\/Duong_Rizzo\/BlackHat-EU-2010-Duong-Rizzo-Padding-Oracle-wp.pdf\" href=\"http:\/\/media.blackhat.com\/bh-eu-10\/whitepapers\/Duong_Rizzo\/BlackHat-EU-2010-Duong-Rizzo-Padding-Oracle-wp.pdf\">http:\/\/media.blackhat.com\/bh-eu-10\/whitepapers\/Duong_Rizzo\/BlackHat-EU-2010-Duong-Rizzo-Padding-Oracle-wp.pdf<\/a> <\/li>\n<li><a title=\"http:\/\/www.gdssecurity.com\/l\/b\/2010\/09\/14\/automated-padding-oracle-attacks-with-padbuster\/\" href=\"http:\/\/www.gdssecurity.com\/l\/b\/2010\/09\/14\/automated-padding-oracle-attacks-with-padbuster\/\">http:\/\/www.gdssecurity.com\/l\/b\/2010\/09\/14\/automated-padding-oracle-attacks-with-padbuster\/<\/a> <\/li>\n<\/ul>\n<p>Contrary to what\u2019s inferred in several blog posts, none of the papers successfully describe an encryption attack on ASP.NET.&#160; Rizzo\u2019s paper offers hints to how we can perform an encryption attack (not easy), but given enough time and HTTP requests by the attacker, it can be done.&#160; I\u2019ll describe the special case where the attacker can download any file from certain ASP.NET web sites using an encryption attack.&#160; <em>Update 10\/13\/2010: The PadBuster application in the third site above has been updated to use an encryption attack.<\/em><\/p>\n<p>There are two padding oracles that I\u2019m aware of in ASP.NET, there may be more.&#160; The first oracle is the WebResource.axd handler.&#160; It throws an HTTP 500 error if a padding error is encountered and either HTTP 200 or HTTP 404 if there isn\u2019t a padding error.&#160; The other one is ViewState decryption, but I did not investigate further on the second one, and most sites do not encrypt view state \u2013 that is, they just don\u2019t place sensitive information in the view state and avoid the encryption\/decryption.&#160; Contrary to what\u2019s been mentioned out in the net, the ScriptResource.axd handler is not a padding oracle.&#160; The code for ScriptResource catches a padding error and returns an HTTP 404 in its place.&#160; The ScriptResource handler, however, is what\u2019s exploited in attempting to download any file from the web site.<\/p>\n<p>The first fix has to be on the WebResource handler, to make it behave the same way as the ScriptResource handler (that is, catching the padding exception and returning an HTTP 404).&#160; The processing code for ViewState may need to be fixed as well (like I mentioned, I didn\u2019t explore the ViewState attack vector).&#160; I will also make the assumption that the encrypting method is known (and the attacker knows what the cipher block size is).&#160; This is typically 3DES or AES, but it\u2019s just an additional step to check if the attack works for one or the other.<\/p>\n<p><strong>Finding The WebResource Padding Oracle.<\/strong><\/p>\n<p>First is to find an existing ciphertext for a request to the WebResource handler.&#160; Inspection of the generated HTML page from an ASP.NET application can easily find this.&#160; Even the simplest ASP.NET application will include a WebResource request to the embedded \u201cWebForms.js\u201d resource.&#160; The decrypted form of that request parameter is \u201cs|WebForms.js\u201d.&#160; It doesn\u2019t have to be that specific request \u2013 any WebResource request will do, because we know that it\u2019s a valid request to the ASP.NET application.<\/p>\n<p><strong>Performing The Decryption Attack.<\/strong><\/p>\n<p>With a known valid ciphertext, we use that ciphertext as the prefix blocks for a padding oracle exploit.&#160; I won\u2019t go into detail into the mathematical aspects of this (it\u2019s all described in the papers).&#160; Suffice to say that we perform a padding oracle decryption attack by sending several \u201cknown ciphertext\u201d + \u201cgarbled block\u201d + \u201cciphertext block\u201d to the server.&#160; Decrypting a single ciphertext block will take at most n*256 requests, where n is the number of bytes in a block.&#160; For 3DES-based encryption, that\u2019s a small 2000 requests per block.<\/p>\n<p><strong>Performing The Encryption Attack.<\/strong><\/p>\n<p>The papers and the \u201cpadBuster\u201d utility available for download around the net assumes that the initialization vector (IV) is controllable by the attacker.&#160; It may be true on some systems, but not on the other flaw with ASP.NET (described next).<\/p>\n<p>There is this big vulnerability in one of the HTTP handlers that came out with ASP.NET 3.5.&#160; Specifically, the ScriptResource.axd handler allows download of any file within your application directory.&#160; But only if an attacker can figure out what the encryption key to use in encrypting the download request.&#160; Assuming an attacker can find what the encryption key is, what would the plaintext look like?&#160; A plaintext request for a file in the application directory looks like one of these:<\/p>\n<blockquote>\n<p>r|~\/Web.config<\/p>\n<p>R|~\/Web.config<\/p>\n<p>Q|~\/Web.config<\/p>\n<p>q|~\/Web.config<\/p>\n<\/blockquote>\n<p>The different prefixes indicate different variations of the request (whether the downloaded stream should be gzip\u2019ed and such).&#160; The path could also be an absolute path instead of an application-relative path.<\/p>\n<p>If the attacker does not have the encryption key, and the IV is the prefix of a request to ScriptResource, then it\u2019s easy for an attacker to craft such a request by first performing a decrypting padding oracle attack for the last block of the request against an existing ciphertext block.&#160; Given the intermediary bytes for the last block, the ciphertext block for the second-to-the-last block is derived, and another decrypting attack is made on it.&#160; The chain is followed until the first block, where the IV is derived and the IV sent as a prefix.&#160; This would only involve about 4000 requests to the padding oracle since the length of the desired attack request is only two 3DES blocks (or one AES block).<\/p>\n<p>That\u2019s only if the IV were sent as the prefix to the encrypted block.&#160; It isn\u2019t.&#160; Not for the ScriptResource handler.<\/p>\n<p>However, there\u2019s this other flaw.&#160; If the victim web site makes a certain usage of the ScriptResource handler, the source of the HTML page would have a request (encrypted) that is similar to one of the attack request.&#160; This is with the use of CompositeScripts in the ScriptManager.&#160; With the use of CompositeScripts containing a script reference to a JavaScript file, the encrypted request starts with \u201cQ|\u2026\u201d.&#160; If the attacker can find out that CompositeScripts are used in a page (by using the padding oracle to decrypt the first block of a ScriptResource request and checking if it starts with \u201cQ|\u201d), then that request can be used as a prefix to an attack request.<\/p>\n<p>Specifically, the attack request will be composed of: \u201cprefix\u201d + \u201cgarbled block\u201d + \u201c||~\/Web.config\u201d.<\/p>\n<p>Because of how the ScriptResource handler processes the request, the garbled block could be ignored and the subsequent part of the request for the file download is honored.&#160; This causes the attack to append the contents of the requested file into the rest of the results.<\/p>\n<p>If the attacker can not find an existing ScriptResource usage that has the \u201cQ|\u201d prefix, then it comes down to being able to craft a ciphertext block that would correspond to having a 2-character prefix of \u201cr#\u201d, \u201cR#\u201d, \u201cQ#\u201d, or \u201cq#\u201d.&#160; This is not trivial, but still boils down to only being able to forge a single block.&#160; Because of the nature of block cryptography, a block with the correct prefix could be forged in at most 256*256\/4 (~16000) attempts.&#160; Once that single block is forged, then it can be used as the prefix to the attack request where there is still a garbled block in the middle and a file download at the tail end of the attack.&#160; The attack request will be composed of: \u201cprefix\u201d + \u201cgarbled block\u201d + \u201c|||~\/Web.config\u201d.<\/p>\n<p>16000 HTTP requests.&#160; 8000 requests on average.&#160; It\u2019s not a big number and can be done in a matter of minutes.<\/p>\n<p>The provided code has more inline comments on it.&#160; The constants in the code should be substituted with what\u2019s obtained from visual inspection of the generated HTML file for a page.<\/p>\n<p><a href=\"\/\/peterwong.net\/files\/PaddingOracleExploit.zip\">\/\/peterwong.net\/files\/PaddingOracleExploit.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Or an example Padding Oracle attack in 100 lines of C# code. This post has been in my outbox for weeks, since I did not want to make it generally available before the patches were released.&#160; Now that the patches &hellip; <a href=\"https:\/\/peterwong.net\/blog\/yet-another-take-on-the-padding-oracle-exploit-against-asp-net\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[11,27],"class_list":["post-120","post","type-post","status-publish","format-standard","hentry","category-asp-net","tag-asp-net","tag-security"],"_links":{"self":[{"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/posts\/120","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/comments?post=120"}],"version-history":[{"count":0,"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/posts\/120\/revisions"}],"wp:attachment":[{"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/media?parent=120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/categories?post=120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/peterwong.net\/blog\/wp-json\/wp\/v2\/tags?post=120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}