Уязвимости ViewState

Уязвимости ViewState

В статье рассказывается об уязвимостях ViewState, атаках и способах защиты.

Автор Тимур Юнусов, Positive Technologies

1. Общие сведения о ViewState

«Состояние представления — это метод, который платформа веб-страниц ASP.NET использует для сохранения значений страницы и элемента управления между циклами обработки. При отображении разметки HTML страницы, текущее состояние страницы и значения должны сохраняться во время обратного запроса, сериализуясь в строки в кодировке base64. Затем данные сведения помещаются в скрытое поле или поля состояния представления.»
MSDN
«Что делает ViewState?
- Сохраняет данные элементов управления по ключу, как хэш-таблица.
- Отслеживает изменения состояния ViewState'а.
- Сериализирует и десериализирует сохраненные данные в скрытое поле на клиенте.
- Автоматически восстанавливает данные на postback'ах.»

Из статьи разработчика ASP.NET о механизмах ViewState

Если еще проще, то ViewState – это скрытый параметр в HTML-форме, который передает серверу текущую структуру содержимого страницы. Пример использования: сохранение значений полей формы на странице во время постраничного пролистывания списков.

Несмотря на то, что существуют и активно используются методы избавления от ViewState и работы без него (в основном, с помощью СУБД), эта технология по умолчанию включена в ASP.NET и часто ее используют бездумно.

«Еще более важно понимать, чего ViewState НЕ делает.
Что не делает ViewState?
- ViewState не сохраняет автоматически состояние полей класса (скрытых, защищенных или открытых).
- ViewState не запоминает какую-либо информацию при загрузке страницы (только postback'и).
- ViewState не снимает необходимость загружать данные при каждом запросе.
- ViewState не отвечает за загрузку данных, которые были отправлены на сервер, например, введенных в текстовое поле (хотя ViewState и играет здесь важную роль).»

Из статьи разработчика ASP.NET о механизмах ViewState

Это, естественно, приводит к более глубоким проблемам – отсутствию фильтрации и непониманию того, как правильно должно работать веб-приложение.
Разработчики подчас думают, что раз ViewState – это сериализованная структура, да еще и «зашифрованная» base64, то никакой злоумышленник не сможет добраться до ее содержимого...

На самом же деле, если шифрование и проверка целостности (MAC) отключены, все гораздо проще. Декодируем base64:

Рис. 1. Декодирование VIEWSTATE с помощью base64_decoder.

Открываем декодированный файл в hex-редакторе и видим, что перед любой строковой переменной идут байты, указывающие на длину этой строки (количество байт зависит от длины строки: для строки <128 байт под длину переменной будет выделен один байт).

Рис. 2. Изменяем содержимое сериализованной структуры.

В авторитетных источниках указано, что алгоритм работы сериализации/десериализации в ASP.NET<2.0 – LosFormatter, а в >=2.0 – ObjectStateFormatter. Поэтому, для того чтобы изменить эту переменную, требуется вычислить длину новой строки, перезаписать строку, перезаписать байт (байты) с длиной строки, провести обратное кодирование base64 и подставить во __VIEWSTATE.

Рис. 3. Изменяем содержимое сериализованной структуры.

2. Уязвимости и атаки

Если помножить все вышеизложенное на низкий уровень знаний среднестатистического специалиста о правильной организации безопасности веб-приложения, становится понятно, что возможно проведение атак, использующих следующие уязвимости:
  • Межсайтовое выполнение сценариев (Cross-Site Scripting, XSS)
  • Подмена содержимого (Content Spoofing)
  • Внедрение операторов SQL (SQL Injection)
  • Утечка информации (Information Leakage)
  • Логические атаки (Logical Attacks)
  • Уязвимости самого ViewState
  • Прочие уязвимости

2.1. Межсайтовое выполнение сценариев, Подмена содержимого

Возможность изменения содержимого HTML-страницы следует из главного предназначения ViewState – «Сохранение значений страницы и элементов управления». Если данные из ViewState, помещаемые в тело HTTP-ответа, не проходят необходимую фильтрацию, то мы получаем «Подмену содержимого» и/или «Межсайтовое выполнение сценариев».

Уязвимая конфигурация:
EnableViewStateMac=false
ViewStateEncryptionMode=never|auto
(зависит от RegisterRequiresViewStateEncryption)
ViewStateUserKey=EMPTY

2.2. Утечка информации, Логические атаки

Если разработчик не использует шифрование параметра VIEWSTATE (Securing View State), злоумышленник может декодировать структуру параметра VIEWSTATE и извлечь оттуда конфиденциальные данные. Если же не используется и проверка целостности (MAC), то злоумышленник получает возможность изменить параметры, которые способны повлиять на логику работы веб-приложения, что может повлечь за собой «Обход аутентификации» (Authentication Bypass), «Обход авторизации» (Authorization Bypass), «Злоупотребление функциональными возможностями» (Abuse of Functionality) и т.д.

Уязвимая конфигурация:
ViewStateEncryptionMode=never|auto
EnableViewStateMac=false|true

2.3. Атаки на ViewState

Атакам подвержен и сам механизм ViewState. Например, в сентябре 2010 г. была опубликована уязвимость, позволяющая расшифровать ViewState, зашифрованный алгоритмом AES, с помощью отправки множества запросов серверу и отслеживания разных кодов ошибок [1].

Также в старых версиях (1.0, 1.1) возможны атаки типа «Отказ в Обслуживании» (Denial Of Service, DoS) (в случае, если VIEWSTATE не шифруется) и Replay-атаки (на зашифрованный VIEWSTATE). Последние представляют собой атаки на криптографический протокол, когда перехватываемый пакет можно отправить еще раз и он будет корректно воспринят, что вызовет нарушения в работе алгоритма. Об этих атаках писал Michal Zalewski еще в 2005 году [2].

2.4. Прочие уязвимости

Переменные, записанные в структуру ViewState, так же как и обычные переменные, передаваемые методами GET/POST/COOKIES, могут и должны проверяться на все остальные уязвимости, присущие веб-приложениям, такие как «Внедрение SQL-кода» (SQL Injection), «Выполнение команд ОС» (OS Commanding), а также на другие уязвимости классов «Выполнение кода», «Разглашение информации» и проч.

Уязвимая конфигурация:
EnableViewStateMac=false
ViewStateEncryptionMode=never|auto
(зависит от RegisterRequiresViewStateEncryption)

3. Защита

3.1. EnableViewStateMac

Значение по умолчанию: TRUE
Начиная с версии: 1.0
Включает MAC (Machine Authentication Check) – проверку значения параметра VIEWSTATE с помощью контрольной суммы.
Необходимо задать свойство EnableViewStateMac="True" в элементе Page.
Кроме того, необходимо для активации настроить свойства validationKey и validation элемента machineKey.
Поддерживаются встроенные алгоритмы шифрования: SHA1, MD5, 3DES, AES, HMACSHA256, HMACSHA384, HMACSHA512.

3.2. ViewStateEncryptionMode

Значение по умолчанию: Auto
Начиная с версии: 2.0
Позволяет шифровать параметр VIEWSTATE одним из следующих алгоритмов: DES, 3DES или AES.
Для активации необходимо настроить свойства decryptionKey и decryption элемента machineKey.

3.3. ViewStateUserKey

Значение по умолчанию: EMPTY
Начиная с версии: 1.1
Не все знают, что ViewState позволяет защитить не только себя от подмены, но и все приложение от CSRF с помощью параметра ViewStateUserKey.
ViewStateUserKey – это лишь механизм защиты. Обеспечивать случайность и непредсказуемость этого параметра – задача разработчика.
Необходимо задать свойство ViewStateUserKey="String" в элементе Page.

4. Заключение

Из разделов 2 и 3 видно, что в конфигурациях по умолчанию ViewState надежно защищен от уязвимостей ненулевого дня, однако очень часто, «намучившись» с постоянно выпадающими ошибками о нарушении целостности, неправильных аргументах и т.д., разработчики просто отключают «ключи, вызывающие ошибки», вместе с тем оставляя приложение незащищенным от различных атак.

Однако если веб-приложение настроено верно, вероятность возникновения ошибок и тем более уязвимостей можно свести к 0.

5. Ссылки

[1] http://weblogs.asp.net/scottgu/archive/2010/09/18/important-asp-net-security-vulnerability.aspx
[2] http://seclists.org/bugtraq/2005/May/27

Тени в интернете всегда следят за вами

Станьте невидимкой – подключайтесь к нашему каналу.