cabecera blog BlackArrow

¿Como evadir disable_functions y open_basedir?

Durante la pasada edición de HackRon relatamos en la ponencia «El Red Team siempre gana» algunas técnicas utilizadas durante los test de intrusión, entre ellas se explicó cómo evadir disable_functions y open_basedir. Una situación habitual durante la ejecución de un test de intrusión es la de encontrar aplicadas ciertas medidas de bastionado en los servidores web, lo que dificulta la elevación de privilegios o el uso de éste para pivotar hacia otros puntos de la red corporativa.

Introducción

Dentro de las medidas típicas que se aplican es la de deshabilitar el uso de funciones peligrosas que pudieran ser utilizadas para ejecutar comandos del sistema operativo o para iniciar procesos. Funciones como system() o shell_exec() suelen encontrarse deshabilitadas a través de las directivas de PHP definidas en el archivo de configuración php.ini. Otras funciones quizás menos conocidas como dl() (que permite cargar de forma dinámica una extensión de PHP) pueden pasar desapercibidas al administrador de sistemas y no estar deshabilitadas, por lo que lo habitual en un test de intrusión es enumerar qué funciones se encuentran habilitadas por si alguna ha sido olvidada.

Por otra parte, una medida habitual es limitar el acceso al sistema de ficheros desde los scripts de PHP que se ejecuten en el servidor. Esto se realiza restringiendo el árbol de directorios en el cual se puede operar a través de la directiva open_basedir. Por ejemplo si se limita el acceso a ficheros dentro del árbol de /var/www/, un script PHP no podrá leer el fichero /etc/passwd pese a que el usuario tenga los permisos adecuados. De esta forma se limita y dificulta el alcance de las acciones que se pueden realizar si se logra la ejecución código PHP a través de vulnerabilidades en el aplicativo web (subidas arbitrarias de ficheros,  local file inclusions, etc.).

En estos escenarios tan limitados donde, prácticamente, solo podemos crear y leer ficheros, el pentester suele optar por localizar archivos de configuración o contraseñas hardcodeadas en el código que les permita moverse lateralmente (por ejemplo a través de la reutilización de una contraseña en el SSH). Sin embargo cuando ni siquiera esto resuelta efectivo tenemos que proceder a evadir disable_functions y open_basedir.

Una de las técnicas más fáciles de implementar y poco extendidas es la de abusar de las funcionalidades mail() y putenv(). Esta técnica no es nueva, ya fue reportada a PHP en el año 2008 por gat3way, pero sigue funcionando a día de hoy. A través de la función putenv() podemos modificar las variables de entorno, permitiéndonos asignarle el valor que deseemos a la variable LD_PRELOAD. Grosso modo LD_PRELOAD nos va a permitir pre-cargar una librería .so nuestra antes que el resto de librerías, de tal forma que si un programa utiliza una función de una librería (libc.so por ejemplo) ejecutará la de nuestra librería en vez de la que debería. De esta forma podemos secuestrar o «hookear» funciones, modificando su comportamiento a nuestro antojo.

El problema que tenemos es que, si bien podemos crear un entorno favorable asignando a LD_PRELOAD como valor una librería nuestra creada ad-hoc, seguimos necesitando conseguir ejecutar algún programa. Y este era nuestro problema inicial. Sin embargo existe una solución: en entornos UNIX la función mail() ejecuta un binario. Si observamos la documentación de PHP podemos observar el siguiente fragmento:

La implementación en Windows de mail() difiere bastante de la implementación en Unix. Primero, no usa un binario local para componer mensajes ya que sólo opera en sockets directos, lo que significa que es necesario un MTA escuchando en un socket de red (que puede estar tanto en localhost como en una máquina remota).

Esto se confirma al analizar qué ocurre cuando se ejecuta un PHP que llama a la función mail():

<?php
mail("a", "a", "a", "a");
?>
Functión mail()

Uso de execve al usar mail() en PHP

De tal forma que, al ejecutar el binario que es llamado cuando utilizamos mail(), éste pre-cargará nuestra librería permitiéndonos modificar su comportamiento si hookeamos alguna de las funciones que este llame.

Chankro: herramienta para evadir disable_functions y open_basedir

El Red Team de Tarlogic ha creado una pequeña utilidad para, de forma automática, evadir disable_functions y open_basedir durante los test de intrusión. A través de Chankro generamos un PHP que actuará de dropper, creando en el servidor una librería .so y el binario (un meterpreter, por ejemplo) o script bash (reverse shell, por ejemplo) que deseemos ejecutar libremente, y que posteriormente llamará a putenv() y mail() para lanzar el proceso.

Uso de Chankro

Chankro: herramienta para evadir disable_functions y open_basedir

Le debemos de pasar como argumentos el archivo que ejecutará, el nombre del PHP, la arquitectura del servidor (64 o 32), y la ruta absoluta de donde se dropearán los ficheros. En este ejemplo vamos a generar un PHP que nos permita obtener una reverse shell a través de Netcat:

Chankro.py

Generación de un PHP para evadir disable_functions y open_basedir utilizando Chankro

Una vez subido el fichero generado al servidor, al que tenemos acceso vía alguna vulnerabilidad en el aplicativo web, podemos ejecutar nuestro «rev.sh» enviandole una petición con curl:

Reverse shell utilizando netcat

Reverse shell utilizando netcat

Descargar CHANKRO

La herramienta podéis encontrarla en el GitHub de Tarlogic.

https://github.com/TarlogicSecurity/Chankro

Descubre nuestro trabajo y nuestros servicios de ciberseguridad en www.tarlogic.com

Más artículos de la serie Evasion disable_functions en php

Este artículo forma parte de una serie de articulos sobre Evasion disable_functions en php

  1. ¿Como evadir disable_functions y open_basedir?
  2. Evasión de disable_functions y explotación local en PHP