Skip to the content.

SAML Testing

Some good general references to testing SAML are listed below, this page is just for my additional notes:

AAD SAML testing

When testing SAML integrated with AAD, a number of tools have a problem with the XML in the SAMLResponse generated by Microsofts login service. To this end I have a few modified hacky bits of code that can help with testing.

Modified Espresso Burp plugin for AAD SAML testing

First, a modified version of the Espresso Burp plugin here. Essentially this adds the ability to identify values to repace when performing signature wrapping attacks via XPath as opposed to searching for the string. Due to something, probably XML namespace weirdness, adding search values as strings in the Espresso signature wrapping code for MS generated SAML breaks the plugin. Using more forgiving XPath you can provide yourself works better. I had difficulty figuring out why the plugin was breaking in this way, and due to time pressures instead of fixing the code properly so the generated XPath worked, I added the option to search via XPath instead via anew button.

You can get some help in working out what XPath to use by first using the string add option (as normal), and then deleting that once you see what it is and readding it as a more forgiving variant. Basically, add the replace value in first as a string, look at the XPath Espresso generates, delete the entry from the table and re-add it in a modified form using the XPath button. If you have done it right, the string you are attempting to replace will appear in the table.

If the Espresso generated XPath looks like this:

//Assertion[1]/AttributeStatement[1]/Attribute[9]/AttributeValue[1]

Create a more flexible variant like so and add it using the new XPath button:

//*[local-name() = 'Assertion'][1]/*[local-name() = 'AttributeStatement'][1]/*[local-name() = 'Attribute'][9]/*[local-name() = 'AttributeValue'][1]

Modified Python Signxml module for AAD SAML testing

My fork of this is here, while this waits on a PR I raised to get this pushed into the mainline release.

I added some functionality to allow namespaces to be specifically configured in signed XML.

Heres how you call XMLSigner in the modified code to sign like the Microsoft logon service.

XMLSigner(method=signxml.methods.enveloped, c14n_algorithm=c14n, namespaces={None:'http://www.w3.org/2000/09/xmldsig#'}).sign(xml_root, key=key, cert=cert, reference_uri=reference)

There is also an example of using this modified version of the library to create a forged SAML signature using a new embedded key here in the “forge_saml_response” function.