x5s - automated XSS testing assistant

by Casaba Security, contact us through CodePlex, or email us at casabasecurity .com.
  • Author - John Hernandez
  • Contributors - Chris Weber, Robert Mooney
  • Copyright 2009, 2010 Casaba Security, LLC, all rights reserved
  • Released under a custom BSD-like license

Warning and Disclaimer: Use this tool only on test systems that you own. It is not recommended to use x5s against production systems. x5s may send a large amount of HTTP requests to your website, and will taint all of the inputs that it finds. This can be equated to 'fuzzing' in which case the inputs it taints will wind up in your database and on your website, which may not be desirable on public-facing systems. Casaba takes no responsibility for the use of x5s, and offers no warranty or guarantees about x5s as noted in the EULA and license agreements.

Contents

Why should I use this tool?
Quickstart Tutorial
How does it work?
Limitations and known issues
Installation and quickstart
Detailed configuration and usage
Extensibility

Why should I use this tool?

x5s was first and foremost designed to find encoding and character transformation issues that can lead to XSS vulnerability, and present them in a visual way where they could be reviewed with a quickness. Many tools exist for testing Web-applications to find cross-site scripting bugs. There are browser plugins, Web-scanners, and static code analyzers. We use whatever suits us in a given situation and produces the output we're interested in receiving. We developed x5s for penetration testers and other security-minded persons who already know how to find and exploit an XSS vulnerability. The tool has a slightly different bent than other tools we've used. It's main goals include:
  • Automate finding the encoding issues that can lead to XSS.
  • Identify where character transformations occur by injecting multibyte characters such as higher Unicode code points and non-shortest form character encodings.

Injecting probes to find encoding issues makes sense for finding XSS hotspots, but why should you be concerned with character transformations? Bypassing an XSS filter would be a big problem for any application. By detecting where characters transform, x5s can help you identify where your filters might be bypassed when special characters or encodings are used.

It does not inject any XSS payloads in testing. It simply injects canaries - test strings which include a single-character probe. x5s will replay a new request for each user-controlled input parameter an application accepts. In this way each parameter gets tainted and tested independently of the others.

We wanted to automate the tedious testing process of injecting probes into every input parameter of a Web-app, followed by trying to figure out how that probe was later emitted by the Web-app. However, we did not want to rely on a fully automated scan. Instead we wanted some control and insight into each test case. Was it encoded safely or not? Was it transformed into something else? Was it replaced or dropped? In some cases, testing for XSS involves what can be over-simplified as a 3-step process:
  1. Test user-controlled input using special characters like <, >, ', and ".
  2. Review how the output encodes the special characters.
  3. Inject a full XSS payload to validate that a vulnerability exists.

x5s will automate the first two steps of this process. This has been useful in saving time and effort, and in reducing the potential problem areas to a small, manageable set of 'hot-spots'. Once a hot-spot has been identified, the pen-tester can perform the final step of validation.

Extensibility was intended as well, so that new request parsers could be included in x5s. So in addition to JSON, and traditional form data, new or custom protocols can be considered and used in testing. The character mappings used in the test case configuration are also extensible, by modifying the XML file that ships with x5s.

Quickstart Tutorial

We build tools that work for us and when making them available to the public, realize that everyone else can't read our minds when trying to figure them out. This tutorial aims to walk you through a simple use case and get you started.

How does it work?

The x5s tool will automate testing all of the GET and POST input parameters on the target application, then present the findings in a grid-display for quick visual analysis. The tool goes further by auto-injecting special characters (e.g. higher Unicode, overlong UTF-8) to detect transformations that could lead to XSS. x5s has an extensible design allowing for custom request parsers to be quickly implemented. For example, if the target application uses some custom XHR request format that resembles a hybrid between JSON and RPC, you could implement a parser so all of those inputs would be properly tested.

The x5s tool does not crawl or spider a website. It relies on you browsing and interacting with the site through your favorite Web browser, using Fiddler as a proxy. In this way, all complex Web 2.0 communications are preserved, and x5s will get to see all of the query string parameters, form fields, and JSON parameters as they happen for real. The downside is that you need to be sure to exercise all pages and functionality in your site in order to gain a high level of coverage. Typically this is not a problem for vendors who have automated Web-testing infrastructure already in place. In these cases, just run Fiddler and x5s and your automation in conjunction to gain the coverage you desire.

x5s auto-injects canaries which include single-character probes in attempt to detect how those probes were later encoded or transformed. The probes include but extend beyond traditional ASCII, being sure to test cases where Internationalized software might transform or map special Unicode characters to other ASCII representations:
  • ASCII characters like <, >, ', and "
  • Unicode characters that may transform (case, normalize, best-fit map) to the above ASCII characters
  • Non-shortest form UTF-8 encoded versions of the above ASCII characters

x5s provides several benefits by including each of these test cases. For one, it automates significant portions of the traditional XSS testing process. Beyond that, it leverages special Unicode characters and non-shortest form UTF-8 encodings to test string handling in Internationalized software.

Canaries
Canaries are composed of a unique ID, the Preamble (as specified in the UI), and a single character (also specified in the UI). x5s uses these canaries to identify injected data that has been persisted or reflected by the target web application during testing.

canary = { unique ID + preamble + character probe }

x5s determines the inputs types of a request passed to it via Fiddler, and for each test case configuration enabled in the UI, resends a request containing a canary to the application being evaluated.

To support unknown request protocols (e.g. not application/json, or x-www-form-urlencoded), if the preamble is found in a request by itself, x5s will replace it with a canary, and resend the request back to the web application. This enables a tester to enter the preamble in any field of a Web-app, and allow x5s to call attention to a potentially unknown serialization format. For this and other reasons, it is important to choose a preamble that is unlikely to appear in pages that you are evaluating.

If the canary is found in a response, x5s will evaluate the character probe segment for replacement, transformation, or encoding, and report it as appropriate in the Results tab of the UI.

Replaying Requests
x5s works by replaying a given request N number of times injecting each canary (id preamble probe) once per input point (query string parameter, post data param, JSON value). The canary value is important to give x5s a string it can control, and use to detect its payload in the HTTP response. x5s is extendable through request parsers. We've built request parsers for POST name=value pairs, query string parameters, and JSON. It can be simple to build a new request parser class to handle other communication protocols.

After a probe is injected, x5s inspects the response to find all instances of the preamble. It attempts to determine if the probe, which follows the preamble, was:

a) transformed
b) encoded
c) replaced
d) unchanged

If x5s can't figure out what happened it will assign the result 'unknown'.

The 'results' pane is where you review the findings. It's designed so you can visually scan the results quickly, and look for places where the probes were unsafely rendered on the page. If your impatient, you can just click 'show hotspots'. If you're more curious, you can scan the list, mostly ignoring results that were 'encoded', and looking for results that returned 'none' meaning no encoding or transformation was identified. Other results that may be worth a closer look are 'transformed' and 'unknown'.

Limitations and Known Issues

  1. Auto-injection in x5s doesn't support NTLM auth, so while these requests will be replayed, they will fail because the auth will fail. We would need to implement support for NTLM auth using the provided .NET libraries.
  2. For the same reason cited above, CSRF protections will break the testing methodology of x5s since it doesn't have a method to provide a changing/unique token with each request.
  3. Some false positives exist. We haven't implemented a good way to filter out findings when a canary like 0123pqz< gets sent, and the response contains something like <p>0123pqz</p>. In such a case, the Web application dropped the trailing <, but x5s identified a false positive. To solve this problem we're considering using a postamble along with the preamble values for the next release.

Installation and Quickstart

x5s is a Fiddler addon so install the Fiddler tool first.

Run the X5Setup.msi and follow the prompts. This is the prefered method of installation. Alternately, extract the files from X5Setup.zip to %USERPROFILE%\Documents\Fiddler2\Scripts.

x5s can be uninstalled via Add/Remove Programs in the Control Panel; or if files were extracted from the ZIP file, simply removed from the directory to which they were installed.

To get up and running quickly:
  1. Start Fiddler, and select the x5s tab.
  2. Check Enable to start capturing page metadata.
  3. Enter a Preamble, or use the default - this must be a unique string x5s can use to identify its payload in the response, for example "pqz" or "test321"
  4. Enable Domain Targeting to restrict testing to a particular domain, i.e., the site you'd like to test.
  5. Select each of the auto-injection options you want (e.g. select auto-inject into GET, POST, and Other)
  6. Leave the advanced filter disabled for now
  7. Enable the injection characters you'd like to test through the 'Test Case Configuration' tab.
  8. Browse the site you're testing. x5s will work its magic.
  9. Click the 'Results' tab to review any issues discovered by the tool.
  10. If you don't feel like trying to make sense of the results, just click the 'show hotspots' button and review any that show up.

Detailed configuration and usage

Each of the configuration options for x5s are explained and general usage of the program.

Main Configuration

The screenshot below shows the main configuration screen of x5s. Explanation of the individual options follow.

x5s-config-screen.png

Enable
x5s will lie dormant until you check the box to enable it.

Preamble
Enter a unique string like 'pqqz' or 'test123' that x5s will use to extract results from each response.

Enable Domain Name Targetting
Check this box to limit testing to specific domains. This prevents x5s from going crazy and injecting into every site you browse to. By scoping to a domain name such as nottrusted.com then all subdomains of nottrusted.com will also be considered in scope for testing.

applies to requests Check this box to limit all requests x5s sends to the domains you want.
applies to responses Check this box to limit all responses x5s parses to the domains you want.
Domain Insert the domain name you want to test and click 'Add'.

Enable Results Filtering
Enable any of the available result 'types' to filter data in the 'Results' tab.

None applies to results that did not return transformed or encoded. E.g. a less-than < sign did not get changed or encoded, or a Turkish I remained a Turkish I in the response.
Replacement applies to characters that seem to have been replaced with a known common replacement character such as ? or the Unicode U+FFFD.
Transformed applies to source characters that were transformed to their target (expected) character. E.g. a Turkish I transformed into an ASCII i or I.
Encoded applies to source characters that were encoded in the response, using URL, HTML, NCR, or other known encodings.
ShortestForm applies to source characters that were sent as non-shortest form UTF-8 and returned as their shortest form ASCII representation.
Unknown applies to all other cases.

Auto-Injection Options
This is the meat and potatoes of x5s, where you configure it to automatically inject canaries into every input parameter it can figure out.

Inject GET request parameters enabling this will have x5s automatically inject into every query-string parameter of a request. For example, in the following example:
{ GET foo.bar/page?name1=value1&name2=value2 }
The request will be resent with unique test cases sent for value1 and value2.

Inject POST request parameters enabling this will have x5s automatically inject into each input field of a request body. x5s ships with parsers that know how to parse common request types, including:
  • JSON (e.g. Content-Type application/json)
  • form POST (e.g. Content-Type application/x-www-form-urlencoded)

Note that custom parsers can be written to include any serialization format or MIME type.

Inject into "Other" parameters enabling this tells x5s to inject into input fields that it doesn't have a parser for. This is only possible if the 'preamble' value is included in the request. For example, if you fill out a form and include your preamble in one of the fields (e.g. pqz), x5s will recognize that preamble and resend the request, replacing it with each configured test case.

Throttle request generation is a way to control how x5s sends out the requests it needs to send. Specify a Delay period in milliseconds to slow down how often a batch of requests are sent. Set a 'Batch size' to the number of requests you want to send in a given period. For example, if you want to send requests very slowly, you could set a delay period of 10000 milliseconds and a batch size of 1. When x5s has queued up 100 requests it needs to send, it will send only 1 every 10 seconds.

URI Encoding Options
Control whether the character probes of each test case should be URI encoded. For example, do you want to send the '<' character URI encoded as '%3C' or send it unencoded?

Encoded HTTP Body Data determines whether the test cases in body parameters of any POST request should be URI encoded.
Encoded HTTP Headers determines whether the test cases in HTTP headers of any request should be URI encoded.
Encoded Query String determines whether the test cases in the query string parameters of any GET request should be URI encoded.

General Options
Some options like checking for updates.

Automatically check for updates on start when enabled x5s will check for updates each time Fiddler is started.

Test Case Configuration

The following screen shows the test case configuration tab, which provides a way for you to setup the test cases x5s will work with.

x5s-char-screen.png

Here you control the test cases sent in each parameter, or input field, of each request. x5s test types can be extended, and the included ones are described here. Each character is defined with a name, a source and target code point, and a description.

Enabled Check the box next to any character to enable it to be used in the generated test cases.

Source Code Point Each character has a unique code point defined by Unicode. The source code point is the actual character used in the testing.

Target Code Point Each character has a unique code point defined by Unicode. The target code point is the character we expect to see if there's no encoding of if a transformation occurred. In other words, seeing the target character in the results would indicate a potential XSS vulnerability.

Transformable
These are non-ASCII characters known to transform to ASCII in certain conditions. If any of these test cases result in transformations, then you likely have an interesting area to pursue for testing. For example, the source character U2134 SCRIPT SMALL O character will transform to the U006F LATIN SMALL LETTER O in certain cases like Unicode normalization forms KC and KD and some best-fit mappings.

Traditional
These are plain ASCII characters, useful in traditional testing for XSS or encoding issues.

Overlong
These are the UTF-8 non-shortest form encoding of a given ASCII character.

Results

The following screen shows the Results tab, which is meant to provide a quick visual analysis of the test results. This will be the area you're most interested in as a security tester.

x5s-results-screen.png

The data grid on top shows a list of all the canary occurrences in the response. It's meant for you to quickly scroll down the list and visually see how your test character probes were rendered.

Context The context columns gives a visual snippet of the extracted test case, for quick visual analysis

Transformation The transformation column gives you the result of the test - did the character transform or get encoded?

CodePoint The codePoint column attempts to tell you which source character was used for the test case.

Show Hotspots By clicking this button, you can filter out all the noise and just see what x5s assumes are likely candidates for XSS vulnerability. The filtering here involves some decisions about what source character was used and what the transformation type was.

Clear this button will clear all of the results.

The bottom half of the Results tab attempts to highlight the canary in the source code of the page. This is meant to give you a wider view around the context.

Extensibility

In addition to JSON, and traditional form data, new or custom protocols can be considered and used in testing HTTP requests. The character mappings used in the test case configuration are also extensible, by modifying the XML file that ships with x5s.

New Request Parsers

TBD

Test Case Configuration

In the install folder for x5s, normally My Documents\Fiddler2\Scripts, you'll find a file named ShortMappingList.xml. This file contains the character definitions used in testing. This file can be modified by adding or removing new UnicodeTestMapping records. The format must follow exactly what's there already. An example of a current test case record is included below.

    <UnicodeTestMapping Type="Transformable">
    <Target>
      <UnicodeChar Name="U+003E GREATER-THAN SIGN" CodePoint="003E" />
    </Target>
    <Source>
      <UnicodeChar Name="U+FE65 SMALL GREATER-THAN SIGN" CodePoint="FE65" />
    </Source>
    <Transformations Normalization="True" BestFit="True" ToUpper="False" ToLower="False"/>
    <Description>'Transformable Test Case'
    
The source character U+FE65 SMALL GREATER-THAN SIGN character will transform to the U+003E GREATER-THAN SIGN in certain cases.  
For example, some Unicode normalization forms as well as some best-fit mappings will cause this one-way transformation.

Because it's mostly benign, this character can be useful as a quick test to find out if an application is transforming strings in these ways.  
If a transformation is detected, then further testing should be performed to find cross-site scripting (XSS) attacks.

For example, by attempting to get the word 'script' into the HTML using the U+FE65 SMALL GREATER-THAN SIGN in place of the ASCII '&gt;'.
    </Description>
  </UnicodeTestMapping>

Last edited Apr 8, 2010 at 5:59 PM by chrisweber, version 23

Comments

No comments yet.