• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

Статья Active Recon. Составляем пошаговый план активной разведки

stihl

Moderator
Регистрация
09.02.2012
Сообщения
1,178
Розыгрыши
0
Реакции
510
Deposit
0.228 BTC
stihl не предоставил(а) никакой дополнительной информации.
Активную разведку проводят при пентесте, чтобы узнать максимум информации о цели. При этом допускается, что действия могут быть замечены — например, занесены в логи. На этом этапе мы соберем информацию о 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-адресов тоже впечатляюще велик, то надо использовать трюк с разбивкой на части.

Команда для разделения большого списка 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? Это помогает обеспечить максимальное покрытие при анализе сканерами. Например, сканер может не обнаружить уязвимость по адресу Для просмотра ссылки Войди или Зарегистрируйся, но найдет ее на Для просмотра ссылки Войди или Зарегистрируйся. Или, если доступ к веб‑сервису через 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:port:

grep -E '^https?://([0-9]{1,3}\.){3}[0-9]{1,3}:)[0-9]+)?$' web_app.txt > web_app_ip.txt
Команда для формирования списка в формате domain:port:

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
Также существует Для просмотра ссылки Войди или Зарегистрируйся, написанный на Python. Его я не тестировал.


Поиск виртуальных хостов​

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

Кратко напомню разницу между поддоменом и виртуальным хостом.

  • Поддомены имеют собственные DNS-записи и могут быть публично разрешены.
  • Виртуальные хосты — настройка веб‑сервера; доступ к ним организуется через указание конкретного IP и передачу нужного заголовка Host или через запись в файле /etc/hosts.
Виртуальный хостинг часто используется на shared-серверах, когда по одному IP-адресу отвечает один из нескольких сайтов. Например, один IP может обслуживать example.com, shop.example.com и hidden.example.com, но не все из них будут публично резолвиться. Это делает их интересной целью для исследования.

Брутим список веб‑приложений по 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
Не забудь потом отредактировать системный файл hosts!

Брутфорсим список веб‑приложений по доменам, используя в качестве словаря список поддоменов из 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)
Поиск статусов 401 и 403:

Код:
(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
Теперь соберем результаты в один файл. Для этого выбираем только те URL, в которых найдены директории, и сохраняем их в файл с результатами брутфорса директорий.

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
К этой команде можно добавить статус‑бар, чтобы отслеживать прогресс.

Как вариант можно попробовать утилиту Для просмотра ссылки Войди или Зарегистрируйся. Я лично с ней не работаю, но не исключаю, что она тебе понравится. На вход можно подать файл с веб‑сервисами web_services.txt.


Сохраняем ответы по 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​

Для просмотра ссылки Войди или Зарегистрируйся — это отличная утилита (все того же tomnomnom), которая позволяет находить в сохраненных ответах веб‑сервера разные интересные данные. Очень рекомендую попробовать!

Можно, конечно, использовать и простой grep. Ниже представлены некоторые команды, но это далеко не полный список.

Много интересного можно найти в репозиториях на GitHub, например:
Дальше пройдемся по примерам того, что может искать GF. По сути, это просто регулярки для grep: возможно, кому‑то (как и мне) будет удобно использовать их вручную, без установки лишнего софта. А в перечисленных выше репозиториях можно найти еще больше интересных и полезных регэкспов.

Поиск ключей и секретов 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. Мой коллега недавно Для просмотра ссылки Войди или Зарегистрируйся в своем Telegram-канале метод, с помощью которого все же можно автоматизировать это, хоть и не без костылей. Я изучил этот метод и немного адаптировал под свои нужды.

Вот простая команда для запуска 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

Пример работы
Пример работы
Пример содержимого файла katana_non_get.txt
Пример содержимого файла katana_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, но в рамках нашего пайплайна оно неудобно. Также хорошо себя показывает Для просмотра ссылки Войди или Зарегистрируйся. Однако наилучшим вариантом для нас будет Для просмотра ссылки Войди или Зарегистрируйся или httpx. Они менее информативны, но вполне подойдут для создания общей картины. Кроме того, не забывай обрабатывать и изучать результаты из Censys.

Пример запуска WhatWeb:

whatweb -i web_services.txt
Пример запуска httpx:

cat web_services.txt | httpx -tech-detect
У Wappalyzer есть и консольная версия — Для просмотра ссылки Войди или Зарегистрируйся, аналог браузерного расширения 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. Иногда разработчики убирают часть возможностей только с фронтенда, а на бэкенде он остается (забыли, не успели — всякое бывает). Для поиска таких случаев существуют специальные утилиты и словари, например Для просмотра ссылки Войди или Зарегистрируйся и Для просмотра ссылки Войди или Зарегистрируйся. Также есть популярное расширение для Burp — Param Miner. Среди параметров, которые могут встретиться, можно выделить Debug, RoleId или returnUrl. Они могут привести к включению дебаг‑режима, изменению роли или, например, к Open Redirect.

В этом разделе я кратко расскажу про 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 не нашелся? Даже если его не видно, не беда — собрать его можно самостоятельно с помощью крутой утилиты Для просмотра ссылки Войди или Зарегистрируйся. Подробности по установке и использованию есть на GitHub, включая видео с демонстрацией работы. Если ты тестируешь одно веб‑приложение, ручное нажатие на все кнопки и поля — это путь к качественному результату. Если же скоуп большой и приложение не одно, просто пропусти найденные URL через прокси. Дальше запускай процесс, как описано выше.

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


Строим карту сайта​

Теперь можем собрать все, что мы тщательно собирали и анализировали. Проксируем все собранные и отсортированные URL в Burp, чтобы построить карту приложений в рамках нашего скоупа. Затем продолжаем работу над проектом в Burp.

cat live_url | httpx -http-proxy [URL]http://127.0.0.1:8080[/URL]

Скриншотим​

Существует множество утилит, которые могут проходить по списку адресов и делать скриншоты, например httpx, Eyewitness или Aquatone. Лично я предпочитаю использовать Для просмотра ссылки Войди или Зарегистрируйся. В отличие от аналогов, он делает скриншоты в хорошем качестве, предоставляет более полную сопутствующую информацию и хранит результаты в базе данных SQLite, что полезно для автоматизации.

Готовим окружение:

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 по ключевым словам.

Под конец мы проанализировали используемые технологии и сделали скриншоты. Теперь у нас есть ценная информация, которая позволит лучше понять специфику нашей цели. Это поможет на следующем этапе — активном сканировании на наличие известных и новых уязвимостей.
 
Activity
So far there's no one here
Сверху Снизу