Files
jsecurity101-JonMon/JonMon/token.cpp
T
2023-09-26 09:03:04 -05:00

271 lines
6.7 KiB
C++

#include "token.h"
PAGED_FILE();
NTSTATUS GetTokenUserName(HANDLE hToken, PUNICODE_STRING pFullName) {
ULONG returnLength;
UNICODE_STRING SidString;
WCHAR SidStringBuffer[64];
PTOKEN_USER pTokenInfo = NULL;
ULONG NameLength;
ULONG DomainLength;
UNICODE_STRING DomainName = { 0 };
DomainName.Length = 0;
DomainName.MaximumLength = MAX_ALLOC;
UNICODE_STRING UserName = { 0 };
UserName.Length = 0;
UserName.MaximumLength = MAX_ALLOC;
NTSTATUS status;
PVOID domainBuffer{};
PVOID userBuffer{};
SID_NAME_USE SidNameUse;
PSID pSid = NULL;
domainBuffer = ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, TOKEN_TAG);
if (domainBuffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
DomainName.Buffer = (PWSTR)domainBuffer;
userBuffer = ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, TOKEN_TAG);
if (userBuffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}
UserName.Buffer = (PWSTR)userBuffer;
if (hToken == NULL)
{
status = STATUS_INVALID_PARAMETER;
goto Exit;
}
status = ZwQueryInformationToken(hToken, TokenUser, NULL, 0, &returnLength);
pTokenInfo = (PTOKEN_USER)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, TOKEN_TAG);
if (pTokenInfo == NULL)
{
goto Exit;
}
status = ZwQueryInformationToken(hToken, TokenUser, pTokenInfo, returnLength, &returnLength);
if (!NT_SUCCESS(status))
{
goto Exit;
}
pSid = pTokenInfo->User.Sid;
RtlZeroMemory(SidStringBuffer, sizeof(SidStringBuffer));
SidString.Buffer = (PWCHAR)SidStringBuffer;
SidString.MaximumLength = sizeof(SidStringBuffer);
status = RtlConvertSidToUnicodeString(&SidString, pSid, FALSE);
if (!NT_SUCCESS(status))
{
goto Exit;
}
status = SecLookupAccountSid(pSid, &NameLength, &UserName, &DomainLength, &DomainName, &SidNameUse);
if (!NT_SUCCESS(status))
{
goto Exit;
}
RtlCopyUnicodeString(pFullName, &DomainName);
RtlAppendUnicodeToString(pFullName, L"\\");
RtlAppendUnicodeStringToString(pFullName, &UserName);
//Adding null terminator
pFullName->Buffer[pFullName->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
Exit:
if (pTokenInfo != NULL) {
ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
}
if (domainBuffer != NULL) {
ExFreePoolWithTag(domainBuffer, TOKEN_TAG);
}
if (userBuffer != NULL) {
ExFreePoolWithTag(userBuffer, TOKEN_TAG);
}
return status;
}
NTSTATUS GetUserTokenStatistics(HANDLE hToken, DWORD* AuthenticationId) {
PAGED_CODE();
PTOKEN_STATISTICS pTokenInfo = NULL;
ULONG returnLength;
NTSTATUS status = ZwQueryInformationToken(hToken, TokenStatistics, NULL, 0, &returnLength);
pTokenInfo = (PTOKEN_STATISTICS)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, TOKEN_TAG);
if (pTokenInfo == NULL)
{
goto Exit;
}
status = ZwQueryInformationToken(hToken, TokenStatistics, pTokenInfo, returnLength, &returnLength);
if (!NT_SUCCESS(status))
{
DbgPrint("ZwQueryInformationToken Failed: %08x\n", status);
ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
return status;
}
LUID LogonId = pTokenInfo->AuthenticationId;
*AuthenticationId = LogonId.LowPart;
Exit:
if (pTokenInfo != NULL) {
ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
}
return status;
}
NTSTATUS GetProcessUserName(PUNICODE_STRING pFullName, HANDLE ProcessId, DWORD* AuthenticationId) {
PAGED_CODE();
HANDLE hToken = NULL;
HANDLE hProcess = NULL;
PEPROCESS eProcess = NULL;
if (pFullName == NULL)
{
return STATUS_INVALID_PARAMETER;
}
NTSTATUS status = PsLookupProcessByProcessId(ProcessId, &eProcess);
if (!NT_SUCCESS(status))
{
goto Exit;
}
status = ObOpenObjectByPointer(eProcess, OBJ_KERNEL_HANDLE, NULL, 0x1000, 0, KernelMode, &hProcess);
if (!NT_SUCCESS(status))
{
goto Exit;
}
status = ZwOpenProcessTokenEx(hProcess, TOKEN_QUERY, OBJ_KERNEL_HANDLE, &hToken);
if (!NT_SUCCESS(status)) {
goto Exit;
}
status = GetTokenUserName(hToken, pFullName);
if (!NT_SUCCESS(status))
{
goto Exit;
}
status = GetUserTokenStatistics(hToken, AuthenticationId);
if (!NT_SUCCESS(status))
{
goto Exit;
}
Exit:
if (eProcess != NULL) {
ObDereferenceObject(eProcess);
}
if (hToken != NULL) {
ZwClose(hToken);
}
if (hProcess != NULL) {
ObCloseHandle(hProcess, KernelMode);
}
return status;
}
DWORD GetSessionIdFromToken(HANDLE hToken) {
NTSTATUS status;
DWORD sessionId;
DWORD returnLength = 0;
status = ZwQueryInformationToken(hToken, TokenSessionId, &sessionId, sizeof(sessionId), &returnLength);
if (NT_SUCCESS(status)) {
return sessionId;
}
return 0;
}
NTSTATUS GetImpersonationLevelFromToken(HANDLE hToken) {
PTOKEN_STATISTICS pTokenInfo = NULL;
ULONG returnLength;
NTSTATUS status = ZwQueryInformationToken(hToken, TokenStatistics, NULL, 0, &returnLength);
pTokenInfo = (PTOKEN_STATISTICS)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, TOKEN_TAG);
if (pTokenInfo == NULL)
{
DbgPrint("ExAllocatePoolWithTag Failed: %08x\n", status);
return status;
}
status = ZwQueryInformationToken(hToken, TokenStatistics, pTokenInfo, returnLength, &returnLength);
if (!NT_SUCCESS(status))
{
DbgPrint("ZwQueryInformationToken Failed: %08x\n", status);
ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
return status;
}
else
{
TOKEN_TYPE TokenType = pTokenInfo->TokenType;
if (TokenType == TokenImpersonation) {
DbgPrint("Token Type: %d\n", TokenType);
}
else {
DbgPrint("Token Type: %d\n", TokenType);
}
ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
status = STATUS_SUCCESS;
return status;
}
}
NTSTATUS GetTokenIntegrityLevel(HANDLE hToken, PUNICODE_STRING IntegrityLevel) {
NTSTATUS status;
PTOKEN_MANDATORY_LABEL pTIL = NULL;
ULONG returnLength;
status = ZwQueryInformationToken(hToken, TokenIntegrityLevel, NULL, 0, &returnLength);
pTIL = (PTOKEN_MANDATORY_LABEL)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, TOKEN_TAG);
if (pTIL == NULL)
{
goto Exit;
}
status = ZwQueryInformationToken(hToken, TokenIntegrityLevel, pTIL, returnLength, &returnLength);
if (!NT_SUCCESS(status))
{
DbgPrint("ZwQueryInformationToken Failed: %08x\n", status);
goto Exit;
}
ULONG IntegrityLevelValue = *RtlSubAuthoritySid(pTIL->Label.Sid, (DWORD)(UCHAR)(*RtlSubAuthorityCountSid(pTIL->Label.Sid) - 1));
switch (IntegrityLevelValue) {
case SECURITY_MANDATORY_UNTRUSTED_RID:
RtlInitUnicodeString(IntegrityLevel, L"Untrusted");
break;
case SECURITY_MANDATORY_LOW_RID:
RtlInitUnicodeString(IntegrityLevel, L"Low");
break;
case SECURITY_MANDATORY_MEDIUM_RID:
RtlInitUnicodeString(IntegrityLevel, L"Medium");
break;
case SECURITY_MANDATORY_HIGH_RID:
RtlInitUnicodeString(IntegrityLevel, L"High");
break;
case SECURITY_MANDATORY_SYSTEM_RID:
RtlInitUnicodeString(IntegrityLevel, L"System");
break;
default:
RtlInitUnicodeString(IntegrityLevel, L"Unknown");
break;
}
status = STATUS_SUCCESS;
Exit:
if(pTIL != NULL)
{
ExFreePoolWithTag(pTIL, TOKEN_TAG);
}
return status;
}