[NTOS:SE] Fixes for NT tokens.

- SeIsTokenChild(): Correctly check whether a caller-provided token
  is a child from the current process' primary token by looking at
  its ParentTokenId member.

- Add a SeIsTokenSibling() helper to determine whether a caller-provided
  token and the current process' primary token are siblings, by comparing
  their ParentTokenId's and AuthenticationId's.

NOTE: Children tokens are created through CreateRestrictedToken();
sibling tokens are created through DuplicateToken() (amongst others).

See slide 49 of https://www.slideshare.net/Shakacon/social-engineering-the-windows-kernel-by-james-forshaw
or https://googleprojectzero.blogspot.com/2016/01/raising-dead.html
for some details.
This commit is contained in:
Hermès Bélusca-Maïto 2018-09-26 00:51:38 +02:00
parent 3caab66e22
commit 7f9282927b
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 56 additions and 7 deletions

View file

@ -314,6 +314,13 @@ SeIsTokenChild(
OUT PBOOLEAN IsChild
);
NTSTATUS
NTAPI
SeIsTokenSibling(
IN PTOKEN Token,
OUT PBOOLEAN IsSibling
);
NTSTATUS
NTAPI
SepCreateImpersonationTokenDacl(

View file

@ -717,25 +717,67 @@ SeIsTokenChild(IN PTOKEN Token,
OUT PBOOLEAN IsChild)
{
PTOKEN ProcessToken;
LUID ProcessLuid, CallerLuid;
LUID ProcessTokenId, CallerParentId;
/* Assume failure */
*IsChild = FALSE;
/* Reference the process token */
ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess());
if (!ProcessToken)
return STATUS_UNSUCCESSFUL;
/* Get the ID */
ProcessLuid = ProcessToken->AuthenticationId;
/* Get its token ID */
ProcessTokenId = ProcessToken->TokenId;
/* Dereference the token */
ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken);
/* Get our LUID */
CallerLuid = Token->AuthenticationId;
/* Get our parent token ID */
CallerParentId = Token->ParentTokenId;
/* Compare the LUIDs */
if (RtlEqualLuid(&CallerLuid, &ProcessLuid)) *IsChild = TRUE;
/* Compare the token IDs */
if (RtlEqualLuid(&CallerParentId, &ProcessTokenId))
*IsChild = TRUE;
/* Return success */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
SeIsTokenSibling(IN PTOKEN Token,
OUT PBOOLEAN IsSibling)
{
PTOKEN ProcessToken;
LUID ProcessParentId, ProcessAuthId;
LUID CallerParentId, CallerAuthId;
/* Assume failure */
*IsSibling = FALSE;
/* Reference the process token */
ProcessToken = PsReferencePrimaryToken(PsGetCurrentProcess());
if (!ProcessToken)
return STATUS_UNSUCCESSFUL;
/* Get its parent and authentication IDs */
ProcessParentId = ProcessToken->ParentTokenId;
ProcessAuthId = ProcessToken->AuthenticationId;
/* Dereference the token */
ObFastDereferenceObject(&PsGetCurrentProcess()->Token, ProcessToken);
/* Get our parent and authentication IDs */
CallerParentId = Token->ParentTokenId;
CallerAuthId = Token->AuthenticationId;
/* Compare the token IDs */
if (RtlEqualLuid(&CallerParentId, &ProcessParentId) &&
RtlEqualLuid(&CallerAuthId, &ProcessAuthId))
{
*IsSibling = TRUE;
}
/* Return success */
return STATUS_SUCCESS;