Simple XXE test suite generated specifically for SAML interfaces
Switch branches/tags
Nothing to show
Clone or download
dmuse89 Update saml_xxe_test.py
Edited grammar in --help display.
Latest commit a9b3cf2 May 18, 2018
Permalink
Failed to load latest commit information.
docs Update README.md May 18, 2018
.gitignore Initial commit Apr 30, 2018
LICENSE Initial commit Apr 30, 2018
default_phase1_vectors.yml Use latest version from (internal) SVN May 3, 2018
saml_xxe_test.py Update saml_xxe_test.py May 18, 2018

README.md

SAML-XXE-Test

A simple XXE test suite generated specifically for SAML interfaces.

Introduction

SAML is an XML based markup language and XML parsers employed by SAML endpoints may be susceptible to XXE attacks. SAML messages are usually transmitted using Base64Url() encoding and may additionally be deflated (depending on the used SAML binding). This makes testing for XXE vulnerabilties more difficult, as the encoding needs to be applied to each test-vector when evaluating a SAML endpoint for XXE vulnerabilities.

saml_xxe_test.py automatically performs the required encoding and additionally comes with a predefined set of default test-vectors, most of which attempt to provoke out-of-band feedback. Using saml_xxe_test.py, a security auditor can semi-automatically check a SAML endpoint for XXE vulnerabilities. In its simplest form, running saml_xxe_test.py only requires two arguments:

./saml_xxe_test.py -f url_file.txt -t TARGET

Here, url_file.txt contains URLs of a listener service set up by the auditor and TARGET is replaced by the URL of the SAML endpoint to be tested.

As indicated above, saml_xxe_test.py reads templates of test-vectors from a YAML file and generates a pool of test-vectors by combining the entity definitions of the templates with various protocol schemes, DTD keywords, and provided URLs of a listener service controlled by the auditor. The generated test-vectors are subsequently sent to the targeted SAML endpoint. Requests as well as responses are logged, and the auditor can assess whether or not the tested service is vulnerable by watching out for incoming requests on the prepared listener service. This test scenario is depicted below.

Usage Details

  1. Set up a listener which waits for incoming requests from the service being tested. This could simply be a web server if you only test the http scheme.
  2. Generate a file url_file.txt that contains -preferably unique- listener URLs, one per line1. The URLs must not contain a protocol scheme, i.e., use localhost:5000/RANDOM-UUID (note the missing http://) if the tested service and your listener are both running on localhost. Ensure that your listener is bound to the ports used in url_file.txt and that the listener logs incoming requests.
  3. Using Python 3, run ./saml_xxe_test.py -f url_file.txt -t TARGET This will start sending the default test vectors (http scheme only) as the SAMLRequest parameter via a HTTP-POST Binding to the SAML endpoint TARGET. If the service at TARGET is vulnerable (and has network access), your listener should receive a corresponding request. Incoming requests can easily be mapped to the test-vectors being sent if you use unique identifiers in the URLs listed in url_file.txt.

Options

saml_xxe_test.py allows configuration of the following settings from the commandline.

./saml_xxe_test.py -h
usage: saml_xxe_test.py [-h] -f URL_FILE [-o OUTPUT_FILE] [-t TARGET]
                        [--vector_file VECTOR_FILE] [-m {POST,GET}] [-a]
                        [-p PROXY] [-d] [-i INTERVAL] [-v] [--timeout TIMEOUT]
                        [--dump_vectors] [-s {SAMLRequest,SAMLResponse}]
                        [--store_test STORE_TEST]

required arguments:
  -f URL_FILE, --url_file URL_FILE
                        Full path of Burp Collaborator URL File
  -t TARGET, --target TARGET
                        Target URL as SCHEME://IP:PORT, e.g.,
                        http://localhost:5000

optional arguments:
  -h, --help            Show this help message and exit.
  -o OUTPUT_FILE, --output_file OUTPUT_FILE
                        If no output file is defined, output to terminal is
                        enabled.
  --vector_file VECTOR_FILE
                        A yaml file containing a list of XXE Vectors, defaults
                        to ./default_phase1_vectors.yml The vectors may
                        contain the following placeholders:
                        "${PROTOCOLHANDLE}", "${SYSPUB}",
                        "${PUBLIC_URL_PLACEHOLDER}".
  -m {POST,GET}, --method {POST,GET}
                        Select which HTTP method to use, default is POST. If 
                        set to GET, deflate compression is applied to the SAML
                        message (HTTP-Redirect Binding).
  -a, --aggressive      Build vectors using more protocols.
  -p PROXY, --proxy PROXY
                        Add http(s) proxy address as IP:PORT like
                        127.0.0.1:8080.
  -d, --debug           Enable debug mode.
  -i INTERVAL, --interval INTERVAL
                        Set request interval delay in seconds. Default is a
                        random interval in (5, 15) seconds.
  -v, --verbose         Enabled verbose mode. Sends response to stdout. Auto
                        enabled if no output file is specified.
  --timeout TIMEOUT     Seconds to wait until a request is aborted as timed
                        out. Default is 30 seconds.
  --dump_vectors        Print generated DTD vectors and exit.
  -s {SAMLRequest,SAMLResponse}, --samlparam {SAMLRequest,SAMLResponse}
                        The HTTP parametername to used.  Uses SAMLRequest if 
                        not defined.
  --store_test STORE_TEST
                        Store serialized response objects in a given filename
                        (as python shelve). May be useful for later analysis.

Todos

  • Implement some kind of session macro to allow for testing SAML endpoints which require a valid session before parsing XML (e.g., AssertionConsumerService that checks if the RelayState parameter is bound to a session cookie first).
  • Integrate more closely with a listener service. As an example when using Burp Collaborator, poll for incoming requests and automate evaluation. Alternatively, an active scanner could be integrated into the EsPReSSO extension

References


Footnote 1: If you are using Burp Collaborator as your listener, simply copy the required number of Collaborator URLs into your url_file.txt. At the time of writing, Burp Collaborator supports a number of protocols including http and https.