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:
r#garbage|||~/Web.config
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:
http://www.youtube.com/watch?v=tlCRivo8Sis



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’
OutputEmptyPage(response,strSubstring(1))"
- 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:

Example:
n0def@tremors:~/n0def$ ./Tblock_exploiter.pl

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

31 comments:

  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).

    ReplyDelete
  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!! :)

    ReplyDelete
  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.

    ReplyDelete
  4. would you please explain more about T_exploit implementation?

    is it useful for encrpytion or just decrpytion?

    ReplyDelete
  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.

    ReplyDelete
  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?

    ReplyDelete
  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.

    ReplyDelete
  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.

    ReplyDelete
  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).

    ReplyDelete
  10. @Anonymous: Yep! Good catch!

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

    ReplyDelete
  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.

    ReplyDelete
  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.

    ReplyDelete
  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 padBuster.pl http://example.com/dotnetnuke/ScriptResource.axd?d=q2fyTtVmSGGPWSxcoZcs3Q2 q2fyTtVmSGGPWSxcoZcs3Q2 -plaintext "|||~/Web.config" 16

    returns:

    ERROR: All of the responses were identical.

    Double check the Block Size and try again.

    Help me Sir! ;)

    ReplyDelete
  14. @Dezinho: Try also padbusterdotnet.

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

    Thanks!

    ReplyDelete
  16. Hi,

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

    Thanks,

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

    Thanks.

    ReplyDelete
  18. PadBuster v0.3 runs successfully for me and provides the encrypted value, however when I then use Web.config_bruter.pl, 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 Web.config_bruter.pl instead? I tried but it also just stalled there. I am testing against .net 2

    ReplyDelete
    Replies
    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!
      thanks

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

    ReplyDelete
  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?

    ReplyDelete
  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
    AAAAAAAA0

    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......

    ReplyDelete
  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.

    ReplyDelete
  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

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

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

    ReplyDelete
  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: http://www.codeproject.com/Articles/36822/ASP-NET-data-encryption-decryption-made-easy

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

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

    Using the padbusterdotnet.pl, I managed to successfully get the encrypted value for the web.config but when I tried it with web.config_bruter.pl, 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...

    ReplyDelete
  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

    ReplyDelete
    Replies
    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);

      Delete