Using SQLMap for SQL injection in SOAP Service

I spent way too much time behind the terminal lately. Since setting up my test lab with Kali, Metasploitable2, Mutillidae (2.6.40) it’s all terminal and no gardening. As posted before, Mutillidae is “a a free, open source, deliberately vulnerable web-application providing a target for web-security enthusiest.” You can find the whole feature list at the Mutillidae site. Today I’m going to show you how to use SQLMAP to exploit a vulnerability in one of Mutillidae’s web services, namely “Lookup User”.

Mutillidae

SOAP/WDSL

First thing you need to do is to download a tool that will enable you to play around with the SOAP message. You can use SoapUI for this purpose. It will enable you to load the WDSL which gives you more information about the services delivered by the mutillidae web-service.

Wiki:

The WDSL is an XML-based interface definition language that is used for describing the functionality offered by a web service

The Mutillidae webservice supports several services as you can see from the WDSL below. You can find the following four webvices: GetUser, CreateUser, UpdateUser and DeleteUser.

We’ll use the CreateUser operation in the example.

<?xml version="1.0" encoding="ISO-8859-1"?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="urn:ws-user-account" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="urn:ws-user-account">
<types>
<xsd:schema targetNamespace="urn:ws-user-account"
>
 <xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
 <xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
</xsd:schema>
</types>
<message name="getUserRequest">
  <part name="username" type="xsd:string" /></message>
<message name="getUserResponse">
  <part name="return" type="xsd:xml" /></message>
<message name="createUserRequest">
  <part name="username" type="xsd:string" />
  <part name="password" type="xsd:string" />
  <part name="signature" type="xsd:string" /></message>
<message name="createUserResponse">
  <part name="return" type="xsd:xml" /></message>
<message name="updateUserRequest">
  <part name="username" type="xsd:string" />
  <part name="password" type="xsd:string" />
  <part name="signature" type="xsd:string" /></message>
<message name="updateUserResponse">
  <part name="return" type="xsd:xml" /></message>
<message name="deleteUserRequest">
  <part name="username" type="xsd:string" />
  <part name="password" type="xsd:string" /></message>
<message name="deleteUserResponse">
  <part name="return" type="xsd:xml" /></message>
<portType name="ws-user-accountPortType">
  <operation name="getUser">
    <documentation>Fetches user information is user exists else returns error message
        <br/>
        <br/>Sample Request (Copy and paste into Burp Repeater)
        <br/>
        <br/>POST /mutillidae/webservices/soap/ws-user-account.php HTTP/1.1
        <br/>Accept-Encoding: gzip,deflate
        <br/>Content-Type: text/xml;charset=UTF-8
        <br/>Content-Length: 458
        <br/>Host: localhost
        <br/>Connection: Keep-Alive
        <br/>User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
        <br/>
        <br/><soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:ws-user-account">
        <br/>   <soapenv:Header/>
        <br/>   <soapenv:Body>
        <br/>      <urn:getUser soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <br/>         <username xsi:type="xsd:string">Jeremy</username>
        <br/>      </urn:getUser>
        <br/>   </soapenv:Body>
        <br/></soapenv:Envelope></documentation>
    <input message="tns:getUserRequest"/>
    <output message="tns:getUserResponse"/>
  </operation>
  <operation name="createUser">
    <documentation>Creates new user account
            <br/>
            <br/>Sample Request (Copy and paste into Burp Repeater)
            <br/>
            <br />POST /mutillidae/webservices/soap/ws-user-account.php HTTP/1.1
            <br />Accept-Encoding: gzip,deflate
            <br />Content-Type: text/xml;charset=UTF-8
            <br />Content-Length: 587
            <br />Host: localhost
            <br />Connection: Keep-Alive
            <br />User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
            <br />
            <br /><soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:ws-user-account">
            <br />   <soapenv:Header/>
            <br />   <soapenv:Body>
            <br />      <urn:createUser soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <br />         <username xsi:type="xsd:string">Joe2</username>
            <br />         <password xsi:type="xsd:string">Holly</password>
            <br />         <signature xsi:type="xsd:string">Try Harder</signature>
            <br />      </urn:createUser>
            <br />   </soapenv:Body>
            <br /></soapenv:Envelope></documentation>
    <input message="tns:createUserRequest"/>
    <output message="tns:createUserResponse"/>
  </operation>
  <operation name="updateUser">
    <documentation>If account exists, updates existing user account else creates new user account
            <br/>
            <br/>Sample Request (Copy and paste into Burp Repeater)
            <br/>
            <br />POST /mutillidae/webservices/soap/ws-user-account.php HTTP/1.1
            <br />Accept-Encoding: gzip,deflate
            <br />Content-Type: text/xml;charset=UTF-8
            <br />Content-Length: 587
            <br />Host: localhost
            <br />Connection: Keep-Alive
            <br />User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
            <br />
            <br /><soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:ws-user-account">
            <br />   <soapenv:Header/>
            <br />   <soapenv:Body>
            <br />      <urn:updateUser soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <br />         <username xsi:type="xsd:string">Joe2</username>
            <br />         <password xsi:type="xsd:string">Holly</password>
            <br />         <signature xsi:type="xsd:string">Try Harder</signature>
            <br />      </urn:updateUser>
            <br />   </soapenv:Body>
            <br /></soapenv:Envelope></documentation>
    <input message="tns:updateUserRequest"/>
    <output message="tns:updateUserResponse"/>
  </operation>
  <operation name="deleteUser">
    <documentation>If account exists, deletes user account
            <br/>
            <br/>Sample Request (Copy and paste into Burp Repeater)
            <br/>
            <br/>POST /mutillidae/webservices/soap/ws-user-account.php HTTP/1.1
            <br/>Accept-Encoding: gzip,deflate
            <br/>Content-Type: text/xml;charset=UTF-8
            <br/>Content-Length: 587
            <br/>Host: localhost
            <br/>Connection: Keep-Alive
            <br/>User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
            <br/>
            <br/><soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:ws-user-account">
            <br/>   <soapenv:Header/>
            <br/>   <soapenv:Body>
            <br/>      <urn:deleteUser soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <br/>         <username xsi:type="xsd:string">Joe</username>
            <br/>         <password xsi:type="xsd:string">Holly</password>
            <br/>      </urn:deleteUser>
            <br/>   </soapenv:Body>
            <br/></soapenv:Envelope>
            </documentation>
    <input message="tns:deleteUserRequest"/>
    <output message="tns:deleteUserResponse"/>
  </operation>
</portType>
<binding name="ws-user-accountBinding" type="tns:ws-user-accountPortType">
  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
  <operation name="getUser">
    <soap:operation soapAction="urn:ws-user-account#getUser" style="rpc"/>
    <input><soap:body use="encoded" namespace="urn:ws-user-account" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
    <output><soap:body use="encoded" namespace="urn:ws-user-account" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
  </operation>
  <operation name="createUser">
    <soap:operation soapAction="urn:ws-user-account#createUser" style="rpc"/>
    <input><soap:body use="encoded" namespace="urn:ws-user-account" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
    <output><soap:body use="encoded" namespace="urn:ws-user-account" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
  </operation>
  <operation name="updateUser">
    <soap:operation soapAction="urn:ws-user-account#updateUser" style="rpc"/>
    <input><soap:body use="encoded" namespace="urn:ws-user-account" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
    <output><soap:body use="encoded" namespace="urn:ws-user-account" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
  </operation>
  <operation name="deleteUser">
    <soap:operation soapAction="urn:ws-user-account#deleteUser" style="rpc"/>
    <input><soap:body use="encoded" namespace="urn:ws-user-account" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></input>
    <output><soap:body use="encoded" namespace="urn:ws-user-account" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/></output>
  </operation>
</binding>
<service name="ws-user-account">
  <port name="ws-user-accountPort" binding="tns:ws-user-accountBinding">
    <soap:address location="http://xxx.xx.1.1x/mutillidae/webservices/soap/ws-user-account.php"/>
  </port>
</service>
</definitions>

Download the WDSL by saving the webpage as XML. The saved XML is to be loaded into SoapUI or your tool of preference.

As you can see in the image below, the WDSL is loaded and showing all possible operations/services provided by the Mutillidae web-service. You can also see the SOAP message for creating a user. Just hit the play button to see what happens. In the left window you’ll see the response of the web-service. In my case user ? already exist. Just because I hit the play button already too often.

Hybrid Cloud Security

BurpSuite

What we now want is to capture the SOAP request going to the web-service with burpsuite. We can use the captured data together with SQLMAP to check if SQL Injection is possible in one of the parameters used in the request. (username, password or signature).

In SoapUI go to File -> Preferences -> Proxy Settings and change the proxy to the same proxy as set in Burpsuite. Proxy -> last tab “Options”is where you set the proxy in Burpsuite. Please make sure the “Intercept Client Request” & “Intercept Server Responses” is set correctly (I have unchecked everything @ both client/server, added “url is in target scope” and upped it to be the first item. In Tab “Target” add the ip/url you use for Mutillidae as in scope)

Check if the listener is up & running by using netstat -l | grep “portnumber you use for proxy”. Once you confirmed the listener is up and running you can go back to SoapUI and hit the play button again to send the SOAP message to the web-service. This time burpsuite intercepts the request. What you see in Burpsuite is the SOAP message with the header for the post request added to it.

Hybrid Cloud Security

SQLMAP

Save the whole request to a file (right click “copy to file”). The file will be input for the Sqlmap -r parameter.

Start a terminal window and use the following command to start of sqlmap ->

sqlmap -r /pathtoyoursavedfile/savedfile.txt –technique B -p username –current-user

Hybrid Cloud Security

This command uses the saved text file as a request to the web-service to see if parameter (the -p) username is exploitable using an SQL injection. The technique used here is boolean-based blind. The –current-user parameter tells SQLMAP to see if it can bring back the current user which is in our case root@locahost. You can play around with the command line with some help from the SQLMAP parameter page.

SQLMAP is an easy to use tool to check for SQL injection points. Once you know how to assemble the request package or what target to hit, SQLMAP does the rest. It saves a lot of time. The downside to using such a tool is that you don’t have to be very knowledge to use it. The above is more like trick which learned you nothing about what SQL injections are about.

Some recommended sources to go through to get a more deeper understanding of SQL Injections:

  1. Testing for SQL Inject @ OWASP.org
  2. Watch the whole web pen testing workshop given by Jeremy Duin & Conray Reynolds.
  3. Vulnerable by Design -> great source for vulnerable VM images

Leave a Reply

Your email address will not be published. Required fields are marked *

20 − 13 =