Привет, Codeby!
Расскажу тебе о том, как написать простой фаззер на Python.
Ты наверное хочешь спросить: зачем писать фаззер на Python, если уже есть
Пример:
Но ты скажешь, что есть расширение Turbo Intruder для Burp Suite, позволяющее производить фаззинг не покидая Burp,
я же тебе отвечу: во-первых в Turbo Intruder нет поддержки прокси, либо я этого не знаю, а если я ошибаюсь, то кинь в меня ссылкой , и во-вторых, могу же написать что то свое, почему бы не попробовать, согласись?
Сама идея возникла, когда я искал уязвимости при авторизации по номеру телефона через числовые коды в SMS. Нужен был удобный инструмент для подбора SMS-кодов.
В итоге, все это вылилось в фаззер, под названием rafuzz.
Фаззер работает через консоль, и принимает следующие параметры:
Пример запуска:
Одна из основных частей фаззера это класс для парсинга http запроса из Burp Suite:
В классе BurpRequestParser все просто, без использования регулярных выражений проходим построчно по http запросу и сохраняем в словаре результаты в ключах url, headers, method, path, http_version, post_data, в headers при этом также создаются пары ключ-значение по информации по заголовкам.
Вторая важная часть - это класс описания запроса
Результат парсинга http запроса передается в конструктор класса Request, в итоге получаем объект запроса с которым достаточно удобно обращаться к параметрам запроса, например request.url, request.method, request.post_data и др.
Основная логика фаззера описана в функции main:
Если коротко описать логику работы этой функции, то в нем выполняются следующие шаги:
Из минусов в текущей реализации:
Я думаю это все, что я тебе хотел рассказать про фаззер. Не суди строго, это моя первая статья здесь.
Ссылка на репозиторий GitHub - radaram/rafuzz: Fuzzer for working with an http request presented in text format from Burp Suite.Ставьте пальцы вверх, подписывайтесь
До встречи, Codeby!
Расскажу тебе о том, как написать простой фаззер на Python.
Ты наверное хочешь спросить: зачем писать фаззер на Python, если уже есть
Ссылка скрыта от гостей
? Я тебе отвечу - мне нужна была возможность использовать http запросы, представленные в текстовом формате, которые были получены из Burp Suite, например, так умеет sqlmap с параметром -r, в котором передается путь до текстового файла c http запросом.Пример:
HTTP:
GET /get?test=FUZZ HTTP/1.1
Host: httpbin.org
User-Agent: test-agent
Accept: application/json
Content-Type: application/json;charset=utf-8
Connection: close
Content-Length: 16
Но ты скажешь, что есть расширение Turbo Intruder для Burp Suite, позволяющее производить фаззинг не покидая Burp,
я же тебе отвечу: во-первых в Turbo Intruder нет поддержки прокси, либо я этого не знаю, а если я ошибаюсь, то кинь в меня ссылкой , и во-вторых, могу же написать что то свое, почему бы не попробовать, согласись?
Сама идея возникла, когда я искал уязвимости при авторизации по номеру телефона через числовые коды в SMS. Нужен был удобный инструмент для подбора SMS-кодов.
В итоге, все это вылилось в фаззер, под названием rafuzz.
Фаззер работает через консоль, и принимает следующие параметры:
Параметр | Описание | Обязательный параметр |
frequest | Путь к файлу с http запросом | да |
protocol | Протокол запроса http/https | да |
fproxies | Путь к файлу со списком прокси | нет |
range_start | Начало диапазона для SMS-кода | да |
range_end | Конец диапазона для SMS-кода | да |
range_step | Шаг для диапазона | нет |
min_len | Минимальная длина кода | нет |
stop_status | Http статус при получении которого фаззер останавливает работу | нет |
output_type | Тип вывода all/found, по умолчанию found all - выводит в консоль все ответы API цели found - выводит в консоль ответ API цели если был угадан SMS-код | нет |
print_request | Вывод в консоль http запроса | нет |
Пример запуска:
Bash:
python3 rafuzz.py --frequest request.txt --range_start 1 --range_end 5 --min_len 4 --protocol http --fproxies proxies.txt --stop_status 200 --output_type all --print_request True
Одна из основных частей фаззера это класс для парсинга http запроса из Burp Suite:
Python:
class BurpRequestParser(object):
def __init__(self, text: str):
self.text = text
def parse_text(self):
result = {
"headers": {}
}
lines = self._split_into_list(self.text)
request_method, path, http_version = lines[0].split(" ")
result["method"] = request_method
result["path"] = path
result["http_version"] = http_version
start_post_data = False
i = 1
for line in lines[1:]:
if line in ("\n", ""):
start_post_data = True
break
values = line.split(":")
header = values[0].strip()
value = ":".join(values[1:]).strip()
result["headers"][header] = value
i += 1
post_data = ""
if start_post_data and len(lines) > i:
for line in lines[i+1:]:
post_data += line
if post_data:
result["post_data"] = post_data
url = result["headers"]["Host"] + path
result["url"] = url
return Request(result)
def _split_into_list(self, text):
return text.split("\n")
В классе BurpRequestParser все просто, без использования регулярных выражений проходим построчно по http запросу и сохраняем в словаре результаты в ключах url, headers, method, path, http_version, post_data, в headers при этом также создаются пары ключ-значение по информации по заголовкам.
Вторая важная часть - это класс описания запроса
Python:
class Request(object):
def __init__(self, data: dict):
self.data = data
def __getattr__(self, name: str):
try:
return self.data[name]
except KeyError:
return None
def __setitem__(self, key, item):
self.data[key] = item
def __getitem__(self, key):
return self.data[key]
def __str__(self):
request_text = f"{self.method} {self.path} {self.http_version}\n"
headers = "\n".join(["{}: {}".format(h, v) for h, v in self.headers.items()])
request_text += headers
if self.post_data:
request_text += "\n\n" + self.post_data
return request_text
def items(self):
return self.data.items()
def set_data(self, data: dict):
self.data = data
def get_data(self):
return self.data
Результат парсинга http запроса передается в конструктор класса Request, в итоге получаем объект запроса с которым достаточно удобно обращаться к параметрам запроса, например request.url, request.method, request.post_data и др.
Основная логика фаззера описана в функции main:
Python:
async def main(args):
backend_parser = BurpRequestParser
rp = RequestParser(args.frequest, backend_parser)
request = rp.parse_text()
request.url = args.protocol + "://" + request.url
key_request, subkey_request = find_world_in_request(request)
if args.fproxies:
ph = ProxiesHandler(args.fproxies)
else:
ph = None
response_handler = ResponseHandler(
stop_status=args.stop_status,
output_type=args.output_type,
print_request=args.print_request,
)
range_step = args.range_step or 1
async with aiohttp.ClientSession() as session:
for value in get_values_from_range(args.range_start, args.range_end, range_step, args.min_len):
replica_request = Request(request.get_data().copy())
replica_request.url = request.url
replace_world_in_request(replica_request, key_request, subkey_request, value)
no_answer = True
attempt_request_limit = 10
request_count = 0
response = None
while no_answer:
proxy = None
if ph:
if not ph.proxies:
print("List of working proxies is empty")
sys.exit()
proxy = ph.get_random_proxy()
try:
response = await do_request(session, replica_request, proxy=proxy)
except (aiohttp.client_exceptions.ClientProxyConnectionError, asyncio.TimeoutError):
print(f"There was failed request attempt with the proxy {proxy}")
if ph:
ph.exclude_not_working_proxy(proxy)
else:
no_answer = False
finally:
request_count += 1
if no_answer and request_count > attempt_request_limit:
print("you have exceeded maximum request limit")
break
await response_handler.handle(replica_request, response)
Если коротко описать логику работы этой функции, то в нем выполняются следующие шаги:
- Парсинг http запрос из Burp Suite,
- Обработка списка прокси если они были указаны
- Создание сессия через aiohttp
- Итерация по диапазонам SMS-кода
- Замена в объекте запроса ключевого слова FUZZ на новый SMS-код
- Выполнение запроса через aiohttp
- Исключение прокси из списка если через него не проходил запрос
- Печать в консоль результата
Из минусов в текущей реализации:
- Работа только с числовыми значениями для перебора
- Отсутствие подробной документации
- Малое количество тестов
- Отсутствие замеров по производительности
Я думаю это все, что я тебе хотел рассказать про фаззер. Не суди строго, это моя первая статья здесь.
Ссылка на репозиторий GitHub - radaram/rafuzz: Fuzzer for working with an http request presented in text format from Burp Suite.
До встречи, Codeby!
Последнее редактирование модератором: