stihl не предоставил(а) никакой дополнительной информации.
Активную разведку проводят при пентесте, чтобы узнать максимум информации о цели. При этом допускается, что действия могут быть замечены — например, занесены в логи. На этом этапе мы соберем информацию о URL и эндпоинтах сервисов заказчика, определим используемые технологии — в общем, вытащим все, что поможет нам в продвижении.
Эта статья продолжает цикл, посвященный созданию идеального рабочего процесса. Эти статьи призваны помочь исследователям и техническим специалистам разобраться в последовательности действий, анализе результатов и выборе инструментов.
Дальше будем считать, что пассивную разведку мы уже завершили и у нас есть определенная информация о цели. Процесс я подробно описывал в прошлой статье, так что при дальнейшем обсуждении будем исходить из того, что у нас уже есть некоторые наработки.
Давай подумаем о предстоящих целях. На этом этапе наша задача сводится к следующему:
Пример команды:
Основные статус‑коды (на случай, если кто‑то позабыл):
Команда для разделения большого списка URL на части:
Пример команды для поэтапного запуска:
Команда для объединения нескольких файлов в один файл:
Или оставь только самые важные статус‑коды, например 200, 301, 302, 500, 502 и 503. Ответы на коды 401 и 403 можно будет потом собрать отдельно.
Но сначала подготовим список для сканирования:
Почему мы объединяем домены и IP? Это помогает обеспечить максимальное покрытие при анализе сканерами. Например, сканер может не обнаружить уязвимость по адресу Для просмотра ссылки Войдиили Зарегистрируйся, но найдет ее на Для просмотра ссылки Войди или Зарегистрируйся. Или, если доступ к веб‑сервису через IP заблокирован, мы сможем просканировать его по домену. От нас никто не уйдет!
Если скоуп большой, можем разбить задачу на части и сканировать в многопоточном режиме:
Команда для запуска Naabu на отдельных частях списка IP-адресов:
Сохрани всё в файл open_ports.txt:
Прежде чем двигаться дальше, разделим текущий список на два отдельных. Это позволит нам эффективно искать виртуальные хосты — как через привязку IP к доменам, так и с помощью брутфорса доменов для конкретного IP-адреса.
Команда для создания списка в формате ip
ort:
Команда для формирования списка в формате domain
ort:
Чтобы решить эту проблему, можно использовать на этом этапе httprobe, а затем повторить те же шаги.
Удаляем префиксы http:// и https://:
Составляем список доменов:
Составляем список с IP-адресами:
Осталось собрать список поддоменов, которые не резолвятся.
Пример команды:
Возникает вопрос: зачем нам два файла, а не один? Все просто: файл со статус‑кодами 401 и 403 мы потом дополним и будем пробовать байпасы.
Итак, списки для байпаса у нас есть, теперь подготовим список для брутфорса.
Ты, возможно, запутался, и это нормально — процесс не из легких. Давай посмотрим, что у нас получилось:
Httprobe (веб) — утилита создана нашим любимым tomnomnom, работает неплохо, но не настолько богата возможностями, как httpx.
Команда для установки:
go install github.com/tomnomnom/httprobe@master
Пример команды для запуска:
Также существует Для просмотра ссылки Войдиили Зарегистрируйся, написанный на Python. Его я не тестировал.
Кратко напомню разницу между поддоменом и виртуальным хостом.
Брутим список веб‑приложений по IP-адресам, используя в качестве словаря неразрешенные поддомены.
Важно заметить, что по‑хорошему нам следовало бы добавить сюда весь список доменов, а не только те, что не резолвились. Это позволило бы нам обнаружить IP-адреса с виртуальными хостами. Однако на практике без автоматизации ты устанешь просматривать результаты вручную. Поэтому я рекомендую сосредоточиться только на нерезолвящихся доменных именах из заранее подготовленного файла not_resolv_subdomain.txt.
Не забудь потом отредактировать системный файл hosts!
Брутфорсим список веб‑приложений по доменам, используя в качестве словаря список поддоменов из SecLists.
или Зарегистрируйся и Для просмотра ссылки Войди или Зарегистрируйся.
Ниже — примеры команд для запуска.
Поиск статуса 200:
Поиск статусов 401 и 403:
Брутфорс разными методами:
Теперь соберем результаты в один файл. Для этого выбираем только те URL, в которых найдены директории, и сохраняем их в файл с результатами брутфорса директорий.
или Зарегистрируйся.
К этой команде можно добавить статус‑бар, чтобы отслеживать прогресс.
Как вариант можно попробовать утилиту Для просмотра ссылки Войдиили Зарегистрируйся. Я лично с ней не работаю, но не исключаю, что она тебе понравится. На вход можно подать файл с веб‑сервисами web_services.txt.
Это делается, чтобы найти в ответах что‑то интересное.
Теперь поищем новые адреса в ответах из fff_res, которые относятся к нашему скоупу и пока отсутствуют в файле url_list.
Важно: команда inscope не видит домены, которые могут передаваться внутри длинной ссылки на другой домен.
Как вариант можно использовать небольшой самописный скрипт. Однако это дополнительная мера, и я бы все равно рекомендовал ориентироваться на первый вариант. В конце концов, можно просто бегло просмотреть список.
Не забудь добавить найденные URL к существующему списку.
или Зарегистрируйся — это отличная утилита (все того же tomnomnom), которая позволяет находить в сохраненных ответах веб‑сервера разные интересные данные. Очень рекомендую попробовать!
Можно, конечно, использовать и простой grep. Ниже представлены некоторые команды, но это далеко не полный список.
Много интересного можно найти в репозиториях на GitHub, например:
Поиск ключей и секретов AWS:
Поиск URL-адресов S3:
Поиск глобальных переменных PHP:
Поиск HTML input с типом file:
Поиск LFI/RFI:
Поиск заголовков HTTP:
Поиск опасных функций PHP:
Поиск популярных фреймворков и сервисов:
Поиск доменов Firebase:
Поиск ключей API и секретов в строках:
Поиск сообщений об ошибках:
Поиск сообщений об ошибках конфигурации и отсутствующих ресурсах:
Поиск ключей AWS:
Поиск сериализованных данных PHP:
Поиск заголовков сервера:
Поиск email-адресов:
Поиск заголовков CORS:
Поиск URL-адресов:
Поиск закодированных данных:
Поиск ошибок PHP:
Поиск строк в кавычках:
Поиск IP-адресов:
Поиск настроек cURL:
Поиск функций Go:
Поиск конфиденциальной информации:
Сбор уникальных UUID:
или Зарегистрируйся в своем Telegram-канале метод, с помощью которого все же можно автоматизировать это, хоть и не без костылей. Я изучил этот метод и немного адаптировал под свои нужды.
Вот простая команда для запуска Katana, которая фильтрует все методы, кроме GET, и передает их для сканирования dast-шаблонами в Nuclei:
Пример работы
Пример содержимого файла katana_non_get.txt
Результаты Nuclei можно при желании экспортировать в Burp, чтобы сразу проверить, нет ли ложных срабатываний, или уже потом прицельно запускать конкретные проверки.
Для просмотра ссылки Войдиили Зарегистрируйся
Для работы тебе понадобится небольшой Python-скрипт, который любезно предоставил Для просмотра ссылки Войдиили Зарегистрируйся.
Если скоуп большой и у тебя нет времени прокликать все по отдельности, можно просто собрать список JS-файлов в терминале. Используй для этого простую команду:
Если мы работаем с каким‑то веб‑приложением, то удобно собрать JavaScript прямо со страницы в браузере. Для этого можно использовать команду в консоли браузера:
или Зарегистрируйся. Однако наилучшим вариантом для нас будет Для просмотра ссылки Войди или Зарегистрируйся или httpx. Они менее информативны, но вполне подойдут для создания общей картины. Кроме того, не забывай обрабатывать и изучать результаты из Censys.
Пример запуска WhatWeb:
Пример запуска httpx:
У Wappalyzer есть и консольная версия — Для просмотра ссылки Войдиили Зарегистрируйся, аналог браузерного расширения Wappalyzer. На большом скоупе она мне кажется менее удобной из‑за меньшей читаемости вывода, чем упомянутые выше инструменты. Но знать о ней стоит, она особенно хорошо подходит для точечных проверок.
Для просмотра ссылки Войдиили ЗарегистрируйсяДля просмотра ссылки Войди или Зарегистрируйся
Эта утилита использует библиотеку Wappalyzer, которая включает в себя набор правил и шаблонов (фингерпринтов) для распознавания различных веб‑технологий. В общем, все то же самое, что и в аналогичном браузерном расширении, но доступно из командной строки.
Скажем, можно найти включенный режим отладки в Symphony:
Или, может, проверим, есть ли в скоупе GraphQL?
Ты, наверное, уже понял, что это просто примеры, и каждый может дополнить этот список своими интересными находками. К примеру, сюда можно добавить потенциально интересные файлы — с расширениями xml, json, txt и прочими. В общем, все, что пожелаешь!
или Зарегистрируйся и Для просмотра ссылки Войди или Зарегистрируйся. Также есть популярное расширение для Burp — Param Miner. Среди параметров, которые могут встретиться, можно выделить Debug, RoleId или returnUrl. Они могут привести к включению дебаг‑режима, изменению роли или, например, к Open Redirect.
В этом разделе я кратко расскажу про Arjun. Более подробно ты можешь ознакомиться с ним в документации, но обычно я запускаю его такой командой:
Еще есть флаг -i targets.txt, с помощью которого можно загрузить список целей. Однако помни, что просканировать все подряд вряд ли получится из‑за ограниченного времени. Так что эту возможность стоит применять скорее нацеленно, чем массово.
Если внимательно изучить документацию, то можно узнать, что Arjun умеет пассивно собирать имена параметров...
Тема с API довольно серьезная, и тут может найтись множество уязвимостей, поэтому я остановлюсь на ней чуть подробнее.
Выше мы рассмотрели команду для поиска Swagger в заранее собранном списке адресов. Окей, допустим, мы его нашли. Что делать дальше?
Теперь запускаем вот этот скрипт в консоли браузера.
Он покажет список эндпоинтов и методов.
Для просмотра ссылки Войдиили Зарегистрируйся
Запусти Python-скрипт, предварительно скопировав из браузера данные, которые поместишь в строку endpoints. Затем замени baseURL, указав только доменное имя.
Вот такой результат получится, и с ним можно работать дальше.
Для просмотра ссылки Войдиили Зарегистрируйся
Что делать, если Swagger не нашелся? Даже если его не видно, не беда — собрать его можно самостоятельно с помощью крутой утилиты Для просмотра ссылки Войдиили Зарегистрируйся. Подробности по установке и использованию есть на GitHub, включая видео с демонстрацией работы. Если ты тестируешь одно веб‑приложение, ручное нажатие на все кнопки и поля — это путь к качественному результату. Если же скоуп большой и приложение не одно, просто пропусти найденные URL через прокси. Дальше запускай процесс, как описано выше.
Вообще, тестирование API заслуживает отдельной статьи. Существует масса отличных инструментов, таких как Для просмотра ссылки Войдиили Зарегистрируйся и Для просмотра ссылки Войди или Зарегистрируйся, которые стоило бы рассмотреть. Но мы здесь целимся в универсальный воркфлоу, так что об этом, возможно, поговорим в другой раз.
или Зарегистрируйся. В отличие от аналогов, он делает скриншоты в хорошем качестве, предоставляет более полную сопутствующую информацию и хранит результаты в базе данных SQLite, что полезно для автоматизации.
Готовим окружение:
Скриншотить лучше всего не по списку с доменами, а по списку с открытыми портами. Это довольно очевидно, но в пылу азарта можно и не заметить, что делаешь что‑то не то.
Смотрим результаты:
Также мы поискали виртуальные хосты, собрали структуру веб‑приложений в проекте Burp, сформировали списки с JS-файлами, URL-адресами, в том числе с параметрами, и отсортировали интересные URL по ключевым словам.
Под конец мы проанализировали используемые технологии и сделали скриншоты. Теперь у нас есть ценная информация, которая позволит лучше понять специфику нашей цели. Это поможет на следующем этапе — активном сканировании на наличие известных и новых уязвимостей.
Эта статья продолжает цикл, посвященный созданию идеального рабочего процесса. Эти статьи призваны помочь исследователям и техническим специалистам разобраться в последовательности действий, анализе результатов и выборе инструментов.
Дальше будем считать, что пассивную разведку мы уже завершили и у нас есть определенная информация о цели. Процесс я подробно описывал в прошлой статье, так что при дальнейшем обсуждении будем исходить из того, что у нас уже есть некоторые наработки.
Давай подумаем о предстоящих целях. На этом этапе наша задача сводится к следующему:
- отфильтровать собранные в пассивном режиме URL-адреса;
- собрать информацию об открытых портах;
- найти виртуальные хосты;
- сделать скриншоты веб‑сервисов;
- дополнить список URL-адресов с помощью брутфорса директорий и поиска интересных эндпоинтов;
- сохранить ответы на запросы по собранным URL и найти в них важную информацию;
- построить список URL-адресов с параметрами;
- собрать список файлов JavaScript;
- построить карту веб‑приложений и сервисов в Burp.
Фильтруем URL по статус-кодам
Итак, будем считать, что у нас уже есть огромный список уникальных URL и доменов, собранных пассивно. Чтобы эффективно с ними работать, нужно отсортировать их по статус‑кодам. Этот шаг я включил в этап Enum, потому что тут мы уже активно взаимодействуем с целевой инфраструктурой и это уже не относится к пассивным методам.Пример команды:
cat uniq_passive_urls | httpx -mc 200,201,202,204,206,301,302,401,403,404,405,500,502,503 -o live_passive_url
Основные статус‑коды (на случай, если кто‑то позабыл):
- 200 OK — страница доступна;
- 201 Created — ресурс успешно создан сервером (например, при загрузке файлов или тестировании API);
- 202 Accepted — запрос принят, но пока обрабатывается асинхронно;
- 203 Non-Authoritative Information — сервер отдает модифицированный кешированный контент;
- 204 No Content — запрос выполнен успешно, но в ответе нет содержимого;
- 205 Reset Content — клиенту нужно сбросить представление, например очистить форму;
- 206 Partial Content — сервер предоставляет часть файла по Range;
- 301 Moved Permanently / 302 Found — сигнализируют о возможных редиректах;
- 401 Unauthorized — требуется авторизация;
- 403 Forbidden — доступ запрещен, хотя ресурс существует (полезно для обхода ACL);
- 404 Not Found — ресурс не найден, но иногда через обход можно обнаружить что‑то интересное;
- 405 Method Not Allowed — может свидетельствовать о наличии нестандартных методов (например, PUT, DELETE);
- 500 Internal Server Error — указывает на баг в обработке запроса;
- 502 Bad Gateway / 503 Service Unavailable — проблемы на серверной стороне, иногда в тексте ошибки содержится что‑то интересное.
Команда для разделения большого списка URL на части:
split -l 5000 ../uniq_passive_urls target_part_
Пример команды для поэтапного запуска:
( trap 'pkill -P $$' SIGINT; for file in target_part_*; do httpx -list "$file" -mc 200,201,202,204,206,301,302,401,403,404,405,500,502,503 -o "httpx-optimized_${file}.txt" & done; wait )
Команда для объединения нескольких файлов в один файл:
cat httpx-optimized_* | anew live_passive_url
Или оставь только самые важные статус‑коды, например 200, 301, 302, 500, 502 и 503. Ответы на коды 401 и 403 можно будет потом собрать отдельно.
Сканируем порты
Утилита Naabu, думаю, всем знакома (если нет, у нее отличная документация). Здесь я покажу, как запустить сканирование в активном режиме.Но сначала подготовим список для сканирования:
cat live_subdomains.txt ip_list_resolved | anew for_port_scan
Почему мы объединяем домены и IP? Это помогает обеспечить максимальное покрытие при анализе сканерами. Например, сканер может не обнаружить уязвимость по адресу Для просмотра ссылки Войди
naabu -list for_port_scan -verify -ec -retries 1 -p 0-65535 -warm-up-time 0 -c 50 -nmap-cli "nmap -sV -oA nmap-out" -o open_ports.txt
Если скоуп большой, можем разбить задачу на части и сканировать в многопоточном режиме:
split -l 500 ../for_port_scan target_part_
Команда для запуска Naabu на отдельных частях списка IP-адресов:
( trap 'pkill -P $$' SIGINT; for file in target_part_*; do naabu -silent -list "$file" -verify -ec -retries 1 -p 0-65535 -warm-up-time 0 -c 50 -rate 500 -nmap-cli "nmap -sV -sC -oA nmap-out_${file}" -o "naabu-optimized_${file}.txt" & done; wait )
Сохрани всё в файл open_ports.txt:
cat optimized_* | anew open_ports.txt
info
Если сканируемый скоуп велик, лучше сначала запустить Naabu и передать Nmap файл со списком портов open_ports.txt, чем пользоваться командами из примеров выше.Формируем список веб-сервисов
Берем список из файла open_ports.txt и передаем его утилите httpx. На выходе получаем файл web_services.txt с веб‑сервисами на разных портах.cat open_ports.txt | httpx -o web_app.txt
Прежде чем двигаться дальше, разделим текущий список на два отдельных. Это позволит нам эффективно искать виртуальные хосты — как через привязку IP к доменам, так и с помощью брутфорса доменов для конкретного IP-адреса.
Команда для создания списка в формате ip
grep -E '^https?://([0-9]{1,3}\.){3}[0-9]{1,3}:)[0-9]+)?$' web_app.txt > web_app_ip.txt
Команда для формирования списка в формате domain
grep -Ev '^https?://([0-9]{1,3}\.){3}[0-9]{1,3}:)[0-9]+)?$' web_app.txt > web_app_domain.txt
Важный нюанс
Утилита httpx заменяет порты 80 и 443 префиксами http:// и https:// соответственно, оставляя нестандартные порты, такие как 8083, без изменений.Чтобы решить эту проблему, можно использовать на этом этапе httprobe, а затем повторить те же шаги.
Удаляем префиксы http:// и https://:
sed 's|https\?://||' web_app.txt > web_app2
Составляем список доменов:
grep -Ev '^([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+$' web_app2 > web_app_domain.txt
Составляем список с IP-адресами:
grep -E '^([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+$' web_app2 > web_app_ip.txt
Обрабатываем список доменов
После этапа пассивной разведки у нас уже есть неплохой список собранных поддоменов, и теперь пора его обработать. Вот что мы собираемся сделать:- собрать список невалидных адресов (понадобится для поиска виртуальных хостов);
- собрать список адресов, возвращающих коды состояния 401 и 403;
- собрать список адресов, возвращающих 404.
Осталось собрать список поддоменов, которые не резолвятся.
Пример команды:
comm -23 <(sort subdomains | uniq) <(sort live_subdomains.txt | uniq) > not_resolv_subdomain.txt
Коды 401, 403 и 404
Теперь, имея на руках два списка поддоменов, нужно собрать из них те, которые резолвятся через публичные списки поддоменов и имеют статусы 401, 403 и 404. Это делается для последующего брутфорса и поиска способов обхода авторизации. Команда ниже сохранит в два файла нужные адреса со статус‑кодами 401, 403 и 404 для брута.cat live_subdomain.txt | httpx -mc 401,403 -o 401_403.txt
cat live_subdomain.txt | httpx -mc 404 -o 404.txt
Возникает вопрос: зачем нам два файла, а не один? Все просто: файл со статус‑кодами 401 и 403 мы потом дополним и будем пробовать байпасы.
Итак, списки для байпаса у нас есть, теперь подготовим список для брутфорса.
cat 401_403.txt 404.txt | anew for_brute_dir.txt
Ты, возможно, запутался, и это нормально — процесс не из легких. Давай посмотрим, что у нас получилось:
- resolv_subdomain.txt;
- not_resolv_subdomain.txt;
- responses_401_403.txt;
- responses_404.txt.
Альтернативы httpx
Если httpx вдруг чем‑то тебя не устраивает или ты сомневаешься в корректности его результатов (такое за ним уже замечали), то существуют альтернативы, которые можно использовать. Давай кратко рассмотрим доступные варианты.Httprobe (веб) — утилита создана нашим любимым tomnomnom, работает неплохо, но не настолько богата возможностями, как httpx.
Команда для установки:
go install github.com/tomnomnom/httprobe@master
Пример команды для запуска:
cat subdomains_list | httprobe -c 80 --prefer-https | sort | anew host_alive
Также существует Для просмотра ссылки Войди
Поиск виртуальных хостов
Поиск виртуальных хостов — слабо документированная тема, и я пока не встречал полных гайдов и инструкций по их обнаружению. В этом разделе поделюсь своим подходом к поиску в рамках нашего воркфлоу. Но помни, это направление требует дальнейших исследований и практических тестов.Кратко напомню разницу между поддоменом и виртуальным хостом.
- Поддомены имеют собственные DNS-записи и могут быть публично разрешены.
- Виртуальные хосты — настройка веб‑сервера; доступ к ним организуется через указание конкретного IP и передачу нужного заголовка Host или через запись в файле /etc/hosts.
Брутим список веб‑приложений по IP-адресам, используя в качестве словаря неразрешенные поддомены.
Важно заметить, что по‑хорошему нам следовало бы добавить сюда весь список доменов, а не только те, что не резолвились. Это позволило бы нам обнаружить IP-адреса с виртуальными хостами. Однако на практике без автоматизации ты устанешь просматривать результаты вручную. Поэтому я рекомендую сосредоточиться только на нерезолвящихся доменных именах из заранее подготовленного файла not_resolv_subdomain.txt.
Код:
cat web_app_ip.txt | while IFS=":" read -r ip port; do ffuf -noninteractive -s -t 50 -rate 100 -p 0.2 -w not_resolv_subdomain.txt -ac -mc all -u "http://$ip:$port/" -H "Host: FUZZ" -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" -o "vhost_brute_${ip}_${port}.txt" done
Брутфорсим список веб‑приложений по доменам, используя в качестве словаря список поддоменов из SecLists.
Код:
cat web_app_domain.txt | while IFS=":" read -r domain port; do ffuf -noninteractive -s -t 50 -rate 100 -p 0.2 -w /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -ac -mc all -u "http://$domain:$port/" -H "Host: FUZZ.$domain" -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36" -o "vhost_brute_${domain}_${port}.txt" done
Работа со списками URL
Брут директорий
Не стоит брутить все подряд — это неэффективно при огромном объеме задач. Логичнее будет пробрутить те домены, которые возвращают коды состояния 401, 403 и 404. Часто таким способом удается выявить ошибки в настройках системы доступа. Например, доступ к корню / закрыт, а вот во вложенные директории можно попасть. Подобным образом я обнаружил доступ к Kibana на одном из сайтов правительства Республики Чехия.www
Готовые словари для перебора поддоменов можно скачать с GitHub. Например, Для просмотра ссылки ВойдиНиже — примеры команд для запуска.
Поиск статуса 200:
Код:
(trap 'kill 0' SIGINT; while IFS= read -r url; do target_name=$(echo $url | sed "s/[^a-zA-Z0-9]/_/g"); echo "Starting feroxbuster for $url"; ~/feroxbuster -k -r -e -u "$url" -w /path_to_wordlist --random-agent -s 200 -d 1 --rate-limit 50 --scan-limit 1 -o "result_brute_dir/${target_name}.txt"; done < brute.txt)
Код:
(trap 'kill 0' SIGINT; while IFS= read -r url; do target_name=$(echo $url | sed "s/[^a-zA-Z0-9]/_/g"); echo "Starting feroxbuster for $url"; ~/feroxbuster -k -r -e -u "$url" -w /path_to_wordlist --random-agent -s 401,403 -d 1 --rate-limit 50 --scan-limit 1 -o "result_brute_dir/${target_name}.txt"; done < brute.txt)
Код:
while read -r line; do ffuf -u "${line}/PATH" -X METHOD -w ~/path_to_wordlistATH -w ~/Documents/wordlist/http_methods:METHOD -mc 200 -o "results_$(echo ${line} | tr '/:' '__').json" -of json; done <404.txt
grep -oriahE "https?://[^"\'> ]+/[^"\'> ]+" * | anew ../brute_res
Поиск эндпоинтов
Katana — один из лучших инструментов для краулинга. Чтобы не перегружать статью, я не буду подробно описывать значения каждого параметра — ты можешь изучить их самостоятельно в Для просмотра ссылки Войдиcat web_app.txt | while read string; do katana -u "$string" -d 10 -jc -jsl -f url -kf all -silent -ct 500 -rl 20 | anew urls_active_katana; done
К этой команде можно добавить статус‑бар, чтобы отслеживать прогресс.
Как вариант можно попробовать утилиту Для просмотра ссылки Войди
Сохраняем ответы по URL-адресам
Не забудь собрать все найденные и отсортированные URL в один файл!cat urls_active_katana brute_res live_passive_url | anew live_url
Это делается, чтобы найти в ответах что‑то интересное.
cat live_url | fff -d 5 -S -o fff_res
warning
Не удаляй уже обработанные файлы! Просто перемещай их в отдельную папку.Теперь поищем новые адреса в ответах из fff_res, которые относятся к нашему скоупу и пока отсутствуют в файле url_list.
grep -oriahE "https?://[^"\'> ]+" fff_res | inscope | sort | uniq | comm -23 - <(sort url_list) | anew url_fff
Важно: команда inscope не видит домены, которые могут передаваться внутри длинной ссылки на другой домен.
Как вариант можно использовать небольшой самописный скрипт. Однако это дополнительная мера, и я бы все равно рекомендовал ориентироваться на первый вариант. В конце концов, можно просто бегло просмотреть список.
Код:
# Извлекаем все URL из fff_res
grep -oriahE "https?://[^"\'> ]+" fff_res | {
# Читаем URL построчно
while read -r url; do
# Проверяем, проходит ли URL через inscope
if echo "$url" | inscope; then
echo "$url"
else
# Проверяем, содержит ли URL любой домен из scope.txt
while read -r domain; do
if echo "$url" | grep -qF "$domain"; then
echo "$url"
break
fi
# Укажи файл со списком доменов
done < scope.txt
fi
done
} | sort | uniq | comm -23 - <(sort url_list) | anew url_fff
Не забудь добавить найденные URL к существующему списку.
cat url_fff | anew live_url
Анализируем список URL
Для просмотра ссылки ВойдиМожно, конечно, использовать и простой grep. Ниже представлены некоторые команды, но это далеко не полный список.
Много интересного можно найти в репозиториях на GitHub, например:
- Для просмотра ссылки Войди
или Зарегистрируйся (emadshanab); - Для просмотра ссылки Войди
или Зарегистрируйся (NitinYadav00); - Для просмотра ссылки Войди
или Зарегистрируйся (Rix4uni); - Для просмотра ссылки Войди
или Зарегистрируйся (Dwisiswant0); - Для просмотра ссылки Войди
или Зарегистрируйся (1ndianl33t).
Поиск ключей и секретов AWS:
grep -HanriE "(aws_access|aws_secret|api[[I]-]?key|ListBucketResult|S3_ACCESS_KEY|Authorization:|RSA PRIVATE|Index of|aws[/I]|secret|ssh-rsa AA)" <файл>
Поиск URL-адресов S3:
grep -hrioaE "[a-z0-9.-]+\\.s3\\.amazonaws\\.com|[a-z0-9.-]+\\.s3-[a-z0-9-]+\\.amazonaws\\.com|[a-z0-9.-]+\\.s3-website.-|//s3\\.amazonaws\\.com/[a-z0-9.[I]-]+|//s3-[a-z0-9-]+\\.amazonaws\\.com/[a-z0-9.[/I]-]+" <файл>
Поиск глобальных переменных PHP:
grep -HnrE "\\$_(POST|GET|COOKIE|REQUEST|SERVER|FILES)|php://(input|stdin)" <файл>
Поиск HTML input с типом file:
grep -HnriE "<input[^\>]+type=["']?file["']?" <файл>
Поиск LFI/RFI:
grep -HnriE "include\s*\(\s*\$[I](GET|POST|REQUEST|COOKIE|SERVER|FILES)\[.[I]\]\s[/I]\)|require\s*\(\s*\$[/I](GET|POST|REQUEST|COOKIE|SERVER|FILES)\[.[I]\]\s[/I]\)" .
Поиск заголовков HTTP:
grep -hroiE "^< [a-z0-9_\\-]+: .*" <файл>
Поиск опасных функций PHP:
grep -HnriE "^a-z0-9_ ?\\(" <файл>
Поиск популярных фреймворков и сервисов:
grep -HnriE "django|laravel|symfony|graphite|grafana|X-Drupal-Cache|struts|code ?igniter|cake ?php|grails|elastic ?search|kibana|log ?stash|tomcat|jenkins|hudson|com.atlassian.jira|Apache Subversion|Chef Server|RabbitMQ Management|Mongo|Travis CI - Enterprise|BMC Remedy|artifactory" <файл>
Поиск доменов Firebase:
grep -Hnri "firebaseio.com" <файл>
Поиск ключей API и секретов в строках:
grep -harioE "(\\?"|"|%22)[a-z0-9_-][I](api[[I]-]?key|S3|aws[/I]|secret|passw|auth)[a-z0-9_-][/I](\\?"|"|%22): ?(\\?"|"|%22)[^"&]+(\\?"|"|%22)" <файл>
Поиск сообщений об ошибках:
grep -HnraiE '(Application-Trace|Routing Error|DEBUG"? ?[=:] ?True|Caused by:|stack trace:|Microsoft .NET Framework|Traceback|[0-9]:in`|#!/us|WebApplicationException|java\.lang\.|phpinfo|swaggerUi|on line [0-9]|SQLSTATE)' .
Поиск сообщений об ошибках конфигурации и отсутствующих ресурсах:
Код:
grep -HnriE "There is no app configured at that hostname|NoSuchBucket|No Such Account|You're Almost There|a GitHub Pages site here|There's nothing here|project not found|Your CNAME settings|InvalidBucketName|PermanentRedirect|The specified bucket does not exist|Repository not found|Sorry, We Couldn't Find That Page|The feed has not been found.|The thing you were looking for is no longer here, or never was|Please renew your subscription|There isn't a Github Pages site here.|We could not find what you're looking for.|No settings were found for this company:|No such app|is not a registered InCloud YouTrack|Unrecognized domain|project not found|This UserVoice subdomain is currently available!|Do you want to register|Help Center Closed" <файл>
Поиск ключей AWS:
grep -HanrE "([^A-Z0-9]|^)(AKIA|A3T|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{12,}" <файл>
Поиск сериализованных данных PHP:
grep -HnrE "a:[0-9]+:{|O:[0-9]+:"|s:[0-9]+:"" <файл>
Поиск заголовков сервера:
grep -hri "server: " <файл>
Поиск email-адресов:
grep -hrioaE "[a-z0-9_/\\.:-]+@[a-z0-9-]+\\.[a-z0-9.-]+" <файл>
Поиск заголовков CORS:
grep -HnriE "Access-Control-Allow" <файл>
Поиск URL-адресов:
grep -oriahE "https?://[^"\'> ]+" <файл>
Поиск закодированных данных:
grep -HnroE "([^A-Za-z0-9+/]|^)(eyJ|YTo|Tzo|PD[89]|aHR0cHM6L|aHR0cDo|rO0)[%a-zA-Z0-9+/]+={0,2}" <файл>
Поиск ошибок PHP:
grep -HnriE "php warning | php error | fatal error | uncaught exception | include_path | undefined index | undefined variable | \\?php | <\\?[^x]|stack trace\\: | expects parameter [0-9]* | Debug Trace" <файл>
Поиск строк в кавычках:
grep -hroiaE ""[^"]+"|'[^']+'" <файл>
Поиск IP-адресов:
grep -HnroE "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])" <файл>
Поиск настроек cURL:
grep -HnrE "CURLOPT_(HTTPHEADER|HEADER|COOKIE|RANGE|REFERER|USERAGENT|PROXYHEADER)" <файл>
Поиск функций Go:
grep -HnriE "func [a-z0-9_]+\\(" <файл>
Поиск конфиденциальной информации:
grep -Eo 'https?://[^ ]+\.(env|yaml|yml|json|xml|log|sql|ini|bak|conf|config|db|dbf|tar|gz|backup|swp|old|key|pem|crt|pfx|pdf|xlsx|xls|ppt|pptx)' <файл>
Сбор уникальных UUID:
grep -Eo '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}' <файл> | sort -u | anew UUID.txt
URL с параметрами
Теперь нужно отфильтровать из собранных пассивно URL-адресов только те, которые содержат параметры, и записать эти URL в файл. Для этого используй командуgrep '\?' url_list | anew param_urls
POST-запросы
Любая автоматизация, будь то пайплайны или самописные скрипты, с которыми я сталкивался, всегда касалась только GET-методов. Я нигде не видел способов автоматизировать проверку параметров в POST-запросах, что, на мой взгляд, огромное упущение для комьюнити. Ведь в POST-запросах уязвимостей не меньше, чем в GET. Мой коллега недавно Для просмотра ссылки ВойдиВот простая команда для запуска Katana, которая фильтрует все методы, кроме GET, и передает их для сканирования dast-шаблонами в Nuclei:
Код:
katana -silent -u http://testphp.vulnweb.com -fs fqdn -js-crawl -jsluice -jsonl -or -ob -automatic-form-fill | jq -r '.request.method,.request.endpoint,.request.body' | paste - - - | tee katana_non_get.txt | while read method url body; do
if [[ "$method" == "GET" ]]; then continue; fi
nuclei -silent -im openapi -l <(./to_openapi.py "$method" "$url" "$body") -dast -t /templates/ -proxy http://127.0.0.1:8080 -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0"
done | tee nuclei_vulns_non_get.txt


Результаты Nuclei можно при желании экспортировать в Burp, чтобы сразу проверить, нет ли ложных срабатываний, или уже потом прицельно запускать конкретные проверки.
Для просмотра ссылки Войди
Для работы тебе понадобится небольшой Python-скрипт, который любезно предоставил Для просмотра ссылки Войди
Код:
#!/usr/bin/python3
from urllib.parse import urlparse, parse_qs, unquote
import json
from sys import argv
method = argv[1]
url = argv[2]
body = argv[3]
url = urlparse(url)
url_params = parse_qs(url.query)
body_params = parse_qs(body)
out = json.dumps({
'servers': [{'url': f'{url.scheme}://{url.netloc}'}],
'paths': {
url.path: {
method: {
'parameters': [ {'name'aram, 'in':'query', 'schema':{'type': 'string', 'example': url_params[param][0]}} for param in url_params ],
'requestBody': {
'required': True,
'content': {
'application/x-www-form-urlencoded': {
'schema': {
'type': 'object',
'properties': { param: {'type':'string', 'example':body_params[param][0]} for param in body_params}
}
}
}
}
}
}
}
})
print(out)
Список JS-файлов
После проксирования списка собранных URL в Burp и прокликивания нам нужно собрать список JS-файлов. Я обычно делаю это прямо в Burp.Если скоуп большой и у тебя нет времени прокликать все по отдельности, можно просто собрать список JS-файлов в терминале. Используй для этого простую команду:
grep -E -i '\.(js|mjs|jsx|tsx|ts|vue|svelte|xjs|xjsp|es|es6|cjs|jsp|jsonp|ejs|hbs|astro|lit|jsc|jsxp|coffee|purs)(\.|$)' clear_urls.txt | sort | anew js_list.txt
Если мы работаем с каким‑то веб‑приложением, то удобно собрать JavaScript прямо со страницы в браузере. Для этого можно использовать команду в консоли браузера:
javascript:console.log('JavaScript Files:\n' + Array.from(document.scripts).filter(script => script.src).map(script => script.src).join('\n'));
Технологии
Наверняка ты заметил, что консольных утилит для анализа используемых технологий немного. Среди самых популярных браузерных — расширение Wappalyzer, но в рамках нашего пайплайна оно неудобно. Также хорошо себя показывает Для просмотра ссылки ВойдиПример запуска WhatWeb:
whatweb -i web_services.txt
Пример запуска httpx:
cat web_services.txt | httpx -tech-detect
У Wappalyzer есть и консольная версия — Для просмотра ссылки Войди
Для просмотра ссылки Войди
Эта утилита использует библиотеку Wappalyzer, которая включает в себя набор правил и шаблонов (фингерпринтов) для распознавания различных веб‑технологий. В общем, все то же самое, что и в аналогичном браузерном расширении, но доступно из командной строки.
Еще немного фильтруем
Эта глава носит творческий характер, и лучше подходить к решению задач, описанных в ней, с долей креативности и на основании имеющихся у тебя на руках данных об используемых технологиях. Здесь я приведу примеры того, что интересного можно найти в уже собранных данных. Например, можно поискать в итоговом списке URL-адресов формы авторизации, регистрации, панели администрирования и прочее.
Код:
cat live_urls | grep -i "login" | anew login_urls.txt
cat live_urls | grep -iE "register|signup|sign-up" | anew register_urls.txt
cat live_urls | grep -iE "admin|dashboard|manage|control" | anew admin_urls.txt
Скажем, можно найти включенный режим отладки в Symphony:
cat live_urls | grep "/_profiler"
Или, может, проверим, есть ли в скоупе GraphQL?
cat live_urls | grep -iE "graphql|gql|query" | anew graphql_urls.txt
Ты, наверное, уже понял, что это просто примеры, и каждый может дополнить этот список своими интересными находками. К примеру, сюда можно добавить потенциально интересные файлы — с расширениями xml, json, txt и прочими. В общем, все, что пожелаешь!
Скрытые параметры
Я не открою здесь Америку, но не упомянуть об этом в контексте статьи просто нельзя. Речь идет о поиске скрытых параметров в URL. Иногда разработчики убирают часть возможностей только с фронтенда, а на бэкенде он остается (забыли, не успели — всякое бывает). Для поиска таких случаев существуют специальные утилиты и словари, например Для просмотра ссылки ВойдиВ этом разделе я кратко расскажу про Arjun. Более подробно ты можешь ознакомиться с ним в документации, но обычно я запускаю его такой командой:
arjun -u [URL]https://example.com/endpoint.php[/URL] -oT arjun_output.txt -m GET,POST -w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt -t 10 --rate-limit 30 --headers "User-Agent: Mozilla/5.0"
Еще есть флаг -i targets.txt, с помощью которого можно загрузить список целей. Однако помни, что просканировать все подряд вряд ли получится из‑за ограниченного времени. Так что эту возможность стоит применять скорее нацеленно, чем массово.
Если внимательно изучить документацию, то можно узнать, что Arjun умеет пассивно собирать имена параметров...
Вкратце об API и Swagger
Swagger — это инструмент для работы с документацией REST API: он позволяет просматривать доступные эндпоинты и отправлять к ним запросы прямо из браузера. Он встречается довольно часто, так что почему бы не поискать его отдельно в уже собранных URL-адресах?cat live_urls | grep -iE "(api[-/]doc|apidoc|swagger)[/?]"
Тема с API довольно серьезная, и тут может найтись множество уязвимостей, поэтому я остановлюсь на ней чуть подробнее.
Выше мы рассмотрели команду для поиска Swagger в заранее собранном списке адресов. Окей, допустим, мы его нашли. Что делать дальше?
Теперь запускаем вот этот скрипт в консоли браузера.
Код:
JSON.stringify(
[...document.querySelectorAll('.opblock-summary')].map(e =>
e.querySelector('.opblock-summary-path') &&
[e.querySelector('.opblock-summary-method').innerText, e.querySelector('.opblock-summary-path').getAttribute('data-path')]
).filter(item => item !== null)
)
Он покажет список эндпоинтов и методов.
Для просмотра ссылки Войди
Запусти Python-скрипт, предварительно скопировав из браузера данные, которые поместишь в строку endpoints. Затем замени baseURL, указав только доменное имя.
Код:
from requests import request
import re
# Скопируй сюда список методов и путей из Swagger и ниже еще пропиши baseURL
endpoints = [["POST","/applepaysessions"],["GET","/sessions/{sessionId}/upsales"],["GET","/userinfo"]]
unique_params = []
for i in endpoints:
match = re.search(r"{([^{}]*)}", i[1])
if match:
content = match.group(1)
unique_params.append(content)
for i in set(unique_params):
print("url = url.replace('{" + i + "}','ololo')")
bearer = ""
#bearer = "Bearer eyJhbGciO..."
baseURL = "http://example.com"
body={"login":"zastraxyu_bratyxy"}
headers = {'Authorization': bearer}
proxies = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080"
}
for ep in endpoints:
method = ep[0]
url = baseURL+ep[1]
url = url.replace('{login}','dsfdsf')
url = url.replace('{orgID}','eadf5f91-b4a1-11eb-90fd-9418826ee072')
response = request(method, url, headers=headers, data=body, proxies=proxies, verify=False)
status_code = response.status_code
text = response.text[:100]
print(status_code, method, url, text, '\n-------\n')
print('DONE')
Вот такой результат получится, и с ним можно работать дальше.
Для просмотра ссылки Войди
Что делать, если Swagger не нашелся? Даже если его не видно, не беда — собрать его можно самостоятельно с помощью крутой утилиты Для просмотра ссылки Войди
Вообще, тестирование API заслуживает отдельной статьи. Существует масса отличных инструментов, таких как Для просмотра ссылки Войди
Строим карту сайта
Теперь можем собрать все, что мы тщательно собирали и анализировали. Проксируем все собранные и отсортированные URL в Burp, чтобы построить карту приложений в рамках нашего скоупа. Затем продолжаем работу над проектом в Burp.cat live_url | httpx -http-proxy [URL]http://127.0.0.1:8080[/URL]
Скриншотим
Существует множество утилит, которые могут проходить по списку адресов и делать скриншоты, например httpx, Eyewitness или Aquatone. Лично я предпочитаю использовать Для просмотра ссылки ВойдиГотовим окружение:
sudo apt install gccgo-go
sudo apt install golang-go
sudo apt install google-chrome
go install github.com/sensepost/gowitness@latest
Скриншотить лучше всего не по списку с доменами, а по списку с открытыми портами. Это довольно очевидно, но в пылу азарта можно и не заметить, что делаешь что‑то не то.
gowitness scan file -f web_services.txt --save-content --write-db
Смотрим результаты:
gowitness report serve
Выводы
Мы изучили инструменты и алгоритмы для активной разведки, обработали собранные пассивно URL-адреса и добавили новые — из ответов веб‑сервисов, результатов работы Katana, а также найденные с помощью перебора директорий и фаззинга скрытых параметров.Также мы поискали виртуальные хосты, собрали структуру веб‑приложений в проекте Burp, сформировали списки с JS-файлами, URL-адресами, в том числе с параметрами, и отсортировали интересные URL по ключевым словам.
Под конец мы проанализировали используемые технологии и сделали скриншоты. Теперь у нас есть ценная информация, которая позволит лучше понять специфику нашей цели. Это поможет на следующем этапе — активном сканировании на наличие известных и новых уязвимостей.