ffuf (fuzz faster u fool) — это быстрый инструмент для фаззинга веб-приложений, написанный на Go. Используется в информационной безопасности и пентестинге для поиска уязвимостей и их тестирования.

Что такое фаззинг?🤔
Фа́ззинг (fuzzing или fuzz testing) — техника тестирования программного обеспечения, заключающаяся в передаче приложению на вход неправильных, неожиданных или случайных данных. Предметом интереса являются падения изависания, нарушения внутренней логики и проверок в коде приложения, утечки памяти, вызванные такими данными на входе.


Установка

Официальный репозиторий утилиты GitHub

Установка wordlists:

cd ~  
mkdir wordlists  
cd wordlists  
wget http://ffuf.me/wordlist/common.txt  
wget http://ffuf.me/wordlist/parameters.txt  
wget http://ffuf.me/wordlist/subdomains.txt

Словарь с популярными паролями: GitHub

Флаги ffuf

HTTP-опции

ФлагПрименение
-HЗаголовок HTTP запроса в формате "Имя: Значение". Можно использовать несколько параметров -H
-XHTTP-метод (по умолчанию: GET). Пример использования
-dДанные POST. Пример использования
-rПереходить по перенаправлениям (по умолчанию: false)
-recursionРекурсивный скан. URL должен заканчиваться на FUZZ (по умолчанию: false). Пример использования
-recursion-depthМаксимальная глубина рекурсии (по умолчанию: 0)
-replay-proxyПовторять совпадающие запросы с использованием этого прокси
-timeoutТайм-аут HTTP-запросов в секундах (по умолчанию: 10)
-uЦелевой URL с ключевым словом FUZZ. Пример использования
-xHTTP/SOCKS прокси URL

Общие опции

ФлагПрименение
-VПоказать информацию о версии (по умолчанию: false)
-acАвтоматическая калибровка параметров фильтрации (по умолчанию: false)
-accПользовательская строка автоматической калибровки. Может использоваться несколько раз. Подразумевает -ac
-cОкрашивать вывод (по умолчанию: false)
-maxtimeМаксимальное время выполнения в секундах (по умолчанию: 0)
-pЗадержка между запросами в секундах или диапазон случайной задержки. Например, "0.1" или "0.1-2.0". Пример использования
-sТихий режим — печатать только найденные совпадения (по умолчанию: false)
-saОстановиться при всех случаях ошибок. Подразумевает -sf и -se (по умолчанию: false)
-seОстановиться при случайных ошибках (по умолчанию: false)
-sfОстановиться, если > 95% ответов возвращают 403 Forbidden (по умолчанию: false)
-tКоличество одновременных потоков (по умолчанию: 40). Пример использования
-vПодробный вывод: печать полного URL и места перенаправления (если есть) с результатами (по умолчанию: false)

Опции сопоставления

ФлагПрименение
-mcСоответствие кодам состояния HTTP или "all" для всего (по умолчанию: 200, 204, 301, 302, 307, 401, 403). Пример использования
-mlСоответствие количеству строк в ответе
-mrСоответствие регулярному выражению
-msСоответствие размеру HTTP-ответа
-mwСоответствие количеству слов в ответе

Опции фильтрации

ФлагПрименение
-fcФильтровать коды состояния HTTP из ответа. Список кодов и диапазонов, разделенных запятыми
-flФильтровать по количеству строк в ответе. Список количеств строк и диапазонов, разделенных запятыми
-frФильтровать по регулярному выражению
-fsФильтровать по размеру HTTP-ответа. Список размеров и диапазонов, разделенных запятыми. Пример использования
-fwФильтровать по количеству слов в ответе. Список количеств слов и диапазонов, разделенных запятыми

Опции ввода

ФлагПрименение
-DРежим совместимости с wordlist, DirSearch. Используется совместно с флагом -e (по умолчанию: false)
-eСписок расширений, разделенных запятыми. Расширяет ключевое слово FUZZ. Пример использования
-icИгнорировать комментарии в wordlist (по умолчанию: false)
-input-cmdКоманда, создающая ввод. --input-num обязателен при использовании этого метода ввода. Переопределяет -w
-input-numКоличество входных данных для тестирования. Используется совместно с --input-cmd (по умолчанию: 100)
-modeРежим многопользовательского взаимодействия с wordlist. Доступные режимы: clusterbomb, pitchfork, sniper (по умолчанию: clusterbomb)
-requestФайл, содержащий сырой HTTP-запрос
-request-protoПротокол для -request (по умолчанию: https)
-wПуть к файлу wordlist и (необязательно) ключевое слово, разделенное двоеточием. Например, /путь/к/wordlist:КЛЮЧЕВОЕ_СЛОВО (по умолчанию: FUZZ). Пример использования


Примеры использования

Username enumeration

Для перебора пользователей можно использовать флаг -X, чтобы отправять POST-запросы, и флаг -d для установки тела запроса.

Пример:

При вводе неправильного логина выводится сообщения об ошибке.

IMG

При входе в аккаунт на сервер отправляется следующий POST-запрос:

POST /login HTTP/2
Host: 0aed007204edce5285af7b550032008d.web-security-academy.net/login
Cookie: session=A2mZdRv71ZtY7jlsemzgtHkRmx8tiDQo
Content-Length: 35
Cache-Control: max-age=0
Sec-Ch-Ua: "Not-A.Brand";v="99", "Chromium";v="124"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Linux"
Upgrade-Insecure-Requests: 1
Origin: https://0a03003203ac78008601588400b10000.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.60 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://0a03003203ac78008601588400b10000.web-security-academy.net/login
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Priority: u=0, i

username=USERFUZZ&password=PASSFUZZ

Можно попробовать перебрать username с помощью следующей команды:

ffuf -w ~/wordlists/portswigger_login.txt -X POST -d "username=FUZZ&password=x" -u https://0aed007204edce5285af7b550032008d.web-security-academy.net/login

В ответах можно увидеть, что для логина atlanta длина ответа отличается от остальных. Попробую ввести его.

IMG

Для перебора пароля пользуемся таким же алгоритмом.

Content Discovery

Basic

Через ffuf нужно найти утекшие файлы на сайте. Попробуем пофаззить данный URL: http://ffuf.me/cd/basic.

cu63:~/ $ ffuf -u http://ffuf.me/cd/basic/FUZZ -w wordlists/common.txt

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/basic/FUZZ
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

class                   [Status: 200, Size: 19, Words: 4, Lines: 1, Duration: 173ms]
development.log         [Status: 200, Size: 19, Words: 4, Lines: 1, Duration: 96ms]
:: Progress: [4686/4686] :: Job [1/1] :: 253 req/sec :: Duration: [0:00:12] :: Errors: 0 ::

Recursion

Флаг -recursion полезен в случаях, когда нужно проверить все возможные пути и поддиректории, в частности для обнаружения API-ендпоитов. Попробуем найти все файлы тут: http://ffuf.me/cd/recursion.

cu63:~/ $ ffuf -u http://ffuf.me/cd/recursion/FUZZ -w wordlists/common.txt -recursion

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/recursion/FUZZ
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

admin                   [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 81ms]
[INFO] Adding a new job to the queue: http://ffuf.me/cd/recursion/admin/FUZZ

[INFO] Starting queued job on target: http://ffuf.me/cd/recursion/admin/FUZZ

users                   [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 487ms]
[INFO] Adding a new job to the queue: http://ffuf.me/cd/recursion/admin/users/FUZZ

[INFO] Starting queued job on target: http://ffuf.me/cd/recursion/admin/users/FUZZ

96                      [Status: 200, Size: 19, Words: 4, Lines: 1, Duration: 94ms]
:: Progress: [4686/4686] :: Job [3/3] :: 408 req/sec :: Duration: [0:00:10] :: Errors: 0 ::

File Extensions

Флаг -e полезен, когда мы хотим искать файлы с определенным расширением. Это может быть .js, .log, .xml и т.д.

Попробуем найти файл с расширением .log на данном ендпоинте: http://ffuf.me/cd/ext.

cu63:~/ $ ffuf -u http://ffuf.me/cd/ext/FUZZ -recursion -e .log -w wordlists/common.txt

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/ext/FUZZ
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/common.txt
 :: Extensions       : .log
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

logs                    [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 415ms]
[INFO] Adding a new job to the queue: http://ffuf.me/cd/ext/logs/FUZZ

[INFO] Starting queued job on target: http://ffuf.me/cd/ext/logs/FUZZ

users.log               [Status: 200, Size: 19, Words: 4, Lines: 1, Duration: 96ms]
:: Progress: [9372/9372] :: Job [2/2] :: 437 req/sec :: Duration: [0:00:23] :: Errors: 0 ::

No 404 Status

Часто встречаются случаи, когда запрос к несуществующей странице обрабатывается, и мы получаем ответ со статус-кодом 200. Если запустить фаззер обычным образом на URLhttp://ffuf.me/cd/no404, то каждый запрос будет попаданием)

ffuf -u http://ffuf.me/cd/no404/FUZZ -w wordlists/common.txt

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/no404/FUZZ
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

.git_release            [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.listings               [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.cvsignore              [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.htaccess               [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.forward                [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.bashrc                 [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.gitmodules             [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.git/index              [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.rhosts                 [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]
.swf                    [Status: 200, Size: 669, Words: 126, Lines: 23, Duration: 98ms]

Перейду по первой же ссылке — http://ffuf.me/cd/no404/.git_release:

IMG

А вот и причина. Для того, чтобы отбросить ненужные варианты, можно применять различные фильтры. Попробуйте получить правильные ендпоинты)

Решение^3 ☕
cu63:~/ $ ffuf -u http://ffuf.me/cd/no404/FUZZ -w wordlists/common.txt -fs 669
  
        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/
      
       v2.1.0-dev
________________________________________________
  
  :: Method           : GET
  :: URL              : http://ffuf.me/cd/no404/FUZZ
  :: Wordlist         : FUZZ: /Users/cu63/wordlists/common.txt
  :: Follow redirects : false
  :: Calibration      : false
  :: Timeout          : 10
  :: Threads          : 40
  :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
  :: Filter           : Response size: 669
________________________________________________
  
  secret                  [Status: 200, Size: 25, Words: 4, Lines: 1, Duration: 96ms]
  :: Progress: [4686/4686] :: Job [1/1] :: 443 req/sec :: Duration: [0:00:11] :: Errors: 0 ::

Param Mining

Так же фаззинг отлично подходит для поиска скрытых параметров. Для этого FUZZ подставляется в URL следующим образом: https://some-site.com/page?FUZZ=1.

Давайте попробуем найти их для данного запроса: http://ffuf.me/cd/param/data.

cu63:~/ $ ffuf -u 'http://ffuf.me/cd/param/data?FUZZ=1' -w wordlists/parameters.txt

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/param/data?FUZZ=1
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/parameters.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

debug                   [Status: 200, Size: 24, Words: 3, Lines: 1, Duration: 98ms]
:: Progress: [2588/2588] :: Job [1/1] :: 442 req/sec :: Duration: [0:00:06] :: Errors: 0 ::

Rate Limited

На многих сайтах можно встретить ограничение на количество запросов в секунду.

Попробуем пофаззить данный URL: http://ffuf.me/cd/rate:

cu63:~/ $ ffuf -u http://ffuf.me/cd/rate/FUZZ -w wordlists/common.txt

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/rate/FUZZ
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

:: Progress: [4686/4686] :: Job [1/1] :: 441 req/sec :: Duration: [0:00:11] :: Errors: 0 ::

Ничего не найдено. Чтобы выяснить причину добавим 429 в отображаемые с помощью -mc 429:

ffuf -u http://ffuf.me/cd/rate/FUZZ -w wordlists/common.txt -mc 429

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/rate/FUZZ
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 429
________________________________________________

.well-known/oauth-authorization-server [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 100ms]
.well-known/openpgpkey  [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 101ms]
.well-known/reload-config [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 82ms]
.well-known/pvd         [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 84ms]
.well-known/posh        [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 84ms]
.well-known/security.txt [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 84ms]
.well-known/resourcesync [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 89ms]
.well-known/thread      [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 83ms]
.well-known/stun-key    [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 88ms]
.well-known/timezone    [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 96ms]
.well-known/webfinger   [Status: 429, Size: 178, Words: 8, Lines: 8, Duration: 93ms]

А вот и причина. 429 ошибка — это Too Many Requests. Замедлим наш фаззер, выставив задержку между запросами с помощью флага -p 0.1. Для увеличения скорости можно запустить несколько фаззеров одновременно с помощью флага -t.

cu63:~/ $ ffuf -u http://ffuf.me/cd/rate/FUZZ -w wordlists/common.txt -p 0.1 -t 5

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/rate/FUZZ
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 5
 :: Delay            : 0.10 seconds
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

oracle                  [Status: 200, Size: 19, Words: 4, Lines: 1, Duration: 97ms]
:: Progress: [4686/4686] :: Job [1/1] :: 26 req/sec :: Duration: [0:03:01] :: Errors: 0 ::

Pipes

Иногда не разумно хранить словарь каких либо значений, например, числовых id. В таком случае можно использовать pipes. Для этого напишу простейший цикл на Python:

for i in range(1, 1000):
    print(i)

Далее перенаправлю его вывод через pipes в fuff. Для того, чтобы ffuf принимал значения из пайпа, нужно использовать флаг -w -.

Попробую это на данном URL: http://ffuf.me/cd/pipes.

python pipe.py $>2 | ffuf -w - -u 'http://ffuf.me/cd/pipes/user?id=FUZZ'

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/pipes/user?id=FUZZ
 :: Wordlist         : FUZZ: -
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

657                     [Status: 200, Size: 13, Words: 3, Lines: 1, Duration: 83ms]
:: Progress: [999/999] :: Job [1/1] :: 460 req/sec :: Duration: [0:00:02] :: Errors: 0 ::

Так же значения могут храниться в закодированом виде, например, base64 или URL-encode. Возможно, даже используются хеши от значений. Для перебора таких параметров также удобно использовать пайпы.

Попробуйте найти нужное значение в base64 для этого URL: http://ffuf.me/cd/pipes/user2.

Решение^3 ☕
import base64

    
for i in range(1, 1000):
    print((base64.b64encode(str(i).encode('utf-8')).decode()))
python pipe.py | ffuf -w - -u 'http://ffuf.me/cd/pipes/user2?id=FUZZ'

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/pipes/user2?id=FUZZ
 :: Wordlist         : FUZZ: -
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

ODg4                    [Status: 200, Size: 13, Words: 3, Lines: 1, Duration: 94ms]
:: Progress: [999/999] :: Job [1/1] :: 438 req/sec :: Duration: [0:00:02] :: Errors: 0 ::
А тут уже нужен md5 для URL: http://ffuf.me/cd/pipes/user3.

Что такое md5?🤔
MD5 (Message Digest 5) — это 128-битный алгоритм хеширования. Предназначен для создания «отпечатков» или дайджестов сообщения произвольной длины и последующей проверки их подлинности. Широко применялся для проверки целостности информации и хранения хешей паролей.

Напишу скрипт:
import hashlib


for num in range(1, 1001):
    num_str = str(num)
    num_bytes = num_str.encode('utf-8')
    m = hashlib.md5()
    m.update(num_bytes)
    print(m.hexdigest())
Использую пайп:
cu63:~/ $ python ./pipe.py| ffuf -w - -u 'http://ffuf.me/cd/pipes/user3?id=FUZZ'

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me/cd/pipes/user3?id=FUZZ
 :: Wordlist         : FUZZ: -
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

4daa3db355ef2b0e64b472968cb70f0d [Status: 200, Size: 13, Words: 3, Lines: 1, Duration: 92ms]
:: Progress: [1000/1000] :: Job [1/1] :: 431 req/sec :: Duration: [0:00:02] :: Errors: 0 ::

Subdomains. Virtual Host Enumeration

Можно аналогичным образом искать субдомены. Для этого можно использовать HTTP-заголовок Host, чтобы указать домен. В ffuf для этого используется флаг -H: -h "Host: FUZZ.ffuf.me".

Найдем валидный субдомен:

ffuf -w wordlists/subdomains.txt -u http://ffuf.me -H "Host: FUZZ.ffuf.me" -fs 1495

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://ffuf.me
 :: Wordlist         : FUZZ: /Users/cu63/wordlists/subdomains.txt
 :: Header           : Host: FUZZ.ffuf.me
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response size: 1495
________________________________________________

redhat                  [Status: 200, Size: 15, Words: 2, Lines: 1, Duration: 93ms]
:: Progress: [1907/1907] :: Job [1/1] :: 429 req/sec :: Duration: [0:00:04] :: Errors: 0 ::