
Привет! Ни для кого не секрет, что качественные вордлисты - это ключ к эффективному фаззингу и, как следствие, большему покрытию скоупа и хорошим файндингам во время пентеста и баг-баунти. Однако вордлисты в общем доступе далеко не всегда дадут достаточное покрытие, какими бы большими они ни были. У веб-приложения может быть свой специфический нейминг путей и параметров. Некоторые ручки могут находиться на внескоуповых доменах и дублироваться на скоуповых, иногда даже с измененной функциональностью. Часть параметров и вовсе не удастся найти без ручного анализа JavaScript-кода приложения.
Здесь в игру вступают кастомные вордлисты, закрывающие все вышеперечисленные нюансы. Благодаря ним можно значительно эффективнее проводить фаззинг путей веб-приложения, а также брутить параметры его запросов.
Эта статья - первая из цикла про кастомные словари, рассказывающая про сбор базового вордлиста без особых усилий. В следующей статье я расскажу про создание более комплексного кастомного вордлиста, требующего больших затрат по времени.
А мне точно это нужно?
Не важно, баунти-хантер вы или пентестер, большее покрытие таргета - это хорошо, ведь всегда есть шанс наткнуться на забытые разработчиками параметры и пути. Даже один новый найденный ассет может дать вам преимущество перед другими исследователями.
Если у вас широкий скоуп с большим количеством поддоменов, шансы найти такие ассеты куда больше, чем на пентесте небольшой компании с парой поддоменов. Но даже в этом случае, если есть время, не стоит пренебрегать созданием кастомных вордлистов. Как-то раз во время пентеста небольшой компании благодаря кастомному вордлисту мне удалось обнаружить XSS в скрытом параметре на платёжной странице.
Отдельно стоит упомянуть, что кастомные словари неплохо себя показывают на регулярных пентестах (Penetration Testing as a Service) и в баг-баунти на больших программах с регулярно обновляющейся кодовой базой. Формируя кастомный вордлист на основе текущего состояния системы, вы делаете его ключом к скрытой поверхности атаки в будущем. Например, вы перехватили JSON-ответы API аутентифицированного пользователя и получили слова, которые невозможно найти в веб-архивах, сфокусированных в основном на сохранении статики. Эти уникальные слова в данный момент могут не участвовать в активной логике приложения, но с большой вероятностью могут появиться в следующих итерациях разработки приложения во время вашего следующего тестирования.
В рабочем флоу важно правильно распределять свое время и не делать самоцелью создание вордлиста. Иначе может случиться так, что вы потратите много времени на это в надежде найти скрытый функционал, но не успеете уделить достаточно внимания исследованию основной бизнес-логики таргета. Воспринимайте кастомные вордлисты как дополнительную часть OSINT.
Лично я при пентесте составляю вордлист во второй половине работы, уже после того, как сделал базовый рекон и посмотрел основной функционал. После чего выборочно использую словарь, руководствуясь своей хакерской интуицией. Иногда не делаю кастомный вордлист вообще, если требуется проверить много бизнес-логики.
Базовый кастомный вордлист
Ниже написал процесс сбора базового кастомного вордлиста на примере тестового приложения.
1. Ручной краулинг с прокси
Все начинается с того, чтобы вручную посетить таргеты с включенным прокси и собрать достаточное количество запросов. В своей работе я использую Firefox с расширением FoxyProxy, направляющим запросы в Burp Suite.



Сохраненные в 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'

3. Фаззинг со стандартными вордлистами
Также важно пофаззить пути веб-приложения общедоступными вордлистами, чтобы найти скрытые ручки и, самое главное, сохранить ответы на них. Содержимое ответов на открытой кастомной админ-панели может содержать достаточно много слов для нашего вордлиста, а JS-файлы на странице входа - еще больше.
Для фаззинга я использую инструмент ffuf и вордлисты fuzz.txt, content discovery all.txt. Второй достаточно большой, его советую оставлять запущенным на ночь на VPS в tmux.
Валидные страницы можно сразу отправлять в Burp через параметры -r -replay-proxy http://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/<url>-fuzz.out

4. Собираем URL из архивов через gau
gau - инструмент, позволяющий собрать сохраненные URL домена на различных сайтах-архивах вроде webarchive.org. То есть, по сути, осуществить быстрый автоматизированный OSINT - найти URL, которые в приложении уже нигде не фигурируют, но остались в истории Интернета. Не игнорируйте этот шаг - очень много файндингов идёт именно отсюда.
Пример команды:
cat <subdomains.txt> | 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:

5. Парсим JavaScript-файлы через xnLinkFinder
xnLinkFinder - инструмент для краулинга и поиска URL в JavaScript-файлах. Примечателен тем, что умеет проверять относительные пути, а также собирать отдельный вордлист параметров, который мы потом совместим с нашим основным кастомным словарем.
Инструмент нужен для увеличения покрытия - он находит ручки, скрытые в JS-файлах.
Хотя инструмент и позиционируется как краулер, я не вижу смысла делать краулинг повторно после того, как мы сделали его через Katana. Поэтому рекомендую использовать xnLinkFinder как парсер для JavaScript-файлов.
Сохраните запросы-ответы из Burp, выделив все URL в таргете - ПКМ - Save selected items - base64-encode requests and responses.


Пример команды (-sp - домен со схемой для подстановки перед относительными URL, -sf - фильтр по одному или нескольким доменам в XML-файле Burp Suite, если их несколько):
xnLinkFinder -i <urls.xml> -sp https://example.com -sf example.com -o xnlinkfinder.out -op xnlinkfinder-params.out -d 3

В результате вы получите список найденных 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.

В результате получаются два вордлиста (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

Использование вордлистов на практическом примере
Param Miner
Param Miner - расширение для Burp Suite от небезызвестного Джеймса Кеттла.
Для начала его нужно настроить в одноименной вкладке сверху, указав ему наш вордлист и поставив галочку use custom wordlist. Также я использую некоторые другие опции, которые вы можете видеть на скриншоте.

Запустить расширение очень просто - ПКМ по запросу - Extensions - Param Miner - Guess …

Советую для каждого запроса выбирать логичные варианты: Guess query params для GET-запросов, body params для POST/PUT/PATCH-запросов. Guess cookies/headers советую сканить лишь один раз, логика с большой вероятностью будет повторяться на всем таргете (но, естественно, смотрите по ситуации).
Если хотите побольше узнать про другие опции Param Miner’а, можете почитать об этом в нашей статье.
После завершения сканирования видим новый Issue о том, что найден скрытый параметр internal_receipt_id на ручке deiteriypay.local:8090/checkout:

Параметр internal_receipt_id был зашит в файл app.js и был успешно извлечён расширением GAP.

Благодаря этому legacy-параметру на тестовом стенде удалось найти XSS:

2. ffuf
Кастомный вордлист не ограничивается брутом параметров. Он может быть использован и для фаззинга путей. Однако пути зачастую куда капризнее к неймингу, и на реальном таргете словарь с параметрами требует доработки, чтобы использоваться для фаззинга путей.
Я не знаю ни одного инструмента, который умел бы анализировать нейминг путей и генерировать на его основе потенциальные URL. Нечто похожее реализовано в kiterunner - фаззере API, однако его функционал рекурсивного фаззинга ограничен встроенными вордлистами. Возможно, в этой задаче могут хорошо помочь нейросети. Если знаете подходящие инструменты для работы с кастомными словарями - делитесь в комментариях!
Поэтому для грамотного покрытия таргета стоит уделить хотя бы немного времени ручному анализу нейминга URL и редактуре вордлиста с параметрами. Но, конечно, можно и просто закинуть вордлист с параметрами на фаззинг как https://example.com/FUZZ.
На тестовом стенде, прочитав вордлист Links от GAP, можно увидеть, что в нейминге часто используется разделение нескольких слов через - и префиксы типа deiteriy-, deit-. Также мы знаем, что API расположен на /api/v1/.

На основании этих данных сделаем мутации вордлиста с параметрами, добавив к словам, начинающимся со строчной буквы, префиксы, а также соединив эти слова через дефисы. Сканировать будем 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[i] for (p = 1; p <= np; p++) print px[p] "-" a[i] } for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { if (i == j) continue combo = a[i] "-" a[j] print combo for (p = 1; p <= np; p++) print px[p] "-" combo } } }' "$ATOMS" | sort -u > "$OUTPUT" rm -f "$ATOMS"


Вордлист получился внушительным, именно поэтому выше я упоминал, что для мутаций стоит работать с максимально очищенным вариантом словаря.
Фаззинг API тестового стенда и результаты:


Выводы
Кастомные вордлисты могут помочь более широко покрыть таргет, а также найти скрытый функционал, недоступный при использовании стандартных вордлистов. Однако создание вордлистов - процесс не полностью автоматический и требует времени. Важно грамотно его распределять, воспринимая кастомные вордлисты как дополнение к OSINT.
В итоге общий флоу создания кастомного вордлиста получается таким:

Делитесь в комментариях мнениями насчет статьи, своими подходами к составлению и использованию вордлистов, а также инструментами, которые для этого применяете.
Увидимся в следующей части! В ней я расскажу про более продвинутое составление кастомных вордлистов с добавлением во флоу OSINT, а также про утилиты и подходы к очистке словарей. Ещё затрону инструменты, которые помогают собрать вордлист без GAP - например, если вы используете Caido вместо Burp.
Комментарии (4)

dimas846
30.04.2026 10:52Ни для кого не секрет, что качественные вордлисты - это ключ к эффективному фаззингу и, как следствие, большему покрытию скоупа и хорошим файндингам во время пентеста и баг-баунти.
Ни для кого не секрет, что качественные списки слов и входных данных для перебора (wordlists) — это ключ к эффективному тестированию программ путём подачи большого количества случайных или специально подготовленных данных (fuzzing) и, как следствие, к большему охвату проверяемой области системы (scope coverage) и обнаружению полезных уязвимостей или проблем безопасности (findings) во время тестирования на проникновение (penetration testing, pentest) и в программах поиска уязвимостей за вознаграждение (bug bounty).

Gutt
30.04.2026 10:52Ни для кого не секрет, что качественные вордлисты - это ключ к эффективному фаззингу и, как следствие, большему покрытию скоупа и хорошим файндингам во время пентеста и баг-баунти.
Не могу не экспрессировать свой диповый эгримент с этим трули эстонишинговым стейтментом!
OlegZH
"Вы это прекратите!" (с) Стругацкие, "Понедельник начинается в субботу".
Зачем всё это? Это с порога отбивает читать дальше, даже, если дальше идёт описание какой-нибудь дельной вещи.
Даже не знаю, что делать. Одно из двух: либо напроситься в Хабр в качестве редактора, который должен (вместо какой-нибудь модельки))) править чужие статьи для их всяческого улучшения, или писать собственные статьи на те же темы с воспроизведением тех же результатов (но и предложением собственных), но своими словами. Лучше, наверное, второе. ;-)
gotch
Так у меня не у одного пошла кровь из глаз?
Извиняюсь, ничего что я по-русски?
Кастомные
вордлист
фаззинг
скоуп
файндинг
пентест
баг-баунти
нейминг
внескоуповых
брутить
таргет
ассет
флоу
рекон
эндпоинты