Bypassear uploader con validacion en JavaScript

Iniciado por Xt3mP, Abril 20, 2012, 02:39:49 AM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Abril 20, 2012, 02:39:49 AM Ultima modificación: Abril 20, 2012, 10:54:37 AM por Pr0ph3t
Estamos en una época en donde utilizar tecnología dinámica (refiriendome a programación; como lo es JavaScript, entre otros) hace que un sitio se posicione entre los favoritos por la interacción en tiempo real entre cliente > servidor < cliente. Algo de lo más notorio de lo anterior mencionado es que trae consigo mismo un enfoque en la seguridad a nivel cliente dejando de lado la seguridad a nivel servidor (cosa que es terriblemente riesgoso). Esta ocasión me encontré con un uploader de imagenes que no permitía subir ningún archivo; y no porque validará la extensión, si no que utiliza funciones natas de PHP que hacen que la operación de cargar el archivo sea incorrecta:



A primera instancia notamos (como ya mencione) que no valida la extensión del archivo por lo que si no existieran esas funciones tendríamos desde ya nuestra shell arriba; por otro lado, notamos que hace referencia al archivo upload_.php que en realidad no nos sirve de nada por lo que procedemos buscando algo que nos sea útil. Generalmente, estos uploaders no tienen un .htaccess o un index que restringa el listado de archivos, es decir, quedan al descubierto los demás archivos encontrandonos así con el resto de los archivos del servidor (al menos los de la carpeta en cuestión); navegando por dichos archivos notamos que existe otro uploader más pero este es para archivos .mp3:


Intentando subir la shell en extensión .php (como lo hemos estado intentando hasta ahorita) notamos que nos regresa en tiempo real un error de la siguiente manera ya que valida la extensión del archivo:


A simple vista nos damos cuenta que se trata de algún lenguaje dinámico, como lo es JavaScript por lo que procedí a revisar el código fuente y nos encontramos con la siguiente función:

Código: javascript
function validar() {
var archivo = document.SubirMp3.mp3.value;
extensiones_permitidas = new Array(".mp3", ".wma");
mierror = "";

if (!archivo) {
//Si no tengo archivo, es que no se ha seleccionado un archivo en el formulario
mierror = "No has seleccionado ningún archivo";
}else{
//recupero la extensión de este nombre de archivo
extension = (archivo.substring(archivo.lastIndexOf("."))).toLowerCase();
//alert (extension);
//compruebo si la extensión está entre las permitidas
permitida = false;
for (var i = 0; i < extensiones_permitidas.length; i++) {
if (extensiones_permitidas[i] == extension) {
permitida = true;
break;
}
}
if (!permitida) {
mierror = "Compruebe la extensión del archivo de sonido seleccionado. \nSólo se pueden subir archivos con extension: " + extensiones_permitidas.join();
}else{
//submito!
SubirMp3.submit();
return true;
}
}
//si estoy aqui es que no se ha podido submitir
alert (mierror);
return false;

}


Notamos que nos valida la extensión tomando de referencia el último punto (.) por lo que si intentamos subir shell.mp3.php sería inútil, revisando el resto del código fuente notamos que hace referencia a otro archivo .php que es el encargado de procesar el archivo en cuestión, y esto era de esperarse, ya que en el uploader anterior también hacia referencia a otro archivo.

Es aquí donde entra el ingenio para saltarse la protección en JavaScript, aclaro que todavía no estaba seguro si subiría la shell porque creí que tenía también comprobación en PHP.

Lo que hicimos fue abrir un documento de texto (en cualquier editor) y simular el formulario original quedándonos de esta manera:

Código: html
<form action="http://web/path/path/uploadmp3_.php" method="POST" ENCTYPE="multipart/form-data" onSubmit="return validar()">
<input name="mp3" type="file"><input name="submit" type="submit" value="Enviar"></FORM>


Después, cargamos la shell como archivo (al dar click en el file loader) y presionamos Enviar; como en este caso no existe ninguna función validar() que al dar click al ítem submit nos regresa true porque no hay nada que impida que el formulario se envíe a el target indicado, y ¿qué resultado obtenemos?, que en este caso no valida la extensión por PHP haciendo que esto sea posible:


Por lo tanto, mi recomendación es que si quieren ser parte de estos sitios bonitos, no solo comprueben la seguridad a nivel cliente, si no también a nivel servidor.

Nota: Para hacer esto más sencillo también basta con enviar cabeceras (y el archivo en ellas) o desactivar JavaScript directamente:


P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
Cada vez que me das Karma me motivas


Muy Buen Aporte, esta muy bien explicado

Entonces él dijo, "cruzad con vuestras tropas y atacad porque es lo único que le queda a nuestro pueblo...".