Deserialización de phar, nueva técnica de explotación en PHP

La semana pasada Sam Thomas de Secarma presentó en la BlackHat USA una nueva técnica de deserialización en PHP sin usar la función unserialize(), que permite a un atacante usar las vulnerabilidades relacionadas con archivos para conseguir ejecución remota de código.

Archivos Phar

La mayoría de las operaciones con archivos en PHP permiten utilizar varios wrappers como si fuera una URL, como data://, zlib:// o php:// cuando se accede a una ruta de archivo. Algunos de estos wrappers se utilizan a menudo para explotar vulnerabilidades RFI donde un atacante puede controlar la ruta completa del archivo para la inclusión. Por ejemplo, los wrappers se usan para obtener el código fuente que de otro modo se ejecutaría, o para inyectar código PHP propio para su ejecución:
include('php://filter/convert.base64-encode/resource=index.php');
include('data://text/plain;base64,cGhwaW5mbygpCg==');

Pero hasta ahora, nadie prestó atención al wrapper phar://. Lo interesante de los archivos Phar (Archivo PHP) es que contienen metadatos en formato serializado. Vamos a crear un archivo Phar y agregar un objeto con algunos datos como metadatos:
// create new Phar
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('');

// add object of any class as meta data
class AnyClass {}
$object = new AnyClass;
$object->data = 'rips';
$phar->setMetadata($object);
$phar->stopBuffering();

Nuestro archivo recién creado test.phar tiene el siguiente contenido:


Como podéis ver nuestro objeto se almacenó como una cadena serializada.

Inyección de objetos PHP

Evidentemente si ahora se realiza una operación en nuestro archivo Phar a través del wrapper phar://, sus metadatos serializados se deserializarán (parece un trabalenguas).

Esto significa que nuestro objeto inyectado en los metadatos se cargará en el scope de la aplicación. Si esta aplicación tiene una clase llamada AnyClass y tiene el método mágico __destruct () o __wakeup () definido, entonces esos métodos se invocarán automáticament, es decir, podemos activar cualquier método destructor o de activación en la base del código. O peor aún, si estos métodos operan con nuestros datos inyectados, esto puede conducir a más vulnerabilidades.
class AnyClass {
    function __destruct() {
        echo $this->data;
    }
}
// output: rips
include('phar://test.phar');

Explotación

Básicamente un atacante debe ser capaz de elaborar y poner un archivo Phar en el servidor web objetivo (con metadatos serializados maliciosos) y luego que sea llamado.

Por ej., Sam Thomas encontró algunos trucos sobre cómo introducir un archivo Phar en un archivo JPG falso, por lo que una característica común de carga de imágenes ya es suficiente. Cualquier otra operación de archivo que haga referencia a nuestro phar también nos valdría.

Podéis pensar que ésto no parece tan crítico porque si un atacante puede controlar la ruta completa del archivo en operaciones tales como "include(), fopen(), file_get_contents(), file() etc., ya presenta una vulnerabilidad crítica en sí misma. Pero la entrada del usuario utilizada en estas funciones generalmente se valida.

Sin embargo, la deserialización se desencadena para el contenedor phar:// en cualquier operación de archivo. Por lo tanto, otras operaciones de archivos, como file_exists() que simplemente verifica la existencia de un archivo, hasta ahora se consideraban menos sensibles a estos problemas de seguridad y están menos protegidas.

Más info y casos de estudio en la presentación oficial:

https://github.com/s-n-t/presentations/blob/master/us-18-Thomas-It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It.pdf

Fuente: https://blog.ripstech.com/2018/new-php-exploitation-technique/

Comentarios