Кастомные вордлисты для самых маленьких

Страницы:  1

Ответить
 

Professor Seleznov


pic
Привет! Ни для кого не секрет, что качественные вордлисты - это ключ к эффективному фаззингу и, как следствие, большему покрытию скоупа и хорошим файндингам во время пентеста и баг-баунти. Однако вордлисты в общем доступе далеко не всегда дадут достаточное покрытие, какими бы большими они ни были. У веб-приложения может быть свой специфический нейминг путей и параметров. Некоторые ручки могут находиться на внескоуповых доменах и дублироваться на скоуповых, иногда даже с измененной функциональностью. Часть параметров и вовсе не удастся найти без ручного анализа JavaScript-кода приложения.
Здесь в игру вступают кастомные вордлисты, закрывающие все вышеперечисленные нюансы. Благодаря ним можно значительно эффективнее проводить фаззинг путей веб-приложения, а также брутить параметры его запросов.
Эта статья - первая из цикла про кастомные словари, рассказывающая про сбор базового вордлиста без особых усилий. В следующей статье я расскажу про создание более комплексного кастомного вордлиста, требующего больших затрат по времени.
А мне точно это нужно?
Не важно, баунти-хантер вы или пентестер, большее покрытие таргета - это хорошо, ведь всегда есть шанс наткнуться на забытые разработчиками параметры и пути. Даже один новый найденный ассет может дать вам преимущество перед другими исследователями.
Если у вас широкий скоуп с большим количеством поддоменов, шансы найти такие ассеты куда больше, чем на пентесте небольшой компании с парой поддоменов. Но даже в этом случае, если есть время, не стоит пренебрегать созданием кастомных вордлистов. Как-то раз во время пентеста небольшой компании благодаря кастомному вордлисту мне удалось обнаружить XSS в скрытом параметре на платёжной странице.
Отдельно стоит упомянуть, что кастомные словари неплохо себя показывают на регулярных пентестах (Penetration Testing as a Service) и в баг-баунти на больших программах с регулярно обновляющейся кодовой базой. Формируя кастомный вордлист на основе текущего состояния системы, вы делаете его ключом к скрытой поверхности атаки в будущем. Например, вы перехватили JSON-ответы API аутентифицированного пользователя и получили слова, которые невозможно найти в веб-архивах, сфокусированных в основном на сохранении статики. Эти уникальные слова в данный момент могут не участвовать в активной логике приложения, но с большой вероятностью могут появиться в следующих итерациях разработки приложения во время вашего следующего тестирования.
В рабочем флоу важно правильно распределять свое время и не делать самоцелью создание вордлиста. Иначе может случиться так, что вы потратите много времени на это в надежде найти скрытый функционал, но не успеете уделить достаточно внимания исследованию основной бизнес-логики таргета. Воспринимайте кастомные вордлисты как дополнительную часть OSINT.
Лично я при пентесте составляю вордлист во второй половине работы, уже после того, как сделал базовый рекон и посмотрел основной функционал. После чего выборочно использую словарь, руководствуясь своей хакерской интуицией. Иногда не делаю кастомный вордлист вообще, если требуется проверить много бизнес-логики.
Базовый кастомный вордлист
Ниже написал процесс сбора базового кастомного вордлиста на примере тестового приложения.
1. Ручной краулинг с прокси
Все начинается с того, чтобы вручную посетить таргеты с включенным прокси и собрать достаточное количество запросов. В своей работе я использую Firefox с расширением FoxyProxy, направляющим запросы в Burp Suite.
pic
pic
pic
Сохраненные в Burp Suite запросы и ответы нам понадобятся к концу этой главы, чтобы распарсить их через расширение и собрать вордлист.
Автоматизированные краулеры смогут прокликать все статичные страницы, однако они плохо справляются с динамическим функционалом, поэтому без ручного этапа никуда. Зарегистрируйтесь в личном кабинете, поменяйте пароль, отправьте сообщение в поддержку, оплатите подписку и т.д. - сделайте все возможные действия, доступные через UI.
Так вы получите больше запросов к API и соответствующих ответов сервера.
2. Автоматизированный краулинг
Как я упоминал выше, посещением всех статичных страниц займется автоматика. Я использую краулер Katana - он достаточно быстрый, и в нем есть удобный динамический анализ ссылок в JavaScript-файлах.
Не забудьте передать краулеру сессионную Cookie, если на таргете имеется функционал, закрытый за авторизацией. Запросы краулера аналогично проксируйте в Burp Suite.
Также для перестраховки от блокировки WAF-ом советую менять User-Agent на стандартный агент браузера.
Пример команды (можете заменить параметр глубины кроулинга -depth по вашему желанию, то же самое с рейт-лимитами в параметре -rl):
katana -u https://example.com (-list urls.txt) -depth 5 -js-crawl -jsluice -known-files all -proxy http://127.0.0.1:8080 -rl 100 -o katana-example-com.out -v -H 'User-Agent: xxx' -H 'Cookie: xxx=xxx'
pic
3. Фаззинг со стандартными вордлистами
Также важно пофаззить пути веб-приложения общедоступными вордлистами, чтобы найти скрытые ручки и, самое главное, сохранить ответы на них. Содержимое ответов на открытой кастомной админ-панели может содержать достаточно много слов для нашего вордлиста, а JS-файлы на странице входа - еще больше.
Для фаззинга я использую инструмент ffuf и вордлисты fuzz.txt, content discovery all.txt. Второй достаточно большой, его советую оставлять запущенным на ночь на VPS в tmux.
Валидные страницы можно сразу отправлять в Burp через параметры -r -replay-proxyhttp://127.0.0.1:8080 (-r — следовать редиректам, -replay-proxy — направлять в прокси Burp Suite только те запросы, которые прошли фильтрацию). Это позволяет за один проход и собрать результаты фаззинга и запроксировать валидные эндпоинты в Burp.
Если нужно отфильтровать другой код ответа, меняйте 403 в -fc на соответствующий (можно перечислять через запятую, например -fc 403,404).
Пример команды:
ffuf -c -w fuzz.txt -u https://example.com/FUZZ -rate 80 -t 5 -fc 403 -H "User-Agent: Mozilla Firefox" -r -replay-proxy http://127.0.0.1:8080 -o ffuf/-fuzz.out
pic
4. Собираем URL из архивов через gau
gau - инструмент, позволяющий собрать сохраненные URL домена на различных сайтах-архивах вроде webarchive.org. То есть, по сути, осуществить быстрый автоматизированный OSINT - найти URL, которые в приложении уже нигде не фигурируют, но остались в истории Интернета. Не игнорируйте этот шаг - очень много файндингов идёт именно отсюда.
Пример команды:
cat  | gau --blacklist ttf,woff,svg,png,jpg --fc 404 --o gau.out --verbose
На практике аргумент blacklist не всегда работает корректно, поэтому советую инверсивно грепать статику из вывода gau:
cat gau.out | grep -vE '\.ttf|\.woff|\.svg|\.png|\.jpg'
Полученные URL прогоняем через тот же ffuf, чтобы запроксировать их в Burp, как во втором шаге.
Так как мое тестовое приложение локальное и не оставило следов в сети, для примеров, связанных с OSINT, буду использовать сайт www.spacex.com:
pic
5. Парсим JavaScript-файлы через xnLinkFinder
xnLinkFinder - инструмент для краулинга и поиска URL в JavaScript-файлах. Примечателен тем, что умеет проверять относительные пути, а также собирать отдельный вордлист параметров, который мы потом совместим с нашим основным кастомным словарем.
Инструмент нужен для увеличения покрытия - он находит ручки, скрытые в JS-файлах.
Хотя инструмент и позиционируется как краулер, я не вижу смысла делать краулинг повторно после того, как мы сделали его через Katana. Поэтому рекомендую использовать xnLinkFinder как парсер для JavaScript-файлов.
Сохраните запросы-ответы из Burp, выделив все URL в таргете - ПКМ - Save selected items - base64-encode requests and responses.
pic
pic
Пример команды (-sp - домен со схемой для подстановки перед относительными URL, -sf - фильтр по одному или нескольким доменам в XML-файле Burp Suite, если их несколько):
xnLinkFinder -i  -sp https://example.com -sf example.com -o xnlinkfinder.out -op xnlinkfinder-params.out -d 3
pic
В результате вы получите список найденных URL и вордлист с параметрами.
Полученные URL также нужно спроксировать в Burp Suite через ffuf.
6. Формируем кастомный вордлист через GAP
GAP - расширение для Burp от автора xnLinkFinder. Именно ради него мы проксировали все запросы в Burp на предыдущих этапах. Оно парсит все URL в таргете и составляет на их основе кастомный вордлист. Скачать его можете из BApp Store.
Для более полного покрытия советую перед запуском расширения включить следующие опции:
  • Include URL path words? (в Parameters mode и в Words mode)
  • JSON params (в Request и Response Parameters)
  • Cookie names
  • Name and Id attributes of HTML input fields
  • Include potential params?
  • Params from links found
  • Selected target(s)
Также укажите директорию в поле Auto save output directory и нажмите Save options.
Для запуска: ПКМ по домену в Target - Extensions - GAP.
pic
В результате получаются два вордлиста (Params, Words) и список URL (Links).
В завершение совмещаем вордлисты GAP-а с вордлистом параметров xnLinkFinder, удаляем дубли и получаем кастомный вордлист!
cat xnlinkfinder-deiteriypay-params.out http-deiteriypay.local/deiteriypay.local_20260414_155944_params.txt http-deiteriypay.local/deiteriypay.local_20260414_155944_words.txt | sort -u > wordlist-final.txt
pic
Использование вордлистов на практическом примере
  • Param Miner
Param Miner - расширение для Burp Suite от небезызвестного Джеймса Кеттла.
Для начала его нужно настроить в одноименной вкладке сверху, указав ему наш вордлист и поставив галочку use custom wordlist. Также я использую некоторые другие опции, которые вы можете видеть на скриншоте.
pic
Запустить расширение очень просто - ПКМ по запросу - Extensions - Param Miner - Guess …
pic
Советую для каждого запроса выбирать логичные варианты: Guess query params для GET-запросов, body params для POST/PUT/PATCH-запросов. Guess cookies/headers советую сканить лишь один раз, логика с большой вероятностью будет повторяться на всем таргете (но, естественно, смотрите по ситуации).
Если хотите побольше узнать про другие опции Param Miner’а, можете почитать об этом в нашей статье.
После завершения сканирования видим новый Issue о том, что найден скрытый параметр internal_receipt_id на ручке deiteriypay.local:8090/checkout:
pic
Параметр internal_receipt_id был зашит в файл app.js и был успешно извлечён расширением GAP.
pic
Благодаря этому legacy-параметру на тестовом стенде удалось найти XSS:
pic
2. ffuf
Кастомный вордлист не ограничивается брутом параметров. Он может быть использован и для фаззинга путей. Однако пути зачастую куда капризнее к неймингу, и на реальном таргете словарь с параметрами требует доработки, чтобы использоваться для фаззинга путей.
Я не знаю ни одного инструмента, который умел бы анализировать нейминг путей и генерировать на его основе потенциальные URL. Нечто похожее реализовано в kiterunner - фаззере API, однако его функционал рекурсивного фаззинга ограничен встроенными вордлистами. Возможно, в этой задаче могут хорошо помочь нейросети. Если знаете подходящие инструменты для работы с кастомными словарями - делитесь в комментариях!
Поэтому для грамотного покрытия таргета стоит уделить хотя бы немного времени ручному анализу нейминга URL и редактуре вордлиста с параметрами. Но, конечно, можно и просто закинуть вордлист с параметрами на фаззинг как https://example.com/FUZZ.
На тестовом стенде, прочитав вордлист Links от GAP, можно увидеть, что в нейминге часто используется разделение нескольких слов через - и префиксы типа deiteriy-, deit-. Также мы знаем, что API расположен на /api/v1/.
pic
На основании этих данных сделаем мутации вордлиста с параметрами, добавив к словам, начинающимся со строчной буквы, префиксы, а также соединив эти слова через дефисы. Сканировать будем URL http://deiteriypay.local:8090/api/v1/FUZZ. Пример баш-скрипта для очистки и мутаций словаря будет приведен ниже.
Мутации вордлиста стоит проводить на как можно более чистом и маленьком вордлисте, чтобы он не раздулся в размерах. Более подробно про очистку вордлистов я расскажу в следующей части статьи. А пока что приведу пример мутации вордлиста для тестового стенда.
Я заметил, что в вордлисте много повторяющихся слов с заглавной буквы. Решил почистить вордлист, убрав слова с заглавной буквы и слова короче 3 символов, и сделать конкатенацию слов с дефисами и префиксами. Я написал баш-скрипт, но можно удобнее это делать через Python. В помощь с написанием простых скриптов рекомендую использовать ИИ.
#!/usr/bin/env bash
set -euo pipefail
INPUT="${1:-wordlist-final.txt}"
OUTPUT="${2:-paths-mutated.txt}"
PREFIXES="deiteriy deit"
if [[ ! -f "$INPUT" ]]; then
exit 1
fi
ATOMS=$(mktemp)
# Очистка и подготовка "атомов"
sed 's/[-_]/\n/g' "$INPUT" | \
grep -v '[A-Z]' | \
awk 'length >= 3' | \
grep -vxE "$(echo $PREFIXES | tr ' ' '|')" | \
sort -u > "$ATOMS"
# Генерация мутаций
awk -v prefixes="$PREFIXES" '
BEGIN { np = split(prefixes, px, " ") }
{ a[NR] = $0; n = NR }
END {
for (i = 1; i <= n; i++) {
print a
for (p = 1; p <= np; p++)
print px[p] "-" a
}
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (i == j) continue
combo = a "-" a[j]
print combo
for (p = 1; p <= np; p++)
print px[p] "-" combo
}
}
}' "$ATOMS" | sort -u > "$OUTPUT"
rm -f "$ATOMS"
pic
pic
Вордлист получился внушительным, именно поэтому выше я упоминал, что для мутаций стоит работать с максимально очищенным вариантом словаря.
Фаззинг API тестового стенда и результаты:
pic
pic
Выводы
Кастомные вордлисты могут помочь более широко покрыть таргет, а также найти скрытый функционал, недоступный при использовании стандартных вордлистов. Однако создание вордлистов - процесс не полностью автоматический и требует времени. Важно грамотно его распределять, воспринимая кастомные вордлисты как дополнение к OSINT.
В итоге общий флоу создания кастомного вордлиста получается таким:
pic
Делитесь в комментариях мнениями насчет статьи, своими подходами к составлению и использованию вордлистов, а также инструментами, которые для этого применяете.
Увидимся в следующей части! В ней я расскажу про более продвинутое составление кастомных вордлистов с добавлением во флоу OSINT, а также про утилиты и подходы к очистке словарей. Ещё затрону инструменты, которые помогают собрать вордлист без GAP - например, если вы используете Caido вместо Burp.-Источник
 
Loading...
Error