mirror of
https://github.com/jsecurity101/JonMon
synced 2026-06-08 15:08:08 +00:00
271 lines
6.7 KiB
C++
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;
|
|
} |