HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > БЕЗОПАСНОСТЬ И УЯЗВИМОСТИ > Безопасность и Анонимность > Защита ОС: вирусы, антивирусы, файрволы.
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 21.07.2021, 21:04
Marylin
Постоянный
Регистрация: 01.09.2019
Сообщений: 378
С нами: 3526561

Репутация: 0
По умолчанию

Всем привет!

На повестке дня – подсистема безопасности Win. Рассмотрим такие понятия как: системные объекты, права пользователей и их привилегии, токены и дескрипторы безопасности, списки контроля доступа DACL/SACL и записи в них ACE, проведём экскурсию в процесс Lsass.exe, познакомимся с диспетчером объектов, системным монитором SRM и узнаем, каким образом утилите "runas.exe" удаётся запускать процессы с админскими правами. Одним словом попытаемся бросить камень в стеклянную форточку Win и посмотрим, что из этого выйдет.

Содержание:

1. Знакомство с объектами

2. Дескриптор безопасности объекта

2.1. Структура дескриптора SD
2.2. Списки DACL и записи в них АСЕ
2.3. Эксперимент в отладчике WinDbg
3. Формат идентификатора SID

4. Под занавес..

-------------------------------------------------------

1. Знакомство с объектами

Известно, что Win построена на объектной модели. Это значит, что если в операционных системах класса Linux всё является файлом, то в глазах большого Билли мир существует в виде объектов. К числу объектов можно отнести всё, с чем нам приходится иметь дело в процессе программирования – это армия всевозможных физ.устройств Device, драйверы и контролёры, процессы и потоки, файлы и папки, таймеры, семафоры, мьютексы, рабочий стол и многое другое. В программе М.Руссиновича "Object Explorer", на своей семёрке я насчитал 42 именованных типов объектов, и это только доступные нам как смертным. Помимо них, в нёдрах оси имеются ещё и безымянные ресурсы, так-что здесь есть где развернуться.

Чтобы хоть немного навести порядок в этой кухне, все объекты система сортирует по типам – так в литературе появился термин "Объект типа". На программном уровне, каждый объект описывается своей структурой "OBJECT_HEADER", за которой тут-же располагается непосредственно и сам объект. В заголовке Header, тушке объекта присвоено имя "Body", и это самое последнее поле структуры (см.рис.ниже). При таких раскладах ясно, что системе требуется некий руководящий орган, который управлял-бы всем этим сообществом. Протекторат возложил эту задачу на плечи диспетчера объектов – службе уровня ядра.

На рисунке ниже скрин программы, куда я вставил прототип структуры Header из ядерного отладчика WinDbg. Если выбрать в левом окне просмотрщика раздел "ObjectTypes", можно ознакомиться с полным списком именованных объектов ядра (правый клик запрашивает свойства):




Каждый из объектов имеет свой заголовок Header, его структура одинакова для всех. В данном случае, в заголовке видим число указателей на объект(18), счётчик открытых дескрипторов(4), состояние, тип объекта(7), маску, флаги, информацию о создании, и по смещению 14h – наиболее интересное для нас поле "SecurityDescriptor" SD, что в привычном нам понимании означает дескриптор безопасности объекта. Если мыслить глобально, то именно на этом крохотном дескрипторе держится вся подсистема контроля доступа к объектам Win, в чём мы убедимся позже.

Отметим, что дескриптор SD могут иметь только разделяемые именованные объекты системы, поскольку безымянные как-правило тусуются в самом ядре и по определению не нуждаются в защите. В эту-же корзину отправляется и понятие "разделяемый" – если объект используется кем-то одним, то защищаться ему не от кого. Таким образом, объекты бывают защищаемые (с активным дескриптором безопасности) и незащищаемые, когда дескриптор присутствует, но забит нулями.

2. Дескриптор безопасности объекта

Дескриптор SD содержит информацию о владельце объекта в виде его SID (Security Identifier), а так-же включает в себя следующие два списка контроля-доступа, которые назвали Access-Contol List [ACL]:


• Discretionary Access-Control List [DACL] – список управления избирательным доступом, в котором перечислены пользователи и группы, с выданными им правами на доступ к объекту. В списке DACL хранится информация о доверенных лицах в системе, которым разрешён/запрещён доступ к данному объекту.

• System Access-Control List [SACL] – системный список управления доступом, который позволяет админам регистрировать в журнале событий неправомерные попытки доступа к защищённым объектам. Системный список SACL пока нам не интересен – мы остановимся лишь на пользовательском DACL.

В свою очередь, в списке DACL имеются несколько записей Access-Control Entry [ACE], по одной на каждую группу пользователей в системе. Например если зарегистрированных юзеров с одинаковыми правами двое, они собираются в свою группу и для этой группы в списке DACL будет выделена одна запись АСЕ. Вторая запись может хранить параметры доступа к объектам учёткой System, а третью – диспетчер объектов может пожертвовать группе (или пользователю) с правами админа. Нужно понимать, что записи АСЕ в списках DACL являются последними элементами в цепочке контроля доступа к объектам, и вся вселенная вращается вокруг именно АСЕ.

Когда наш процесс пытается получить доступ к защищённому ресурсу, диспетчер объектов либо предоставляет, либо запрещает доступ. К примеру, это может быть попытка открыть системный файл функцией CreateFile(), с запросом на запись или удаление. Если у файлового объекта нет списка управления доступом DACL (такие объекты называют ещё Null-Dacl), диспетчер не задумываясь предоставит нам доступ. В противном случае, служебные процедуры диспетчера начнут поиск принадлежащей нам записи ACE в списке DACL объекта, с последующей проверкой наших прав. Как показала практика, такая схема работает отменно и никогда не даёт сбоев, если только не выдать себя за другое лицо.

2.1. Структура дескриптора SD

На физическом уровне, в заголовке OBJECT_HEADER объекта прописан лишь указатель на дескриптор безопасности SD, а сам дескриптор может находиться где угодно в пространстве ядра. Он оформлен в виде одноимённой структуры с таким прототипом:


C-подобный:


Код:
struct SECURITY_DESCRIPTOR
  Revision     db
0
;
// версия дескриптора
Sbz1         db
0
;
// **(байт выравнивания версии на 16-бит границу)
Control      dw
0
;
// флаги настроек дескриптора
Owner        dd
0
;
// указатель на SID владельца
Group        dd
0
;
// указатель на SID группы
Sacl         dd
0
;
// указатель на "SACL_HEADER"
Dacl         dd
0
;
// указатель на "DACL_HEADER"
ends
Здесь, ревизия интересна только самой системе. Следующий байт так-же не несёт полезной нагрузки и вставлен для выравнивания структуры в памяти, на границу слова Word. А вот дальше уже интересней.. В поле "Control" лежит 16-битный набор флагов, которые определяют, действительный или нет в объекте список DACL. Если объект защищённый, то в поле Control обязательно должен быть установлен бит
Код:
"SE_DACL_PRESENT=4"
, иначе даже при физическом наличии списка он будет проигнорирован диспетчером объектов. Остальные флаги комбинируются с основным, и могут определять авто-наследуемость дескриптора потомками, защиту от модификации и прочее. Типичное значение флагов
Код:
= 0x8814
. Раскройте спойлер ниже, и соберите из констант это значение – должно получиться как минимум
Код:
DACL/SACL_PRESENT
.


В следующих полях "Owner/Group" дескриптора, прописаны линки на идентификатор SID владельца, и группы в которую он входит. Ну и в хвосте свои позиции заняли два указателя на столь важные для нас (и в первую очередь для самого объекта) списки DACL и SACL соответственно. Рассмотрим их подробней..

2.2. Списки DACL и записи в них АСЕ

Список контроля-доступа к объекту DACL можно воспринимать как таблицу с произвольным кол-вом строк, и 32 столбцами "AccessMask" (dword). В каждой из строк таблицы имеется запись АСЕ, которая закреплена за конкретной группой пользователей в системе. В столбцах-же, хранятся уже непосредственно права на доступ к объекту в виде логической единицы да/нет. Всю таблицу в лице списка DACL описывает структура DACL_HEADER, а строки с записями в ней – структура ACE_HEADER.


C-подобный:


Код:
struct DACL_HEADER
;
//
!
process
0
0
.
.
.
.
.
.
.
.
.
.
PROCESS
891
df030  SessionId
:
1
Cid
:
127
c 
        Peb
:
7
ffdf000  ParentCid
:
00e8
DirBase
:
5
f59cf80  ObjectTable
:
ab871bb8
HandleCount
:
33.
Image
:
TOKEN
.
EXE
Так мы получили адрес окружения нашего процесса в ядерной памяти
Код:
0x891df030
, и теперь передаём его команде
Код:
!object
, в надежде получить указатель на заголовок объекта OBJECT_HEADER (см.первый скрин). Здесь отладчик вернул адрес
Код:
0x891df018
(у вас он будет другим), и сразу-же командой
Код:
dt
я погружаюсь в его детали:


C-подобный:


Код:
lkd
>
!
object
891
df030
Object
:
891
df030  Type
:
(
847
bfeb0
)
Process
;
//
dt _object_header
891
df018
;
//
!
sd
94840e70
;
//
Revision
:
0x1
-
>
Sbz1
:
0x0
-
>
Control
:
0x8814
SE_DACL_PRESENT
;
//
Owner
:
S
-
1
-
5
-
32
-
544
;
//
Group
:
S
-
1
-
5
-
21
-
1365493694
-
2245328239
-
4151685940
-
513
;
//
Dacl
:
//
Dacl
:
-
>
AclRevision
:
0x2
-
>
Dacl
:
-
>
Sbz1
:
0x0
-
>
Dacl
:
-
>
AclSize
:
0x50
-
>
Dacl
:
-
>
AceCount
:
0x3
;
//
Dacl
:
-
>
Sbz2
:
0x0
-
>
Dacl
:
-
>
Ace
[
0
]
:
-
>
AceType
:
ACCESS_ALLOWED_ACE_TYPE
-
>
Dacl
:
-
>
Ace
[
0
]
:
-
>
AceFlags
:
0x0
-
>
Dacl
:
-
>
Ace
[
0
]
:
-
>
AceSize
:
0x18
-
>
Dacl
:
-
>
Ace
[
0
]
:
-
>
Mask
:
0x001fffff
-
>
Dacl
:
-
>
Ace
[
0
]
:
-
>
SID
:
S
-
1
-
5
-
32
-
544
-
>
Dacl
:
-
>
Ace
[
1
]
:
-
>
AceType
:
ACCESS_ALLOWED_ACE_TYPE
-
>
Dacl
:
-
>
Ace
[
1
]
:
-
>
AceFlags
:
0x0
-
>
Dacl
:
-
>
Ace
[
1
]
:
-
>
AceSize
:
0x14
-
>
Dacl
:
-
>
Ace
[
1
]
:
-
>
Mask
:
0x001fffff
-
>
Dacl
:
-
>
Ace
[
1
]
:
-
>
SID
:
S
-
1
-
5
-
18
-
>
Dacl
:
-
>
Ace
[
2
]
:
-
>
AceType
:
ACCESS_ALLOWED_ACE_TYPE
-
>
Dacl
:
-
>
Ace
[
2
]
:
-
>
AceFlags
:
0x0
-
>
Dacl
:
-
>
Ace
[
2
]
:
-
>
AceSize
:
0x1c
-
>
Dacl
:
-
>
Ace
[
2
]
:
-
>
Mask
:
0x00121411
-
>
Dacl
:
-
>
Ace
[
2
]
:
-
>
SID
:
S
-
1
-
5
-
5
-
0
-
132935
-
>
Sacl
:
//
Sacl
:
-
>
AclRevision
:
0x2
-
>
Sacl
:
-
>
Sbz1
:
0x0
-
>
Sacl
:
-
>
AclSize
:
0x1c
-
>
Sacl
:
-
>
AceCount
:
0x1
-
>
Sacl
:
-
>
Sbz2
:
0x0
-
>
Sacl
:
-
>
Ace
[
0
]
:
-
>
AceType
:
SYSTEM_MANDATORY_LABEL_ACE_TYPE
-
>
Sacl
:
-
>
Ace
[
0
]
:
-
>
AceFlags
:
0x0
-
>
Sacl
:
-
>
Ace
[
0
]
:
-
>
AceSize
:
0x14
-
>
Sacl
:
-
>
Ace
[
0
]
:
-
>
Mask
:
0x00000003
-
>
Sacl
:
-
>
Ace
[
0
]
:
-
>
SID
:
S
-
1
-
16
-
12288
Разберём на атомы последнюю запись Аce[2] списка DACL..

Значит она стандартного типа "ACCESS_ALLOWED_ACE_TYPE" размером 0x1C=28 байт, имеет маску доступа к объекту
Код:
0x00121411
, и принадлежит пользователю с идентификатором входа в систему
Код:
S-1-5-5-0-132935
. У остальных записей SID уже другой, причём двух одинаковых быть не может. Кроме того делаем вывод, что DACL данного объекта "Process" действителен, т.к. в самом начале поле "Control" имеет взведённый флаг "SE_DACL_PRESENT". Попробуйте перевести маску из Hex в Bin, и наложить её на скрин выше. Так вы узнаете доступные юзеру
Код:
S-1-5-5-0-132935
права, в отношении подопытного процесса.

3. Формат идентификатора SID

Идентификатор безопасности Security-Identifier (SID) – двоичная структура, которая однозначно идентифицирует учётную запись пользователя, группы, службы, домена или компьютера. SID выдаётся подсистемой Lsass (Local Security Authority Sub-System) в момент установки операционной системы, а так-же при регистрации новых пользователей. Системе не удобно оперировать привычными нам именами в строковом виде, поэтому она идентифицирует пользователя при помощи SID. Соответственно в проверке доступа к защищённым объектам и списках DACL участвуют так-же только SID'ы, что продемонстрировано в эксперименте с отладчиком выше.

Структура SID хорошо документирована и состоит из нескольких частей, которые указаны на следующем рисунке. Чтобы ознакомится с зарегистрированными в системе SID, можно позвать крошечную консольную утилиту "whoami" (Who Am I, кто я?), или универсальный тяжеловес WMI (Windows Management Instrumentation). Соответствие имени пользователя и его SID можно отследить и в ключе реестра: [HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList]:




Полезную смысловую нагрузку несут в себе три поля идентификатора – это Authority, Sub-Authority, и последний RID. На платформе Win всех мастей ревизия всегда одинакова и равна
Код:
S-1
, а 96-битное значение компьютера (или домена), генерируется системой от фонаря рандомно.


• Поле "Authority" имеет фиксированную длину и определяет класс учётной записи:

C-подобный:


Код:
;
//--- Типы SID_AUTHORITY --------
SECURITY_NULL_SID_AUTHORITY
=
0
SECURITY_WORLD_SID_AUTHORITY
=
1
SECURITY_LOCAL_SID_AUTHORITY
=
2
SECURITY_CREATOR_SID_AUTHORITY
=
3
SECURITY_NON_UNIQUE_AUTHORITY
=
4
SECURITY_NT_AUTHORITY
=
5
• Поле "Sub-Authority" имеет переменную длину и идентифицирует учётную запись внутри указанного класса. Это поле может иметь значение нуль, тогда SID определяет класс или группу учётных записей.

• Относительные идентификаторы "RID" одинаковы для всех компьютеров. Например RID учётки "Админ" всегда имеет значение 500, а RID гостя равен 501. Когда учётную запись создаёт админ, идентификатор нового пользователя начинается со значения 1000 и увеличивается на 1 для каждой следующей учётки. Кроме того, в системе имеется несколько широко-известных (Well-Known) учётных записей. К ним относятся группы "Все", "Интерактивные" и т.д. С исчерпывающим списком SID и их описанием можно ознакомится на сайте MSDN по
этому линку.

В системе существует специальный SID для обозначения идентификатора сессии "LogonSID" – он тоже используется в записях ACЕ и назначается юзерам, которые вошли в систему аутентифицировано (указав свой логин и пароль) и работают в ней на текущий момент. SID сессии одноразовый и существует, пока пользователь не вышел из системы – при каждом последующем входе генерируется новый LogonSID для того-же пользователя. К примеру SID моей текущей сессии имеет значение
Код:
S-1-5-5-0-132935
, хотя постоянный SID моей-же учётной записи равен
Код:
S-1-5-21-1365493694-xxxx-4151685940-1000
.

4. Под занавес..

Таким образом идеология ограничения прав доступа к объектам сводится к тому, что пользователь имеет маркер доступа к объекту "AccessToken", а объект имеет свой дескриптор безопасности "SecurityDescriptor" со-списком DACL, и записями АСЕ в нём. Когда процесс хочет получить доступ к объекту, монитор безопасности SRM берёт токен процесса, и сопоставляет его с записью АСЕ запрошенного объекта. Состав, структуру и назначение токена я оставил для следующей части статьи, чтобы была возможность переварить теорию выше. До скорого, пока!
 
Ответить с цитированием

  #2  
Старый 21.07.2021, 23:06
MLNK
Новичок
Регистрация: 23.01.2018
Сообщений: 0
С нами: 4371257

Репутация: 0
По умолчанию

Спасибо за статью, было бы интересно почитать про обзор твоей рабочей станции. Система, настройки софт. Думаю многим было бы интересно.
 
Ответить с цитированием

  #3  
Старый 22.07.2021, 10:32
Crazy Jack
Новичок
Регистрация: 08.07.2017
Сообщений: 0
С нами: 4657944

Репутация: 0
По умолчанию

Спасибо за статью. Коротко и ясно.
P.S.Может кому понадобится полное описание идентификаторов безопасности (SID), но там на месяц разбираться .
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.