Introduction

He hecho esta web donde puedes ver imágenes de perros y/o gatos. Explota una aplicación PHP vía LFI y sal de un contenedor de Docker.
Getting the Flags
Reconocimiento Incial
Comenzamos realizando un escaneo de puertos abiertos.

Ahora vamos a profundizar en dichos puertos.

Vamos a realizar un escaneo de directorios del puerto 80.

Vamos a ver cómo se ve la web.

Ahora vamos a mirar en el directorio flag.php (aunque parece que está vacío ya que ocupa 0B).

Profundización
Vamos a mirar el código fuente de la página.

Parece que hay un id que puede ser cambiado a voluntad. Vamos a entrar en el perro.
Explotación
Vamos a probar LFI sobre el id dog.

Parece que el archivo importante es index.php, que además contiene una función include(). Vamos a intentar listarlo.

Este error puede ocurrir debido al include, porque se vuelve cíclico. Así que vamos a usar filtros php:
http://dogcat.thm/?view=php://filter/convert.base64-encode/resource=dog/../index

Vamos a decodear la string:

Aquí podemos ver dos problemas:
- El primero es el que ya conocemos. Hay una LFI debido a que la función
containsStr()sólo comprueba quedogocatesté contenido, no quue sólo sea eso. - El segundo es que nos permite configurar la extensión del archivo. En caso de que no se configure, este será PHP.
Vamos a usar esto a nuestra ventaja:
php://filter/convert.base64-encode/resource=dog/../../../../../../../../etc/passwd:
php://filter/convert.base64-encode/resource=dog/../../../../../../../../etc/passwd&ext=
Ahora vamos a decodear la string.

Vamos a ver que encontramos.

Hemos encontrado nuestras peticiones. Sabemos que corre Apache2. Ahora debemos intentar escalar la LFI a RCE. Como hemos visto que podemos acceder a los logs, puede que este sea un método para conseguirlo.

Vamos a probar a inyectar PHP en el parámetro User-Agent:

Ahora modificamos el endpoint de la petición para incluir el comando en el parámetro cmd.

Vamos a mandarlo y a observar el log.

Aquí podemos ver que el log ya ha sido contaminado. Para que surta efecto, tenemos que cambiar el User-Agent para que sea normal de nuevo. Así que vamos a la página normal y metemos el comando.

Como podemos observar, en la misma linea de antes, se ve la respuesta del comando. Vamos ahora a intentar conseguir una reverse shell, para ello uso mi página favorita para dicho propósito: revshells.

Como hay espacios y caracteres especiales, vamos a URL encodearla.

Ahora nos ponemos en escucha y probamos a mandarlo.

Vamos a buscar la primera flag.
Escalada de PrivilegiosSeguimos investigando y nos encontramos con que podemos ejecutar un comando sin contraseña como root:

Vamos a mirar en GTFOBins:

Parece que podemos conseguir una shell de root fácilmente, vamos a ello:

Parece que ya somos root.

Vamos a leerlas.

Si investigamos, podemos inferir que estamos en un contenedor de Docker:
Escape del Docker
Vamos a intentar escapar del contenedor. Vamos a ver si podemos ver si hay scripts personalizados de bash:

Vamos a investigar estos archivos:

Aquí podemos ver un archivo que puede que se ejecute periódicamente (por el hecho de ser un script que realiza backups). Como somos root, podemos ejecutarlo. Además, aunque el script está en el contenedor, las rutas que se mencionan en el script no pertenecen al contenedor, por lo que podemos inferir que se está ejecutando desde el host real.
Debido a que tenemos permisos de escritura en el archivo, podemos intentar conseguir una reverse shell desde el host.

Nos ponemos en escucha y...

Ahora buscamos la flag:
Conclusión
Hemos enumerado puertos y encontrado una web. Hemos practicado:
- Enumeración.
- LFI.
- Log poisoning.
- Escalada de privilegios.
- Escape de contenedor Docker.
