Blog. Just Blog

Как узнать, какие привилегии есть у процесса

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Ранее я уже писал, как устанавливать нужные привилегии для процесса. Сегодня будет пример, как можно получать список доступных привилегий. Но сперва немного констант и структур, которые необходимы для работы с привилегиями.
  1. TOKEN_QUERY     = 8h
  2. TokenPrivileges = 3
  3.  
  4. struct LUID
  5.   LowPart  dd ?
  6.   HighPart dd ?
  7. ends
  8.  
  9. struct LUID_AND_ATTRIBUTES
  10.   pLuid       LUID
  11.   Attributes  dd ?
  12. ends
  13.  
  14. struct TOKEN_PRIVILEGES
  15.   PrivilegeCount   dd ?
  16.   Privileges       LUID_AND_ATTRIBUTES
  17. ends
Теперь теория. Каждому процессу соответствует свой дескриптор маркера доступа (токен), через который выполняется большинство операций, касающихся безопасности, прав доступа и подобного. Для получения информации о привилегиях надо запросить информацию о токене с помощью функции GetTokenInformation, указав в качестве класса сведений TokenPrivileges, то есть данные о привилегиях. Токен должен быть предварительно открыт с помощью функции OpenProcessToken или OpenThreadToken. На выходе будет получен массив структур TOKEN_PRIVILEGES. Поочередно перебирая эти структуры, можно определить все привилегии, которыми обладает процесс.

С помощью функции LookupPrivilegeName можно получить имя вида "Se...Privilege", а по нему, вызвав функцию LookupPrivilegeDisplayName, получить ее описание. На практике удалось выяснить, что в списке привилегий могут встречаться записи с пустыми значениями локальных уникальных идентификаторов (LUID) или со значениями, для которых в заголовочных файлах не определено соответствующих записей. Затрудняюсь сказать, как поступать в таких случаях, так что предпочту их просто пропускать. На всякий случай можно дополнительно проверять LUID, соответствующие следующему списку.
  1. pr_list db 'SeCreateTokenPrivilege',0
  2.         db 'SeAssignPrimaryTokenPrivilege',0
  3.         db 'SeLockMemoryPrivilege',0
  4.         db 'SeIncreaseQuotaPrivilege',0
  5.         db 'SeUnsolicitedInputPrivilege',0
  6.         db 'SeMachineAccountPrivilege',0
  7.         db 'SeTcbPrivilege',0
  8.         db 'SeSecurityPrivilege',0
  9.         db 'SeTakeOwnershipPrivilege',0
  10.         db 'SeLoadDriverPrivilege',0
  11.         db 'SeSystemProfilePrivilege',0
  12.         db 'SeSystemtimePrivilege',0
  13.         db 'SeProfileSingleProcessPrivilege',0
  14.         db 'SeIncreaseBasePriorityPrivilege',0
  15.         db 'SeCreatePagefilePrivilege',0
  16.         db 'SeCreatePermanentPrivilege',0
  17.         db 'SeBackupPrivilege',0
  18.         db 'SeRestorePrivilege',0
  19.         db 'SeShutdownPrivilege',0
  20.         db 'SeDebugPrivilege',0
  21.         db 'SeAuditPrivilege',0
  22.         db 'SeSystemEnvironmentPrivilege',0
  23.         db 'SeChangeNotifyPrivilege',0
  24.         db 'SeRemoteShutdownPrivilege',0
  25.         db 'SeUndockPrivilege',0
  26.         db 'SeSyncAgentPrivilege',0
  27.         db 'SeEnableDelegationPrivilege',0
  28.         db 'SeManageVolumePrivilege',0
  29.         db 'SeImpersonatePrivilege',0
  30.         db 'SeCreateGlobalPrivilege',0
  31.         db 'SeTrustedCredManAccessPrivilege',0
  32.         db 'SeRelabelPrivilege',0
  33.         db 'SeIncreaseWorkingSetPrivilege',0
  34.         db 'SeTimeZonePrivilege',0
  35.         db 'SeCreateSymbolicLinkPrivilege',0
  36.         db 0
Получить LUID, соответствующий каждой из строк списка, можно с помощью функции LookupPrivilegeValue, чтобы затем сравнить полученное значение со значением из записей массива привилегий. Итоговый код получится примерно следующим:
  1.         invoke  GetCurrentProcess
  2.  
  3.         invoke  OpenProcessToken,eax,TOKEN_QUERY,hToken
  4.         or      eax,eax
  5.         ; Ошибка
  6.         jz      loc_exit
  7.  
  8.         ; Получить список привилегий
  9.         invoke  GetTokenInformation,[hToken],TokenPrivileges,\
  10.                 info_buff,INFO_BUFF_SIZE,buff_size
  11.  
  12.         ; Указатель на список привилегий
  13.         mov     esi,info_buff
  14.         ; Количество привилегий
  15.         mov     ebx,[esi+TOKEN_PRIVILEGES.PrivilegeCount]
  16. loc_loop:
  17.         ; Все привилегии обработаны?
  18.         or      ebx,ebx
  19.         jz      loc_done
  20.  
  21.         mov     [pr_n_size],STRING_BUFF_SIZE
  22.         ; Получить название привилегии
  23.         lea     eax,[esi+TOKEN_PRIVILEGES.Privileges.pLuid]
  24.         invoke  LookupPrivilegeName,NULL,eax,pr_name,pr_n_size
  25.         ; Такое название есть?
  26.         or      eax,eax
  27.         jnz     loc_get_desc
  28.  
  29.         ; LUID привилегии пустой?
  30.         cmp     [esi+TOKEN_PRIVILEGES.Privileges.pLuid.LowPart],0
  31.         jne     @f
  32.         cmp     [esi+TOKEN_PRIVILEGES.Privileges.pLuid.HighPart],0
  33.         je      loc_next
  34. @@:
  35.         ; Просканировать список привилегий
  36.         mov     edi,pr_list
  37. loc_scan:
  38.         mov     [tluid.LowPart],0
  39.         mov     [tluid.HighPart],0
  40.  
  41.         ; Получить значение LUID привилегии из списка
  42.         invoke  LookupPrivilegeValue,NULL,edi,tluid
  43.         ; Значения LUID совпадают?
  44.         mov     eax,[esi+TOKEN_PRIVILEGES.Privileges.pLuid.LowPart]
  45.         cmp     eax,[tluid.LowPart]
  46.         jne     loc_scan_next
  47.         mov     eax,[esi+TOKEN_PRIVILEGES.Privileges.pLuid.HighPart]
  48.         cmp     eax,[tluid.HighPart]
  49.         jne     loc_scan_next
  50.  
  51.         invoke  lstrcpy,pr_name,edi
  52.         jmp     loc_get_desc
  53. loc_scan_next:
  54.         invoke  lstrlen,edi
  55.         add     edi,eax
  56.         inc     edi
  57.         cmp     byte [edi],0
  58.         jne     loc_scan
  59.         jmp     loc_next
  60.  
  61. loc_get_desc:
  62.         ; Очистить строку описания
  63.         invoke  RtlZeroMemory,pr_desc,STRING_BUFF_SIZE
  64.         mov     [pr_d_size],STRING_BUFF_SIZE
  65.         ; Получить описание привилегии
  66.         invoke  LookupPrivilegeDisplayName,NULL,\
  67.                 pr_name,pr_desc,pr_d_size,tmp
  68.  
  69.         ...
  70.         ...
  71.         ; pr_name -> название привилегии
  72.         ; pr_desc -> описание привилегии
  73.         ...
  74.         ...
  75. loc_next:
  76.         ; Следующая привилегия в списке
  77.         add     esi,sizeof.TOKEN_PRIVILEGES
  78.         dec     ebx
  79.         jmp     loc_loop
  80. loc_done:
  81.         invoke  CloseHandle,[hToken]
В приложении пример программы с исходным текстом, которая выводит все привилегии, с которыми она запущена.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

Get.Privileges.Demo.zip (3,230 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 403 | Комментариев: 2

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (30.01.2024 в 16:46):
А у меня нет бесятки, не могу проверить.
Vad (30.01.2024 в 16:44):
SeUnsolicitedInputPrivilege - Требуется для чтения нежелательных входных данных с устройства терминала. Право пользователя: неприменимо (из справки Microsoft). Под Win10 при вызове LookupPrivilegeValue у меня дает ошибку ERROR_NO_SUCH_PRIVILEGE 1313 (0x521). А у вас ??

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0041 сек.) / Память: 4.5 Mb
Наверх