От XSS уязвимости до полного административного доступа
В этом посте я расскажу вам о недавнем реальном тестировании, где я использовал stored XSS для получения административного доступа, даже несмотря на защиту с использованием HTTPOnly флага в cookies. Также я продемонстрирую, как мне удалось обойти эту меру безопасности и захватить учетную запись администратора.
Давайте начнем с краткого объяснения, что такое защита HTTPOnly и как она помогает разработчикам предотвратить кражу учетных данных через cookies.
Пару слов о cookies, этот механизм аутентифицирует пользователя и различает каждого в зависимости от их привилегий в веб-приложении. Cookies имеют различные меры безопасности, чтобы улучшить их использование и защитить конечного пользователя.
Некоторые из доступных атрибутов cookies:
Объяснение HTTPOnly от PHP.net:
Когда установлено в true, cookie будет доступно только через протокол HTTP. Это означает, что cookie не будет доступно для языков программирования, таких как JavaScript.
Это значит, что если наш XSS payload является частью HTML DOM, мы все равно не сможем получить доступ к значению cookie, чтобы выдать себя за жертву для захвата аккаунта.
Нам нужно найти альтернативные пути для эксплуатации нашей XSS:
После объяснения, что такое HTTPOnly, давайте углубимся в суть атаки:
Наше путешествие начинается с клиента, который владеет социальной медиа-платформой, на которой размещаются пользовательские посты и раздел комментариев для взаимодействия с другими пользователями.
Страница комментариев приложения выглядит примерно так:
Первое, что сразу приходит в голову, это внедрить тестовый XSS-payload, чтобы увидеть, отражается ли он обратно (временно или постоянно) на фронтенде приложения.
К сожалению, это не сработало из-за защиты CloudFlare, внедренной администратором при развертывании приложения:
Значит от нас потребуется гораздо больше усилий, чтобы обойти эту защиту и внедрить нашу вредоносную XSS нагрузку.
Мы можем попытаться обойти CloudFlare Proxy защиту и раскрыть исходный IP-адрес веб-сервера с помощью некоторых техник или найти HTML / JavaScript нагрузку, которая «обманет» CloudFlare, чтобы тот пометил ее как допустимую для выполнения на фронтенде.
На этот раз я выбрал второй вариант.
После нескольких попыток внедрить классические XSS нагрузки из списка xss-payload-list, все XSS, которые я вставил, были отфильтрованы прокси-сервером CloudFlare и помечены как неисполнимые.
На этом этапе я понял, что нужно конкретно постараться и найти специально разработанную нагрузку для обхода CloudFlare защиты.
Наконец, я придумал рабочую нагрузку, которая отразилась обратно в DOM HTML, а именно:
И мы получили отстутк на наш временный вебхук от XSS!
Примечание: важно отметить, что мы имеем дело со stored XSS, так как комментарии сохраняются в базе данных приложения и извлекаются каждый раз, когда пользователь посещает соответствующий раздел комментариев на посте.
На этом этапе у нас есть проверенная точка инъекции, но этого мало. Нужно найти способ полностью использовать потенциал воздействия этой уязвимости.
Кража cookie администратора исключена (помните о флаге HTTPOnly?). Так что я пришел к осознанию, что мы могли бы манипулировать непосредственно HTML DOM.
Возвращаемся на этап Разведки...
На начальном этапе исследования веб-приложения мой плагин Wappalyzer для Chrome определил, что приложение было написано на Python:
На сегодняшний день существует несколько популярных Python-фреймворков для веб-разработки, такие как Django и Flask.
Изучив исходный код HTML, можно выявить фреймворк Django:
Этот фреймворк обычно управляется через /admin, со страницей под названием «Django Administration»:
Конечно, на этом этапе у меня не было прав администратора, и я получил сообщение об несанкционированном доступе при попытке зайти на страницу с уже авторизованным cookie.
Держитесь... далее ещё интереснее...
Мне пришла блестящая идея! Мы можем отправлять XHR/AJAX запросы на /admin от имени авторизованного пользователя (конечно, с правами администратора).
Это позволит нам украсть HTML-контент страницы Django Admin, извлечь CSRF nonce-токен, а затем отправить GET/POST запрос.
Так как мы работаем в рамках того же домена, в этом сценарии не происходит нарушения Same-origin policy, что позволяет нам изменять и удалять данные клиента, включая сброс их личных паролей 😈
А главная фишка в том, что нам не потребовалась фишинговая атака или какие-либо перенаправления на мою страницу с XSS, так как страница с комментариями изначально доступна всем!
Последняя нагрузка использовала двойной вызов функций JavaScript «fetch» для того, чтобы сначала получить содержимое страницы /admin, а затем отправить ответ обратно на мой экземпляр webhook:
Контент со страницы администратора Django был захвачен в разделе Raw Content, как показано ниже:
И наконец, отрендеренная HTML-страница 🥳
Заключение
В этой статье были продемонстрированы нестандартные способы использования простой XSS атаки, даже с такими сильными защитами, как HTTPOnly.
Никогда не надо недооценивать такую простую уязвимость, как XSS, даже в современных быстро развивающихся веб-приложениях, основанных на передовых технологиях. Ваша фантазия может привести вас к новым высотам — используйте её с умом!