HTB Business CTF 2025 - Vault writeup
Vault was a challenge at the HTB Business CTF 2025 (or Global Cyber Skills Benchmark CTF 2025) from the ‘Cloud’ category.
We got a public URL for this challenge: http://volnaya-vault-static-website.s3-website.eu-north-1.amazonaws.com/
As expected, there was a web app running on that URL. The app was displaying some files and allowing users to download them.
The web app loads a list of files from http://volnaya-vault-lb-69672775.eu-north-1.elb.amazonaws.com/api/files. When downloading files, the app will make calls to http://volnaya-vault-lb-69672775.eu-north-1.elb.amazonaws.com/api/download.
I would assume the files are stored inside an s3 bucket. However, the API URL doesn’t look like an usual s3 bucket. This might be because it is load-balanced? (elb = elastic load balancer). I don’t know, I haven’t really worked with this before.
But if I take a look at the download request, I can see that the URL starts with https://volnaya-vault.s3.eu-north-1.amazonaws.com/vault/public/
So ‘volnaya-vault’ is the bucket’s name.
Now that we have a bucket name, let’s try using aws s3 cli to see what files are there.
There are two files in the ‘private’ folder that are not visible in the web app (or the API called by the app).
Obviously, the first thing I attempted was downloading files from that s3 bucket.
But that failed. Now we either have to find some form of AWS credentials (I used some random valid creds I had for this) or some other way of accessing those files from the ‘private’ folder.
When looking at the download URL again, I noticed that the URL contains some credentials (the security token was the most visible for me).
This is called a pre-signed URL and it is used to allow public users to download documents stored in S3.
The web application is probably using a token to generate signed URLs that allow unauthenticated users to download the files.
I wanted to check if I can trick the API into giving me files from the private folder instead of the files from the public folder that I can see.
The most obvious option here would be a path traversal attack. Instead of a filename from the public folder, I used ‘../private/
It looks like path traversal works. I am now able to download both those documents from S3.
After downloading both of those files, there’s nothing interesting in the PDF but it looks like the .docx file contains the flag for this challenge.