https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7f9282927b8cbb5f6633d2...
commit 7f9282927b8cbb5f6633d24c69f9f1d3c7dcb42d Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Wed Sep 26 00:51:38 2018 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Fri Sep 28 00:45:01 2018 +0200
[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... or https://googleprojectzero.blogspot.com/2016/01/raising-dead.html for some details. --- ntoskrnl/include/internal/se.h | 7 ++++++ ntoskrnl/se/token.c | 56 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 7 deletions(-)
diff --git a/ntoskrnl/include/internal/se.h b/ntoskrnl/include/internal/se.h index 993c6ceb11..6095bd9e01 100644 --- a/ntoskrnl/include/internal/se.h +++ b/ntoskrnl/include/internal/se.h @@ -314,6 +314,13 @@ SeIsTokenChild( OUT PBOOLEAN IsChild );
+NTSTATUS +NTAPI +SeIsTokenSibling( + IN PTOKEN Token, + OUT PBOOLEAN IsSibling +); + NTSTATUS NTAPI SepCreateImpersonationTokenDacl( diff --git a/ntoskrnl/se/token.c b/ntoskrnl/se/token.c index 0b20030b8d..f41ef93f52 100644 --- a/ntoskrnl/se/token.c +++ b/ntoskrnl/se/token.c @@ -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;