https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7f9282927b8cbb5f6633d…
commit 7f9282927b8cbb5f6633d24c69f9f1d3c7dcb42d
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Wed Sep 26 00:51:38 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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-b…
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;