0

While the main thread impersonates a client, my code creates a thread and assigns it the impersonation token using SetThreadToken. Then the main thread closes the token.

Specifically, the main thread does this:

  1. Get a primary token using LogonUser.
  2. Get an impersonation token using DuplicateToken from the primary token.
  3. Call ImpersonateLoggedOnUser.
  4. Spawn a secondary thread and call SetThreadToken on the thread with the impersonation token.
  5. RevertToSelf.
  6. CloseHandle on both the impersonation and the primary token.

At this point, the secondary thread is still running. Does the impersonation token remain usable for the secondary thread even though the token handle has been closed in the main thread?

j6t
  • 9,150
  • 1
  • 15
  • 35
  • 1
    yes, when you assign thread to token ( via `SetThreadToken`) - additional reference will be added to this token. as result it will be not destroyed when you close it handle. – RbMm Oct 17 '18 at 08:17
  • Thanks. But for `SetThreadToken` I need an impersonation token, so I have to `DuplicateToken` anyway. The main thread impersonates the user because it has to do something else on their behalf, too. – j6t Oct 17 '18 at 08:21
  • understand. any object (token as well) remain valid until exist reference to it. handle to object this is reference. when you assign token to thread - additional reference will be added to this token object. as result you can close handle. token will be valid until you not asign another token to your worker thread or this thread not exit – RbMm Oct 17 '18 at 08:23

1 Answers1

1

windows kernel use reference counting on objects. the TOKEN is object too. when you assign token to thread (via SetThreadToken) the pointer to TOKEN object is stored in ETHREAD object and additional reference added to TOKEN object. of course kernel cannot rely on close you or not original handle (reference) to TOKEN object. this is general pointer counting rule - if A stored pointer to B in self - it add reference to B, for it will be valid until A use B. the token will be valid until your thread not impersonate another token, or end impersonation or exit. anyway after you assign token to thread you can close handle to it - token remain valid


if exist interest, how internal SetThreadToken work:

SetThreadToken call NtSetInformationThread with ThreadImpersonationToken information class. from kernel side implementation called PsAssignImpersonationToken - this api declared in ntifs.h. it implementation call PsImpersonateClient which and reference the passed token. as result it become valid util assigned to thread

The server thread could already be impersonating a client when PsImpersonateClient is called. If this is the case, the reference count on the token representing that client is decremented.

but anyway - we not need for this internal knowledge - need general think understand - object reference counting. if pointer to token saved in thread - this token of course must be valid until used by thread. as result it referenced. when thread stop using this token (change pointer or exit) - token dereferenced

Community
  • 1
  • 1
RbMm
  • 31,280
  • 3
  • 35
  • 56
  • Do you have any references that confirm your point? Perhaps code examples? – j6t Oct 17 '18 at 09:12
  • @j6t - no reference. this is windows internal knowledge, however if pointer to `TOKEN` saved in `Thread->ImpersonationInfo->Token` of course reference is added to token, for it will be valid. code example which you want ? – RbMm Oct 17 '18 at 09:15
  • Windows internal knowledge? Are you a Microsoft employee working on the Windows kernel? Perhaps you know about a well-known open source software that uses the pattern under discussion. – j6t Oct 17 '18 at 09:22
  • @j6t - i of course not Microsoft employee , but try think yourself - how we can store pointer to object (token) for use in future, without add reference to it, for sure that it will be valid, until we use it ? this is general knowledge – RbMm Oct 17 '18 at 09:40