HTB Academy, Penetration Testing, API, Web Exploitation, API Attacks, Caido, OWASP Top 10 API Attacks, API Security, JWT, Caido Multipoint Injections, Brute Forcing

CWEE Prep: HTB Academy API Attacks Skills Assessment

Walkthrough of the HTB Academy API Attacks Skills Assessment


API Attacks Skills Assessment

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:

Swagger UI for Inlanefreight E-Commerce Marketplace API version v2. Security vulnerabilities in v1 have been addressed. Sections include Authentication, Customers, Products, Roles, Supplier-Companies, and Suppliers.

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: 83.136.249.164:32665

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

Authenticating as a customer using provided creds

Starting out by navigating to the swagger page

image.png

I tried the customer login endpoint first and that one ended up working

Getting a JWT to authenticate with the creds provided

image.png

{
  "jwt": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6Imh0YnBlbnRlc3RlckBoYWNrdGhlYm94LmNvbSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6WyJTdXBwbGllcnNfR2V0IiwiU3VwcGxpZXJzX0dldEFsbCJdLCJleHAiOjE3NjU1ODEwMDcsImlzcyI6Imh0dHA6Ly9hcGkuaW5sYW5lZnJlaWdodC5odGIiLCJhdWQiOiJodHRwOi8vYXBpLmlubGFuZWZyZWlnaHQuaHRiIn0._eUvZy_hA1HkDi_z1lKn23CWRdUIN6OJc0EfyZMNiZ2vRM15DO_pnzwql-iLiYWxX5A0untlorwkS32R0eBzGA"
}

I also tried submitting the creds to login as a supplier, but that gave the error “Invalid Credentials”

Putting that JWT into the authorize button I am now logged in using the creds given

image.png

Checking my roles

image.png

I have access to two API’s

{
  "roles": [
    "Suppliers_Get",
    "Suppliers_GetAll"
  ]
}

Testing Capabilities as this account

Testing /api/v2/suppliers

image.png

To start, it seems that the roles for an account authenticating as a customer are a bit permissive. It doesn't make sense for customers to be able to list all of the suppliers. This endpoint also leaks some sensitive information about the suppliers. We can see the name and email address of all the suppliers so a customer could reach out to them directly instead of using the e-commerce platform.

Being able to see that there is no security question set is also strange, as is providing customers with the file URI path to the professional CVPD file

Taking one of the suppliers so that have some supplier ID’s to query the other end point with

"suppliers": [
    {
      "id": "00ac3d74-6c7d-4ef0-bf15-00851bf353ba",
      "companyID": "f9e58492-b594-4d82-a4de-16e4f230fce1",
      "name": "James Allen",
      "email": "J.Allen1607@globalsolutions.com",
      "securityQuestion": "SupplierDidNotProvideYet",
      "professionalCVPDFFileURI": "SupplierDidNotUploadYet"
    },

Moving onto /api/v2/suppliers/{ID}

Throwing the supplier ID from the paste above doesn’t show anything else super interesting

image.png

Looking at the question it tells us our target is /flag.txt

That makes me think that the professionalCVPDFFileURI field above is gonna be interesting.

Enumerating other API endpoints and theorizing an attack chain

Looking at the Suppliers API endpoints

image.png

There is a PATCH for updating the currently authenticated users info

image.png

In this patch I can set the professionalCVPDFFileURI

The problem here being that this is the only place I am seeing where I am able to manipulate this field, and I am not authenticated as a supplier. So once I authenticate as a supplier I can set this field to probably /flag.txt and then I can output the supplier info for the account I manipulate and I should be given the CV as a base64 encoded string and that should be the flag.

Looking at the sample supplier I pasted into this doc earlier has a big hint

"suppliers": [
    {
      "id": "00ac3d74-6c7d-4ef0-bf15-00851bf353ba",
      "companyID": "f9e58492-b594-4d82-a4de-16e4f230fce1",
      "name": "James Allen",
      "email": "J.Allen1607@globalsolutions.com",
      "securityQuestion": "SupplierDidNotProvideYet",
      "professionalCVPDFFileURI": "SupplierDidNotUploadYet"
    },

The security question is not set.

Looking at /api/v2/authentication/suppliers/passwords/resets/security-question-answers

image.png

It looks like I can just set a new password for a supplier?

image.png

Looks like that failed.

Brute Forcing Security Question Answers with Caido Multipoint Injections

There isn’t another supplier password reset function.

Possible avenues are brute forcing the answer to the question which would be kinda weird because I don’t know the question.

If there isn’t rate limiting implemented on the API endpoint I can also try and bruteforce the password for that email.

Having that first line of thought that I don’t know the question prompted me to go back and look through the responses for other supplier accounts.

Downloading the response to my request to get all the suppliers and then opening it up in vscode, sure enough there are some supplier accoutns where the question is set, and it is something that shouldn’t be too hard to bruteforce..

image.png

Taking this one to try first

{
      "id": "eac0c347-12e0-4435-b902-c7e22e3c9dd5",
      "companyID": "f9e58492-b594-4d82-a4de-16e4f230fce1",
      "name": "Patrick Howard",
      "email": "P.Howard1536@globalsolutions.com",
      "securityQuestion": "What is your favorite color?",
      "professionalCVPDFFileURI": "SupplierDidNotUploadYet"
    }

Going back to supplier account password reset API

image.png

Before clicking execute I opened up Caido and then made sure the proxy was set to intercept because I am going to brute force the security question answer using Caido Automate

Below you can see the request I captured after clicking execute

image.png

Right click —> send to automate

The field being populated with supplier did not provide yet seems to just be the default value.

I Highlighted the field for the security question answer and then clicked the + to set this as my injection point

image.png

I didn’t have a list of colors handy to upload as a payload file

Googling, seclists did have a list of colors.. under Misc/Security-Question-Answers page

https://github.com/danielmiessler/SecLists/blob/3e2b1b1cfd23ac5680899e9fff8d496c0a8e59f7/Miscellaneous/Security-Question-Answers/html-colors.txt#L4

I copy pasted that into the simple list payload field in Caido

image.png

I left the settings for the attack the same except for setting the # of workers to 50 to speed things up

image.png

Then I clicked run attack

Filtering for responses containing the word true in the HTTQL field I find nothing. So either I have a bad list OR i need to try another user.

image.png

resp.raw.ncont:"false"

Filtering the list of suppliers for the word color there are only 5 accounts that have the security question set to favorite color

image.png

Trying out all the emaisl with my current word list didn’t work

I am quite confident that this is the path forward though.. so trying another word list.

Trying out this one

https://gist.github.com/mordka/c65affdefccb7264efff77b836b5e717

Manually updating the emails for the 5 accounts was a bit tedious, and I wanted to try out injecting into more than one field at once with caido.

Looking into this

https://docs.caido.io/guides/automate_multiple

It looks like for what I want to do the matrix attack strategy is the most reasonable

image.png

So I changed my attack strategy to matrix in the drop down box by run

Then I highlighted the email field and put in all 5 of the emails identified

image.png

Then I highlighted the security question answer and put in the new color list I found

image.png

Clicked ran

When I changed the attack strategy it added the URL encoding preprocessor, and that made me get an error “user is not a supplier” because it was subbing out the @ in the emails

image.png

Removing that and running it again

image.png

Filtering for a response with true I get a success finally

image.png

{
  "SupplierEmail": "B.Rogers1535@globalsolutions.com",
  "SecurityQuestionAnswer": "rust",
  "NewPassword": "Password1234"
}

Abusing a Local File Inclusion Vulnerability for the Flag

I logged out of my current authentication session, now I want to authenticate as a supplier

Authenticating using the B.rogers account

image.png

I successfully get a JWT

image.png

Finally circling back to what I think is the attack chain I theorized earlier.

I go to the PATCH endpoint /api/v2/suppliers/current-user

I am authorized as a supplier so I should be able to set the ProfessionalCVPDFFileURI field to what I am assuming is one flag.txt tile file on the targets system

image.png

I get a response of true!

Now I can use the /api/v2/suppliers/current-user/cv endpoint to get my ‘CV’ as a b64 encoded string

image.png

Taking that b64 encoded string to HTB and I get the flag

image.png