Форум программистов, компьютерный форум, киберфорум
_lunar_
Войти
Регистрация
Восстановить пароль
Рейтинг: 5.00. Голосов: 2.

Объекты операционной системы. Часть 3: Уровень целостности

Запись от _lunar_ размещена 08.12.2021 в 01:51
Обновил(-а) _lunar_ 29.12.2022 в 10:17

Объекты операционной системы. Часть 1: Общие сведения
Объекты операционной системы. Часть 2: Объект ядра

Честно говоря, третью часть блога "Объекты операционной системы" я хотел написать совершенно про другое.
В планах было показать работу ядерного отладчика WinDbg, но в процессе подготовки материала и копания ядра ОС наткнулся на кое-что интересное.
Поэтому практической частью работы WinDbg думаю займёмся позже. А сейчас предлагаю познакомиться с Integrity Level (или уровень целостности).

Уровень целостности это своего рода метка, установленная в ACL (в частности в SACL) в одном из его ACE, а точнее в SYSTEM_MANDATORY_LABEL_ACE.
Если кто-то запутался вот небольшой FAQ по Access Control List (список управления доступом):
ACL это общее понятие для SACL (системный список управления доступом) и DACL (список управления доступом на уровне конкретного аккаунта).
У SACL и у DACL есть свои ACE - запись управления доступом. ACE достаточно много и их комбинация как раз и определяет того, кто может получить доступ к SACL и DACL.
Это и есть основа механизма защиты от неправомерного доступа к объектам ядра ОС Windows.

Но вернёмся к Integrity Level.
Integrity Level, если они есть, хранятся в SACL объекта.
Со времён Windows XP были определены следующие уровни целостности:

Код:
SID: S-1-16-0
Значение: 0x00000000L
Обозначение: ML_UNTRUSTED
Метка RID: SECURITY_MANDATORY_UNTRUSTED_RID
Описание: Недоверенный уровень целостности (An untrusted integrity level)
Применение: Processes started by Anonymous account

SID: S-1-16-4096
Значение: 0x00001000L
Обозначение: ML_LOW
Метка RID: SECURITY_MANDATORY_LOW_RID
Описание: Низкий уровень целостности (A low integrity level)
Применение: Internet Explorer Protected Mode process or AppContainer process (TOKEN_LOWBOX (0x00004000))

SID: S-1-16-8192
Значение: 0x00002000L
Обозначение: ML_MEDIUM
Метка RID: SECURITY_MANDATORY_MEDIUM_RID
Описание: Средний уровень целостности (A medium integrity level)
Применение: Process for regular applications with enabled UAC

SID: S-1-16-8448
Значение: 0x00002100L
Обозначение: ML_MEDIUM_PLUS
Метка RID: RID: SECURITY_MANDATORY_MEDIUM_PLUS_RID
Описание: Уровень целостности выше среднего (A medium plus integrity level)
Применение: Can be used as a priority between medium and high

SID: S-1-16-12288
Значение: 0x00003000L
Обозначение: ML_HIGH
Метка RID: SECURITY_MANDATORY_HIGH_RID
Описание: Высокий уровень целостности (A high integrity level)
Применение: Applications executed with UAC elevation

SID: S-1-16-16384
Значение: 0x00004000L
Обозначение: ML_SYSTEM
Метка RID: SECURITY_MANDATORY_SYSTEM_RID
Описание: Системный уровень целостности (A system integrity level)
Применение: Services or system applications, such as Winlogon and Wininit
Если в SACL нет метки RID, объект имеет уровень целостности по умолчанию ML_MEDIUM (S-1-16-8192).

С релизом Windows Vista (как мы уже знаем из предыдущих моих блогов) были внедрены защищенные процессы (а в Windows 8.1 ещё и защищенные сервисы и их процессы).
Соответственно был добавлен следующий уровень целостности:

Код:
SID: S-1-16-20480
Значение: 0x00005000L
Обозначение: ML_PROTECTED_PROCESS
Метка RID: SECURITY_MANDATORY_PROTECTED_PROCESS_RID
Описание: Уровень целостности защищенного процесса (A protected-process integrity level)
Применение: Included in a token for protected processes

А вот с релизом Windows 10 появился ещё один уровень целостности - Secure Process (самый высший на данный момент).
Что это такое? В двух словах - это виртуальная машина, состоящая из Изоляции ядра и Целостности памяти.
Windows использует функции аппаратной виртуализации для создания защищенной области системной памяти, изолированной от обычной операционной системы.
Это защищает процессы операционной системы от несанкционированного доступа к чему-либо, находящемуся за пределами безопасной зоны.
Даже если вредоносная программа использует эксплойт, который должен позволить взломать эти процессы Windows, виртуализация является дополнительным уровнем защиты, который изолирует их от атак.
Целостность памяти это функция, которая является подмножеством изоляции ядра.
Для Windows обычно требуются цифровые подписи для драйверов устройств и другого кода, который работает в режиме ядра ОС низкого уровня.
Когда Целостность памяти включена, служба целостности кода в Windows запускается внутри контейнера, защищенного гипервизором, созданного изоляцией ядра.
Это должно сделать почти невозможным получение вредоносным ПО доступа к ядру ОС.
В Windows 10 и более новых ОС для виртуальной машины есть своё отдельное ядро - securekernel.exe (расположенное в папке System32),
а также хост для инициализации - secinit.exe (как wininit.exe для сессии 0, и winlogon.exe->userinit.exe для сессии 1),
и свой модуль целостности кода - skci.dll (как ci.dll для обычного ядра).
Очень неплохая статья про новый вид защиты HyperGuard (как раз то самое ядро securekernel.exe) вышла прям 1 января.
Кому интересно, могут ознакомиться
HyperGuard – Secure Kernel Patch Guard: Part 1 – SKPG Initialization
HyperGuard – Secure Kernel Patch Guard: Part 2 – SKPG Extents
HyperGuard – Secure Kernel Patch Guard: Part 3 – More SKPG Extents

Уровень целостности Secure Process выглядит следующим образом:

Код:
SID: S-1-16-28672
Значение: 0x00007000L
Обозначение: ML_SECURE_PROCESS
Метка RID: SECURITY_MANDATORY_SECURE_PROCESS_RID
Описание: Уровень целостности безопасного процесса (A secure process integrity level)
Применение: Included in a token for protected processes, new for Windows 10

Логика работы Integrity Level такова: процесс с меньшим RID не может получить доступ к ACL процесса с большим RID.
Процессы, запускаемые обычным пользователем (в том числе администратором), получают средний уровень целостности (S-1-16-8192).
А процессы, запущенные через UAC с правами администратора - высокий уровень целостности (S-1-16-12288).
Здесь следует упомянуть одно интересное правило, которое Microsoft оставила в целях контроля над ОС (ведь не имея доступа к системе, контроль над ОС будет утерян полностью).
Как вы заметили RID повышается с определенным шагом, равным 0x1000. Этот шаг необходимо повышать равномерно.

Но вот что необычно: SID S-1-16-28672 определен как 0x7000 и по отношению к SID S-1-16-20480 это два шага.
Здесь либо существует какой-то скрытый от посторонних глаз SID, либо Microsoft сознательно запретила абсолютно любой доступ к безопасным процессам.


Интерес вызвал у меня SECURITY_MANDATORY_PROTECTED_PROCESS_RID.
Как я не искал эту метку, найти средствами, предоставленными Microsoft, я не смог.
Для примера, откроем WinDbg и проверим SACL процесса System (ядра операционной системы):
Нажмите на изображение для увеличения
Название: 33.png
Просмотров: 221
Размер:	18.0 Кб
ID:	7276
Посмотрите на его SID, он равен S-1-16-16384, что соответствует SECURITY_MANDATORY_SYSTEM_RID.
Но данный процесс в Windows Vista и более новых ОС является не просто системным, а полностью защищенным (хоть и без метки PS_PROTECTED_TYPE в Vista, 7 и 8), и по всей логике должен иметь SID S-1-16-20480.

Я внёс некоторые изменения в механизм распознавания SID таких процессов в KernelExplorer, пока только в консольную версию, и это не полная реализация (как видите отсутствует доступ к некоторым частям SACL):
Нажмите на изображение для увеличения
Название: 11.png
Просмотров: 281
Размер:	55.6 Кб
ID:	7278
Повторюсь, так вижу я представление защищенных процессов. Почему ядерные API этого не видят, я не знаю.
Как видите KernelExplorer определил SID процесса System как S-1-16-20480 и соответственно SECURITY_MANDATORY_PROTECTED_PROCESS_RID.
У потоков процесса нужно делать наследование токена, чтобы определить SID. Но как правило он такой же как и у родительского процесса.

И приведу ещё один скриншот - механизм распознавания SID у незащищенного процесса lsass.exe, который является системным
Нажмите на изображение для увеличения
Название: 22.png
Просмотров: 273
Размер:	39.7 Кб
ID:	7277
Здесь всё правильно: процесс без защиты и он системный, соответственно SID S-1-16-16384.


И вот что я думаю по этому поводу - доступа у отладчика к SECURITY_MANDATORY_PROTECTED_PROCESS_RID нет.
А ACL он просто вычисляет от указателя на PSECURITY_DESCRIPTOR.
Делается это следующим образом, рассмотрим пример:
Код:
PROCESS_SECURITY_DESCRIPTOR: 0x0000000000355AE0 (length: 136 bytes)
{
    SID_REVISION: 1 (field: 1 byte)
    Sbz1: 0 (field: 1 byte)
    Flags: SE_SELF_RELATIVE | SE_SACL_AUTO_INHERITED | SE_SACL_PRESENT | SE_DACL_PRESENT (field: 2 bytes)
    Offset group: 0x0000000000355B04 (field: 4 bytes)
    Offset owner: 0x0000000000355AF4 (field: 4 bytes)
    Offset SACL: 0x0000000000355B4C (field: 4 bytes)
    Offset DACL: 0x0000000000355B10 (field: 4 bytes)
    SID group: S-1-5-18 >> NT AUTHORITY\система (length: 12 bytes)
    SID owner: S-1-5-32-544 >> BUILTIN\Администраторы (length: 16 bytes)

    SACL_REVISION: 2
    SACL Sbz1: 0
    SACL size: 28 bytes
    SACL:ACE count: 1
        SACL:ACE[0].address: 0x0000000000355B54
            SACL:ACE[0].AceType: SYSTEM_MANDATORY_LABEL_ACE_TYPE
            SACL:ACE[0].AceFlag: 0
            SACL:ACE[0].AceSize: 20 bytes
            SACL:ACE[0].Mask: 0x3
            SACL:ACE[0]->SID: S-1-16-16384
            SACL:ACE[0]->RID: ML_SYSTEM
    SACL Sbz2: 0

    DACL_REVISION: 2
    DACL Sbz1: 0
    DACL size: 60 bytes
    DACL:ACE count: 2
        DACL:ACE[0].address: 0x0000000000355B18
            DACL:ACE[0].AceType: ACCESS_ALLOWED_ACE_TYPE
            DACL:ACE[0].AceFlag: 0
            DACL:ACE[0].AceSize: 20 bytes
            DACL:ACE[0].Mask: 0x1fffff
            DACL:ACE[0]->SID: S-1-5-18
        DACL:ACE[1].address: 0x0000000000355B2C
            DACL:ACE[1].AceType: ACCESS_ALLOWED_ACE_TYPE
            DACL:ACE[1].AceFlag: 0
            DACL:ACE[1].AceSize: 24 bytes
            DACL:ACE[1].Mask: 0x121411
            DACL:ACE[1]->SID: S-1-5-32-544
    DACL Sbz2: 0
}
К указателю PSECURITY_DESCRIPTOR нужно прибавить размеры SID_REVISION, Sbz1, Flags, все Offset'ы и все SID'ы, размер SIZE_T, а также DACL size.
0x0000000000355AE0 + 1 + 1 + 2 + 4 + 4 + 4 + 4 + 12 (1-5-18 = 4 + 4 + 4 = 12 -> каждая цифра это 4 байта (int)) + 16 (1-5-32-544 = 4 + 4 + 4 + 4 = 16 -> каждая цифра это 4 байта (int)) + 8 (для x64 sizeof(SIZE_T) равен 8) (именно здесь появляется указатель на начало DACL = 0x0000000000355B18) + 60 (DACL size: 60 bytes) = 0x0000000000355B54 (указатель на начало SACL).

Небольшое дополнение.
Разработчик WinObjEx (аналога WinObj от Руссиновича, но с более широким набором инструментов (впрочем как и ProcessHacker куда круче, чем ProcessExplorer))
также считает, что у системных процессов (в частности ядра ОС - ntoskrnl.exe) уровень целостности должен быть ML_PROTECTED_PROCESS
Соответственно в программу внесены изменения, с помощью которых можно определять уровень целостности того или иного процесса
Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 187
Размер:	109.4 Кб
ID:	7351

Объекты операционной системы. Часть 4: Отладчик уровня ядра WinDbg
Размещено в Без категории
Показов 2769 Комментарии 3
Всего комментариев 3
Комментарии
  1. Старый комментарий
    Аватар для Dragokas
    Спасибо. Познавательная статья.

    Мне ещё попадался такой Integrity Level: Const SECURITY_MANDATORY_UIACCESS_RID = SECURITY_MANDATORY_MEDIUM_RID + 0x10
    который появляется у подписанных процессов, которые физически находятся в доверенной папке и в манифесте которых стоит UIAccess = true.
    Запись от Dragokas размещена 16.12.2021 в 13:02 Dragokas вне форума
    Обновил(-а) Dragokas 16.12.2021 в 13:03
  2. Старый комментарий
    Аватар для _lunar_
    Цитата:
    Сообщение от Dragokas Просмотреть комментарий
    Спасибо. Познавательная статья.

    Мне ещё попадался такой Integrity Level: Const SECURITY_MANDATORY_UIACCESS_RID = SECURITY_MANDATORY_MEDIUM_RID + 0x10
    который появляется у подписанных процессов, которые физически находятся в доверенной папке и в манифесте которых стоит UIAccess = true.
    Да, в свежей версии KernelExplorer я уже добавил UIAccess в токен создаваемого User и Elevated процессов (для System процессов это не требуется)
    C++
    1
    2
    
    DWORD UIAccess = TRUE;
    SetTokenInformation(hToken, TokenUIAccess, &UIAccess, sizeof(DWORD));
    Но ещё не реализовал повышения уровня целостности.
    К примеру, если из папки System32 запустить osk.exe (виртуальная клавиатура), то SID в токене процесса будет S-1-16-12288.
    Но если создавать User процесс из KernelExplorer, то SID будет S-1-16-8192, при этом в токене будет UIAccess - Enable и процесс виртуальной клавиатуры будет создан.
    Но это касается только osk.exe, программы у которых в манифесте включен режим запуска из-под администратора, выдадут 740 ошибку, т.к. S-1-16-8192 в токене недостаточно.
    Запись от _lunar_ размещена 18.12.2021 в 20:26 _lunar_ вне форума
    Обновил(-а) _lunar_ 18.12.2021 в 20:27
  3. Старый комментарий
    Дружище, а WinObjEx существует только в 64 битной версии ?
    Запись от Turok123 размещена 02.10.2022 в 11:37 Turok123 вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru