Инструментарий и краткая методика для обнаружения субдоменов при проведении внешнего пентеста / анализа веб-приложений / конкурентной разведки.

banner.png

Amass

Amass — инструмент проекта OWASP, предназначенный для сбора информации об объекте при проведении внешней разведки. Включает в себя несколько модулей, однако для нас полезнее всего модуль enum, который позволяет использовать пассивные (опрос поисковиков и различных агрегаторов) и активные (трансфер зоны NS-серверов, брутфорс) техники для обнаружения субдоменов.

Установка

Amass написан на Golang, поэтому можно забрать готовый исполняемый файл из релизов и просто распаковать его у себя на машине:

$ wget https://github.com/OWASP/Amass/releases/download/v3.5.4/amass_v3.5.4_linux_amd64.zip -O ~/tools/amass.zip
$ cd ~/tools
$ unzip amass.zip && rm amass.zip && mv amass* amass
$ cd -
$ ln -s ~/tools/amass/amass /usr/local/bin/amass

Настройка

Как и recon-ng, Amass использует некоторые сервисы (Shodan, Censys, SecurityTrails, VirusTotal и др.), требущие для работы API-ключ, поэтому сперва нужно создать конфигурационный файл:

# Provide API key information for a data source

[Censys]
apikey = <REDACTED>
secret = <REDACTED>

[GitHub]
apikey = <REDACTED>

[SecurityTrails]
apikey = <REDACTED>

[Shodan]
apikey = <REDACTED>

[VirusTotal]
apikey = <REDACTED>

Полный образец конфига можно найти здесь. В нем очень много доступных настроек, однако все они могут быть заданы в виде аргументов командной строки, что является более гибким вариантом, поэтому в файле настроек я оставил только API-токены.

Использование

$ amass enum -v -df root-domains.txt -blf blacklisted-subdomains.txt -nf known-subdomains.txt -ipv4 -src -oA amass/out/subdomains.txt -config amass/config.ini -active -brute

Я остановился на использовании такого набора параметров. Вот, что они значат:

  • -v — более подробный вывод;
  • -df <STRING> — путь к текстовому файлу, содержащему список корневых доменов для анализа;
  • -blf <STRING> — путь к текстовому файлу, содержащему список субдоменов, которые следует исключить из скоупа анализа;
  • -nf <STRING> — путь к текстовому файлу, содержащему список субдоменов, о которых у пентестера уже есть информация (для них будет пропущен ряд процедур поиска);
  • -ipv4 — для каждого обнаруженного доменного имени показывать его IPv4-адрес;
  • -src — для каждого обнаруженного доменного имени показывать источник, откуда была получена эта информация;
  • -oA <STRING> — путь для сохранения результатов сканирования (форматы: txt, json);
  • -config <STRING> — путь к файлу конфигурации;
  • -active — использовать актиное сканирование (AXFR-запросы);
  • -brute — использовать брутфорс субдоменов.

Последние два флага использовать с осторожностью, т. к. это может привлечь дополнительное внимание.

Также для некоторых флагов есть аналоги, не требующие создание файлов для входных значений. Удобно, когда целей для сканирования не много:

$ amass enum -v -d hackerone.com -bl xyz.hackerone.com -ipv4 -src -oA amass/out/subdomains.txt -config amass/config.ini -active -brute

Пример

Для примера соберем информацию о субдоменах ресурса zonetranfer.me, уязвимого к трансферу зоны:

$ amass enum -v -d zonetransfer.me -ipv4 -src -o amass/out/subdomains.txt -config amass/config.ini -active -brute

amass-1.png

amass-2.png

Если запросить трансфер зоны напрямую с помощью dig, можно видеть, что Amass не обнаружил все записи NS-сервера nsztm1.digi.ninja, поэтому есть необходимость в дополнительной утилите для автоматизации zone transfer:

$ dig zonetransfer.me ns
$ dig axfr @nsztm1.digi.ninja zonetransfer.me

dig-ns.png

dig-axfr.png

Ссылки

Knockpy

Knockpy — инструмент, который отлично справляется с проверкой возможности выгрузки зон DNS и автоматически делает это, если ответ положителен. Также умеет брутить субдомены по словарю, что относит его к категории «активных» энумеров.

Установка

Knockpy написан на Python (требует v2.7.6), поэтому для установки нужно клонировать репозиторий и запустить setup.py:

$ git clone https://github.com/guelfoweb/knock ~/tools/knock
$ cd ~/tools/knock
$ sudo python -m pip install -r requirements.txt
$ sudo python setup.py install
$ cd -

Использование

Пользоваться просто, как три копейки: указываем целевой домен в позиционном аргументе, и, при желании, кастомный словарь для перебора через флаг -w (но мы этого делать не будем):

$ knockpy hackerone.com

Пример

Пробуем на примере того же самого zonetransfer.me, который разрешают легально сканировать и зонтрансферить:

$ knockpy zonetransfer.me

knockpy.png

После обнаружения трансфера зоны и ее выгрузки, предлагаю насильно остановить процесс через ^C, потому что брутить субдомены можно более эффективно (см. следующий параграф). Полученные записи нужно вручную добавить в текстовый файл с результатами.

MassDNS

Следующим шагом может стать валидация того факта, что все полученные субдомены живы и резолвятся. Для этого эффективно использовать MassDNS, ведь, по словам разработчика:

MassDNS is capable of resolving over 350,000 names per second using publicly available resolvers…

Установка

Проект написан на C, поэтому клонируем исходники и компилируем бинарник:

$ git clone https://github.com/blechschmidt/massdns ~/tools/massdns
$ cd ~/tools/massdns
$ make
$ cd -
$ ln -s ~/tools/massdns/bin/massdns /usr/local/bin/massdns

Использование

Чтобы просто резолвить все записи DNS из собранного списка, можно использовать комманду такого вида:

$ massdns -r ~/tools/massdns/lists/resolvers.txt -s 15000 -t A -o S -w massdns-a.txt subdomains.txt
  • -r <STRING> — путь к текстовому файлу, содержащему список резолверов;
  • -s <VALUE> — интенсивность сканирования, кол-во одновременных запросов;
  • -t <VALUE> — тип записи, который нужно спрашивать у DNS-сервера;
  • -o <VALUE> — формат вывода, S для простого текстового файла;
  • -w <STRING> — путь для сохранения результатов сканирования;
  • <STRING> — путь к текстовому файлу, содержащему список субдоменов для сканирования.

Брутить же субдомены можно так:

$ ~/tools/massdns/scripts/subbrute.py /usr/share/commonspeak2/subdomains/subdomains.txt hackerone.com |massdns -r ~/tools/massdns/lists/resolvers.txt -t A -o S -w results.txt

Хороший словарь есть в коллекции commonspeak2-wordlists:

$ git clone https://github.com/assetnote/commonspeak2-wordlists /usr/share/commonspeak2

Пример

$ massdns -r ~/tools/massdns/lists/resolvers.txt -s 15000 -t A -o S -w massdns-a.txt subdomains.txt

massdns-resolve.png

Altdns

При совсем жестком недостатке результатов, полученных на предыдущих этапах, можно подключить утилиту Altdns, которая генерирует на лету различные мутации субдоменов из предложенного словаря и опционально проверяет их существование.

Установка

Устанавливается через PyPI на вторую версию Python:

$ sudo python -m pip install py-altdns

Отдельно скачаем словарь для мутаций:

$ mkdir altdns
$ wget https://raw.githubusercontent.com/infosec-au/altdns/master/words.txt -O altdns/words.txt

Использование

$ altdns -i subdomains.txt -o data_output -w words.txt -r -s results_output.txt
  • -i <STRING> — путь к текстовому файлу, содержащему список известных существующих субдоменов (цели);
  • -o <STRING> — путь к текстовому файлу, в который сохранятся все мутации;
  • -w <STRING> — путь к текстовому файлу, содержащему список слов, на основе которых будут мутировать субдомены;
  • -r — осуществлять резолв по генерируемому списку;
  • -s <STRING> — путь к текстовому файлу для сохранения результатов.

Лучше не использовать флаг -r, а сгенерировать список мутировавших субдоменов и проверить их существование с помощью massdns.

Пример

$ altdns -i subdomains.txt -o subdomains-mutated.txt -w altdns/words.txt
$ massdns -r ~/tools/massdns/lists/resolvers.txt -s 15000 -t A -o S -w massdns-a-mutated.txt subdomains-mutated.txt

massdns-resolve-mutated.png

Следует иметь в виду, что некоторые резолверы из дефолтного списка massdns отдают устаревшую/некорректную информацию (видно на скриншоте), поэтому лучше всегда перепроверять информацию.

Список публично доступных (бесплатных) DNS-серверов для России можно найти на public-dns.info.

Дополнительные способы

Еще один очень известный брутер:

Асинхронный DNS-брутфорсер:

Как заОСИНТить DNS с AWS за $0.02:

Если речь идет о брутфорсе виртуальных хостов (aka Virtual Host Routing), то можно:

1. Фаззить заголовок Host и анализировать ответы сервера с помощью wfuzz:

$ wfuzz -H 'Host: FUZZ.example.local' -u 'http://example.local/' -w /usr/share/seclists/Discovery/DNS/shubs-subdomains.txt --hc 400 --hh 0

2. Использовать тулзу vhostbrute.

В Nmap NSE есть скрипт для брутфорса DNS:

$ nmap --script dns-brute --dns-servers ns.example.com example.com

Также домены можно брутить с помощью известного gobuster:

$ gobuster dns -d hackerone.com -i -w /usr/share/commonspeak2/subdomains/subdomains.txt

gobuster-dns.png

А еще использовать гугл дорки:

site:*.hackerone.com -www
site:*.*.hackerone.com
site:hackerone.com inurl:login,register,upload,logout,redirect,redir,goto,admin

И онлайн-сервисы:

Методика

В конечном итоге вырисовывается такая методика обнаружения субдоменов:

  1. Пассивное обнаружение:
  2. Активное обнаружение:
    • Knockpy (AXFR)
    • massdns (Brute)
    • [опц.] AltDNS + massdns (Permutate & Brute)
  3. Проверка резолва:
    • massdns (Resolve)

Ссылки