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

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

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

..продолжимпервую часть статьи, где были представлены общие сведения о системных объектах Win. Чтобы не потерять логическую нить, предыдущая рекомендуется к прочтению, поскольку здесь ставка делается на то, что вы уже знакомы с понятиями: идентификатор пользователя SID, дескриптор безопасности объекта и его список DACL. Организовать качественную подсистему безопасности можно лишь в том случае, когда есть чёткая модель того, что нужно защищать и кому/что разрешается делать. В этой области инженерами Microsoft проделан огромный объём работы, так-что сконцентрируем своё внимание исключительно на основных моментах. За роялем сегодня токен юзера, его права и привилегии.

Содержание:

1. Аутентификация пользователей в системе;

2. Маркер доступа к объектам (токен);

3. Права и привилегии пользователей;

4. Практика – информация о токенах и дескрипторах(SD) процесса;

5. Подводим итоги.

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

1. Регистрация пользователя в системе

Ядром подсистемы безопасности является служба Lsass.exe, или "Local Security Authority Sub-System". В автозагрузке Win лежит процесс входа пользователей Winlogon.exe, который как швейцар проводит фейс-контроль вновь прибывших и открывает им двери в систему. Winlogon является критическим важным процессом (если убить, то рухнет вся ОС), поэтому провайдер аутентификации Authui.dll и интерфейсное окно входа в систему запускаются внутри дочернего процесса Winlogon, под названием LogonUI.exe (см.папку system32). После того-как пользователь вводит свои учётные данные, процесс LogonUI завершается, а Winlogon остаётся активным, чтобы в фоне отлавливать комбинацию клавиш юзера [Ctrl+Alt+Delete] для смены пользователей. При обнаружении таковой, Winlogon опять зовёт LogonUI и так в бесконечном цикле.

На следующем этапе, Winlogon передаёт имя и пароль юзера в службу безопасности LSA, которая обращается к Authui.dll для аутентификации пользователя. Если всё в порядке и юзер с таким именем существует, провайдер вычисляет NTLM-хеш введённого пасворда и сравнивает его с дайджестом (хешем) из базы данных "диспетчера учётных записей" SAM – Security Account Manager. Если проверка подтвердит пользователя и не найдёт оснований, чтобы выпроводить его за порог, провайдер формирует и возвращает в Lsass уже знакомый нам идентификатор безопасности пользователя SID (Security Identifier). В противном случае, на территории охранной зоны включается ревун, и на незадачливого юзверя направляются сразу несколько ярких прожекторов.

Теперь получив SID, подсистема Lsass вызывает функцию NtCreateToken() в мониторе безопасности SRM, чтобы создать т.н. маркер-доступа клиента "AccessToken". На системах х86-32, структура токена имеет размер 480-байт и в неё заложен профиль безопасности пользователя. Помимо прочего, он содержит в себе SID'ы юзера и группы в которую он входит, а так-же его привилегии. Остальные поля в токене носят информационный характер и в данном случае не представляют для нас интереса. Примерно так выглядит взаимодействие субъектов в этом сообществе:



Обратите внимание, что создавать токены доступа к объектам может не только служба безопасности Lsass, но и мы и с вами, как рядовые пользователи. Благодаря именно этой возможности консольной утилите "runas.exe" удаётся запускать процессы выдавая себя за админа системы. Она использует функцию из библиотеки advapi32.dll LogonUser(), которая пытается зарегать нового юзверя на локальном узле. При удачных обстоятельствах, функция создаёт токен с настройками по умолчанию, и теперь он будет представлять новорождённого юзера во-всех его начинаниях, то как старт процессов и прочее. Если функция нарвётся на шипы подсистемы безопасности и по какой-либо причине не сможет выполнить свою задачу, то в EAX вернёт логический нуль. Вот её прототип:

C-подобный:


Код:
BOOL
LogonUserA
(
LPCSTR  lpszUsername
,
;
// имя юзера = произвольное
LPCSTR  lpszDomain
,
;
// имя домена/сервера = GetComputerName()
LPCSTR  lpszPassword
,
;
// пароль юзера = 0
DWORD   dwLogonType
,
;
// тип входа в систему = LOGON32_LOGON_NEW_CREDENTIALS
DWORD   dwLogonProvider
,
;
// провайдер обеспечения входа = LOGON32_PROVIDER_DEFAULT (Authui.dll)
PHANDLE phToken
)
;
// сюда вернётся дескриптор токена нового пользователя!
Далее, установив в этом токене нужные привилегии, можно будет вызывать процессы от чужого имени, посредством функции CreateProcessAsUser(). В качестве альтернативы, имеется ещё одна обёртка, сочетающая в себе сразу две функции выше под названием CreateProcessWithLogonW(). Одним выстрелом дробью она и создаёт нового юзера, и сразу запускает указанный в аргументе процесс. В общем выбор у нас широкий, правда в клинических случаях нам как "художникам" самим потребуются некоторые привилегии, но это уже дело техники и всегда можно найти забытый инженерами люк (например использовать не первичный токен, а токен олицетворения, или ограниченный токен).

2. Маркер доступа к объектам "AccessToken"

Токен сам является системным объектом, который хранит SID и привилегии пользователя. Он создаётся локальным органом безопасности LSA после того-как идентификация юзера успешно пройдёт цензуру. В последующем, каждый процесс, который так или иначе запускается от имени данного пользователя, сопровождается копией его токена. Токен используется системой исключительно для предоставления процессу доступа к защищённым объектам, и в зависимости от указанных в нём привилегий позволяет выполнять различные системные операции. Уже упоминалось, что защищённые объекты ожидают пользовательский SID в своих списках DACL, который как-раз и берётся из токена пользователя. В отличии от имени и пароля в базе реестра SAM, токен нигде не сохраняется, а при каждой загрузке системы создаётся вновь.

Алгоритм проверки прав доступа к объекту со стороны нашего процесса выглядит так:

1. Если SID из токена не совпадает с SID в элементе ACE объекта, то осуществляется переход к следующему ACE в цепочке, иначе переход к п.2.

2. Если элемент ACE запрещает доступ к объекту обладателю данного SID, но он является владельцем объекта (и запрос только на чтение), доступ к объекту разрешается, иначе переход к п.3.

3. Если достигнут конец списка DACL – попытка доступа отклоняется.

4. Если DACL объекта пуст, доступ к нему запрещён всем субъектам, за исключением владельца, которому разрешены чтение и изменение списка DACL (право WRITE_DAC).

5. Если у объекта нет дескриптора безопасности SD (например, у файлов на диске FAT), то все могут получить любые права-доступа к данному объекту.

Обсуждать коня в вакууме как-то не комильфо, поэтому проведём небольшой эксперимент в отладчике WinDbg, чтобы посмотреть на токен реального приложения. Значит даём команду
Код:
!process 0 0
для сбора инфы об активных процессах, и находим среди них адрес окружения своего – я получил
Код:
0x8a058d20
. Теперь передаю этот адрес той-же команде !process, чтобы она отфильтровала лог и вернула информацию только о моём процессе, забросив в топку все остальные. Объём выводимой инфы можно контролировать параметром в диапазоне 0-7, где нуль минимум, а 7 макс.инфы – нам достаточно единицы. В выхлопе отладчика будет красоваться адрес структуры принадлежащего нам токена =
Код:
0xa5e41030
:

C-подобный:


[CODE]
lkd
>
!
process
8
a058d20
1
PROCESS
8
a058d20 SessionId
:
1
Cid
:
0
ab0 Peb
:
7
ffdf000 ParentCid
:
0
abc
DirBase
:
5
f524a40 ObjectTable
:
a8c2b388 HandleCount
:
33.
Image
:
EXAMPLE
.
EXE

Token a5e41030
;
// TOKEN_SOURCE"? Для этого, в конце команды указываем имя интересующего нас поля, и завершаем команду жирной точкой. Можно даже связывать отображение вложенных структур по типу:

Код:
dt _token a5e41030 TokenSource.SourceIdentifier.
(отобразит локальный идентификатор LUID):

C-подобный:


Код:
lkd
>
dt _token a5e41030 TokenSource
.
nt
!
_TOKEN
+
0x000
TokenSource
:
+
0x000
SourceName
:
[
8
]
"User32 "
+
0x008
SourceIdentifier
:
_LUID
2.1. Типы токенов

Обратите внимание на поле по смещению 0x0a4 под названием "TokenType" – это тип токена. Здесь оно хранит константу(1) = TOKEN_PRIMARY. Дело в том, что в природе мирно сосуществуют две разновидности токенов: первичный и наследуемый.

• Первичный токен: Token_Primary = 1
Это основной токен процесса, и создается он только ядром Win. Содержимое представляет информацию о безопасности по умолчанию. Функция UserLogon() и подсистема Lsass всегда создаёт только первичный токен, хэндл которого можно получить вызовом OpenProcessToken(). Ещё одна функция CreateRestrictedToken() тоже создаёт его, но только урезанный в привилегиях вариант, о чём собственно и говорит название "Restricted" (ограниченный). На вход ей нужно подать первичный токен, а на выходе получим только шелуху от него. Такие токены Lsass обычно "дарит" гостям системы.

• Токен олицетворения: Token_Impersonation = 2
Токен данного типа заимствует права первичного токена, чтобы олицетворять клиентский процесс на сервере. К примеру токены олицетворения передаются от процессов к каждому из его потоков, так-что получить дескриптор можно функцией OpenThreadToken(). Однако в полной мере достоинства наследуемых токенов раскрываются в клиент-серверных приложениях, когда серверы предоставляют клиентам такие расшаренные объекты как: файлы, принтеры, базы-данных и прочее.

Получив запрос сервер должен убедиться, что у клиента есть разрешение на доступ к запрашиваемому объекту – для этого ему нужен SID учётной записи клиента, который и передаётся в токене олицетворения механизмом заимствования прав. Меняет тип токена с первичного на токен-олицетворения функция ImpersonateLoggedOnUser(), а обратную операцию проводят RevertToSelf() или DuplicateTokenEx().

3. Привилегии пользователей

Рассмотрим некоторые вопросы лингвистики..
Знаете-ли вы, какая разница между привилегией и правом пользователя? На сайте MSDN привилегией называют расширенные права юзеров, что собственно ничуть не проясняет ситуацию. Однако если уйти в доки с головой, то найти тонкую грань между двумя этими терминами всё-таки можно.

• Права "Rights" (так-же известные как разрешения) всегда связаны с определенным объектом системы, который выдаёт нам право на открытие файла, запись, чтение из него и прочее. Монитор безопасности SRM разграничивает права пользователей на доступ к объекту, просматривая его список DACL. Обычно DACL'ы и их записи АСЕ сохраняются вместе с объектом. Например файловая запись АСЕ лежит прямо рядом с ним на диске – атрибут безопасности файла в NTFS равен 50h (см.спеки Ntfs):



•Привилегии-же связаны с определенными действиями в системе, и предоставляются пользователям, а не объектам. Они позволяют переопределять права на доступ к объекту, поэтому с их назначением мы (как админы) должны быть очень осторожны. Например юзер с привилегией
Код:
SE_RESTORE
может без проблем перезаписать практически любой файл в системе, а привилегия
Код:
SE_BACKUP
наоборот позволяет считать защищённый системный файл.

Добавляет привилегий в токен функция AdjustTokenPrivileges(), но перед этим не помешало-бы узнать полный их список в системе. Проблема в том, что за время своего существования Win не однократно редактировала этот лист и может получиться так, что поддержка требуемой нам привилегии просто прекратилась и её место заняла какая-нибудь новая. Например начиная с Win-7, широко известной привилегии SeTcbPrivilege с идентификатором(7) уже не существует, и можно долго гадать, почему-же она не выставляется.

Функции для работы с подсистемой безопасности Lsass сосредоточены в библиотеке пользовательского уровня Advapi32.dll (advanced, расширенные API). Среди них имеются две интересные функции Set/GetTokenInformation(), которые как и следует из названий оперируют информацией в токене. Вот их прототип:

C-подобный:


Код:
BOOL GetTokenInformation
  TokenHandle             dd
0
;
// дескриптор токена
TokenInformationClass   dd
0
;
// класс запрашиваемой информации
TokenInformation        dd
0
;
// линк на буфер под инфу
TokenInformationLength  dd
0
;
// размер буфера
ReturnLength            dd
0
;
// переменная, куда вернётся кол-во байт
Значит в первый аргумент передаём дескриптор токена, который возвращает OpenProcessToken(). Во-втором аргументе нужно указать класс/тип запрашиваемой информации – поскольку мы планируем получить список системных привилегий, то ставим константу(3) "TokenPrivileges". Для этих функции всего предусмотрено 48 разнообразных классов, и соответственно такое-же количество информации о токене они способны вернуть. В следующих аргументах указываем адрес и размер буфера, а так-же адрес переменной, куда функция вернёт требуемый размер буфа для конкретного типа инфы.

Если функция отработает успешно, вернёт в EAX логическую единицу и в буфере получим данные, которые описывает структура "TOKEN_PRIVILEGES". Первое поле в ней "PrivilegeCount" – это общее число поддерживаемых привилегий, а дальше следует массив вложенных структур "LUID_AND_ATTRIBUTES" с описанием каждой привилегии в отдельности. Таким образом, первое поле хранит кол-во вложенных структур, что совпадает с кол-вом зареганных в системе привилегий. Чтобы узнать, какие из общего списка назначены нам, нужно будет проверить поле с атрибутом во-вложенных структурах.

C-подобный:


Код:
struct TOKEN_PRIVILEGES
  PrivilegeCount   dd
0
Privileges       LUID_AND_ATTRIBUTES
ends
;
//--------------------
struct LUID_AND_ATTRIBUTES
  Luid             dq
0
;
// ID привилегии (8-байт)
Attributes       dd
0
;
// откл(0), вкл.в дефолте(1), вкл.программно(2)
ends
Так мы получим в буфере идентификаторы LUID всех привилегий (Local Identifier), и чтобы привести их в дружелюбный текстовый вид, нужно будет позвать функцию LookupPrivilegeName(). Она ожидает на входе идентификатор, и возвращает соответствующую ему строку. Родственная ей функция LookupPrivilegeValue() проводит обратную операцию, т.е. принимая имя, возвращает LUID. Завернём всё вышесказанное в код:

C-подобный:


Код:
format pe console
entry  start
;
//------------
section
'.inc'
data readable
include
'win32ax.inc'
include
'equates\advapi32.inc'
;
//------------
.
data
szEnabled    db
'      
;
//----- Открываем первичный токен своего процесса
invoke  GetCurrentProcess
         invoke  OpenProcessToken
,
eax
,
TOKEN_QUERY
,
hToken
;
//----- Запрос списка привелегий в токене
;
//----- (первый вызов возвращает требуемый размер буфера)
invoke  GetTokenInformation
,
[
hToken
]
,
TokenPrivileges
,
buff
,
0
,
pReturn
         invoke  GetTokenInformation
,
[
hToken
]
,
TokenPrivileges
,
buff
,
[
pReturn
]
,
pReturn

        cinvoke  printf
,

,
dword
[
buff
]
;
//----- В буфере лежат все привилегии - перебираем их..
align
16
mov     ecx
,
dword
[
buff
]
;
// PrivilegeCount
mov     esi
,
buff
+
4
;
// начало массива "LUID_AND_ATTRIBUTES"
@@
:
push    esi ecx esi
         mov
[
strSize
]
,
128
;
// обновить длину строки
mov     eax
,
[
esi
]
;
// LUID очередной привилегии
push    eax
         invoke  LookupPrivilegeName
,
0
,
esi
,
privStr
,
strSize
;
// в строку его,
pop     eax
        cinvoke  printf
,

,
eax
,
privStr
;
// ..и на консоль
pop     eax
         mov     eax
,
[
eax
+
8
]
;
// взять атрибут
or      eax
,
eax
;
// если нуль (отключена),
je      @next
;
//  ..пропустить.
mov     esi
,
szEnabled
;
// иначе: попалась активная привилегия!
cmp     eax
,
SE_PRIVILEGE_ENABLED
;
// программно включена?
je      @prn
         mov     esi
,
szDefault
;
// значит идёт в дефолте.
@prn
:
cinvoke  printf
,

,
esi

@next
:
pop     ecx esi
         add     esi
,
sizeof
.
LUID_AND_ATTRIBUTES
;
// перейти в массиве на сл.привилегию
dec     ecx
;
// счётчик -1
jnz     @b
;
// повторить, если не нуль..
@exit
:
cinvoke  _getch
        cinvoke  exit
,
0
;
//------------
section
'.idata'
import data readable
library  kernel32
,
'kernel32.dll'
,
msvcrt
,
'msvcrt.dll'
,
advapi32
,
'advapi32.dll'
include
'api\kernel32.inc'
include
'api\msvcrt.inc'
include
'api\advapi32.inc'


Если верить функции GetTokenInformation() (а не верить ей у нас нет причин), то семёрка поддерживает всего 24 привилегии, причём по-умолчанию у меня (как входящего в группу админов) включены только три из них. "ChangeNotify" имеют все пользователи, "Impersonate" позволяет олицетворять себя с другими лицами, а привилегию "CreateGlobal" система назначает только админам, что даём им право создавать глобальные объекты в пространстве имён. Список всех привилегий и заложенный в них глубокий смысл можно найти в репозитории MSDNпо этой ссылке.

Обратите внимание на идентификаторы – первые четыре привилегии(0,1,2,3) под семёркой уже отправлены в утиль, причём и дальше порядок не последовательный. Более того, содержимое листа привязано и к версии операционной системы. Так, запустив этот код на своём буке с Win-10 я обнаружил, что в ней пропала привилегия с идентификатором(4), зато появилась новая с LUID=36, под громким названием "SeDelegateSessionUserImpersonatePrivilege". На сайте RSDN есть статья
"Что такое привилегии?"– можете почитать на досуге.

3.1. Включение привилегий в токене

Ладно, лист поддержки получили.. теперь попробуем повысить себя в ранге и добавить парочку привилегий в токен функцией AdjustTokenPrivileges(). Она может как включать, так и отключать ненужные привилегии. Данная операция требует, чтобы токен был открыт с доступом
Код:
TOKEN_QUERY + TOKEN_ADJUST_PRIVILEGES
. Вот её описание:


C-подобный:


Код:
BOOL AdjustTokenPrivileges
  TokenHandle             dd
0
;
// хендл токена безопасности
DisableAllPrivileges    dd
0
;
// 1 = отмена всех привилегий, 0 = добавить в токен
NewState                dd
0
;
// нужные привилегии в виде структуры TOKEN_PRIVILEGES
BufferLength            dd
0
;
// размер буфера (опционально)
PreviousState           dd
0
;
// лист предыдущих (опционально)
ReturnLength            dd
0
;
// размер PreviousState (опционально)
Если во-второй аргумент запихать логическую единицу, функция превратит токен в ограниченный "Resticted", удалив из него все привилегии кроме "SeChangeNotify". Особого внимания заслуживает здесь аргумент "NewState", который является указателем на структуру "TOKEN_PRIVILEGES". Как упоминалось выше, в первом поле этой структуры лежит счётчик вложенных структур "LUID_AND_ATTRIBUTES", за которым следует и сам массив. Значит чтобы добавить в токен, например, четыре какие-нибудь дополнительные привилегии, можно воспользоваться такой конструкцией в секции-данных программы:

C-подобный:


Код:
align
16
newState
:
;
//
cinvoke  printf
,

;
//----- Открываем первичный токен своего процесса
invoke  GetCurrentProcess
         invoke  OpenProcessToken
,
eax
,
\
                                  TOKEN_QUERY
+
TOKEN_ADJUST_PRIVILEGES
,
\
                                  hToken
         or      eax
,
eax
         jnz     @f
        cinvoke  printf
,

jmp     @exit
;
//----- Получаем LUID'ы привилегий по их именам
@@
:
invoke  LookupPrivilegeValue
,
0
,

,
Luid1
         invoke  LookupPrivilegeValue
,
0
,

,
Luid2
         invoke  LookupPrivilegeValue
,
0
,

,
Luid3
         invoke  LookupPrivilegeValue
,
0
,

,
Luid4
;
//----- Выставляем привилегии в токене!
invoke  AdjustTokenPrivileges
,
[
hToken
]
,
0
,
newState
,
0
,
0
,
0
or      eax
,
eax
         jnz     @f
        cinvoke  printf
,

jmp     @exit
;
//----- Запрос списка привелегий
;
//----- (первый вызов возвращает требуемый размер буфера)
@@
:
invoke  GetTokenInformation
,
[
hToken
]
,
TokenPrivileges
,
buff
,
0
,
pReturn
         invoke  GetTokenInformation
,
[
hToken
]
,
TokenPrivileges
,
buff
,
[
pReturn
]
,
pReturn

        cinvoke  printf
,

,
dword
[
buff
]
;
//..............
;
//
invoke  OpenProcessToken
,
-
1
,
TOKEN_QUERY
,
hToken
;
//----- SID юзера в системе ----------
invoke  GetTokenInformation
,
[
hToken
]
,
TokenUser
,
buff
,
0
,
pReturn
         invoke  GetTokenInformation
,
[
hToken
]
,
TokenUser
,
buff
,
[
pReturn
]
,
pReturn
         mov     eax
,
dword
[
buff
]
invoke  ConvertSidToStringSid
,
eax
,
buff
         mov     eax
,
dword
[
buff
]
cinvoke  printf
,

,
eax
;
//----- Получим SID из токена ----------
invoke  GetTokenInformation
,
[
hToken
]
,
TokenGroups
,
buff
,
0
,
pReturn
         invoke  GetTokenInformation
,
[
hToken
]
,
TokenGroups
,
buff
,
[
pReturn
]
,
pReturn

         mov     ecx
,
dword
[
buff
]
mov     esi
,
buff
+
4
@@
:
mov     eax
,
[
esi
+
SID_AND_ATTRIBUTES
.
Attributes
]
and     eax
,
SE_GROUP_LOGON_ID
         cmp     eax
,
SE_GROUP_LOGON_ID
         je      @found
         add     esi
,
sizeof
.
SID_AND_ATTRIBUTES
         dec     ecx
         jnz     @b
        cinvoke  printf
,

jmp     @exit

@found
:
mov     eax
,
dword
[
esi
]
invoke  ConvertSidToStringSid
,
eax
,
buff
         mov     eax
,
dword
[
buff
]
cinvoke  printf
,

,
eax
;
//----- Перечислим привелегии в токене ----------
invoke  GetTokenInformation
,
[
hToken
]
,
TokenPrivileges
,
buff
,
0
,
pReturn
         invoke  GetTokenInformation
,
[
hToken
]
,
TokenPrivileges
,
buff
,
[
pReturn
]
,
pReturn

        cinvoke  printf
,

,
dword
[
buff
]
mov     ecx
,
dword
[
buff
]
mov     esi
,
buff
+
4
@@
:
cmp
[
esi
+
LUID_AND_ATTRIBUTES
.
Attributes
]
,
0
jz      @fuck
         push    esi ecx
         mov
[
strSize
]
,
128
invoke  LookupPrivilegeName
,
0
,
esi
,
privStr
,
strSize
        cinvoke  printf
,

,
privStr
         pop     ecx esi
@fuck
:
add     esi
,
sizeof
.
LUID_AND_ATTRIBUTES
         dec     ecx
         jnz     @b
;
//----- Общая статистика токена ----------
;
invoke  GetTokenInformation
,
[
hToken
]
,
TokenStatistics
,
buff
,
0
,
pReturn
;
invoke  GetTokenInformation
,
[
hToken
]
,
TokenStatistics
,
buff
,
[
pReturn
]
,
pReturn
;
cinvoke  printf
,

,
eax
;
//**************************************************************
cinvoke  printf
,

;
//----- Owner (владелец).
;
//----- SID, который будет записан как владелец любых объектов,
;
//----- созданных процессом с этим токеном доступа.
invoke  GetTokenInformation
,
[
hToken
]
,
TokenOwner
,
buff
,
0
,
pReturn
         invoke  GetTokenInformation
,
[
hToken
]
,
TokenOwner
,
buff
,
[
pReturn
]
,
pReturn
         mov     eax
,
dword
[
buff
]
invoke  ConvertSidToStringSid
,
eax
,
buff
         mov     eax
,
dword
[
buff
]
cinvoke  printf
,

,
eax
;
//----- PrimaryGroup.
;
//----- SID, который будет записан как основная группа любых объектов,
;
//----- созданных процессом с этим токеном доступа.
invoke  GetTokenInformation
,
[
hToken
]
,
TokenPrimaryGroup
,
buff
,
0
,
pReturn
         invoke  GetTokenInformation
,
[
hToken
]
,
TokenPrimaryGroup
,
buff
,
[
pReturn
]
,
pReturn
         mov     eax
,
dword
[
buff
]
invoke  ConvertSidToStringSid
,
eax
,
buff
         mov     eax
,
dword
[
buff
]
cinvoke  printf
,

,
eax
;
//----- DefaultDacl.
;
//----- DACL, который будет назначен любым объектам,
;
//----- созданным процессом c этим токеном, если не указан явный ACL.
invoke  GetTokenInformation
,
[
hToken
]
,
TokenDefaultDacl
,
buff
,
0
,
pReturn
         invoke  GetTokenInformation
,
[
hToken
]
,
TokenDefaultDacl
,
buff
,
[
pReturn
]
,
pReturn

         mov     esi
,
dword
[
buff
]
push    esi
         movzx   eax
,
[
esi
+
DACL_HEADER
.
AclRevision
]
movzx   ebx
,
[
esi
+
DACL_HEADER
.
AclSize
]
movzx   ecx
,
[
esi
+
DACL_HEADER
.
AceCount
]
mov
[
counter
]
,
ecx
        cinvoke  printf
,

,
eax
,
ebx
,
ecx

         pop     esi
         add     esi
,
sizeof
.
DACL_HEADER
         mov     ecx
,
[
counter
]
@@
:
push    esi ecx
         movzx   eax
,
[
esi
+
ACCESS_ALLOWED_ACE
.
AceFlags
]
movzx   ebx
,
[
esi
+
ACCESS_ALLOWED_ACE
.
AceSize
]
mov     ecx
,
[
esi
+
ACCESS_ALLOWED_ACE
.
Mask
]
mov
[
offset
]
,
ebx
         push    esi
        cinvoke  printf
,

,
[
number
]
,
ebx
,
\
[
number
]
,
eax
,
\
[
number
]
,
ecx
         pop     esi
         add     esi
,
ACCESS_ALLOWED_ACE
.
SidStart
         invoke  ConvertSidToStringSid
,
esi
,
sidBuff
         mov     eax
,
dword
[
sidBuff
]
cinvoke  printf
,

,
[
number
]
,
eax

         pop     ecx esi
         inc
[
number
]
add     esi
,
[
offset
]
dec     ecx
         jnz     @b

@exit
:
cinvoke  _getch
        cinvoke  exit
,
0
;
//------------
;
//------------
section
'.idata'
import data readable
library  kernel32
,
'kernel32.dll'
,
msvcrt
,
'msvcrt.dll'
,
advapi32
,
'advapi32.dll'
include
'api\kernel32.inc'
include
'api\msvcrt.inc'
include
'api\advapi32.inc'


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

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

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

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

Как всегда, нет слов. Одни восхищения!
 
Ответить с цитированием

  #3  
Старый 30.09.2021, 16:57
igtech
Новичок
Регистрация: 29.09.2021
Сообщений: 0
С нами: 2433688

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

Всем привет, немного, наверное, простой вопрос, но почему не срабатывает !process 0 0?

************* Path validation summary **************
Response Time (ms) Location
OK D:\test\symbols
0:000> !process 0 0
kdexts!DebugExtensionInitialize failed with 0x80004005
The !process extension command was not found in loaded extensions, but is
available as part of the kdexts extension. Run .update kdexts to install
No export process found
0:000> .load kdexts
kdexts!DebugExtensionInitialize failed with 0x80004005

0:000> .load D:\test\kdexts.dll

**** WARNING loaded *kernel* extension dll for usermode

0:000> !process 0 0

**** WARNING loaded *kernel* extension dll for usermode

**** NT ACTIVE PROCESS DUMP ****
unable to get nt!MmUserProbeAddress
NT symbols are incorrect, please fix symbols

...
как заставить работать комманду?
 
Ответить с цитированием

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

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

попробуйте запустить отладчик в режиме ядра CTRL+K, и загрузите символы
Цитата:

**** NT ACTIVE PROCESS DUMP ****
невозможно получить nt! MmUserProbeAddress
Символы NT неверны, исправьте символы

 
Ответить с цитированием
Ответ



Предыдущая тема Следующая тема

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


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




ANTICHAT ™ © 2001- Antichat Kft.