Макросъёмка вскрытого чипа материнской платы сервера IIS с обугленными следами на кристалле, рядом экран с искажённым Base64-блоком ViewState в пурпурных пикселях.


Февраль 2026 года, Mandiant фиксирует компрометацию веб-сервера с LMS-платформой KnowledgeDeliver - один hardcoded machineKey из стандартного web.config дал атакующему RCE на произвольном экземпляре без аутентификации. CVE-2026-5426, CVSS 9.1 (Critical). За несколько месяцев до этого тот же сценарий отработал против Sitecore: sample machineKey из deployment guide 2017 года остался в продакшене у клиентов (CVE-2025-53690, CVSS 9.0, CISA KEV). А в июне 2025-го Kudelski Security разгребал incident response на ASP.NET-приложении в секторе здравоохранения - публично известный machineKey, ViewState-инъекция, Godzilla webshell в памяти, Cobalt Strike. Три инцидента за год, один и тот же примитив: десериализация ViewState в ASP.NET при известном криптографическом ключе. И он работает как часы.

Механика ViewState и роль machineKey​

ViewState - встроенный механизм ASP.NET Web Forms для сохранения состояния страницы между HTTP-запросами. При рендеринге HTML сервер сериализует текущее состояние контролов через ObjectStateFormatter в Base64-строку и кладёт её в скрытое поле __VIEWSTATE. При postback сервер десериализует полученное значение и восстанавливает состояние. Механизм придумали до того, как индустрия осознала масштаб угроз десериализации - и именно поэтому ASP.NET Web Forms до сих пор остаётся настолько привлекательной целью. Подробнее - в нашем обзоре cve эксплойт разработка.

Для защиты от подмены используется machineKey - пара криптографических ключей из web.config или machine.config:
  • validationKey - формирует MAC (Message Authentication Code) для проверки целостности ViewState
  • decryptionKey - шифрует содержимое
Оба ключа хранятся как ASCII hex-строки. Если атакующий знает эти ключи - он подписывает произвольный сериализованный объект так, что сервер принимает его за легитимный ViewState. Десериализация ObjectStateFormatter допускает gadget-цепочки из ysoserial.net (TypeConfuseDelegate, TextFormattingRunProperties, ActivitySurrogateSelector), и результат предсказуем: выполнение произвольного кода на сервере. По OWASP Top 10 (2021) это пересечение A08 (Software and Data Integrity Failures - insecure deserialization) и A05 (Security Misconfiguration - hardcoded credentials).

Бизнес-логика атаки прямая: RCE через ViewState deserialization ASP.NET открывает дорогу к web shell (T1505.003, Persistence), вытаскиванию конфигов для дальнейших ключей, разведке хоста (T1082, Discovery) и латеральному движению. В инциденте Mandiant с Sitecore после начального RCE атакующий архивировал корневую директорию веб-приложения (\inetpub\sitecore\SitecoreCD\Website), создавал локальные учётки администраторов и дампил SAM/SYSTEM для компрометации кэшированных credentials. CrowdStrike в Global Threat Report 2025 фиксирует среднее время латерального движения после initial access в 62 минуты (рекорд - 51 секунда). Полная цепочка от ViewState RCE до доменного контроля укладывается в этот тайминг.

Хронология защиты ViewState​

Механизм прошёл несколько итераций, и понимание этой хронологии определяет выбор тест-кейса при эксплуатации:
  • До 2014 - параметр EnableViewStateMac=false полностью отключал MAC. machineKey не нужен - payload принимается без подписи (MAC validation bypass ASP.NET в чистом виде).
  • Сентябрь 2014 - Microsoft выпустил hotfix KB2905247, запретивший отключение MAC через EnableViewStateMac в ASP.NET >= 1.1.
  • 2016, ASP.NET >= 4.5 - ViewState принудительно защищён MAC и шифрованием. Значения EnableViewStateMac=false и ViewStateEncryptionMode=false просто игнорируются.
Технически обход MAC возможен через реестр (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{Version}, ключ AspNetEnforceViewStateMac = 0), но на практике это экзотика. Основной вектор - не отключение MAC, а знание machineKey.

Как найти machineKey: web.config, Badsecrets и OSINT​

Поиск machineKey - первый этап эксплуатации ViewState в ASP.NET. Способов несколько, и часто они не требуют ничего сложного.

web.config и machine.config​

Любая уязвимость типа arbitrary file read (LFI, XXE, SSRF с обработчиком file:///) в ASP.NET-приложении фактически эквивалентна RCE: достаточно прочитать web.config из корня приложения. Как формулирует Black Lantern Security, «the bar for total compromise of the web server is pushed all the way down to just read-access to files in the webroot». По MITRE ATT&CK это реализация техники Credentials In Files (T1552.001, Credential Access).

Стандартные пути для machine.config:
  • 32-bit: C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config
  • 64-bit: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config
Если machineKey не задан явно в web.config, IIS использует автосгенерированный ключ из machine.config. Тут эксплуатация требует доступа к системному конфигурационному файлу, что заметно усложняет задачу.

Badsecrets и Blacklist3r: обнаружение публичных ключей​

Тысячи machineKey утекли через форумы разработчиков, sample-конфигурации в документации вендоров, ответы на StackOverflow и публичные GitHub-репозитории. Badsecrets (Python, от Black Lantern Security) содержит корпус из нескольких тысяч таких ключей и проверяет целевое приложение за секунды: badsecrets --url https://target/page.aspx. Инструмент сам вытаскивает [B]VIEWSTATE и [/B]VIEWSTATEGENERATOR из HTML-ответа сервера и сверяет с базой. Если страница не рендерит ViewState напрямую, Badsecrets дополнительно тестирует токены WebResource.axd и ScriptResource.axd. Для массового сканирования инструмент интегрирован как модуль BBOT: bbot -f subdomain-enum -m badsecrets -t target.com.

Blacklist3r (AspDotNetWrapper.exe) - более ранняя альтернатива с тем же смыслом, но требует Windows/.NET: AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata <viewstate_value> --purpose=viewstate --modifier=<generator> --macdecode. На пентесте я обычно начинаю с Badsecrets - работает на Linux и не тянет за собой зависимости. Blacklist3r подключаю когда нужна расшифровка конкретного ViewState для анализа содержимого.

Поиск machineKey в открытых репозиториях​

OSINT-фаза при десериализации ASP.NET пентесте часто недооценивается. GitHub-дорки, которые работают:
  • "machineKey" "validationKey" extension:config
  • "machineKey" site:github.com filetype:xml
  • Поиск конкретных строк из документации целевого вендора (sample keys из installation guides)
В инциденте CVE-2025-53690 machineKey был опубликован в официальных Sitecore deployment guides для XP 9.0 и Active Directory 1.4 (и более ранних версий). В CVE-2026-5426 - стандартный web.config с hardcoded ключами поставлялся вместе с KnowledgeDeliver. Оба случая - CWE-321 (Use of Hard-coded Cryptographic Key). По MITRE ATT&CK переиспользование таких ключей реализует технику Reduce Key Space (T1600.001, Defense Impairment): криптографическое пространство ключей сводится к конечному списку известных значений. По сути, шифрование есть - а толку ноль.

Разбор CVE-2026-5426 и CVE-2025-53690

CVE-2026-5426: KnowledgeDeliver​

CVSS: 9.1 (Critical). Вектор: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
CWE: CWE-321 (Hard-coded Cryptographic Key) + CWE-502 (Deserialization of Untrusted Data)
EPSS: 0.0101, percentile 0.6074 (выше медианы)
CISA SSVC: Track. Exploitation: none, Automatable: yes, Technical Impact: total

KnowledgeDeliver - LMS от Digital Knowledge, распространённая в Японии. Все инсталляции до 24 февраля 2026 года использовали стандартизированный web.config с идентичными machineKey. Получил ключ из одного экземпляра (или из стандартного конфига) - скомпрометировал любой другой.

Вектор CVSS показателен: атака по сети (AV:N), низкая сложность (AC:L), без привилегий (PR:N), без взаимодействия пользователя (UI:N). CISA оценивает как автоматизируемую (Automatable: yes) - имея ключ и шаблон payload, эксплуатацию можно раскатать на все экземпляры платформы. Два CWE в одном CVE отражают двойную природу проблемы: hardcoded ключ (CWE-321) превращает штатную десериализацию (CWE-502) в RCE-вектор.

CVE-2025-53690: Sitecore​

CVSS: 9.0 (Critical). Вектор: AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
CWE: CWE-502 (Deserialization of Untrusted Data)
EPSS: 0.5109, percentile 0.9885 (Top 5% - очень высокая вероятность эксплуатации)
Затронутые продукты: Experience Manager (XM) до 9.0, Experience Platform (XP) до 9.0, Experience Commerce, Managed Cloud
CISA KEV: добавлена 2025-09-04, дедлайн патчинга 2025-09-25. SSVC: Act, Exploitation: active

По данным Mandiant, атакующий слал HTTP POST-запросы к /sitecore/blocked.aspx - легитимная страница Sitecore, доступная без аутентификации и содержащая скрытую ViewState-форму. Сервер зафиксировал Event ID 1316 (event code 4009) с сообщением Viewstate verification failed - первый запрос с кривым payload. Последующие запросы возвращали HTTP 200 - десериализация отработала.

Расшифровка захваченного ViewState (27760 байт в зашифрованном виде) выявила встроенную .NET-сборку Information.dll - малварь WEEPSTEEL. Штука собирает информацию об ОС, дисках, сетевых адаптерах и процессах, сериализует в JSON и отправляет через скрытое поле __VIEWSTATE в HTTP-ответе. Канал эксфильтрации маскируется под легитимный ASP.NET-трафик - красиво, надо признать.

Отличие от CVE-2026-5426: Attack Complexity = High (AC:H) и Scope = Changed (S:C) - уязвимость бьёт за пределами уязвимого компонента. EPSS 0.51 (Top 5%) подтверждает активную эксплуатацию. На GitHub доступен публичный PoC-репозиторий ErikLearningSec/CVE-2025-53690-POC.

Третий инцидент: ASP.NET в здравоохранении​

Kudelski Security в июне 2025 года описал incident response на публично-доступном ASP.NET-приложении. machineKey совпал с известными из публичных списков. Характерная деталь: в метаданных загруженной .NET-сборки обнаружился PDB-путь C:\Users\hbada\Desktop\ActivitySurrogateSelector\LoadLibrary\obj\Debug\LoadLibrary.pdb - прямое указание на использование gadget ActivitySurrogateSelector из ysoserial.net. Даже не потрудились почистить артефакты. Event ID 1316 (event code 4009) в логах приложения зафиксировал попытки инъекции. После RCE атакующий развернул in-memory Godzilla webshell (загрузка .NET-сборок из HTTP-параметра, AES-расшифровка, динамическая загрузка без записи на диск) и Cobalt Strike. Дополнительно - AMSI bypass через hardware breakpoints на AmsiScanBuffer.

Все три инцидента реализуют одну цепочку по MITRE ATT&CK: Exploit Public-Facing Application (T1190, Initial Access) через Weaken Encryption (T1600, Defense Impairment). По данным Mandiant M-Trends 2025, exploits составляют 38% всех векторов initial access - и web.config machineKey exploit остаётся одним из самых надёжных среди них.

Эксплуатация ViewState ASP.NET: пошаговый разбор​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

Параметры --path и --apppath критичны для .NET >= 4.5: они участвуют в формировании Purpose string для деривации ключей. Укажешь неправильно - payload не пройдёт валидацию, и ты будешь час гадать, почему ключ «не работает». В legacy-режиме (.NET < 4.5) вместо них указывается --generator=<__VIEWSTATEGENERATOR>.

Выбор ysoserial.net gadget chain зависит от доступных сборок на сервере. TextFormattingRunProperties требует Microsoft.PowerShell.Editor.dll или аналогов. TypeConfuseDelegate универсальнее - работает с базовыми .NET-сборками. ActivitySurrogateSelector подтверждён в инциденте Kudelski Security по артефакту PDB-пути.

Для тест-кейса 3 (шифрование включено, .NET < 4.5) - нюанс, на котором спотыкаются: удаление параметра __VIEWSTATEENCRYPTED из запроса заставляет сервер обработать ViewState без расшифровки. Без этого шага сервер возвращает ошибку MAC validation.

Доставка и верификация RCE​

Payload отправляется POST-запросом на целевую страницу в параметре __VIEWSTATE. Страница должна обрабатывать ViewState - логин, любая форма с postback, или даже endpoint вроде /sitecore/blocked.aspx (случай CVE-2025-53690). Признаки успешной эксплуатации ViewState ASP.NET:
  • OOB-callback (DNS/HTTP) на контролируемый сервер - самый надёжный способ
  • HTTP 500 от приложения (payload не возвращает валидный ViewState, что вызывает ошибку после выполнения кода)
  • Event ID 1316 (source: ASP.NET, event code 4009) в Windows Application Event Log
По данным Claranet, при всех тест-кейсах успешная эксплуатация возвращает HTTP 500. Это не ошибка в привычном смысле - код выполнился, но процесс формирования ответа ASP.NET ломается из-за невалидного результата десериализации. Не пугайтесь пятисотки - она тут скорее хороший знак.

Детектирование и защита от десериализации ViewState​

Обнаружение атаки​

Event ID 1316 (event code 4009, источник ASP.NET) - ключевой индикатор. Лог содержит IP атакующего, User-Agent, base64-encoded payload и path страницы. Во всех трёх описанных инцидентах этот event стал отправной точкой расследования.

Маппинг полной атаки по MITRE ATT&CK:

ФазаТехникаID
Initial AccessExploit Public-Facing ApplicationT1190
Defense ImpairmentReduce Key SpaceT1600.001
ExecutionWindows Command ShellT1059.003
PersistenceWeb ShellT1505.003
Credential AccessCredentials In FilesT1552.001
DiscoverySystem Information DiscoveryT1082
MultipleValid AccountsT1078

Сетевой индикатор: аномально большие POST-запросы к ASP.NET-страницам. В инциденте Sitecore payload составлял 27760 байт в зашифрованном виде. Правило WAF на пороговый размер __VIEWSTATE - практичный первый барьер. Мониторинг скомпилированных DLL в C:\Windows\Microsoft.NET\Framework64\<version>\Temporary ASP.NET Files\ - индикатор загруженного webshell. По данным Kudelski Security, эти артефакты позволяют восстановить исходный код webshell даже после удаления .aspx-файла.

Предотвращение hardcoded machineKey уязвимости​

Генерация уникальных ключей - единственная надёжная защита:
XML:
<machineKey
  validationKey="AutoGenerate,IsolateApps"
  decryptionKey="AutoGenerate,IsolateApps"
  validation="SHA1" decryption="AES" />
IsolateApps обеспечивает изоляцию между приложениями на одном сервере. Для web farm - криптографически стойкие случайные ключи (validationKey: 128 hex-символов для SHA1, decryptionKey: 64 hex-символа для AES), но никогда из документации, примеров или StackOverflow. Sitecore в advisory к CVE-2025-53690 подтверждает: обновлённые версии автоматически генерируют уникальный machineKey при развёртывании.

Проверка текущих ключей через Badsecrets уместна как pre-deployment check на CI/CD. ViewStateUserKey (ViewStateUserKey = Session.SessionID в Page_Init) привязывает ViewState к сессии и блокирует replay-атаки с чужим ViewState - но не спасает от hardcoded machineKey, если ключ известен атакующему. Долгосрочная стратегия - миграция с Web Forms на ASP.NET MVC, Razor Pages или ASP.NET Core, где ViewState отсутствует как концепция. Но мы-то понимаем, что legacy-приложения на Web Forms будут жить ещё долго.

Три инцидента за год вскрыли проблему масштабнее конкретных CVE: вендоры годами поставляли коммерческие продукты с sample или hardcoded machineKey. Sitecore - deployment guide до 2017 года. KnowledgeDeliver - стандартный web.config для всех клиентов. ASP.NET-приложение в здравоохранении - ключ из публичного списка. По данным IBM X-Force Threat Intelligence Index 2025, среднее время между публикацией CVE и устранением в организации - 29 месяцев. Для RCE ASP.NET уязвимости через ViewState это означает: тысячи экземпляров с известными ключами останутся открытыми минимум два года после регистрации CVE.

На пентестах .NET-приложений я начинаю с Badsecrets - попадание по публичному ключу из корпуса даёт готовый path к RCE без единой дополнительной уязвимости. Если ключ не в списке - ищу file read для web.config. Если цель - коммерческий продукт на .NET, проверяю документацию вендора на наличие sample machineKey в guides. Проблема не уйдёт: CrowdStrike фиксирует, что 75% вторжений в 2024 году используют валидные credentials, а hardcoded machineKey - та же категория. Корневая причина не в протоколе ViewState, а в привычке переиспользовать секреты. Пока вендоры копируют один и тот же <machineKey> из StackOverflow в документацию, а администраторы разворачивают продакшен без замены sample-конфигов, ViewState deserialization ASP.NET останется одним из самых коротких путей от HTTP-запроса до shell. Если хочешь отработать эту цепочку руками - на HackerLab есть лабы с .NET-десериализацией, где можно погонять ysoserial.net по всем четырём тест-кейсам.
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →