Exploring JavaScript's exploits: A deep dive into XSS vulnerabilities

December 8, 2022

Ramp Up JavaScript

JavaScript, a programming language widely used on the Internet, can be utilized on both the client and server side for development. It's implemented on almost all web pages. This article will delve into JavaScript's unique and intriguing behaviours, including how they can be exploited in an XSS attack or a cross site scripting attack. We'll explore how these behaviours can be used in security research, and why they're relevant to web security, particularly in the context of the OWASP top ten.

Function calls

In JavaScript, functions are first-class objects that refer to the Function object. Unlike other objects, the Function object can be called and return a value.

There are numerous ways to invoke a function in JavaScript. It can be called directly, functions can be chained to call each other, or they can be called from objects/prototypes.

XSS Payloads

The payloads below provide examples of how the alert() function can be invoked. An attacker can use these payloads to demonstrate the presence of a Cross Site Scripting (XSS) vulnerability. This is a classic xss example or cross site scripting example, illustrating what is cross site scripting and how an xss attack can be executed.

window.alert()
window['alert']()
alert()
alert``
onload=alert
\u0061lert()
globalThis.alert()
window?.alert()
eval?.('ale'+'rt('+')')
[1].find(alert)=alert,()
var x=x||alert;x()
alert(1),ErrExit
[][0]??alert()
null??alert()
undefined??alert()
x??alert();var x;

Newlines

JavaScript supports newlines that are not valid ASCII characters (\u2028 and \u2029). These two chars can be used just like any other newline char. To test this function, you can run the following commands below, copy the output and run it.

console.log('alert//\u2028(1)')
console.log('alert//\u2029(1)')

As a Proof of Concept, you can see that the code you executed is presented on a “single line” and that a comment (//) is in place. The JavaScript code still works without problems and this is because \u2028 and \u2029 are seen as a new line.

Comments

The most common JavaScript comments are the double forward slash (//) and multi-line comments (/**/), but JavaScript also supports two additional comments that are rarely mentioned. The <!-- and --> are both supported within JavaScript. These comments are built-in and are also supported in the backend when Node.js is running. The JavaScript code below is valid and uses all four comment methods.

Hoisting

In JavaScript, variables and functions can be used before they are declared, which can lead to many strange behaviours.

In the code snippet below, the function x is used in the if statement before it is declared, but because of the way JavaScript is hoisting, the function x is automatically declared in the hoisting process before the code is executed.

This behaviour causes the if statement to execute and print the text “Oh snap“.

JavaScript function hoisting

If you define variables directly in a function, the variable (x) will set its value (20) both inside and outside the function.

This behaviour is intriguing from a security research perspective, especially when considering cross-site scripting or 'xss attack'. When the attacker can control a value set in a function, he can infect other code processes that use this variable, which is a classic example of an 'xss attack' or 'cross site scripting attack'.

Imagine that a developer creates two variables with the same name, one inside a function and one outside. The developer doesn’t realise that they are the same variable, so in reality, (s)he created a single variable that is being reused when the function is called. This is because (s)he had forgotten to declare the variable with var, let or const.

In this code, the variable str is first set to the value location.search and the variable name is set to the value returned by the ParamNames function (infected). When the ParamNames function is called, it uses the same variable name (str) that was used outside the function. This made the variable str update its value globally because the variable str wasn’t properly declared inside the function.

Error behaviour

JavaScript runs until an error occurs, as long as it is not a syntax error.

Envision discovering a Cross Site Scripting (XSS) vulnerability, a prime example of web security threats listed in the OWASP top ten. The XSS attack works, but you aim to halt any subsequent code execution. By triggering a JavaScript error, which serves as an 'exit command', you can ensure that the JavaScript runs the code, including your XSS attack payload, and ceases when it encounters the error. This is a practical XSS prevention method often used in security research.

Document Object Model (DOM) XSS methods

An input susceptible to a DOM XSS, a type of cross-site scripting attack, hands an attacker a significant advantage when exploiting an XSS. In a DOM XSS, sometimes, the attacker only requires a single character, the backslash (\), to exploit the vulnerability. This is a classic XSS attack example that highlights the importance of robust web security measures.

The backslash character can be used to write in Hex, Unicode and Octal encoded forms. In this case, the payload <h1>Hello</h1> can be written in all the different ways listed below:

1. <h1>Hello</h1>
2. \x3Ch1\x3EHello\x3C\x2Fh1\x3E
3. \u003Ch1\u003EHello\u003C\u002Fh1\u003E
4. \u{3C}h1\u{3E}Hello\u{3C}\u{2F}h1\u{3E}
5. \74\150\61\76Hello\74\57\150\61\76

This method can be used to exploit one of our vulnerable code snippet (#10).

Code Styles

JavaScript code can be written in many strange ways sometimes. Some code styles are nearly never used in development, but only in attack scenarios. These code styles are therefore a great advantage for an attacker…

Unicode

Instead of writing JavaScript as intended, you can also write characters [a-zA-Z] in Unicode encoded form. This will run the code without any problems.

1. var a; a == \u0061 // true
2. alert() == \u0061\u006c\u0065\u0072\u0074() // true

JSFuck

JavaScript can be written with only six characters ([]()+!): this method is called JsFuck. This code style can be used to bypass restricted filters, protections and/or to write stealth exploits/payloads.

(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]] === "ert" // true

JsFuck works when it’s mixed with regular JavaScript code style. Below is a payload that calls the alert() function from the object top.

top['al'+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]](1)

The payload used JsFuck to embed the string "ert" (with quotes) to the top object, resulting in the following payload: top['al'+"ert"](1)

Cross-Site Scripting (XSS) exploitation

XSS, also known as cross-site scripting, is an often underestimated vulnerability, frequently referred to as “the pop-up window alert(1)“. An XSS attack should be exploited like any other vulnerability to demonstrate its full potential impact, such as a takeover of a victim’s account, showcasing a real-life cross site scripting example.

Session hijack

If the cookie has weak security, it becomes a playground for an attacker to exploit XSS, or cross-site scripting, and potentially take over the entire account from the victim. In a typical XSS attack example, the attacker hijacks the session value(s) in the cookie and sends them to a server they own, highlighting the importance of web security.

Iframe exploit

When a session is used within cookies and use strong security, this is where creativity comes into play. A good technique would be to take advantage of iframes. If the iframe security policy is weak, you can use the XSS to embed an iframe that mirrors the original domain and hijack the data within the embedded iframe.

XSS Keylogger

JavaScript can be used to write a keylogger that hijacks the victim’s keystrokes, making it possible to hijack credentials in clear text.

Keyloggers can be combined with other exploitation techniques, such as the iframe exploitation technique explained above. By combining these two techniques, it is possible to follow the victim and hijack all keystrokes from almost any endpoint.

XSS exploitation frameworks

Metasploit offers JavaScript exploitation modules, e.g. the JavaScript keylogger. This module is good to include in your report as a Proof of Concept when an XSS vulnerability is detected in an application.

Take note that YesWeHack has recently released a tool called xsstools. This XSS development framework, written by our Tech Ambassador BitK, makes it easier to create XSS payloads. This tool is perfect for constructing a functional Proof of Concept to exhibit a real impact.

START HUNTING!🎯