Enumeración de Subdominios a la Potencia 🧪

Los últimos 10 años he interactuado en mayor medida con proyectos tecnológicos que descansan sobre infraestructura cloud, y una de las prácticas estándar por parte de los equipos de desarrollo y arquitectura, es la utilización de subdominios como una fuente inagotable para la resolución de problemas, la integración con servicios de terceros, el despliegue de interfaces API, y un largo etcétera.

En este sentido, las empresas con buenas prácticas (léase, por favor, de la siguiente manera: “buenas prácticas” = “presupuesto”) pueden llegar a tener múltiples ambientes para un único proyecto, por ejemplo:

  • https://web-app.qa.target.com
  • https://web-app.dev.target.com
  • https://web-app.uat.target.com
  • https://web-app.prod.target.com

Y con el transcurso de los días, semanas o meses, siempre se suscitan requerimientos que bajan desde el área comercial y se transforman en un desafío técnico a resolver; finalmente, terminan por convertirse en un ambiente nuevo y adicional, aunque la mayoría de las veces, en uno o múltiples subdominios:

  • https://abcd.api.web-app.qa.target.com
  • https://abcd.api.web-app.dev.target.com
  • https://abcd.api.web-app.uat.target.com
  • https://abcd.api.web-app.prod.target.com

Para intentar resolver esta problemática, ideé un procedimiento de enumeración que llamo enumeración de subdominios a la potencia (en inglés sería algo como subdomain enumeration raised to the power), usando el concepto básico de potenciación: bn = ?

What the hack! 😂

Bug Bounty, Ethical Hacking & Pentesting

Esto representa un serio problema a la hora de tener buenos resultados cuando toca ejecutar actividades de reconocimiento y enumeración, porque estoy completamente seguro de que al menos el 95% de los pentester (me incluyo) no programa sus propias herramientas de kaking (al menos en Chile), y por consecuencia, se utilizan recursos que entregan resultados medianamente efectivos y, sin cuestionar los resultados, se utilizan como datos “fidedignos” a partir de los cuales se puede trabajar.

En el caso del bug bounty, se habla bastante acerca del proceso de automatización, en el cual, por supuesto, se incluye la enumeración de subdominios, pero, ¿cómo obtener buenos o mejores resultados en bug bounty cuando ya hay cientos o miles de cazadores de recompensas utilizando las mismas herramientas, procedimientos y programas?

Uso de potenciación como factor de alcance

Entonces, considerando los planteamientos anteriores, tenemos 2 premisas que pueden ser planteadas de la siguiente forma:

  1. Se escanea el recurso *.target.com con cualquier tipo de herramienta, y obtenemos N resultados, a partir de los cuales se realiza un ethical hacking
  2. Se escanea el recurso *.target.com con cualquier tipo de herramienta, y obtenemos N resultados que debemos someter a la conceptualización del uso de potencias para amplificar el alcance, y posteriormente, a partir de esos resultados, realizar un ethical hacking

Estas 2 premisas dependen del azar, ya que siempre obtendremos N resultados. Sin embargo, al aplicar la premisa N°2, tenemos mayores probabilidades de identificar una mayor cantidad de subdominios.

Y como se trata meramente del azar, porque no podemos aseverar el resultado ni la base de la potencia, finalmente podríamos decir que es una potencia común: bn = ?

Enumeración de subdominios a la potencia: *.target.com

Compartiré entonces los resultados de uno de mis experimentos, el cual fue realizado con ayuda de la herramienta Amass:

Paso N°1: enumeración inicial con el siguiente verbo:

amass enum -d target.com -o target.com_1.txt

Resultado: 135 subdominios (generalmente, con este resultado, se realizaría un ethical hacking)

Paso N°2: aplicar la primera potenciación usando split_by_dots.py

python3 split_by_dots.py -f target.com_1.txt -o target.com_2.txt

Resultado: 171 subdominios

Paso N°3: segunda enumeración, ahora, con subdominios a la potencia:

amass enum -df target.com_2.txt -o target.com_3.txt

Resultado: 746 subdominios

Paso N°4: segunda potenciación usando split_by_dots.py

python3 split_by_dots.py -f target.com_3.txt -o target.com_4.txt

Resultado: 1,117 subdominios

Paso N°5: tercera enumeración, nuevamente, con subdominios a la potencia:

amass enum -df target.com_4.txt -o target.com_5.txt

Resultado: 156 subdominios

Paso N°6: tercera potenciación usando split_by_dots.py

python3 split_by_dots.py -f target.com_5.txt -o target.com_6.txt

Resultado: 217 subdominios

Paso N°7: cuarta y última enumeración con subdominios a la potencia:

amass enum -df target.com_6.txt -o target.com_7.txt

Resultado: 329 subdominios

Paso N°8 y final: unificación de datos y eliminación de duplicados usando join_txt_files.py

python3 join_txt_files.py -d /home/ubuntu/target.com -o total_unique_subdomains.txt

Resultado: 1235 subdominios válidos y únicos para procesar

Explicación del resultado y procesamiento de los datos

  1. El repositorio con los scripts: https://github.com/JoshuaProvoste/subdomain-enumeration-raised-to-the-power
  2. El script split_by_dots.py recorre cada uno de los subdominios enumerados por Amass, y los convierte en nuevos subdominios a partir de una división basada en la cantidad de subdominios por cada host, posibilitando que en cada nueva enumeración de Amass se logren identificar subdominios adicionales
  3. El script join_txt_files.py unifica todos los subdominios del proceso, eliminando duplicados, para generar finalmente una lista de subdominios únicos y válidos
  4. Estos 1235 subdominios pueden ser procesados de múltiples maneras, al punto de que podrían duplicarse para ser procesados por herramientas como httpx (https://github.com/projectdiscovery/httpx)
  5. Bajo un contexto convencional, se habría realizado un ethical hacking con 135 subdominios, y no con 1235
  6. Este procedimiento de enumeración de subdominios a la potencia puede realizarse con cualquier herramienta definida para este fin, el uso de Amass es sólo a modo de ejemplo
  7. Para esta publicación utilicé sólo 1 de los experimentos que he realizado, y el más fácil de todos, ya que en días anteriores logré enumerar más de 100,000 subdominios en un programa privado de bug bounty en la plataforma Bugcrowd

Uso de permutaciones

Me compartieron una herramienta que genera wordlists basadas en combinación y permutaciones; se genera un diccionario de hipotéticos subdominios, y a partir de ese diccionario, realizar un procedimiento para verificar si esos subdominios existen realmente o no:

En cambio, en el procedimiento de enumeración de subdominios a la potencia, no genero un wordlist de posibles subdominios para luego validar si existen, al contrario: realizo un proceso de enumeración (1), divido en partes los subdominios ya enumerados (2), y vuelvo a realizar el proceso de enumeración de subdominios a partir de los subdominios divididos (3), es decir, aplicando el concepto de potencia (bn = ?).

Si bien es cierto en cada paso con split_by_dots.py se genera una lista de subdominios, no es una lista de permutaciones basadas en combinación de datos, sino que una división de los subdominios que la herramienta Amass ya enumeró y validó como asset.