5 minutes
HuntressCTF: Malibu
Another challenge in the 2024 HuntressCTF: Mailbu. This was a very cool challenge involving HTTP enumeration and a local s3-compatible MinIO server.
Challenge Description
What do you bring to the beach?
NOTE: There are two things to note for this challenge.
This service takes a bit more time to start. If you see a Connection refused, please wait a bit more. This service will not immediately respond or prompt you… it is waiting for your input. If you just hit Enter, you will see what it is.
Extra tip, once you know what the service is, try connecting in a better way. Then use some of the context clues and critical thinking based off its response and the challenge description. You don’t need any bruteforcing once you understand the infrastructure and enumerate. 😉
Solve
After clicking on the ‘Start’ button, we get the following output in the challenge description:
Connect with:
nc challenge.ctf.games 32685
Please allow up to 30 seconds for the challenge to become available.
Being the impatient person I am, naturally I spam the port until it becomes available. Eventually we get back the following output when hitting Enter after connecting with netcat:
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ nc challenge.ctf.games 32685
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close
400 Bad Request
Okay, it’s running an HTTP server. Let’s try connecting with our browser.
Nope!
At this point I thought I could try a simple directory brute force attack with ffuf
. It was only after doing this that I learned Huntress didn’t want any brute-forcing tools in use for these challenges… sorry!
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -u http://challenge.ctf.games:32685/FUZZ -e .txt -fc 403
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://challenge.ctf.games:32685/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
:: Extensions : .txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
:: Filter : Response status: 403
________________________________________________
:: Progress: [1019/175328] :: Job [1/1] :: 90 req/sec :: Duration: [0:00:04] :: Errors: 0 ::
I didn’t get any hits anyway.
Next, I tried to inspect the HTTP headers by issuing a curl
command to the server instead of connecting via netcat.
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ curl -I challenge.ctf.games:32685
HTTP/1.1 400 Bad Request
Accept-Ranges: bytes
Content-Length: 225
Content-Type: application/xml
Server: MinIO
Vary: Origin
Date: Sat, 05 Oct 2024 13:14:57 GMT
Oh interesting, we get the Server
header in the curl
output which tells us it’s running MinIO. From previous experience I’ve used MinIO a tiny amount, so I know that a CLI tool mc
exists that can easily interact with MinIO servers. After installing mc
in my Kali VM, I set up the standard alias of myminio
to point to this challenge server.
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ mc alias set myminio http://challenge.ctf.games:32685/
Enter Access Key:
Enter Secret Key:
Added `myminio` successfully.
Seeing as nothing in the challenge has indicated the presence of an access key or secret key, I just enter a blank value for both fields. Now I start trying out different mc
subcommands to see if there’s anything I can access without these keys.
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ mc tree myminio
mc: <ERROR> Unable to tree. Access Denied.
This “Access Denied.” was the story of my life for the next 15 minutes. Then I saw on discord that my teammate MFDoom had found a successful response when trying out some different directories on the HTTP endpoint.
He finds the successful response with /bucket
! This tells me that the name of the bucket hosted on the MinIO server is simply bucket
. This confused me since I thought that surely “bucket” would be included in the wordlist I was using with ffuf
, right?
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ cat /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt | grep bucket
buckets
bitbucket
Next time I’m using directory-list-2.3-medium.txt
, it’s official.
Moving on, we’re able to list out the entire contents of the bucket with the tree
subcommand of mc
.
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ mc tree myminio/bucket --files
myminio/bucket
├─ 38LDk6qIUzWwQjAO
├─ 3op3bh3wt0UoiUdT
├─ 5mhZtNDDBSVzhlrb
├─ 7IDagfca3QZYSRgd
├─ 7Rj3oaTOuKvA3EW0
├─ 8YlMFCa9BWCZXmKR
├─ 97MuW0tx8IewGWxg
├─ BG9VLyRlN9GJS9ux
├─ DNsykdKT5uAGHsYD
├─ EqfLxsvyfuEg8jaY
├─ HachcFhr0NdSUnMM
├─ IGXOd77WYkvcJRWv
├─ J5IXPg332sMlFfGk
├─ J8P9Bpk0oGHEzrq2
├─ JSgXGUKoPHHEZoCE
├─ OZovt7G1MGliy4B0
├─ RJdCUqYCpdYJvPA2
├─ SEWF4wxTu4VlqD48
├─ SZwY6DC1fOGKBvvP
├─ TUJpQPoAnqe4YqE7
├─ UjIimwaqLqfUL7ET
├─ Zf0q0bMh1IofPo3Z
├─ aBARJ5ea7d6XBcWM
├─ ctAcXVpViTssbs8a
├─ i7dez8Y7Ik6F6pIx
├─ oeVZnUpnS7EMRJMO
├─ oqI8p0vTGbKgjqa3
├─ qMyvVfSdZ1NtoouN
├─ wGWQuJ6gEuqzGQaG
├─ xU4mWsu5fVUHa58T
├─ 235208pO
│ └─ OJgfc538
│ └─ SZNspAry
│ └─ pCgdi4Ud
│ └─ SXIkXaOmYIEYz5FD
├─ 23Ote8p4
│ └─ oZ2fXA6r5Gw8GZQG
├─ 38E7HhAV
│ └─ vGnh7ISrU0O5HRP6
├─ 3gqwCoPQ
│ └─ OedgNe7JP3edyfpc
<SNIP>
├─ wW9vscj9
│ ├─ B3gw6kMmEhkPqTfv
│ └─ dYatcKnF
│ └─ 5OwM3MN6
│ └─ dmjeFywmb0xJiQW3
├─ wY0zTfdV
│ └─ PU0r9Jvy
│ └─ afeHifxK
│ └─ Qb6rhgQy
│ └─ JrzNEiJv74JPHxQ1
└─ zc4r8PGw
└─ tp7SKwWZ
├─ 3OqYaNBDqw8z3Rcx
└─ BHLJENiD
└─ 5XkWxXjo
└─ tYK5g9HqkhWa7Yoo
I won’t list out the entire contents, but rest assured there was a ton of folders and a ton of files. Digging into the subcommands available with mc
, I found mirror
which is exactly the kind of command I was looking for. I wanted to be able to download all the files to my local machine and search for a flag. If that didn’t work, I was thinking I would have to combine all the files and do some sort of decoding, as the contents of a single file I inspected looked a lot like base64:
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ mc get myminio/bucket/DNsykdKT5uAGHsYD ./file && cat file && rm file
...:32685/bucket/DNsykdKT5uAGHsYD: 1.87 KiB / 1.87 KiB ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 6.36 KiB/s 0sIXKeegORG7feOfODgQWo8IXWuHh3HTFFNwedqKwPBtmVKYQkjfuR5szR1NpJkY6J0bfTirpZa<SNIP>61gQWlU9URnMSV2bBZXVOHFnyOfdG5U2KtnpjranLWWLwAoUeKhFGaSTXEakCIEqKiddJsC1OTHb79V5AqffatyupWFzlTij6HwbnNAoO5xCCpiOFas7VRQFw8oLfZIHhjMtxVZItQWXt3C0wdiXUzdm72lqodW7T8I3tFbB2
So I ran the mirror
command to download all the files.
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ mkdir bucket && mc mirror myminio/bucket ./bucket
...8PGw/tp7SKwWZ/3OqYaNBDqw8z3Rcx: 266.22 KiB / 266.22 KiB ┃▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓┃ 53.11 KiB/s 5s
Then I immediately ran grep
to search for a flag. Looks like Huntress was being nice to us after figuring out all the MinIO interactions.
┌──(venv)─(kali㉿kali)-[~/huntress]
└─$ grep -ri 'flag' ./bucket
./bucket/gIiPsOj6/0BAm5Rs6/RHhBn2am/nyyrGhWi/ljclVzlDd6alCxyi:2BYN7jdLWEy3S5z <SNIP> nS4FTLflag{800e6603e86fe0a68875d3335e0daf81}FNdU1n6FoDAYTO <SNIP>