Saturday, October 2, 2010

Breaking .NET encryption with or without Padding Oracle

I have had many questions regarding Padbusterdotnet after our previous post Investigating .NET Padding Oracle Exploitation. Here I'll try to answer some of them.

How can I download the Web.config?
Since Microsoft patches are already out now I will disclose how to download the files remotely. Padbuster v0.2 and Pudbusterdotnet cannot alone download the Web.config. For achieving this result I have made a Poc that you can find here.

Update 04/10/10: A couple of days after the release of our initial exploit Brian Holyfield added these (and more features) in Padbuster v0.3. Now Padbuster is a swiss army knife to fully exploit .NET Ajax handlers.

The most common way to download files remotely from unpatched framework 3.5 Sp1 and 4.0 is to obtain after decryption a string similar to the one below:
Note: first bytes magic values are "r#","R#","q#","Q#".

Therefore you should use Padbusterdotnet to encrypt the string "|||~/Web.config" and bruteforce the values of a test block that will be added at the beginning of the encrypted data . Since the S-Box of Triple Des and AES give a total different block for each byte that changes on the first block, we can simply substitute random bytes in the first block.

This is quite reliable, but it takes some thousand requests to be successful.

See the exploit code in action, with full details:

Do I really need a Padding Oracle for breaking .NET encryption?
The answer here is NO. In unpatched framework 3.5 Sp1 (and maybe above) "ScriptResource.axd" is flawed. If you send the "T" magic value as the first letter of the first block after decryption, it will decrypt the whole "d" parameter. You do not need Padding Oracle at all.

In addition since it's a pure fast bruteforce attack, you do not need to check for 404 vs 500 errors: you just need to check for 200 status codes.

This feature exists because of the following code in "ScriptResource.axd" handler:

"case ‘T’
- where strSubstring(1) is the “d” parameter decrypted

 As you can see to decrypt any string encoded with the MachineKey you just need to bruteforce the first block (this is very fast because you need to guess only 1 letter). If you prepend this block, you can instantly decrypt any string, so you don't need Padding Oracle Anymore.

P.s. since you also see the plaintext from your encrypted block, you could be able to encrypt arbitrary values.

The following is the output you get from the handler:

n0def@tremors:~/n0def$ ./

parent.Sys.Application._onIFrameLoad(); &X; :�ס�{ ts~{��ס�{ ts~{�{ t{ r|~/mydocument.js
Exploit code is very similar to Web.config_bruter for decrypting. For encrypting is a bit more difficult... for now :D


  1. Wow, that code is totally out of place. I can't believe I missed it, I went near it a couple times when I found evidence of the web.config file exposure issue in there.

    At least ms put not just 1, but 2 protections preventing the special files exposure in the patch (check sign first, and also don't serve .js files).

  2. i've generated an encrypted value that is equal to ♠=↓hπ¥ßSWΩB♦▐Y╫|||~/web.config. now i should bruteforce first block for a valid string like Q#...... or something like that. i tested your brute force and it does nothing in a bout 50'0000 requests. i think it is not probable to generate some valid 16bytes !!!
    because of it's random nature it may takes millions of requests!! :)

  3. @Anonymous: I have tested it against a couple of applications and servers. It works correctly in an average of 15000 , 30000 requests. Random generator does it's job, for just a couple of bytes.

    To check if you did it correctly, check the "T" exploit. You should get 20 or more "T" block per each "Q#" like blocks.

  4. would you please explain more about T_exploit implementation?

    is it useful for encrpytion or just decrpytion?

  5. @eglasius: Yep, "T" option is weird and out of place there!

    @Anonymous: T_exploit is something very nasty. Imagine that you have customerrors = ON. You can still exploit ScriptResource.axd for decrypting instantly anything. You just need to prepend a bruted "T" block + null IV to any encrypted message. Even Viewstate...?... Automatic decryption.

    It could be used also for instant encryption, since you get the plaintext for any encrypted text block. Some bytes could be missing from the response, this makes it a bit harder to exploit for encryption.

  6. ok the T exploit is clear now,
    and this is true , you can decrypt any message through T exploit and bypass MS workaround.
    and to get (Q# or R#) is about from 200 - 60000 requests.
    but could this help for encryption?
    I think we need the intermediate bytes from padbuster to help us to encrypt our payload.
    so T exploit alone is not enough.
    my question, how did @Julian doing it with 7000 requests only?

  7. @freesrvs: You could use it also for encryption. you can get the intermediary values from XOR P(1) with C(n-1). The problem I see that makes it a little harder is that it uses Encoding.UTF8.

    However there are workarounds for that.

  8. @freesrvs: as far as I can see "T" exploit makes "customerrors = ON" a valid Padding Oracle.

    If you add a T block at the beginning of the testsample, you can check for error 404 vs good 200 response. This way I thing it's the easiest for initial (and broken) workarounds.

  9. Great work Giorgio..and nice exploit script!! Do you have any plans to release a faster T-Block optimized exploit?

    As an FYI, we just released v0.3 of PadBuster which includes an integrated Brute Force mode similar to what the bruter script does. I do not plan on integrating T-Block optimizations into PadBuster, however, as I feel it is too specific to the .NET exploit and not likely re-useable for other padding oracle exploits (I could be wrong, but thats my thought for now at least).

  10. @Anonymous: Yep! Good catch!

    @Brian: Thank you Brian!!! I am already working on a T block optimization attack tool :D

  11. @Giorgio,
    regarding to MS workaround
    After applying Padbuster v0.3 -prefix still cannot bypass scottGu workaround
    All status are same "200" if the victim is using custom error.
    can you explain in details how to bypass the MS workaround ,
    the -prefix is only prepends the cipher text before the real cipher text, could this bypass the custom error?
    it is not clear for me.

  12. @freesrvs: Yes, it can. Invalid padding errors are thrown as custom errors exceptions. Custom errors can have "200" status code; the tool checks also the length of the response. Looking for status codes maybe not enough as it may depends from server configuration.

    However the tools check also for response length and accept custom strings to identify error response from a manual analysis.

  13. Why after i tried to run padBuster 0.3 with the correct sintax, returns it to me:

    ERROR: Encrypted Bytes must be evenly divisible by Block Size (16)
    Encrypted sample length is 17. Double check the Encoding and Block Size.

    i've copied the webResource rightly, like:

    perl q2fyTtVmSGGPWSxcoZcs3Q2 -plaintext "|||~/Web.config" 16


    ERROR: All of the responses were identical.

    Double check the Block Size and try again.

    Help me Sir! ;)

  14. @Dezinho: Try also padbusterdotnet.

  15. I still don't understand the "T" exploit. Could you please give me a simple example showing the exploit!!


  16. Hi,

    Can u please upload your web.config configuration and also a pcap sample of a successful attack?


  17. Is it possible to guess the machine key without downloading the web.config file using PadBuster or PadBusterDotNet?


  18. PadBuster v0.3 runs successfully for me and provides the encrypted value, however when I then use, it does not do anything - it just sits there for ever.

    I think it is because there is no ScriptResource.axd file on the server, as I get an error when trying to access it - what can I do to exploit this?

    Can I use WebResource.axd with instead? I tried but it also just stalled there. I am testing against .net 2

    1. hey,i have a problem to find the encrypted value.
      here is the error,all of the responses were identical.
      double check the block size and try again.
      do me a favour!

  19. can it use on decrypting MD5 viewstate or jsp encrypted com.sun.face.VIEW value ?

  20. I am playing a cat and mouse game... Now the encrypted sample starts with a - minus sign and is being mistaken for a switch.. Any way around that?

  21. Hello sir i tried it on Version Information: Microsoft .NET Framework Version:2.0.50727.4206; ASP.NET Version:2.0.50727.4016

    everything done.
    padbuster gave me value

    and after that i tried web.config bruter and it also said:

    Resulting Exploit Block:QbmrDsOvmkKdXLb44rSf7zGqWKFVEJe3cGLutKTRjg0AAAAAAAAAAAAA

    but when i tried to download web.config their was an error so can you explain how to i can download web.config file when i have all these values......

  22. I am just using Padbuster v0.3 and this simply works on .Net attack, encrypting string as well as identifying and exploiting padding oracles in all web application. Also some extra new features make this version unique.

  23. @J: Just to clarify: This post is the first public exploit of Ms10-070. Padbuster v0.3 was published after this, and integrates some of the techniques herein described and some extra features.

    However I suggest to read this post and also the previous Blog Post on the subject for:
    - Passive fingerprinting for patching
    - Understanding which ASP.NET version is installed (e.g. 2.0, 3.5, 3.5sp1 or 4.0)
    - Exploit the issue without using some known encrypted string
    - Exploiting the issues without Padding Oracling

  24. Is there any info anywhere how to generate ScritResource d=xxxx encrypted strings once you know the machine key?

  25. when i ran , it's run but i wait very long and not display the result. Please help me to solve this problem

  26. @Anonymous if you know the machine key it's pretty easy to use it for encryption/decription.

    The following one is a very valuable resource:

    @Anonymous: does not work against all ASP.NET versions: it will not work against version 2.0

  27. First of all thanks for your awesome work! I really did enjoy trying this out.

    Using the, I managed to successfully get the encrypted value for the web.config but when I tried it with, it ran more than 10,000 times but no luck so I stopped it. Other people have been successful with number of requests well below this I'm afraid.

    The site runs .NET 2.0.50727.3603. How do we actually hope that a random generated prefix value would possibly match in a low number of tries like this? May be I am missing some inside info on how this really works...

  28. padbusterdotnet is facing issue with HTTPS. For one of the sites, it returns 500 response. When I switch to superverbose I found that connection could not be established properly. Any suggestion..
    Thanks in advance

    1. Hi Anon. It can be the problem of invalid certificates. Check the traffic if you see some clue like: Unknown CA.
      Then you can edit the tool, adding an option to bypass check certificate.
      Look for the LWP object and add
      $lwp->ssl_opts(verify_hostname =>0);

    2. I am trying by bruteforce attack. It only keeps sending me requests. It has been more than 5 hours. Is there any way to make it process faster ????

  29. nice work but are there different webresource.axd cause there is this site that is net,padding oracle vulnerable but the webresource is not short and also is divided here is how it looks script src="/WebResource.axd?d=k1dv91ZrEzLQmFgKzmZSRK_oShvrFoTHKrUTA93yrpavLuYbCON6XzXmyhBff9hciYLRaSXiP8qyfaAGdOjh-XSnNueoNPQYHqgezjZJcME1&t=635307452147475859" type="text/javascript"

    1. ERROR: Encrypted Bytes must be evenly divisible by Block Size (16)
      Encrypted sample length is 81. Double check the Encoding and Block Size.

  30. I am getting "All of the responses were identical" so how can i try for T-block and what can be the command for "T" block. I don't understand T-Block could you please elaborate ?