Week 9 XSS
Week 9 XSS
INF 203
•This type of attacks can be easily performed by providing malicious
user input.
Cross-site scripting is one of the oldest web application attacks known and is dated
around 1996-1998 when it was possible to control frames within a web page through
injected code, thus “crossing” the website boundaries.
The user input will be extracted from query string of the URL:
https://example.com/welcome.php?name=MyName
XSS
https://example.com/welcome.php?name=</
h4><script>alert(‘LOL,XSS
’);</script>
Note that value of name parameter must be URL encoded. Most browsers will do
this automatically.
XSS
The JavaScript will be executed in the browser within the website context.
As you can see from PHP source code, user input is given on output without any kind of
sanitization. Developer forgot to check the user input for malicious patterns or escape it,
and anyone can exploit this vulnerability to perform a number of different attacks.
XSS
To summarize: XSS are possible when the user input is used somewhere on the web
application output without proper protection, and as a result attack users of the
vulnerable application.
ANATOMY OF AN XSS
EXPLOITATION
Anatomy of an XSS Exploitation
Keylogging, Defacing
etc.
Anatomy of an XSS Exploitation
Let’s assume that the goal of an attacker is to steal a session cookie of a user X who is
authenticated into website Y. It can be achieved through XSS in most cases, so first step
will be to find an XSS affecting the website, and ensure that the vulnerable Host
(subdomain) matches the domain field of the cookie.
Once an XSS is located, attacker have to build up a payload and deliver it to the victim.
Penetration testers can use XSS for privilege escalation. Or just to annoy everyone with
alerts on every page .
TYPES OF XSS
Types of XSS
• Stored XSS
• Reflected XSS
• DOM-based XSS
In reality this types can overlap, creating XSS that can’t be classified with mentioned
types and can be addressed as several (e.g. Stored DOM XSS).
Reflected XSS is probably the most common form of XSS. It occurs when untrusted user
data is sent to a web application, and it is immediately echoed back in the page source.
You can recall our example with welcome message, which falls under this category:
<?php
echo '<h4>Hello ' . $_GET['name'] .
'</h4>';
?>
Types of XSS
Persistent (or Stored) XSS are similar to Reflected, however, rather than the malicious
input being directly reflected into the response, it is stored within the web application
and echoed somewhere else within the web application and might be available to all
visitors.
This type of XSS occur also in server-side code, but more useful for attacker than
Reflected XSS.
It is because with a page persistently affected, we are not bound by having to trick a
user. We just exploit the website, and then any visitor that visits will run the malicious
code and be affected.
Types of XSS
The last one is DOM XSS which is a form of cross-site scripting that exists only within
client-side (JavaScript) code.
This vulnerability lives within DOM environment, thus within a page’s client-side script
itself and does not reach server-side code.
This is similar to our Reflected XSS example, but without interacting with the server side.
<script>
document.write("<OPTION
value=1>"+document.location.href.substring(document.locati
on.hre f.indexOf("default=")+8)+"</OPTION>"); </script>
Types of XSS
The key in XSS exploiting is that the client-side script code can access the browser’s
DOM and all the information available in it. It can be URL, history, cookies, web storage
and other.
Don’t forget that you can’t just route user to a webpage that you own and read the
cookies for auth.y.com, Same Origin Policy will allow code access data only for it’s own
website.
In Reflected XSS, victims bring the payload in their HTTP request to the vulnerable
website.
This payload will be inserted into the webpage and executed by their browsers.
So, attacker has to trick the victim to bring the payload with them to website. For
example victim need to click on a link with payload in order for the attack to be
successful.
When this occurs, the malicious payload is run in the victim’s browser within the context
of the vulnerable website.
Reflected XSS
4. Execute the
payload – attacker
gets control over
victim’s machine 2. Victim clicks on link with payload
http://example.com/payld=<script>alert(0)</script>
Victim Vulnerabl
3. Payload is reflected to victim e website
1. Send to victim
<html>
…
<script>alert(0)</
script>
…
</html>
Persistent XSS
Persistent XSS are attacks that lead to the execution of code in all the user’s
web browsers visiting a vulnerable (and exploited) web page.
The injected code is saved by the application in unsanitized form and then rendered on
either the same or another web page in the same website.
Hence, the malicious code can be injected, by the attacker, directly into web application.
This is the most important difference between Reflected and Persistent XSS.
Therefore it is the most dangerous form of XSS as it can target all the
visitors of a website, and in a matter
targeting the website itself (although indirectly).
Persistent XSS
Let’s see an attacking scenario for a Persistent XSS, where attacker delivers payload.
Steps where payload will be executed will be described later
Vulnerable
Database
website
1. <xss_payload> 2
In this scenario submitted parameter is not sanitized for illegal characters and saved in
the database for later use.
The hacker constructs his exploit, carrying XSS payload, which will be stored in
the
database.
The web application is designed so that parameter, submitted by the hacker, is given on
output on page page_out.php without any sanitization.
This scenario is both very common and applies to a number of situations, like either
commenting scripts or personal community members that accept an input.
Persistent XSS
Internet
Visitors of page
By visiting page_out.php in which malicious payload is rendered, all the visitors of the
webpage execute the malicious payload that was submitted by the hacker.
Note that this type of attack is as asynchronous as the exploitation and actual execution
of the code happens at different times.
While in the case of reflected XSS targeted user could defend himself (at least by not
visiting strange link), in the case of Persistent XSS is so covert and neat that as soon as
the user browses the infected page, the code gets executed.
DOM-based XSS
DOM-based XSS differs from the Reflected and Persistent because they are not caused
by server-side problems.
Instead, they appear when JavaScript code uses the user supplied data as part of its
logic. Once again, if sanitization is not put in place injection is possible.
To get user data JavaScript can use the querystring or prompt() function.
It is important to note that this attack does not require any interaction with the server.
You can create local HTML file with following content:
<body>
<script>document.write(location.href);</
script>
</body>
Open the file in the browser, note that it printed its URL (path to the file):
DOM-based XSS
Fortunately some browsers URL-encode URLs and you may see this:
DOM-based XSS
If the malicious payload is saved by the web application within a cookie or web storage,
the victim user will run the malicious payload every time a new request is sent to
vulnerable page.
Note that contents of URL after # (hash or pound) sign are not sent by browser to the
server. This makes DOM-based XSS harder to find. Despite similar exploitation steps to
Reflected XSS, we can’t find out about attack from server logs.
Self-XSS
Obviously, we can try to use social engineering to exploit this issue, but it is
hard to force user to type some strange data into web application.
Therefore self-XSS usually do not pose a risk.
But in some cases, it can be exploited with use of chain of vulnerabilities.
Blind-XSS
We do not have access to the application source code, so we will try to figure out what
data the application gives on output upon user-supplied data.
If there is a correlation between both output-input and the user-supplied data is part of
the output, then we have found a potential mount point for an XSS attack.
Note that most of modern browsers have Reflected XSS filter, so it’s better to search for
Reflected XSS using browsers which doesn’t have one (Firefox or latest Chrome, which
deprecated previously existing filter).
Finding XSS
Once we have spotted these output-input correlations, we will try to inject HTML or
JavaScript code into the input (not any, we have access to the HTML code where payload
is reflected!). Input can be anything: GET/POST parameters, Cookie, any HTTP Header
(User-Agent, etc.).
So, we need to understand what channels the application uses to retrieve data from
user.
Different channels have different level of exploitability. Input from GET method is the
easiest to exploit, you need to only provide a malicious link to victim, and after he or she
clicks on it, browser will execute the payload.
The POST verb is used for forms submission, and its exploitation needs other approach.
Finding XSS
Assuming we’re exploring a normal GET method, we will try browsing the web
application attempting to inject html into the input parameters of the URL.
Keeping in mind that XSS is the injection of HTML and/or JavaScript, we can use
payloads like <plaintext>.
This special HTML tag instructs the browser to treat the remaining web page source as
plain text, thus breaking the appearance of the site. Be careful with this payload when
testing for Stored XSS, it can break whole page. But as a plus – you will immediately tell
if the injection was successful without inspecting the source; you will see a broken web
page layout showing the web page source as part of the website appearance.
Finding XSS
In the above picture we successfully injected the plaintext tag in the HTML source code.
Every tag coming next to the injection point will not be rendered by the web browser, it
will instead be treated as plain text.
That is why the second step would be to check the possibility of injecting scripts using
the <script> tag or DOM events that we will see later.
Finding XSS
Also note that input validation may allow plaintext tag, but deny others like IFRAME or
IMG.
It is clear that using only plaintext tag is not enough to infer the presence of an XSS.
Lets see some examples for finding XSS in white box approach, when you have source
code of application.
Similar to what we have done in black box, we need to look for all the points where the
application outputs data supplied by the user and track it back to the source where it is
retrieved for the first time.
If on this path you found a sanitization or type conversion, then you should be fine (if
sanitization is implemented correctly).
XSS EXPLOITATION
XSS Exploitation
<!DOCTYPE html>
<html><head><Title>Page</Title> </head><body>
<p>The <a href="<?= $_GET['page'] ?>">page</a> could
not be found.</p>
</body></html>
If you want to play with this code, you can run Kali Linux, place this file under
/var/www/html folder with php extension and run Apache service with command:
service apache2
start
XSS Exploitation
page=<script>alert(“XSS”)</
script>
The application will render following:
As we can see, payload successfully inserted, but won’t be executed because it is inside
href attribute.
XSS Exploitation
In this case we need to close attribute and tag by using “> symbols. So our payload will
be:
page="><script>alert("XSS")</
script>
Unfortunately, it will break site structure and show extra characters:
Let’s look into page source, there is extra “> after our payload:
We can play with current payload to remove this characters or try to use another type of
payload. For example:
page="><body
onload="alert(0)
Note that we haven’t closed quotes, because remained quotes in the source code will
close it.
In this case we can even not use < > symbols and just use HTML events with payload like
this:
page="
onmousemove="alert(0)
XSS Exploitation
With this trick we can evade simple validation checks for < > symbols, but in this case we
need to expect user to move mouse over our component. In cases when payload
inserted in different tags like svg, button or body onload event can be used or
combination of onfocus with autofocus attribute.
Sometimes for researches its better and simpler to use numbers in alert window instead
of strings.
XSS Exploitation
With this tag we can use onerror event. And to successfully trigger this event we will
place a corrupted src attribute.
XSS can be used for advanced phishing. You probably will type your password in cases
when a site ask for it, even in the middle of session. Attackers can use this, instead of
simple defacement, they will put a login form which will send your credentials to their
server.
When most of phishing attacks try to convince you that a different website is actually
valid, with XSS vulnerability attack will work on an actual website.
Note that usual fishing defenses will fail because phishing website is the actual website.
And create an valid login form is simple – just copy actual site’s login form and modify
action URL.
Beef
BeEF (The Browser Exploitation Framework) was created to simplify XSS exploitation. It
allow to redirect the victim, perform Man-In-The-Browser attack, control web camera,
incases with old vulnerable browsers run Metasploit Browser Autopwn and achieve
remote shell on the machine.
BeEF is included in Kali Linux. Feel free to use it and get familiar with it’s capabilities to
better understand XSS.
MITIGATION
Mitigation
XSS vulnerabilities relate to Data Validation vulnerabilities. They arise when user input is
not validated and copied in the output.
Validating an input can dramatically reduce chances of XSS. For example if we have cost
field, then we probably need to accept only numbers.
If URL is outputted on the page, then probably we need to check protocol to match only
HTTP/HTTPS and drop others, especially JavaScript.
Context-Aware output encoding
Output, obviously need to be encoded. In cases when data printed between tags, it’s
probably good idea to use HTML-entity, so no new tags are appeared. But sometimes
input can accept tags like img or spoiler, so we need to encode data depending on
context.
If data printed in URL attribute of tag or in attribute in general, then we can use URL-
encoding or quotes sanitization.
Luckily most of libraries have default sanitization functions and it’s better to use one
instead of creating them manually.