Skip to main content
  1. WriteUps/
  2. CTF/

Hack The System Bug BountyCTF - Neovault

·480 words·3 mins
CTF HackTheBox
DarknessE1
Author
DarknessE1
Security Researcher | Web & OSINT
Table of Contents

CHALLENGE NAME
#

NeoVault
#

Description:

Neovault is a trusted banking application that allows users to effortlessly transfer funds to one another and conveniently download their transaction history. We invite you to explore the application for any potential vulnerabilities and uncover the flag hidden within its depths.

📝 Related Bug Bounty Reports

Bug Report #1 - Mongo Object ID Prediction

Bug Report #2 - IDOR


First, I read the two given reports, which really helped set my expectations for the challenge. I began my initial phase by visiting the website, noting its technologies, and navigating every available page. By doing that I saw there was only a login page and a register page. I quickly signed up for an account, logged into the web application, then fired up Burp Suite and started clicking every button I could find. While poking around, I saw a request that exposed some IDs and usernames:

image.png

I was logged in as user102, but the response also revealed another user, neosystem, which I noted. After spending some time without any obvious leads, I looked into the JavaScript files and yes, I found what I expected. There were some juciey endpoints , which I discovered:

image.png

What was interesting was that there was an /api/v1 namespace, while most dashboard features used /api/v2 except for the deposit feature, which didn’t work under v2. I tried hitting several /api/v1 endpoints, but most returned:

API version 1.0 is deprecated .

I kept wondering if the developer had forgotten to remove some old routes. That thought led me back to exploring every request until I reached the transaction history page, where you can download your transaction history as a PDF:

image.png

When I clicked “Download PDF,” Burp showed a POST to /api/v2/transactions/download-transactions:

image.png

I replaced v2 with v1 in the URL and got a new, intriguing error:

image.png

The response complained that _id was not provided at that moment I knew I’d found my way in. I added the header

ContentType: applicationjson

and included an _id parameter in the JSON body:

{ "_id": "replacetheid" }

First, I used my own _id to verify if it downloads my PDF or not, which it did:

image.png

Next, I swapped in neosystem’s _id and I was able to download that user’s PDF too. Inside, it mentioned user_with_flag, hinting that I should target that account next:

image.png
To generate possible IDs, I used the Mongo ObjectID prediction tool from the writeup (after fixing a couple of issues in the Python script). I ran:

╰─ python3 mongo-object.py 685faa8d76d134ba8f5bc5c6 > ../id.txt

Then I fuzzed the _id parameter in the request body using ffuf:

└──╼ $ffuf -X POST -u "http://83.136.255.113:54902/api/v1/transactions/download-transactions" -H "Content-Type: application/json" -H "Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY4NWY5YTIxNDViYTNmYzI0ODFiYWVlMSIsImlhdCI6MTc1MTA5NTg4NywiZXhwIjoxNzUxMDk5NDg3fQ.AFZsJaD3Mmunb0soNw-GTTNnsS8fuYxJRe3x_sCkA7I" -d '{"_id": "FUZZ"}' -w id.txt 

 SNIP................
 
 
685f985145ba3fc2481baea0 [Status: 200, Size: 1936, Words: 142, Lines: 121, Duration: 176ms]

Within minutes, I got a match. I plugged that ID into my request, downloaded the PDF, and finally retrieved the flag.

image.png