Introducción a la solución de problemas de Web scraping con Bash

Durante una prueba de intrusión debe comprobarse hasta qué punto  podría automatizarse la recolección masiva de datos públicos en la aplicación web. Parece contradictorio que los datos públicos puedan afectar la seguridad de nuestros sistemas, pero no lo es tanto si tenemos en cuenta la economía del esfuerzo: mientras menor sea la superficie de ataque de la aplicación web, mayor será el esfuerzo (humano más que computacional) que se tendrá que invertir para la explotación efectiva de una vulnerabilidad y por tanto, mayor será la posibilidad de que los ciberatacantes desistan en sus propósitos si no es un ataque de tipo APT.

Copiar datos manualmente de cinco usuarios, para suministrar información a un programa como Hydra puede ser sencillo, cuando vas por diez ya empiezas a aburrirte, por el quince ya estás pensado en tomar vacaciones y en el número veinte estás decidido a cambiar de trabajo.

La utilización de APIs web sería un medio muy fácil para automatizar el drenado de datos, sin embargo, todas las aplicaciones web no disponen de API ni todos los datos que se brindan tienen que ser necesariamente útiles. Por ese motivo, el web scraping es una técnica más general.

Cuando hablamos de web scraping, estamos tratando con información no estructurada si lo abordamos desde la perspectiva de los modelos de bases de datos. Esta técnica se emplea desde hace mucho tiempo por los bots de motores de búsquedas, agentes de aplicaciones financieras, vigilancia tecnológica y otros. Por tanto, el web scraping no es la excepción sino la norma en Internet. Según Access Watch, el 82.72% del tráfico web, del 3 de septiembre del 2017 fue generado por bots.

Te propongo analizar dos casos  diferentes sobre como el web scraping puede ser utilizado en el marco de una prueba de intrusión en aplicaciones web. Para ello emplearemos Bash para realizar las tareas de programación.

Caso 1. Poniendo a prueba las facilidades de enumeración de cuentas de usuarios.

Problema: Tenemos una aplicación web que expone la información pública de los usuarios bajo rutas como https://example.com/?q=user/9. Es un requisito del proceso de negocio que sea de esta manera porque los demás usuarios del sistema deben poder acceder a ella. La información pública contiene la foto del usuario (opcional) y su nombre como mínimo. Este es un patrón usado en algunos CMS como Drupal.

Cuando analizamos el código fuente de la página web (figura 1) podemos apreciar algunas cosas interesantes:

1

Figura 1. Contenido de la página web. (Por supuesto, los datos y la URL son falsos)

  • La línea 15 contiene el nombre de la cuenta de usuario (aunque no se mostraba en el navegador). Contiene además una cadena única que es foaf:name. Esta cadena no se repite en el código, por lo que nos puede servir para identificar esa línea inequívocamente.
  • La línea 21 contiene el nombre completo del usuario y aparece también la cadena “Listado de Cliente” que también es única en todo el código fuente.

En este punto, un especialista de seguridad pueda llegar a la conclusión que es muy sencillo recolectar todos los nombres de cuentas de usuarios, pero eso reflejado en un informe de pentesting a veces parece carecer de importancia. Por eso tenemos que demostrar que es una debilidad que debe ser resuelta y para ello vamos a realizar una recolección efectiva de todos los nombres de cuentas de usuarios para ponerlo como anexo y de ese modo describir mejor el problema.

Los pasos que daremos a continuación son:

  1. Con una página web de estudio (en este caso nombrada user-web-info.html) realizamos un grep para aislar la línea donde está el nombre de cuenta de usuario.
  2. Comprobado que nos quedamos con la línea de interés, se la enviamos a través de un pipeline a la herramienta AWK y nos quedamos con el cuarto token donde aparece el nombre de la cuenta de usuario.
  3. Comprobado que obtenemos el token correcto, volvemos a realizar un pipeline y auxiliados por cut, aislamos el nombre de cuenta de usuario el cual está delimitado por comillas dobles.
  4. Comprobamos que obtenemos el nombre de cuenta de usuario correcto. Ya disponemos de la combinación  para mapear el dato que nos interesa. Como pueden apreciar, en este caso no vamos a almacenar el nombre completo de la persona, pero si fuera necesario podía seguirse un algoritmo similar de prueba y error hasta dar con la combinación correcta de ejecución de utilidades Bash.
2.png

Figura 2. Proceso para aislar el nombre de cuenta de usuario.

Solo necesitamos auxiliarnos de un bucle (for) y un comando que nos permita obtener un recurso web (Curl/Wget) para hacer nuestro script:

3

Figura 3. Script en Bash para obtener los nombres de cuentas de usuarios.

La secuencia del bucle se obtuvo a través de un proceso de prueba y error para determinar cuáles eran los intervalos válidos. La manera más fácil de hacerlo es crear una cuenta de usuario y fijarse en el ID que se asigna, ese sería el máximo por lo general. Para hallar el mínimo se puede ir probando de 10 en 10 o de 100 en 100 hasta dar con el valor correcto.

En la línea 5, Curl no solo recupera el recurso, sino que lo almacena, a modo de evidencia de la prueba de seguridad.

Todas las cuentas de usuarios son almacenadas en el archivo cuentas.txt.

El comando sleep (línea 7) nos permite hacer una petición por minuto para evadir las configuraciones más básicas de un WAF si este estuviera activo.

Ahora vamos a complejizar un poco el escenario, supongamos que la aplicación web está funcionando sobre HTTPS y solo permite que los usuarios autenticados en el sistema puedan consultar la información pública de los demás usuarios.

En este caso, solo sería necesario que el especialista de seguridad iniciara una sesión en la aplicación web y copiara los datos de la sesión a Curl como se refleja en la próxima figura:

4

Figura 4. Configuración de Curl para un entorno más restrictivo.

Al concluir la ejecución del script, podemos disponer de los nombres de cuentas de usuarios necesarios para enriquecer el informe del pentesting y además realizar una prueba de seguridad de fuerza bruta contra una funcionalidad de autenticación si fuera necesario.

Caso 2. Comprobando plugins de WordPress

Problema: En una ocasión necesitaba comprobar, de una lista bastante grande de plugins, cuales estaban registrados en wordpress.org. Decidí buscar si existía una lista de ellos y efectivamente, así fue. En la dirección plugins.svn.wordpress.org, existe una página web con todos los plugins de wordpress registrados. Dicha página pesaba 4.7 MB. Tenía 69139 líneas de código y más de 4.5 millones de caracteres. Tenía pues dos listas que quería comparar  y por supuesto, el empleo de web scraping era ideal para esta situación.

Antes de abordar el problema quiero destacar algo. Hay muchos plugins que comparten nombres similares. Supongamos  que vamos a buscar si existe el plugin Zing. En la figura 5 podemos ver que existen varios plugins con la cadena zing en su nombre.

5

Figura 5. Aplicación de la utilidad Grep.

Como hicimos en el ejemplo anterior, tenemos que buscar la mejor combinación que permita comprobar la existencia unívoca del plugin en la lista en la página HTML.

En la figura 6 se muestra como no es suficiente la combinación =\PLUGIN, sino que también es necesario incorporar una barra al final quedándose como patrón de búsqueda =\PLUGIN/.

6.png

Figura 6. Solo el empleo de la expresión de búsqueda “=\PLUGIN/” permite aislar el plugin de interés.

Teniendo estos elementos, solo nos falta incorporar un bucle while que recorra el archivo con los plugins que queremos comprobar y el empleo de la condicional if con la utilidad grep. Si el plugin ha sido encontrado, se registrar en el archivo plugin-en-wordpress.org (figura 7).

7.png

Figura 7. Script programador en Bash para la búsqueda de plugins de WordPress.

Conclusiones

Dominar técnicas de web scraping es una competencia imprescindible para un pentester profesional. Existen varias bibliotecas que facilitan este trabajo como Beautiful Soup y Jaunt para Python y Java respectivamente. Combinaciones de utilidades como Grep, Curl, Wget, AWK y Cut, unido al uso de pipelines en Bash, pueden solucionar, casi de inmediato, el 80% de las necesidades de una prueba de seguridad específica. Espero que este artículo  te haya sido útil para mejorar la seguridad de tus aplicaciones web.

S4lud0s y h4st4 el próx1m0 p0st!!!

 

 

 

Anuncios

2 comentarios en “Introducción a la solución de problemas de Web scraping con Bash

  1. Si, brindan unos cursos muy interesantes. Te recomiendo tener de la mano siempre una metodología reconocida como ISSAF, PTES. NIST SP 800-115 es muy buena a modo de introducción también. El conocimiento de estas te puede servir para sistematizar los conocimientos que puedes adquirir a través de Cybrary y otros blog de Internet.

    Los libros de Joel Scambray son excelentes. El pentesting web es un mundo aparte y para ello puedes apoyarte en la Guía de OWASP, en el blog he ido traduciendo y explicando varias pruebas de seguridad de la guía.

    Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s