Происхождение:
В декабре 2020 года центр разведки угроз DBAPPSecurity обнаружил новую группировку BITTER APT. Дальнейший анализ этого инцидента привел нас к обнаружению уязвимости нулевого дня в win32kfull.sys. Образец полученный "из дикой природы" был разработан для таргетинга на новейшую 64-битную операционную систему Windows 10 1909 года в то время. Уязвимость также влияет и может быть использована в последней 64-битной операционной системе Windows 10 20H2. Мы сообщили об этой уязвимости в MSRC, и она исправлена как CVE-2021-1732 в февральском обновлении безопасности 2021 года.

До сих пор мы выявляем очень небольшое количество атак, использующих эту уязвимость. Пострадавшие находятся в Китае.

Временная шкала:
· 2020/12/10: DBAPPSecurity Threat Intelligence Center поймал выявил новую группировку BITTER APT.
· 2020/12/15: Центр анализа угроз DBAPPSecurity обнаружил неизвестную уязвимость ядра Windows в компоненте и приступил к анализу первопричин.
· 2020/12/29: Центр разведки угроз DBAPPSecurity сообщил об уязвимости MSRC.
· 2020/12/29: MSRC подтвердила, что отчет был получен, и возбудила по нему дело.
· 2020/12/31: MSRC подтвердила, что уязвимость является нулевым днем, и запросила дополнительную информацию.
· 2020/12/31: DBAPPSecurity предоставила более подробную информацию MSRC.
· 2021/01/06: MSRC поблагодарила за дополнительную информацию и начала работать над исправлением этой уязвимости.
· 2021/02/09: MSRC исправляет уязвимость как CVE-2021-1732.

Основные моменты:
Согласно нашему анализу, уязвимость нулевого дня используемая в дикой природе имеет следующие основные моменты:
1. Он нацелен на последнюю версию операционной системы Windows 10
1.1. Образец "из дикой природы" ориентирован на последнюю версию 64-битной операционной системы Windows10 1909 (образец был скомпилирован в мае 2020 года).
1.2. Эксплойт нацелен на несколько версий Windows 10, от Windows 10 1709 до Windows 10 1909.
1.3. Эксплойт может быть использован на Windows 10 20H2 с незначительными изменениями.
2. Уязвимость является высокоуровневой, а эксплойт - сложным
2.1. Данный эксплоит обходит KASLR с помощью уязвимой функции.
2.2. Это не уязвимость UAF. Весь процесс эксплойта не связан с распылением кучи или повторным использованием памяти. Средства защиты в виде изоляции не может уменьшить опасность от этого эксплоита. Он не может обнаружить его с помощью Driver Verifier, образец найденный в дикой природе может успешно эксплуатироваться, когда Driver Verifier включен. Трудно выявить данный образец через песочницу.
2.3. Произвольное чтение примитивов достигается за счет функции уязвимости в сочетании с GetMenuBarInfo, что является впечатляющим показателем.
2.4. После достижения произвольных примитивов чтения/записи эксплойт использует атаку только на данные для выполнения эскалации привилегий, которая не может быть остановлена текущими правилами ядра.
2.5. Вероятность успеха эксплойта составляет почти 100%.
2.6. При завершении эксплойта эксплойт восстановит все ключевые элементы структуры, после эксплойта BSOD не будет.
3. Злоумышленник использовал его с осторожностью
3.1. Данный эксплоит самостоятельно выявляет антивирусное программное обеспечение
3.2. Образец выполняет проверку версии сборки операционной системы, если текущая версия сборки меньше 16535(Windows10 1709), эксплойт никогда не будет вызван.
3.3. Образец был собран в мае 2020 года, а выявлен нами в декабре 2020 года, он прожил не менее 7 месяцев. Это косвенно отражает сложность захвата такой скрытой выборки.

Технический анализ
0x00 Триггерный Эффект
Если мы запустим образец в 64-битной среде windows 10 1909, то сможете наблюдать, как текущий процесс изначально работает на среднем уровне доступа.
1613744738848.png

После выполнения кода эксплойта мы могли наблюдать, как текущий процесс выполняется на уровне системы. Это указывает на то, что Токен текущего процесса был заменен токеном системного процесса, что является распространенным методом использования уязвимостей повышения привилегий ядра.

1613744790337.png

Если мы запустим образец в 64-битной среде windows 10 20H2, то сразу же сможем наблюдать BSOD.

1613744815074.png


0x01 Обзор уязвимости
Эта уязвимость вызвана обратным вызовом xxxClientAllocWindowClassExtraBytes в win32kfull!xxxCreateWindowEx. Обратный вызов приводит к рассинхронизации структуры ядра и соответствующего ему флага.

Когда xxxCreateWindowEx создает окно с областью WndExtra, он вызывает xxxClientAllocWindowClassExtraBytes для запуска callback`a, callback вернется в пользовательский режим для выделения области WndExtra. В настраиваемой функции callback`a злоумышленник может вызвать NtUserConsoleControl и передать дескриптор текущего окна, это изменит структуру ядра (который указывает на область WndExtra) на смещение и установит соответствующий флаг, указывающий, что теперь этот элемент является смещением.. После этого злоумышленник может вызвать NtCallbackReturn в callback`e и вернуть произвольное значение. Когда обратный вызов завершается и возвращается в режим ядра, возвращаемое значение перезаписывает предыдущий элемент смещения, но соответствующий флаг не снимается. После этого непроверенное значение смещения напрямую используется кодом ядра для адресации кучи памяти, вызывая доступ за пределы.

0x02 Первопричина
Мы полностью изменили код эксплойта образца и построили на его основе poc. Следующий рисунок является основной логикой выполнения нашего poc, мы объясним логику триггера уязвимости в сочетании с этим рисунком.

1613745349121.png

В win32kfull! XxxCreateWindowEx он вызовет функцию обратного вызова user32! _XxxClientAllocWindowClassExtraBytes для выделения памяти WndExtra по умолчанию. Возвращаемое значение обратного вызова - это указатель режима использования, который затем будет сохранен в образце структуры ядра (WndExtra).

1613745469764.png

Если мы вызовем win32kfull! XxxConsoleControl в пользовательском обратном вызове _xxxClientAllocWindowClassExtraBytes и передадим дескриптор текущего окна, член WndExtra будет изменен на смещение и будет установлен соответствующий флаг (|=0x800).

1613745547686.png

Poc вызывает BSOD при вызове DestoryWindow, win32kfull! XxxFreeWindow проверит флаг выше, если он был установлен, указывая, что член WndExtra является смещением, xxxFreeWindow вызовет RtlFreeHeap, чтобы освободить область WndExtra; в противном случае, указывая, что член WndExtra является указателем режима использования, xxxFreeWindow вызовет xxxClientFreeWindowClassExtraBytes, чтобы освободить область WndExtra.

1613745618505.png

Мы могли бы вызвать NtCallbackReturn в конце пользовательского обратного вызова _xxxClientAllocWindowClassExtraBytes и вернуть произвольное значение. Когда обратный вызов завершится и вернется в режим ядра, возвращаемое значение перезапишет образец смещения, но соответствующий флаг не будет сброшен.

В poc мы возвращаем адрес кучи пользовательского режима, адрес перезаписывает смещение источника на адрес кучи пользовательского режима (fake_offset). Это, наконец, и приводит к тому, что win32kfull! XxxFreeWindow запускает доступ за пределами установленного диапазона при использовании RtlFreeHeap для освобождения кучи ядра.

RtlFreeHeap ожидает очистки RtlHeapBase + offset.
На самом деле RtlFreeHeap очищает RtlHeapBase + fake_offset.
1613745836841.png

Если мы вызовем здесь RtlFreeHeap, он вызовет BSOD.

1613745857142.png

0x03 Эксплойт
Найденный образец представляет собой 64-битную программу, сначала она вызывает CreateToolhelp32Snapshot и некоторые другие функции для перечисления процесса обнаружения «avp.exe» (avp.exe - это процесс антивирусного программного обеспечения Касперского).

1613745915746.png

Однако при обнаружении процесса «avp.exe» он сохранит только некоторое значение в настраиваемую структуру и не выйдет из процесса, полная функция эксплойта все равно будет вызываться. Устанавливаем антивирус Касперского и запускаем образец; он получит системные привилегии как обычно.

1613745955660.png

Затем он вызывает IsWow64Process, чтобы проверить, является ли текущая среда 32-битной или 64-битной, и исправить некоторые смещения в зависимости от результата. Здесь разработчик кода, кажется, совершил ошибку, согласно приведенному ниже исходному коду, g_x64 следует понимать как g_x86, но последующие вызовы указывают, что эта переменная представляет 64-битную среду.

Однако разработчик кода при инициализации устанавливает для g_x64 значение TRUE, вызов IsWow64Process здесь можно игнорировать. Но это, похоже, подразумевает, что разработчик также разработал еще одну 32-битную версию эксплойта.

1613746019732.png

После исправления некоторых смещений он получает адрес RtlGetNtVersionNumbers, NtUserConsoleControl и NtCallbackReturn. Затем он вызывает RtlGetNtVersionNumbers, чтобы получить номер сборки текущей операционной системы, функция эксплойта будет вызываться только тогда, когда номер сборки больше 16535 (Windows10 1709), и если номер сборки больше 18204 (Windows10 1903), он исправит некоторое смещение структуры ядра. Похоже, это означает, что поддержка этих версий была добавлена позже.

1613746051950.png

Если текущая среда проходит проверку, эксплойт будет вызван в исходном образце. Эксплойт сначала ищет байты, чтобы получить адрес HmValidateHandle, и подключает USER32! _XxxClientAllocWindowClassExtraBytes к настраиваемой функции обратного вызова.

1613746074821.png

Затем эксплойт регистрирует два типа оконных классов. Имя одного класса - «magicClass», который используется для создания окна уязвимости. Имя другого класса - «nolmalClass», который используется для создания обычных окон, которые позже помогут произвольному примитиву записи адреса.

1613746118209.png

Эксплойт создает 10 окон, используя normalClass, и вызывает HmValidateHandle для утечки адреса tagWND пользовательского режима каждого окна и смещения каждого окна через адрес tagWND. Затем эксплойт уничтожает последние 8 окон, оставляя только окно 0 и окно 1.

Если текущая программа 64-битная, эксплойт вызовет NtUserConsoleControl и передаст дескриптор окна 1, это изменит член WndExtra окна 0 на смещение. Затем эксплойт передает смещение tagWND ядра для окна 0 для дальнейшего использования.

1613746171583.png

Затем эксплойт использует magicClass для создания другого окна (windows 2), windows 2 имеет определенное значение cbWndExtra, которое было сгенерировано ранее. В процессе создания окна 2 оно запускает обратный вызов xxxClientAllocWindowClassExtraBytes и вводит пользовательскую функцию обратного вызова.

В пользовательской функции обратного вызова эксплойт сначала проверяет, соответствует ли cbWndExtra текущего окна определенному значению, а затем проверяет, является ли текущий процесс 64-битным. Если обе проверки пройдены, эксплойт вызывает NtUserConsoleControl и передает дескриптор окна 2, это изменяет WndExtra окна 2 на смещение и устанавливает соответствующий флаг. Затем эксплойт вызывает NtCallbackReturn и передает смещение tagWND ядра для окон 0. При возврате в режим ядра смещение WndExtra ядра для Windows 2 будет изменено на смещение tagWND ядра для окна 0. Это вызывает последующее чтение / запись в области WndExtra. Окно 2 на чтение / запись в теге ядра структуры tagWND окна 0.

1613746310759.png

После создания окна 2 эксплойт получает примитив для записи тега ядра WND окна 0, устанавливая область WndExtra окна 2. Эксплойт вызывает SetWindowLongW в окне 2, чтобы проверить, нормально ли работает этот примитив.

Если все работает нормально, эксплойт вызывает SetWindowLongW для установки cbWndExtra окон 0 на 0xfffffff, это дает окну 0 примитивы чтения / записи OOB. Затем эксплойт использует примитив записи OOB для изменения стиля окна 1 (dwStyle | = WS_CHILD), после чего эксплойт заменяет исходное spmenu окна 1 поддельным spmenu.

1613746388652.png

Произвольный примитив чтения достигается с помощью поддельного spmenu, работающего с GetMenuBarInfo. Эксплойт считывает 64-битное значение с помощью tagMenuBarInfo.rcBar.left и tagMenuBarInfo.rcBar.top. Этот метод ранее публично не использовался, но он аналогичен идеям из «Эксплуатации уязвимостей LPE в Windows 10 Anniversary Update» (ZeroNight, 2016).

1613746445700.png

Произвольный примитив записи достигается через окно 0 и окно 1, работа с SetWindowLongPtrA, см. Ниже.

1613746465168.png

После достижения произвольных примитивов чтения/записи эксплойт пропускает адрес ядра из исходного spmemu, а затем выполняет поиск по нему, чтобы найти EPROCESS текущего процесса.

Наконец, эксплойт просматривает ActiveProcessLinks, чтобы получить токен SYSTEM EPROCESS и адрес области токенов текущего EPROCESS, и меняет местами текущее значение токена процесса на токен SYSTEM.

1613746532292.png

После достижения повышения привилегий эксплойт восстанавливает измененную область окна 0, окна 1 и окна 2, используя произвольный примитив записи, такой как исходное spmenu окна 1 и флаг окна 2, чтобы гарантировать, что это не вызовет BSOD. Весь процесс эксплойта очень стабилен.


0x04 Заключение
Эта уязвимость нулевого дня - новая уязвимость, вызванная обратным вызовом win32k, ее можно использовать для выхода из песочницы браузера Microsoft IE или Adobe Reader в последней версии Windows 10. Качество этой уязвимости высокое, а эксплойт изощренный. Использование этого «нулевого дня» в естественных условиях отражает высокую уязвимость для организаций. Организация, создавшая данный эксплоит, могла нанять членов со стороны с определенными навыками или купить ее на рынке уязвимостей.


Резюме
Zero-day играет ключевую роль в киберпространстве. Обычно он используется в качестве стратегического резерва для организаций, создающих эксплоиты, и имеет особую миссию и стратегическое значение. С обновлением программного / аппаратного обеспечения и улучшением системы защиты стоимость майнинга и эксплуатации программного/аппаратного обеспечения нулевого дня становится выше и выше.

На протяжении многих лет поставщики по всему миру вкладывают значительные средства в обнаружение APT-атак. Это делает APT-организацию более осторожной при использовании уязвимостей Zero-day. Чтобы максимизировать его ценность, эксплоит будет использоваться только для очень небольшого числа конкретных целей. Небольшая небрежность сократит жизненный цикл нулевого дня. Между тем, некоторые нулевые дни скрывались в течение долгого времени, прежде чем были обнаружены, наиболее ярким примером является MS17-010, используемый EternalBlue,

За последний год (2020) во всем мире были раскрыты десятки атак 0Day / 1Day, в том числе три атаки, отслеживаемые DBAPPSecurity Threat Intelligence Center. Основываясь на имеющихся данных, мы прогнозируем, что в 2021 году будет больше раскрытий нулевого дня по браузерам и повышению привилегий.

Возможность обнаружения в нулевой день является одним из ключевых аспектов, требующих постоянного совершенствования процесса противодействия APT. Помимо атак на конечные точки, также стоит отметить атаки на пограничные системы, критическое оборудование и централизованные системы управления. За последние годы в этих районах также произошло несколько нарушений безопасности.

Быть не раскрытым не означает, что его не существует, скорее всего, он находится в скрытом состоянии. Обнаружение, обнаружение и защита от расширенных угроз требует постоянной итерации и усиления во время игры. Необходимо больше думать о том, как усилить обороноспособность во всех точках, линиях и поверхностях. Кибербезопасности предстоит пройти долгий путь, и нам нужно поддерживать друг друга.


Как защититься от подобных атак
Платформа раннего предупреждения APT-атак DBAPPSecurity может найти известные / неизвестные угрозы. Платформа может отслеживать, фиксировать и анализировать угрозы вредоносных файлов или программ в режиме реального времени, а также может проводить мощный мониторинг вредоносных образцов, таких как троянские кони, связанные с каждым этапом доставки электронной почты, эксплуатацией уязвимостей, установкой / имплантацией и C2.

В то же время платформа проводит углубленный анализ сетевого трафика на основе двустороннего анализа трафика, интеллектуального машинного обучения, эффективного динамического анализа песочницы, богатых библиотек сигнатур, всеобъемлющих стратегий обнаружения и массивных данных анализа угроз. Возможность обнаружения полностью покрывает всю цепочку APT-атак, эффективно обнаруживая APT-атаки, неизвестные угрозы и инциденты сетевой безопасности, которые волнуют пользователей.

ПравилоYara
Код:
rule apt_bitter_win32k_0day {
    meta:
        author = "dbappsecurity_lieying_lab"
        data = "01-01-2021"

    strings:
        $s1 = "NtUserConsoleControl" ascii wide
        $s2 = "NtCallbackReturn" ascii wide
        $s3 = "CreateWindowEx" ascii wide
        $s4 = "SetWindowLong" ascii wide

        $a1 = {48 C1 E8 02 48 C1 E9 02 C7 04 8A}
        $a2 = {66 0F 1F 44 00 00 80 3C 01 E8 74 22 FF C2 48 FF C1}
        $a3 = {48 63 05 CC 69 05 00 8B 0D C2 69 05 00 48 C1 E0 20 48 03 C1}

    condition:
        uint16(0) == 0x5a4d and all of ($s*) and 1 of ($a*)
}
Технический перевод близкий к тексту выполнил AnGel.
Источник:
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!