De LFI a RCE

· · | Ciberseguridad en De LFI a RCE

En este artículo, procederemos a explicar cómo un servidor que utiliza PHP, bajo un conjunto de condiciones determinadas, decanta en la posibilidad de ejecutar comandos arbitrarios en un servidor, técnica conocida como RCE en informática.

Función include de PHP

Al momento de construir una página web, un desarrollador podría identificar segmentos de código que vayan a repetirse en más de una página. Para esto, es típico usar la función include y su semejante require.

Citando la documentación oficial de php para la función include:

La sentencia include incluye y evalúa el archivo especificado[…] Cuando un archivo es incluido, el intérprete abandona el modo PHP e ingresa al modo HTML al comienzo del archivo objetivo y se reanuda de nuevo al final.

Por esta razón, cualquier código al interior del archivo objetivo que deba ser ejecutado como código PHP, tiene que ser encerrado dentro de etiquetas válidas de comienzo y terminación de PHP.

En otras palabras, el contenido del fichero se interpretará como HTML hasta que encuentre una etiqueta PHP. Es decir, como si hubiéramos copiado y pegado el contenido del fichero a incluir dentro del archivo que se está renderizando en el navegador.

Problemática de implementación de include en informática

Esta propiedad, cuando no está correctamente sanitizada, puede servir para obtener información del servidor como: usuarios, ficheros de configuración, puertos abiertos, dispositivos conectados, etc. La explotación de esta vulnerabilidad se consigue introduciendo ficheros no autorizados.

A modo de demostración, se usará DVWA como ejemplo, ya que nos proporciona un laboratorio con la vulnerabilidad LFI en una máquina GNU/Linux,  y BurpSuite para controlar con más comodidad las cabeceras de las consultas y hacer una pequeña demostración:

Para aprovechar adecuadamente una vulnerabilidad LFI, es importante conocer la localización de los ficheros de configuración o contar con una lista de archivos apropiados para enumerarlos.

Como hemos visto en la documentación, esto no será suficiente para obtener los ficheros PHP, ya que debido a la misma naturaleza de la función include, estos se interpretarán antes de que se muestren en la pantalla.

Para poder obtener el contenido, utilizamos los wrappers. En particular, filtraremos el contenido codificando este en Base64:

Se puede decodificar la información en Base64 al usar herramientas web o utilidades instaladas en el sistema operativo.

Combinando este método con una buena lista y un script de automatización, se puede obtener información importante del funcionamiento del servicio web:

infinityspa@infinityspa:~$ base64 -d
PD9waHANCg0KLy8gQ2hlY2sgaWYgdGhlIHJpZ2h0IFBIUCBmdW5jdGlvbnMgYXJlIGVuYWJsZWQNCiRXYXJuaW5nSHRtbCA9ICcnOw0KaWYoICFpbmlfZ2V0KCAnYWxsb3dfdXJsX2luY2x1ZGUnICkgKSB7DQoJJFdhcm5pbmdIdG1sIC49ICI8ZGl2IGNsYXNzPVwid2FybmluZ1wiPlRoZSBQSFAgZnVuY3Rpb24gPGVtPmFsbG93X3VybF9pbmNsdWRlPC9lbT4gaXMgbm90IGVuYWJsZWQuPC9kaXY+IjsNCn0NCmlmKCAhaW5pX2dldCggJ2FsbG93X3VybF9mb3BlbicgKSApIHsNCgkkV2FybmluZ0h0bWwgLj0gIjxkaXYgY2xhc3M9XCJ3YXJuaW5nXCI+VGhlIFBIUCBmdW5jdGlvbiA8ZW0+YWxsb3dfdXJsX2ZvcGVuPC9lbT4gaXMgbm90IGVuYWJsZWQuPC9kaXY+IjsNCn0NCg0KDQokcGFnZVsgJ2JvZHknIF0gLj0gIg0KPGRpdiBjbGFzcz1cImJvZHlfcGFkZGVkXCI+DQoJPGgxPlZ1bG5lcmFiaWxpdHk6IEZpbGUgSW5jbHVzaW9uPC9oMT4NCg0KCXskV2FybmluZ0h0bWx9DQoNCgk8ZGl2IGNsYXNzPVwidnVsbmVyYWJsZV9jb2RlX2FyZWFcIj4NCgkJWzxlbT48YSBocmVmPVwiP3BhZ2U9ZmlsZTEucGhwXCI+ZmlsZTEucGhwPC9hPjwvZW0+XSAtIFs8ZW0+PGEgaHJlZj1cIj9wYWdlPWZpbGUyLnBocFwiPmZpbGUyLnBocDwvYT48L2VtPl0gLSBbPGVtPjxhIGhyZWY9XCI/cGFnZT1maWxlMy5waHBcIj5maWxlMy5waHA8L2E+PC9lbT5dDQoJPC9kaXY+DQoNCgk8aDI+TW9yZSBJbmZvcm1hdGlvbjwvaDI+DQoJPHVsPg0KCQk8bGk+IiAuIGR2d2FFeHRlcm5hbExpbmtVcmxHZXQoICdodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9SZW1vdGVfRmlsZV9JbmNsdXNpb24nICkgLiAiPC9saT4NCgkJPGxpPiIgLiBkdndhRXh0ZXJuYWxMaW5rVXJsR2V0KCAnaHR0cHM6Ly93d3cub3dhc3Aub3JnL2luZGV4LnBocC9Ub3BfMTBfMjAwNy1BMycgKSAuICI8L2xpPg0KCTwvdWw+DQo8L2Rpdj5cbiI7DQoNCj8+DQo=
<?php

// Check if the right PHP functions are enabled
$WarningHtml = '';
if( !ini_get( 'allow_url_include' ) ) {
        $WarningHtml .= "<div class=\"warning\">The PHP function <em>allow_url_include</em> is not enabled.</div>";
}
if( !ini_get( 'allow_url_fopen' ) ) {
        $WarningHtml .= "<div class=\"warning\">The PHP function <em>allow_url_fopen</em> is not enabled.</div>";
}


$page[ 'body' ] .= "
<div class=\"body_padded\">
        <h1>Vulnerability: File Inclusion</h1>

        {$WarningHtml}

        <div class=\"vulnerable_code_area\">
                [<em><a href=\"?page=file1.php\">file1.php</a></em>] - [<em><a href=\"?page=file2.php\">file2.php</a></em>] - [<em><a href=\"?page=file3.php\">file3.php</a></em>]
        </div>

        <h2>More Information</h2>
        <ul>
                <li>" . dvwaExternalLinkUrlGet( 'https://en.wikipedia.org/wiki/Remote_File_Inclusion' ) . "</li>
                <li>" . dvwaExternalLinkUrlGet( 'https://www.owasp.org/index.php/Top_10_2007-A3' ) . "</li>
        </ul>
</div>\n";

?>

Realizar un RCE en Informática a partir de un LFI

Para poder ejecutar código en el servidor remoto (Remote Code Execution en informática), nuestro LFI debe ir acompañado de determinadas condiciones, una de ellas es una desafortunada gestión de privilegios de los ficheros de registro, también llamados logs.

Podría ser que el fichero que almacena los registros de apache2 tenga privilegios de lectura para el usuario que se encarga de manejar el servicio HTTP, permitiendo leer su contenido a través del LFI.

Como este fichero se modifica cada vez que algún cliente consulta al servidor, podemos realizar una consulta que inserte una etiqueta PHP con código controlado por nosotros.

Para conseguirlo, debemos observar los logs del servicio que se pretende explotar:

En el caso de ejemplo, ponemos nuestra carga útil (payload) en el User-Agent. Esto se puede hacer a través de un proxy web o mediante una consulta curl. Para este ejemplo, se utilizó la herramienta BurpSuite:

RCE en informática

Luego, se realiza una consulta incluyendo el fichero de registro (log) seleccionado para ver que el código se ha ejecutado en el servidor remoto:

RCE en informática desde un LFI

Esta técnica que se denomina envenenamiento de registro o log poisoning, se puede aplicar a todo fichero de registro que tenga los permisos apropiados.

Esta vulnerabilidad no se limita a los logs solamente, ya que si un atacante encuentra una manera de subir información a un servidor, podrá transformar el LFI en un RCE (en informática).

Abusar de wrappers PHP

Cuando la opción allow_url_include de PHP se encuentra puesta en On, se puede usar el wrapper

php://input

El cual permite enviar el código a ejecutarse mediante una consulta POST, donde la carga útil se encontrará en el cuerpo de la petición HTTP:

RCE en informática - whoami

Conclusión de un LFI a RCE en informática

Como conclusión, se ha demostrado dos situaciones en las que se puede extender una vulnerabilidad LFI a una vulnerabilidad RCE (Remote Code Execution en informática).

Conviene reflexionar un poco sobre el impacto potencial y la importancia de prevenir este tipo de vulnerabilidades críticas.

Lo usual, ante una vulnerabilidad RCE, es que sea utilizada para subir una web shell o ejecutar código que permita obtener una shell reversa y así obtener acceso al servidor para posteriormente escalar privilegios, control total sobre este y eventualmente comprometer la red corporativa de una organización.