Donnerstag, 2. April 2015

Introduction to WS-Attacker: XML Signature Wrapping (XSW) on Web services

This post introduces WS-Attacker. We start with how to build it from source. After that we setup an example Axis2 Web service and finally we perform an XSW Attack on it.

Building WS-Attacker from Source

WS-Attacker has recently moved its sources from Sourceforge to Github. Thus, we download its source code using the following command:
% git clone
Cloning into 'WS-Attacker'...
remote: Counting objects: 2984, done.
remote: Total 2984 (delta 0), reused 0 (delta 0), pack-reused 2984
Receiving objects: 100% (2984/2984), 90.40 MiB | 2.91 MiB/s, done.
Resolving deltas: 100% (1386/1386), done.
Checking connectivity... done.
% cd WS-Attacker

This clones the whole WS-Attacker repository from Github to our local storage. Next, we need maven and at least openjdk7 to build the tool (note that we use -DskipTests to increase the build speed):
% mvn clean package  -DskipTests
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] WS-Attacker
[INFO] WS-Attacker-Libraries
[INFO] SoapHttpClient
[INFO] WS-Attacker-Framework
[INFO] WS-Attacker-Plugins
[INFO] WS-Attacker-Plugin_SoapAction_Spoofing
[INFO] WS-Attacker-Plugin_WS_Addressing_Spoofing
[INFO] WS-Attacker-Plugin_Options_Tester
[INFO] WS-Attacker-Library_XML_Utilities
[INFO] WS-Attacker-Library_Schema_Analyzer
[INFO] WS-Attacker-Library_Signature_Wrapping
[INFO] WS-Attacker-Plugin_Signature_Wrapping
[INFO] WS-Attacker-Plugin_Denial_of_Service
[INFO] WS-Attacker-Library_Signature_Faking
[INFO] ------------------------------------------------------------------------
[INFO] Building WS-Attacker 1.4-SNAPSHOT
[INFO] ------------------------------------------------------------------------

Depending on your PC's power and your Internet connection's speed, this may take a while. You can find the runnable JAR and all the attack plugins in the directory “runnable” afterwards.

Creating a sample Web Service that uses XML Signatures

% wget
--2015-04-02 13:40:54--
Resolving (,, 2001:610:1:80bc:192:87:106:229
Connecting to (||:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20389041 (19M) [application/zip]
Saving to: ''                        100%[==========================================================================================>]  19.44M  5.40MB/s   in 4.3s

2015-04-02 13:40:59 (4.51 MB/s) - '' saved [20389041/20389041]
% unzip

Next, we need to install rampart, the security module for axis2 which enable XML Signature processing:
% wget                                                      :(
--2015-04-02 13:43:53--
Resolving (,, 2001:610:1:80bc:192:87:106:229
Connecting to (||:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6905111 (6.6M) [application/zip]
Saving to: ''                 100%[==========================================================================================>]   6.58M  2.25MB/s   in 2.9s

2015-04-02 13:43:56 (2.25 MB/s) - '' saved [6905111/6905111]

% unzip

We then need to “install” rampart in the axis2 directory as follows:
% cp rampart-1.6.0/lib/* axis2-1.6.0/lib
% cp rampart-1.6.0/modules/* axis2-1.6.0/repository/modules

We will now start a rampart sample that uses XML Signatures:
% cd  rampart-1.6.0/samples/policy/
% AXIS2_HOME="/tmp/axis2-1.6.0" ant service.02   

To start the service, we use ant and configure the Axis2 Home directory.

Obtaining the signed Message

To use WS-Attacker, we need to obtain a signed message. There are many approaches to achieve this. In this scenario, we start “Wireshark” and run the client sample script (from a second terminal):
% AXIS2_HOME="/tmp/axis2-1.6.0" ant client.02

<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv=""><soapenv:Header xmlns:wsa=""><wsse:Security xmlns:wsse="" soapenv:mustUnderstand="1"><wsu:Timestamp xmlns:wsu="" wsu:Id="Timestamp-1"><wsu:Created>2015-04-02T12:36:45.699Z</wsu:Created><wsu:Expires>2015-04-02T12:41:45.699Z</wsu:Expires></wsu:Timestamp><wsse:BinarySecurityToken xmlns:wsu="" EncodingType="" ValueType="" wsu:Id="CertId-FFCBEBA22B6965E99814279782058481">MIICTzCCAbigAwIBAgIESy9O5zANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJMSzEQMA4GA1UECBMHV2VzdGVybjEQMA4GA1UEBxMHQ29sb21ibzEPMA0GA1UEChMGQXBhY2hlMRAwDgYDVQQLEwdSYW1wYXJ0MRYwFAYDVQQDEw1TYW1wbGUgQ2xpZW50MB4XDTA5MTIyMTEwMzMxMVoXDTM3MDUwNzEwMzMxMVowbDELMAkGA1UEBhMCTEsxEDAOBgNVBAgTB1dlc3Rlcm4xEDAOBgNVBAcTB0NvbG9tYm8xDzANBgNVBAoTBkFwYWNoZTEQMA4GA1UECxMHUmFtcGFydDEWMBQGA1UEAxMNU2FtcGxlIENsaWVudDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAjBQM+kgC0Wm9hk9v4pjLSg5yK0Em2ulyDmODckWv4mZJ8YwJPVgqEIzwRiOnNBH3s+wFCw297zDsnEgDKSQrsPf1smVUOK/slyDPbqZ47Ewcs07nCPfNigncmpbcaluO3bMw9Oqj9VIYjrUHu5xCp2Fe39ZPbwOzLtAmT8b6iucCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAnjPanrVjFVkxnhsj83RJA2tK//v99KpPf3do9VUI2yEgvBZUzH3q2jk3widwEcsJMHgbRr3VTFL7dNVdCYBcI1KiBY9SMa1XZ4RIHmw7gkJt1JTgjKBzfrout2z614KixRf4w7qkDacGxkNspXG/PSlh03Lfm5sb0vzH1aqBl3g==</wsse:BinarySecurityToken><ds:Signature xmlns:ds="" Id="Signature-2">
<ds:CanonicalizationMethod Algorithm="" />
<ds:SignatureMethod Algorithm="" />
<ds:Reference URI="#Id-1699113578">
<ds:Transform Algorithm="" />
<ds:DigestMethod Algorithm="" />
<ds:Reference URI="#Timestamp-1">
<ds:Transform Algorithm="" />
<ds:DigestMethod Algorithm="" />
<ds:KeyInfo Id="KeyId-FFCBEBA22B6965E99814279782058532">
<wsse:SecurityTokenReference xmlns:wsu="" wsu:Id="STRId-FFCBEBA22B6965E99814279782058543"><wsse:Reference URI="#CertId-FFCBEBA22B6965E99814279782058481" ValueType="" /></wsse:SecurityTokenReference>
</ds:Signature></wsse:Security><wsa:To>http://localhost:8080/axis2/services/sample02</wsa:To><wsa:MessageID>urn:uuid:4732fd77-3d09-4639-ba44-41618c2c4a4a</wsa:MessageID><wsa:Action>urn:echo</wsa:Action></soapenv:Header><soapenv:Body xmlns:wsu="" wsu:Id="Id-1699113578"><ns1:echo xmlns:ns1=""><ns1:param0>Hello world</ns1:param0></ns1:echo></soapenv:Body></soapenv:Envelope>

Using WS-Attacker

We use again the second terminal to start WS-Attacker:
% cd /tmp/WS-Attacker/runnable  
% java -jar WS-Attacker-1.4-SNAPSHOT.jar

We use the WSDL URL http://localhost:8080/axis2/services/sample02?wsdl and feed it into WS-Attacker:

We switch to the “Test Request” Tab and replace the XML Request with the one that we obtained in the previous section:

After sending the test request, a SOAP error message is received. Do not bother with it. We will use XSW to renew the timestamp. To go for it, move to the plugin configuration tab.

All we have to do in the plugin configuration tab, is to select and activate the Signature Wrapping Attack from the tree on the left. We can then configure the payload. Payload is the XML content that is going to be executed instead of the originally signed content. In this case, the XML message has to signed elements: The Body Element and the Timestamp element. For the first one, we just change the “Hello World” message to “Hello WS-ATTACKER”. For the Timestamp, WS-Attacker automatically detected that this is a timestamp element. It will update it automatically (see lower highlighting in the screenshot).
A common issue with the XSW Plugin is, that it will not go into the “Ready” state. This happens, when you have not configured any payload.
Next, we move to the “Attack Overview” tab and start the attack.

As we can see, Axis2 could be successfully attacked. We can also see the attack vector that was used.
More details can be obtained by right-clicking on the Signature Wrapping Plugin in the upper table and selecting “Analyze XSW responses”.