lunes, abril 26, 2021

Un RFD (Remote File Downloading) "protegido" por ofuscación

Hace no demasiado, cuando recordaba las charlas que había dado con mi amigo Palako por todo el mundo de hacking, me vinieron las demos de RFD (Remote File Downloading) que contamos en Noruega o Washington D.C. en la que utilizando diferentes ataques de SQL Injection íbamos descargando ficheros del servidor web, junto con otras técnicas de LFI (Local File Inclusion) o RFI (Remote File Inclusion).

Figura 1: Un RFD (Remote File Downloading) "protegido" por ofuscación

En todas estas técnicas, la idea es siempre la misma, ver cómo utilizar código Server-Side para que al final se acceda a un fichero que está en el servidor web y nos lo entregue vía web browser. Ni sé cuantos proyectos de Ethical Hacking a empresas o pentesting a aplicaciones web se han terminado con una sola técnica de estas, ya que en el momento en el que te puedes descargar ficheros del servidor vas a ir a por los "juicy files" que te van a entregar las configuraciones de acceso a la base de datos, los usuarios del servidor web, los datos de la DMZ por las configuraciones de red, etcétera.


De hecho, cuando te enfrentas a una auditoría de un sitio web, es una de las cosas que primero buscas. SQL Injection, Blind SQL Injection, errores verbose que te dan información jugosa, Client-Side Attacks como XSS/CSRF/SSRF y descarga de ficheros. Por eso los pentesters en los Red Team, en los equipos de QA de seguridad y en los equipos de Ethical Hacking, estas disciplinas se entrenan con fuerza. En muchos CTFs de las CONs, conseguir una bandera es descargar un fichero - o muchos - del servidor web. 

Un RFD protegido por ofuscación

El caso que os voy a contar es uno de muchos, pero me hizo gracia encontrármelo de casualidad, ya que, en lugar de hacer las cosas bien, han puesto un parche de oscuridad que seguro que a los bots, y a los menos expertos evita, pero desde luego no a ningún pentester profesional. 

Figura 3: Aplicación PHP que descarga ficheros

En esta implantación, el código que te permite acceder a los ficheros es un fichero PHP que devuelve un fichero PDF o un PNG. Hasta aquí tiene toda la pinta de ganarse la atracción de cualquier auditor de seguridad profesional, pero lo que más llama la atención es que utiliza dos parámetros para conseguir la descarga. El primero de ellos un hash y el segundo un Ln.
Lo primero que puedes pensar es que se trata de un esquema tipo cucharón, donde el programa tira un Select contra una base de datos, y puedes intentar hacer un UNION para que devuelva un Path al fichero que tú quieras. Es un esquema típico de RFD, pero no era así. Analizando el Hash se ve rápidamente que era un BASE64, así que se puede decodificar fácilmente.


Al decodificarlo, se ve que aparece una ruta a un fichero, pero que cuenta con unos caracteres de más al inicio, y otros caracteres del más al final, como si llevara más información de la que es necesaria en esa ruta. 

Figura 6: Decodificando el hash. Aparecen caracteres antes y después de la ruta

Tras probar las cosas que hay que probar, es decir, probar el Hash original con valores aleatorios de LN se observa que no descarga nada y salen todos los ficheros vacíos, pero cuando se pone un LN+1 se descarga un fichero vacío con un nombre que tiene una letra más que el nombre del fichero correcto, y eso hizo saltar el dato final.

Figura 7: con LN+1 busca un fichero con extensión pngo que no existe

Al principio confundí los caracteres de inicio como parte del Path pero viendo este comportamiento y contando LN caracteres hacia atrás desde .png y ver que acaba en la barra de /home, es fácil asumir que el valor de LN es el límite de caracteres que se debe tomar del string de caracteres que viene en el HASH Base64 del parámetro de llamada. Pero... ¿para que sirve la cadena de  caracteres al inicio y la cadena de caracteres al final?

Figura 8:Codificando la ruta de /etc/passwd con los caracteres sobrantes

Para probar si esta suposición es correcta y si tenemos que hacer algo más con los caracteres al inicio y al final, basta con hacer una sencilla prueba. Vamos a dejar los caracteres al principio y los caracteres al final tal y como están, y vamos a meter la ruta al /etc/passwd en el medio. Después vamos a codificar en BASE64 esta cadena. Y ahora hacemos la llamada al programa PHP poniendo este Hash como parámetro uno y como parámetro LN al valor de lenght(/etc/passwd), y vemos si el fichero descarga y que hay dentro.

Figura 9: Fichero /etc/passwd descargado

Como se puede ver, tenemos el fichero /etc/passwd descargado, y haciendo lo mismo todos los ficheros del servidor a los que tenga acceso el usuario del servidor web - que no es root -. Tras unas cuantas pruebas, y ver que con ese sencillo algoritmo era posible descargar todos los ficheros, la respuesta de para qué sirven esos caracteres al inicio y al final es sencillo. Son "Tokens de ofuscación" que el programador ha metido para que no le sea tan fácil a un script kiddie o a un bot automático descargar los ficheros.

Figura 10: Probando con /etc/hosts y los mismos caracteres sobrantes

Realmente es una solución inútil, porque cualquier pentester profesional va a encontrarlo fácilmente, y si tienes que hacer una aplicación web, más vale que conozcas las técnicas de hacking de aplicaciones web, y que sepas cómo desarrollar de forma segura, porque lo que te puede parecer una buena idea, puede ser un desastre de seguridad.

¡Saludos Malignos!

1 comentario: