LIMB
Вход Регистрация

тема

403? Не, не слышал! Как пройти мимо запретных дверей веба

YmbMember · · 1 ответов · 517 просмотров

Вступление

Не удалось прогрузить медиа


Брут директорий - стандартный процесс разведки. Но как же грустно, когда фазер нашёл смачный эндпоинт по типу logs.txt и при переходе по нему сайт бросает в лицо какой-то плохой статус код, ошибку forbidden на пол экрана и средний палец.
Я думаю каждый сталкивался с неприятными статус кодами в ответе (по типу 400 401 403 500 …) и думал что это конец. Но погодите-ка. В этой статье я бы хотел поделиться методами обхода запретов на вкусные директории прямиком из моей методологии. 

Этап 1. Тихонько анализируем
Первый этап в любом тестировании - иметь хоть примерное понимание того, как работает бэк енд. Наведу примеры на практике, как это делаю я. Для примера возьмем, вот такую интересную ссылку, какая бросает 403 forbidden в лицо:
https://target.com/database
Супер. Теперь нам надо понять, как работают фильтры. Поясню, как это делаю я на пальцах:
  1. Добавляем какие то любые эндпоинты в конце, например
https://target.com/database/random
https://target.com/database/random.json

Если запрет стоит на определенные файлы в конкретной директории, это лучше чем если запрет стоит даже на несуществующие файлы в директории /database. Иногда я наблюдаю, что запрет стоит на префиксы:

target.com/.htaccess => 403
target.com/.htarandom => 403
target.com/.hta => 403


То Есть все в ссылки с префиксом .hta у нас в блоке.
Обращаем также внимание на разницу в ответах. Иногда бывает такое, что в зависимости от запрашиваемого эндпоинта ответ разный

Не удалось прогрузить медиа



























Не удалось прогрузить медиа




























Так же всплыла инфа, что сайт стоит на nginx/1.25.5 и фильтрует доступ, скорее всего именно он. Смотрим в гугле, возможно есть какие-то интересные техники по обходу специально под nginx 1.25.5

У вас возникнет вопрос “А зачем мы это все делали?”. Иногда встречается настолько много запрещенных директорий, что тратить время на полноценный тест каждой не очень хочется. Поэтому я беру 403 директории какие ведут себя по разному и тестирую их. Часто бывает такое, что сайт изначально писал один разработчик, а недавно допилил абсолютно другой. Как мы все знаем, это часто приводит к определенным проблемам в безопасности. Разработчик 1 мог настроить запрет не так как Разработчик 2 и оставить какой-то misconfiguration

Этап 2: приступаем к обходу

Прогон инструментами
Есть много простых техник для обхода. Можно добавлять кучу слешей в путь, можно устроить игру с нулевыми байтами, добавлять path traversal и так далее … . Можно менять http версию, методы, добавлять всякие заголовки. Их все я вам изведусь перечислять
Это хоть и очень просто, но времязатратно и скучно. Я просто использую для этого всякие простые скрипты с гитхаба, какие прекрасно справляются с этой задачей, хоть и в 98 проц случаев разбрасываются false positiv’ами. Они довольно примитивные, но эффективные. Вот вам их список:
https://github.com/nazmul-ethi/Bypass-Four03
Не удалось прогрузить медиа






































bash bypass-Four03.sh файл директория

https://github.com/Dheerajmadhukar/4-ZERO-3
Этот инструмент мне нравится тем, что он проводит больше всего тестов из всех перечисленных инструментов. Запускаем скрипт этой командой для проведения всех возможных тестов
bash 403-bypass.sh -u таргет/путь --exploit


Не удалось прогрузить медиа







































https://github.com/trap-bytes/403jump
Этот инструмент мне очень нравиться тем, что он имеет относительно не скудный функционал (если сравнивать из всех вышеперечисленных)



Не удалось прогрузить медиа





















Из главных плюсов могу отметить, что можно проксировать трафик (рекомендую всегда проксировать трафик через burp suite с любым инструментом и мониторить запросы/ответы через logger) и указать куки, если какие-то нашёл param miner.
Запускаем через 
403jump -t таргет/путь -другие_аргументы

Оставлю ниже ещё небольшой подобных инструментов, но мне с головой хватает тех что я перечислил выше


https://github.com/thecyberneh/inside403
https://github.com/Dheerajmadhukar/4-ZERO-3



Кодируем
Ну и кроме этого я делаю небольшие тесты с url encoding’ом. Позаимствовал я этот метод с конференции defcon. Ниже кратко расписал вам, как это работает:

Не удалось прогрузить медиа

























%2573 это дважды url энкоднудая буква s
s → %73 (одинарное кодирование)
%73 → %2573 (двойное кодирование).


То Есть, прокси не разрешал нам заходить на эндпоинт getAllUsers. При запросе на getAllUser%2573, скорее всего, ngnix декодировал у себя URL 1 раз, и сверял, стоит ли запрет по этому пути или нет. Он декодировал getAllUser%2573 и получал getAllUser%73. Понимал что запрета на этот эндпоинт нет и возвращал нам ответ

Советую так играться не только с последней буквой а проявитть немного больше фантазии

Смена буквы на заглавную
Ну тут все до простоты банально, даже мой дед справиться. Возьмём вот такой URL
https://таргет/admin => 403
Тут мы просто играем с буквами, меняя маленькие на заглавные и наоборот
https://таргет/admiN => 200
Если же https://таргет/Admin => 403, то меняем A на а. Суть вы уловили, не будем на этом долго задерживаться   

Логический обход
Тут нам приходит в помощь param miner. Сканируем 403 страницы на наличие  скрытых атрибутов в куки, параметры и POST параметры. Любые находки какие он нашел нужно детально проанализировать. Так как тут нужно включать логику, определенного чек листа нету. Но наведу пару примеров чтобы вы больше поняли о чём идёт речь
Найден параметр forbidden? Пробуем значение false
Найден атрибут view? Пробуем значение true
Найден параметр restricted? пробуем значение false
И всё в таком духе, тут уже думаем сами

Также можно попробовать поманипулировать с Referer. Иногда бек энд выдает 403, базируясь на referer’e. Наведу пример:
Если по ссылке https://таргет/admin/users даёт 403, то запрос к этому же эндпоинту но с 
Referer: https://таргет/admin/ может вернуть 200 =)

Манипуляция с версией http
Сейчас в RFC описаны 5 версий HTTP (часть актуальны, часть устарели). Подмена версии запроса на любую из них, порой позволяет обойти фильтры

Не удалось прогрузить медиа











Вы мне скажите “YmbMember, ты что накурился? Скрипты какие были в начале ведь манипулируют с версиями http”. Соглашусь, но они делают это не со всеми существующими версиями.


Не удалось прогрузить медиа




















В запросе версия HTTP находится вот тут. Но есть одна проблема. Всеми любимый Burp Suite не поддерживает никаких версий HTTP кроме HTTP/1.0, HTTP/1.1 и HTTP/2. Для отправки запросов и получения ответов будем использовать curl

curl --http0.9 http://таргет.com/path
curl --http3 https://таргет.com/path
curl --http1.0 http://таргет.com/path


Метод с вейбек машиной
Иногда запрет на директорию — лишь приглашение для веб-архива. У меня было пару интересных случаев, когда файлы отдающие 403 были заархивированы вейбек машиной
https://web.archive.org/


Не удалось прогрузить медиа





















По одному файлу в поиск устанете вбивать вручную. Советую через waybackurls скачать все заархивированные ссылки в файл
waybackurls таргет.com > файлкудасохраняем
И в этом файле глазами побегать и найти что-то интересное 

Обход 403 на поддомене microsoft
А вот это нереально интересный кейс. Кратко и по делу: Меняем HTTP версию на 1.0 (это можно сделать в burp suite) и удаляем все строки в запросе кроме первой

Не удалось прогрузить медиа


















Не удалось прогрузить медиа









































Почему же это работает ? Все дело в особенности HTTP версии 1.0. Если в заголовке не указывать Host, а сервер и защита настроены неправильно, то туда автоматически подставляется адрес самого сервера. В итоге запрос выглядит так, будто он отправлен с локальной сети. Но для этого нужно чтоб цель поддерживала HTTP 1.0, что встретишь не часто под конец 2025 года. Кому интересно с этим ознакомится подробнее, оставлю референс: https://infosecwriteups.com/403-bypass-lyncdiscover-microsoft-com-db2778458c33

Многосайтовость
Звучит такой метод конечно не очень, но на большее моей фантазии не хватило. Предложите как назвать такой метод в комментариях
Один сервер может запускать одновременно несколько доменов и поддоменов. Обычно их размещают в отдельных папках, например:
  • /var/www/html/ — сайт

  • /var/www/html/subdomain/ — поддомен
И таким способом можно обойти 403. Наведу пример на реальном таргете, с каким я столкнулся при тестировании.
https://blog.site.io/xmlrpc.php => 403

Не удалось прогрузить медиа















https://site.io/blog/xmlrpc.php => 200



Не удалось прогрузить медиа





















Чтобы понять, существует ли функция многосайтовости на сайте, можем просто пробрутить названия поддоменов на основном домене. Я попытался расписать все более понятно на этой схеме:
Не удалось прогрузить медиа


























P.s: Сори за шакальное качество, наверное надо схемы перестать рисовать в paint =)


Заголовки
Как известно, в вебе существует огромное количество официально зарегистрированных HTTP-заголовков. Но на практике их ещё больше — разработчики нередко создают кастомные (неофициальные) заголовки, которые применяются в самых разных целях. Для нас есть парочку часто используемых, какие представляют особый интерес. А конкретно

X-Forwarded-For
X-Forward-For
X-Forwarded-Host
X-Forwarded-Proto
Forwarded
Via
X-Real-IP
X-Remote-IP
X-Remote-Addr
X-Trusted-IP
X-Requested-By
X-Requested-For
X-Forwarded-Server
X-ProxyUser-Ip
Client-IP
Host
X-Originating-IP
X-Custom-IP-Authorization


Если обобщить, то грубо говоря эти заголовки нужны, чтобы сервер знал настоящий IP клиента, через что он подключен, и по какому протоколу пришёл запрос.
Для этого метода нам нужно получить реальный айпи адрес сайта и подставить его в значение всех этих заголовков


P.s: я писал как найти реальный айпи сайта, советую ознакомиться


Тут все просто - переходим на forbidden страницу и через burp intruder прогоняем запрос с каждым из них
Чтобы вручную к заголовкам не подставлять значение с IP адресом, я написал простенький Python скрипт какой за секунду вам сгенерирует все это дело

Не удалось прогрузить медиа






























Python:
print("""From YmbMember для LIMB cc""")
ip = input("Введите IP: ")

headers = {
    "X-Forwarded-For": ip,
    "X-Forward-For": ip,
    "X-Forwarded-Host": ip,
    "X-Forwarded-Proto": ip,
    "Forwarded": ip,
    "Via": ip,
    "X-Real-IP": ip,
    "X-Remote-IP": ip,
    "X-Remote-Addr": ip,
    "X-Trusted-IP": ip,
    "X-Requested-By": ip,
    "X-Requested-For": ip,
    "X-Forwarded-Server": ip,
    "X-ProxyUser-Ip": ip,
    "Client-IP": ip,
    "Host": ip,
    "X-Originating-IP": ip,
}

print("\nСформированные заголовки:")
print("""


""")
for k, v in headers.items():
    print(f"{k}: {v}")

print("X-Custom-IP-Authorization: LOCALHOST.LOCAL")
print("Host: localhost")

Так же можете попробовать дать в скрипту локальные айпи адреса. Например: 127.0.0.1, 0.0.0.0, localhost


Заключение

Надеюсь смог доступно описать все что хотел. Не ленитесь, применяйте все техники какие знаете и это даст свои плоды. Удачи
Не удалось прогрузить медиа
👍41 😁6 🤔9 💯9
Спасибо за советы, пару методов и в правду оказались полезными. Я думал, что испробовал все возможные). Также можно добавить сюда изменение Host-хэдэра (иногда и в правду работает), по типу:
```
Host: [email protected]
```
👍1

Гостевой просмотр. Чтобы отвечать и ставить реакции, войдите или зарегистрируйтесь.