Непонятки с WTSQueryUserToken

Тема в разделе "WASM.X64", создана пользователем k3rnl, 20 сен 2023.

  1. k3rnl

    k3rnl Member

    Публикаций:
    0
    Регистрация:
    28 янв 2021
    Сообщения:
    39
    Привет!
    В общем пытаюсь от WTSQueryUserToken получить токен LocalSystem
    Код (Text):
    1. WTSQueryUserToken(0, &hToken);
    Запускаю сервис с системной привилегией SE_TCB_NAME на рабочей станции Service-0x0-3e7$ (NT AUTHORITY\система, SID S-1-5-18) и из него вызываю WTSQueryUserToken.
    На всех актуальных виндах (7, 10, 11) выдаёт одно и тоже - ERROR_NO_TOKEN (An attempt was made to reference a token that does not exist).
    При этом из-под юзерской сессии WTSQueryUserToken отрабатывает превосходно, выдавая токен юзера.
    MSDN пишет
    Что я делаю не так?
    --- Сообщение объединено, 20 сен 2023 ---
    Возможно пользователь (в частности LocalSystem) может разлогиниться после выполнения всех своих задач.
    Нашёл на одном форуме информацию, что сервис нужно создать с одной из групп загрузки, чтобы он стартовал до того момента, как первый пользователь успеет залогиниться.
    Сейчас сервис стартует в автоматическом режиме SERVICE_AUTO_START с запуском системы и менеджера SC Manager.
    Позже попробую добавить группу загрузки ProfSvc_Group посмотрю изменится ли что-то.
     
  2. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    124
    k3rnl,
    WTSQueryUserToken() возвращает "ERROR_NO_TOKEN", если в текущем сеансе нет зареганых юзеров.
    И зачем вам вообще токен пользователя System? Вроде это было актуально на ХР, когда все дружно жили в одном сеансе\сессии. Начиная с висты лафа-же закончилась, т.к. юзеры System\Service\Network закрылись теперь в изолированной сессии(0), а для смертных осталась старая сессия(1). Если вы и получите системный токен, то использовать его в сессии(1) не сможете, т.к. в структуре токена прописывается и сессия, внутри которой действителен данный токен.

    С содержимым токенов можно ознакомиться в WinDbg так: (1)берём произвольный процесс, (2)запрашиваем указатель на токен родителя, (3)просматриваем его. Вот пример (кроликом пусть будет AkelPad):

    Код (Text):
    1. 0: kd> !process 0 0 AkelPad.exe
    2. -------------------------------
    3. PROCESS fffffa8003f08060
    4.     SessionId: 1   Cid: 0500    Peb: 7efdf000   ParentCid: 0618
    5.     DirBase: 57336000   ObjectTable: fffff8a001da57a0   HandleCount: 238.
    6.     Image: AkelPad.exe
    7.  
    8. 0: kd> !process fffffa8003f08060 1
    9. ----------------------------------
    10. PROCESS fffffa8003f08060
    11.     VadRoot  fffffa8003a99990. Vads 305. Clone 0. Private 1718. Modified 11912. Locked 0.
    12.     DeviceMap              fffff8a002166e30
    13.     Token                  fffff8a002e3ca30   <---- адрес токена //******
    14.     BasePriority           8
    15.     CommitCharge           2886
    16.     Job                    fffffa80027bc2f0
    17.  
    18. 0: kd> dt _token fffff8a002e3ca30
    19. ---------------------------------
    20. nt!_TOKEN
    21.    +0x000 TokenSource         : _TOKEN_SOURCE
    22.    +0x010 TokenId             : _LUID
    23.    +0x018 AuthenticationId    : _LUID
    24.    +0x020 ParentTokenId       : _LUID
    25.    +0x028 ExpirationTime      : _LARGE_INTEGER 0x7fffffff`ffffffff
    26.    +0x030 TokenLock           : 0xfffffa80`0279d710 _ERESOURCE
    27.    +0x038 ModifiedId          : _LUID
    28.  
    29.    +0x040 Privileges          : _SEP_TOKEN_PRIVILEGES  <---- Привилегии   //******
    30.    +0x058 AuditPolicy         : _SEP_AUDIT_POLICY
    31.  
    32.    +0x074 SessionId           : 1       <------------------- Номер сеанса //******
    33.    +0x078 UserAndGroupCount   : 0xf
    34.    +0x07c RestrictedSidCount  : 0
    35.    +0x080 VariableLength      : 0x2bc
    36.    +0x084 DynamicCharged      : 0x400
    37.    +0x088 DynamicAvailable    : 0
    38.    +0x08c DefaultOwnerIndex   : 4
    39.    +0x090 UserAndGroups       : 0xfffff8a0`02e3cd40 _SID_AND_ATTRIBUTES
    40.    +0x098 RestrictedSids      : (null)
    41.    +0x0a0 PrimaryGroup        : 0xfffff8a0`02bca750 Void
    42.    +0x0a8 DynamicPart         : 0xfffff8a0`02bca750  -> 0x501
    43.  
    44.    +0x0b0 DefaultDacl         : 0xfffff8a0`02bca76c _ACL
    45.    +0x0b8 TokenType           : 1 ( TokenPrimary )
    46.    +0x0bc ImpersonationLevel  : 0 ( SecurityAnonymous )
    47.    +0x0c0 TokenFlags          : 0x2000
    48.    +0x0c4 TokenInUse          : 0x1 ''
    49.  
    50.    +0x0c8 IntegrityLevelIndex : 0xe
    51.    +0x0cc MandatoryPolicy     : 3
    52.  
    53.    +0x0d0 LogonSession        : 0xfffff8a0`021ee080 _SEP_LOGON_SESSION_REFERENCES
    54.    +0x0d8 OriginLogonSession  : _LUID
    55.    +0x0e0 SidHash             : _SID_AND_ATTRIBUTES_HASH
    56.    +0x1f0 RestrictedSidHash   : _SID_AND_ATTRIBUTES_HASH
    57.    +0x300 pSecurityAttributes : 0xfffff8a0`02ddfac0 _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION
    58.    +0x308 SessionObject       : 0xfffffa80`03a7e370 Void
    59.    +0x310 VariablePart        : 0xfffff8a0`02e3ce30
    60. 0: kd>

    Из своего сеанса(0), система забрасывает в юзерский сеанс(1) двух диверсантов - это файлы winlogon.exe, и csrss.exe. При этом в их токене сеанс сразу меняется с 0 на 1, чтобы юзер не смог снять его дубликат. Более того, имеется и доп.защита от несанкционированного доступа к системным файлам на уровне фишки "Integrity Level" - процесс с меньшим значением IL не сможет получить доступ к процессу с более высоким IL. Если запустить "Process Explorer", можно убедиться в этом.

    pe.png
     
    k3rnl и Mikl___ нравится это.
  3. k3rnl

    k3rnl Member

    Публикаций:
    0
    Регистрация:
    28 янв 2021
    Сообщения:
    39
    Marylin, благодарю за ответ, но сразу сделаю несколько уточнений.
    Я не первый день работаю с процессами с повышенными правами и прекрасно в этом разбираюсь (это чтобы сразу отбросить вот этот ненужный контент про доступы, сессии, системные токены и т.д.).
    Что мешает запустить процесс с правами System в юзерской сессии 0+n (RtlCreateUserProcess с хендлом системного процесса) и из него сделать CreateProcessAsUser в сессию 0? Правильно - ничего. Тут даже нет никаких проблем чтобы перейти в терминальную сессию на интерактивную рабочую станцию WinSta0 и рабочий стол Default (MS типа хотела прикрыть эту тему начиная с Windows 10 build 1803, но ничего у неё не получилось). Где можно спокойно работать с окнами под тем самым аккаунтом NT AUTHORITY\SYSTEM.
    Касаемо токена - есть куча инструментария для его олицетворения и приведение в полное состояние.
    Integrity Level интересная тема, в своё время разбирался в ней. Каждый уровень увеличивает RID на шаг равный 0x1000. Перепрыгнуть через два и более шага невозможно, только постепенное увеличение SECURITY_MANDATORY. Именно так и работает защита в ОС. И именно поэтому не существует доступа к гипервизору под ядром (SECURITY_MANDATORY_SECURE_PROCESS_RID, SID: S-1-16-28672), т.к. его RID равен 0x00007000L. При этом ближайший RID это SECURITY_MANDATORY_PROTECTED_PROCESS_RID (SID: S-1-16-20480), который равен 0x00005000L.

    Но это всё мы с вами сейчас не в ту сторону копаем. Задача совершенно в другом.
    Я знаю что такое ERROR_NO_TOKEN, вопрос в другом - почему пользователь LacalSystem разлогинен, и поэтому я не могу взять его токен?
    С другой стороны, нет никаких проблем захватить токен процесса lsass.exe (который по своим параметрам (привилегии и т.д.) полностью повторяет токен процесса System), даже в Windows 11 (сам процесс lsass.exe имеет protect LSA, но его токен не защищен). Но задача стоит захватить именно токен System.
     
    Последнее редактирование: 21 сен 2023
    Mikl___ нравится это.
  4. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    124
    k3rnl, я сам плаваю в деталях, а потому и спрашиваю без сарказма, если вы можете "запустить процесс с правами System в юзерской сессии 0+n через RtlCreateUserProcess()", то зачем вам токен юзверя System? Ведь успешный старт процесса будет означать, что этот токен у вас уже имеется. Или я что-то не понимаю? Без системного токена с его уровнем IL мы не сможем создать приоритетный процесс, т.к. SRM нас обломает:

    Token.png

    Ну с переходом из терминальной сессии(0) на интерактивную WinSta0 юзера всё ясно - просто создаём сервис с флагом "SERVICE_INTERACTIVE_PROCESS", тогда диспетчер загрузит службу по дефолтной схеме в станцию "Service-0x0-3e7$" сессии(0), но в момент отображения сервисом окна, переключит станцию на WinSta0 (при этом вроде должен быть активным системный сервис UI0Detect.exe).

    Вы проверяли активных пользователей в сессии(0)?
    LsaEnumerateLogonSessions() из Secur32.dll этим занимается. Далее, полученный от неё LUID юзеров передаём в LsaGetLogonSessionData(), чтобы получить в структуру "SECURITY_LOGON_SESSION_DATA" детальную инфу о сессии. Можно заюзать и WTSQuerySessionInformation(), но она "сериализована" и возвращает что-то одно, в то время как первая стреляет сразу дробью. После сбора этой инфы, наверное можно обратно загнать пользователя в сессию (если он разлогинен), например через LogonUser() из Advapi32.dll.

    Кстати имена трёх юзеров "LocalSystem\Service\Network" это просто алиасы, а фактически "по-батюшке" в формате Domain\Name их возвращает NetWkstaUserGetInfo() из Netapi32.dll. Когда-то я писал утилиту, которая выводит инфу о сессиях (см.скрепку), и у себя на данный момент получил такую картину. Внимание заслуживают здесь столбцы "Domain + UserName" с именами скрытых юзеров в сессии(0) - это LUID: 03e4$=NetworkService, 03e5$=LocalService и 03E7$=SystemLogon:

    SessionInfo.png
     

    Вложения:

    • SessionInfo.zip
      Размер файла:
      2,6 КБ
      Просмотров:
      82
    k3rnl и Mikl___ нравится это.
  5. k3rnl

    k3rnl Member

    Публикаций:
    0
    Регистрация:
    28 янв 2021
    Сообщения:
    39
    Marylin, мне был интересен, скажем так, "чистый" токен самого аккаунта. А так да, вы правы, скорее всего токен любого системного процесса ничем не будет отличаться от токена LocalSystem при правильной его настройке.

    Спасибо за наводку по активным пользователям, позже поэкспериментирую с LSA функциями.

    Про имена NetworkService, LocalService и SystemLogon (он же LocalSystem) знаю.
    Что интересно в Windows 11 появились новые LUID формата 03e5$, так же свой LUID имеет и гипервизор.
    Также есть ещё одно отдельное ото всех окружение - рабочая станция MSSWindowStation и рабочий стол MSSRestrictedDesk, используемые процессом SearchIndexer.exe и его сервисом SearchFilterHost.exe

    В общем тема интересная, и покопаться во внутренностях ОС достаточно увлекательно.
     
    Marylin и Mikl___ нравится это.
  6. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    124
    Ну если ещё в Win10 подвезли уже два новых юзера "UMDF" и "DWM", то вполне возможно на Win11 подтянулись ещё парочка. У меня только 7 и 10, тч проверить новых постояльцев не могу. Кстати их список можно посмотреть в том-же WinDbg, ну или софтом "WinObj".

    Код (Text):
    1. 0: kd> !object \Windows
    2. ------------------------
    3. Object: fffff8a0005c7080   Type: Directory
    4. Name  : Windows
    5.  
    6.     Hash  Address           Type         Name
    7.     ----  -------           ----         ----
    8.      13   fffff8a000f50e10  Directory    WindowStations  <-----//
    9.      26   fffff8a000e99520  Section      SharedSection
    10.      27   fffffa80018fc090  ALPC Port    ApiPort
    11.      33   fffffa8002ced950  ALPC Port    SbApiPort
    12.    
    13. 0: kd> !object fffff8a000f50e10
    14. -------------------------------
    15. Object: fffff8a000f50e10  Type: Directory
    16. Name  : WindowStations
    17.  
    18.     Hash  Address           Type           Name
    19.     ----  -------           ----           ----
    20.      03   fffffa8002e15450  WindowStation  Service-0x0-3e4$  <-- Network
    21.      04   fffffa8002e34e40  WindowStation  Service-0x0-3e5$  <-- Service
    22.      06   fffffa8003af93f0  WindowStation  Service-0x0-3e7$  <-- System
    23.      08   fffffa8002b94530  WindowStation  msswindowstation  <-- ???
    24.      25   fffffa8003a832a0  WindowStation  WinSta0           <-- User

    Win10.png

    Угу.. они были ещё в хрюше ХР.
    Насколько я себе представляю всю эту кухню, отображено на рис.ниже.

    WinSession.png

    согласен.. затягивает не по-детски.
     
    k3rnl и Mikl___ нравится это.
  7. k3rnl

    k3rnl Member

    Публикаций:
    0
    Регистрация:
    28 янв 2021
    Сообщения:
    39
    В общем получилось на выходе набросать небольшую программку (за основу взял свой старый проект).
    IDE и компилятор выбрал Pelles C (посмотреть на что способна эта среда, и на удивление очень неплохо себя показала).
    Может кому-нибудь будет полезен её функционал.

    Небольшой FAQ как пользоваться:
    UI0Detect.exe - сервис для перехода в терминальную сессию (то что было вырезано MS начиная с Windows 10 build 1803)
    Wls0wndh.dll - подпрограмма сервиса UI0Detect.exe (нужна для возврата из терминальной сессии)
    FDUI0Input.sys - драйвер устройств ввода клавиатура и мышь (начиная с Windows 10 build 1803 был изменён драйвер win32kfull.sys)
    Код (Text):
    1. if (gSessionId != gServiceSessionId) // if (gSessionId != 0)
    2. {
    3.     // функции и события устройств ввода
    4. }
    Файлы UI0Detect.exe и Wls0wndh.dll необходимо разместить в папке Windows\System32
    Обязательно установить драйвер FDUI0Input.sys для того, чтобы можно было пользоваться клавиатурой и мышью в сессии 0

    И немного о самой программе:
    из основных - переход в терминальную сессию, создание процессов в терминальной сессии, менеджер привилегий для процессов (двойной клик ЛКМ на списке процессов), снятие защиты с сервиса (пока ещё только наброски, позже расширю функционал).
    Также организовал на выбор самые мощные (по моему мнению) токены - локальная система (с привилегией SeCreateTokenPrivilege) и доверенный установщик TrustedInstaller (для доступа к особым разделам ОС) - можно переключаться по одному нажатию соответствующей кнопки.

    LocalSystem
    KLoader_LSA.jpg

    TrustedInstaller
    KLoader_TISvc.jpg
     

    Вложения:

    Последнее редактирование: 28 сен 2023
    Marylin, alex_dz и Mikl___ нравится это.
  8. k3rnl

    k3rnl Member

    Публикаций:
    0
    Регистрация:
    28 янв 2021
    Сообщения:
    39
    Немного пофиксил код и обновил функционал.

    1. Обратил внимание, что на медленных ПК (и возможно на Windows 7) может появляться второе окно программы при захвате токена Trusted Installer. Это происходит из-за ожидания остановки сервиса TrustedInstaller и последующего закрытия диалогового окна (EndDialog). Теперь остановка сервиса обрабатывается в отдельном потоке, и EndDialog не ждёт окончания процедуры, тем самым окно больше не дублируется.

    2. Сделал функционал по обновлению списков процессов и сервисов через контекстное меню WM_CONTEXTMENU (правой кнопкой мыши -> Update ... List). Не стал мудрить с таймеров, к тому же почему-то в Pelles C отсутствует контрол Timer. Пока что работает так себе, позже доведу до ума.

    3. Расширил функционал по созданию системных процессов - теперь можно создавать и в терминальной сессии, и в пользовательском окружении (путём согласия или отказа на соответствующий вопрос).

    4. Немного осовременил интерфейс диалогового окна для Windows 11 средствами DwmAPI (DwmSetWindowAttribute - DWMWA_WINDOW_CORNER_PREFERENCE и DWMWA_SYSTEMBACKDROP_TYPE). Добавил угловатости (DWMWCP_ROUNDSMALL) и цвета заголовка окна (переливку в зависимости от картинка рабочего стола (DWMSBT_TABBEDWINDOW) оставил). Выглядит вроде неплохо для технологии времён 3.x и 95 :cools:
    1.jpg
    2.jpg
    --- Сообщение объединено, 3 окт 2023 ---
    Прошу прощения - не заметил утечку памяти.
    Из прядущего поста не качайте. Пересобрал билд.
     

    Вложения:

    Marylin нравится это.
  9. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    361
    спасибо
    а можно как-то более юзверь-френдли месаги печатать?
    upload_2023-10-3_0-15-7.png
     
    k3rnl нравится это.
  10. k3rnl

    k3rnl Member

    Публикаций:
    0
    Регистрация:
    28 янв 2021
    Сообщения:
    39
    alex_dz, спасибо за обратную связь.
    Обработчик сообщений добавлю.
    Над GUI менеджерами процессов и сервисов поработаю чуть позже. В той части кода пока только наброски сделал (для проверки основного функционала). Пока думаю что конкретно добавить, лепить всё подряд не хочется, "большой" проект утомляет и со временем начинаешь его забрасывать.

    Наверно тему отдельную создам в wasm проектах, тут дальше постить не вижу смысла. Вопрос этой темы был решён.