Analisis de codigo fuente para bypass de uploader

Después de haber identificado que el hostname del servidor es spartan.store, y considerando que las aplicaciones web de Apache suelen ubicarse en el directorio /var/www/, se nos presenta una oportunidad para explotar la funcionalidad de carga de imágenes en el sistema web. A menudo, los desarrolladores permiten la subida de archivos multimedia, como imágenes, y si no se implementan medidas de seguridad adecuadas, este mecanismo puede ser utilizado para ejecutar código malicioso, como una WebShell.

Exploración de la Funcionalidad de Carga de Imágenes

En este ejemplo, nos enfocamos en una petición HTTP que permite subir una imagen en el sistema, donde incluimos una WebShell dentro de un archivo PHP disfrazado como imagen JPEG:

En esta solicitud, hemos intentado subir una WebShell PHP dentro de un archivo de imagen denominado shell.php. Esto es un intento clásico de evasión de filtros que solo permiten ciertos tipos de archivos, en este caso imágenes JPEG.

Análisis del Código del Sistema

Para entender cómo se gestiona la subida de imágenes, utilizamos sqlmap para leer el código del archivo responsable de manejar estas peticiones:

┌──(root㉿kali)-[/home/kali/Desktop/CPPJ]
└─# proxychains sqlmap -r reporte1-request.txt --file-read=/var/www/spartan.store/System/Sistema/Productos/guardar.php
files saved to [1]:
[*] /root/.local/share/sqlmap/output/172.16.1.6/files/_var_www_spartan.store_System_Sistema_Productos_guardar.php (same file)

Al analizar el archivo guardar.php, encontramos el siguiente fragmento de código que realiza la validación y posible redimensionamiento de las imágenes subidas:

for ($i=0; $i <$listadeProductos; $i++) { 
   
    $nombre_imagen = "uploads/".$listadeProductos['imagen_producto'];
    $rtOriginal = $nombre_imagen;
    $original = imagecreatefromjpeg($rtOriginal);   

    //Definir tamaño máximo y mínimo
    $ancho_final = 200;
    $alto_final = 200;
     
    //Recoger ancho y alto de la original
    list($ancho,$alto)=getimagesize($rtOriginal);

         // Validando si es necesario la redimencion
         if($ancho == 200 && $alto ==200){
            echo "";
            //echo "The image ".$listadeProductos['imagen_producto']." does not need to be resized!\n";
          }else{
            echo "The image ".$listadeProductos['imagen_producto']." does need to be resized!\n";
            $lienzo=imagecreatetruecolor($ancho_final,$alto_final); 
     
            //Copiar $original sobre la imagen que acabamos de crear en blanco ($tmp)
            imagecopyresampled($lienzo,$original,0,0,0,0,$ancho_final, $alto_final,$ancho,$alto);
             
            //Limpiar memoria
            imagedestroy($original);
             
            //Definimos la calidad de la imagen final
            $cal=90;
             
            //Se crea la imagen final en el directorio indicado
            imagejpeg($lienzo,$nombre_imagen,$cal);
          }
           
    $listadeProductos = mysqli_fetch_array($ejecutar_sentencia);
  }

Entendiendo el Proceso de Redimensionamiento

En el código anterior, podemos observar que el sistema redimensiona las imágenes subidas si su tamaño no es exactamente de 200x200 píxeles. Si la imagen es mayor o menor a estas dimensiones, el sistema crea un lienzo en blanco de 200x200 y copia la imagen original sobre este lienzo, cambiando su tamaño.

Este proceso puede afectar la integridad de nuestra WebShell, ya que la imagen es modificada y guardada nuevamente en el sistema, lo que podría eliminar o corromper nuestro código PHP malicioso. Sin embargo, hay una forma de eludir esta redimensión.

Evasión del Redimensionamiento

Para evitar que la imagen sea redimensionada, podemos subir una imagen de exactamente 200x200 píxeles. El código PHP que valida las dimensiones de la imagen revisa si la imagen ya tiene estas dimensiones y, si es así, no se aplica ningún cambio. Esto significa que nuestra WebShell permanecerá intacta si la subimos como un archivo JPEG con un tamaño de 200x200 píxeles.

Sin embargo, como el código PHP de la WebShell no puede ser parte del contenido visible de la imagen, lo añadimos en los metadatos de la imagen. Los metadatos no son afectados por el proceso de validación o redimensionamiento, lo que nos permite ocultar el código malicioso dentro de ellos.

Last updated