Using Burp Suite to Test Web Services with WS-Security

By Chris Bellows ·

During a recent engagement we ran into a web service endpoint that was using WS-Security for authentication, specifically it was using the “Username Token” profile. At first look it did not appear to be an issue for testing as it looks like we only needed to include the proper credentials in the SOAP document header, unfortunately it was a bit more complicated. 

In order to make a successful request to the web service, we need to provide the following items:

  • Username
  • Password
  • Nonce
  • Created

The actual header that is sent with the SOAP request looks like the following:

 <soap:Header>

<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd”>

<wsse:UsernameToken wsu:Id="UsernameToken-4" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd”>

<wsse:Username>userABCD</wsse:Username>

<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">c00lp@ssw0rd</wsse:Password>

<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">MjAxMy0xMi0wOFQxNzo1ODoyOS45MTFaNDYw</wsse:Nonce>

<wsu:Created>2013-12-08T17:58:29.911Z</wsu:Created>

</wsse:UsernameToken>

</wsse:Security>

</soap:Header>

The user name and password are easy to include in every request, the nonce and created values turn out to be problematic.  In order for the server to process a request, the following must be true - the nonce must be unique for every request and the created time stamp must be within a minute or so based on the server’s time. This makes it impossible to just insert a static entity into the SOAP request.

To solve this issue and get the test moving along, it became obvious that this was something that could be handled with a BurpSuite plugin. The Burp plugin would have to determine if a request was going to our target host. If so, it would inject the authentication header with a unique nonce value and a current timestamp.

With that in mind, the following plugin was created.

Once the module has been loaded using the “Extender” tab, a new tab will be added to the current burp session.

On the plugin tab, there are fields to configure the username, password, target host, target port and toggle switches to enable or disable the plugin and verbose logging.

The target host and target port controls, which request the plugin, will attempt to inject the authentication header into. The verbose output switch will log attempted injects into the extender log window.

Here is an example request without the plugin enabled. The server side of this request is just reflecting what was received by the server.

Configure the plugin with the proper settings.

Now when the request is made, the soap header is replaced with the proper authentication information.

The following shows verbose logging output on the extension output window. This helps confirm that the plugin is working, since you normally would not see the actual request that goes out being modified.

Once the plugin is loaded and enabled, all requests that are sent through Burp or are created in Burp (intruder/scanner/etc) will be injected as long as they match the provided host/port. This makes it possible for tools that may not be able to do this authentication to test services that are protected by it.

Chris Bellows

Senior Security Consultant

Chris Bellows is a security consultant with Optiv's application security team. His focus is on attack and penetration testing.