Last active
May 11, 2023 05:54
-
-
Save jsecurity101/5ef14a0b537af36ce448b28c707c6976 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (-not ('TokenInformation.ProcessNativeMethods' -as [type])){ | |
$TypeDef = @' | |
using System; | |
using System.Runtime.InteropServices; | |
namespace TokenInformation { | |
[Flags] | |
public enum ProcessAccess { | |
All = 0x001FFFFF, | |
Terminate = 0x00000001, | |
CreateThread = 0x00000002, | |
VirtualMemoryOperation = 0x00000008, | |
VirtualMemoryRead = 0x00000010, | |
VirtualMemoryWrite = 0x00000020, | |
DuplicateHandle = 0x00000040, | |
CreateProcess = 0x000000080, | |
SetQuota = 0x00000100, | |
SetInformation = 0x00000200, | |
QueryInformation = 0x00000400, | |
QueryLimitedInformation = 0x00001000, | |
Synchronize = 0x00100000 | |
} | |
[Flags] | |
public enum ThreadAccess { | |
TERMINATE = (0x0001), | |
SUSPEND_RESUME = (0x0002), | |
GET_CONTEXT = (0x0008), | |
SET_CONTEXT = (0x0010), | |
SET_INFORMATION = (0x0020), | |
QUERY_INFORMATION = (0x0040), | |
QUERY_LIMITED = (0x00000800), | |
SET_THREAD_TOKEN = (0x0080), | |
IMPERSONATE = (0x0100), | |
DIRECT_IMPERSONATION = (0x0200) | |
} | |
[Flags] | |
public enum TokenAccess { | |
STANDARD_RIGHTS_REQUIRED = 0x000F0000, | |
STANDARD_RIGHTS_READ = 0x00020000, | |
TOKEN_ASSIGN_PRIMARY = 0x0001, | |
TOKEN_DUPLICATE = 0x0002, | |
TOKEN_IMPERSONATE = 0x0004, | |
TOKEN_QUERY = 0x0008, | |
TOKEN_QUERY_SOURCE = 0x0010, | |
TOKEN_ADJUST_PRIVILEGES = 0x0020, | |
TOKEN_ADJUST_GROUPS = 0x0040, | |
TOKEN_ADJUST_DEFAULT = 0x0080, | |
TOKEN_ADJUST_SESSIONID = 0x0100, | |
TOKEN_IMPERSONATEUSER = (TOKEN_DUPLICATE | TOKEN_QUERY), | |
TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY), | |
TOKEN_QUERY_ALL = (TOKEN_QUERY | TOKEN_QUERY_SOURCE), | |
TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | | |
TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | | |
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT | | |
TOKEN_ADJUST_SESSIONID) | |
} | |
[Flags] | |
public enum TOKEN_INFORMATION_CLASS { | |
TokenUser = 1, | |
TokenGroups, | |
TokenPrivileges, | |
TokenOwner, | |
TokenPrimaryGroup, | |
TokenDefaultDacl, | |
TokenSource, | |
TokenType, | |
TokenImpersonationLevel, | |
TokenStatistics, | |
TokenRestrictedSids, | |
TokenSessionId, | |
TokenGroupsAndPrivileges, | |
TokenSessionReference, | |
TokenSandBoxInert, | |
TokenAuditPolicy, | |
TokenOrigin, | |
TokenElevationType, | |
TokenLinkedToken, | |
TokenElevation, | |
TokenHasRestrictions, | |
TokenAccessInformation, | |
TokenVirtualizationAllowed, | |
TokenVirtualizationEnabled, | |
TokenIntegrityLevel | |
} | |
public enum SECURITY_IMPERSONATION_LEVEL { | |
SecurityAnonymous, | |
SecurityIdentification, | |
SecurityImpersonation, | |
SecurityDelegation | |
} | |
[Flags] | |
public enum TOKEN_TYPE { | |
TokenPrimary = 1, | |
TokenImpersonation = 2 | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] | |
public struct TOKEN_STATISTICS { | |
public LUID TokenId; | |
public LUID AuthenticationId; | |
public long ExpirationTime; | |
public uint TokenType; | |
public uint ImpersonationLevel; | |
public uint DynamicCharged; | |
public uint DynamicAvailable; | |
public uint GroupCount; | |
public uint PrivilegeCount; | |
public LUID ModifiedId; | |
} | |
public struct TOKEN_USER | |
{ | |
public SID_AND_ATTRIBUTES User ; | |
} | |
public struct TOKEN_OWNER | |
{ | |
public IntPtr Sid ; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct SID_AND_ATTRIBUTES | |
{ | |
public IntPtr Sid ; | |
public int Attributes ; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct LUID | |
{ | |
public UInt32 LowPart; | |
public Int32 HighPart; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct TOKEN_ORIGIN { | |
public LUID OriginatingLogonSession ; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct TOKEN_MANDATORY_LABEL { | |
public SID_AND_ATTRIBUTES Label ; | |
} | |
public class ProcessNativeMethods { | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern IntPtr OpenProcess( | |
ProcessAccess processAccess, | |
bool bInheritHandle, | |
int processId); | |
[DllImport("advapi32.dll", SetLastError=true)] | |
public static extern bool OpenProcessToken( | |
IntPtr ProcessHandle, | |
uint DesiredAccess, | |
ref IntPtr TokenHandle); | |
[DllImport("advapi32.dll", SetLastError=true)] | |
public static extern bool GetTokenInformation( | |
IntPtr TokenHandle, | |
TOKEN_INFORMATION_CLASS TokenInformationClass, | |
IntPtr TokenInformation, | |
uint TokenInformationLength, | |
ref uint ReturnLength); | |
[DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)] | |
public static extern bool ConvertSidToStringSid( | |
IntPtr pSid, | |
ref string strSid); | |
[DllImport("advapi32.dll", SetLastError=true)] | |
public static extern bool ImpersonateLoggedOnUser( | |
IntPtr hToken); | |
[DllImport("kernel32.dll", SetLastError=true)] | |
public static extern bool CloseHandle( | |
IntPtr hHandle); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern IntPtr OpenThread( | |
ThreadAccess dwDesiredAccess, | |
bool bInheritHandle, | |
uint dwThreadId); | |
[DllImport("advapi32.dll", SetLastError=true)] | |
public static extern bool OpenThreadToken( | |
IntPtr ThreadHandle, | |
uint DesiredAccess, | |
bool OpenAsSelf, | |
ref IntPtr TokenHandle); | |
[DllImport("advapi32.dll")] | |
public extern static bool DuplicateToken( | |
IntPtr ExistingTokenHandle, | |
int SECURITY_IMPERSONATION_LEVEL, | |
ref IntPtr DuplicateTokenHandle | |
); | |
[DllImport("advapi32.dll", SetLastError = true)] | |
public static extern bool RevertToSelf(); | |
} | |
} | |
'@ | |
Add-Type -TypeDefinition $TypeDef | |
} | |
function Get-IntegrityLevel { | |
param ( | |
[Parameter(ValueFromPipelineByPropertyName)] | |
[Int32] | |
[Alias('Id')] | |
$ProcessId | |
) | |
if (($PSBoundParameters.ContainsKey('ProcessId'))) | |
{ | |
$Processes = Get-Process -Id $ProcessId | |
} | |
else{ | |
$Processes = Get-Process | |
} | |
foreach ($p in $Processes) | |
{ | |
$ProcessHandle = [TokenInformation.ProcessNativeMethods]::OpenProcess( | |
'QueryLimitedInformation', | |
$False, | |
$p.Id | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($ProcessHandle -eq [IntPtr]::Zero){ | |
Write-Warning $LastError | |
continue | |
} | |
$TokenHandle = [IntPtr]::Zero | |
$TokenResult = [TokenInformation.ProcessNativeMethods]::OpenProcessToken( | |
$ProcessHandle, | |
[TokenInformation.TokenAccess] 'TOKEN_QUERY, TOKEN_QUERY_SOURCE', | |
[Ref] $TokenHandle | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if (!$TokenResult) { | |
Write-Warning $LastError | |
} | |
$ProcessInformation = "Displaying Process/Primary Information" | |
$ProcessTokenIntegrityLevel = Get-TokenInformation -TokenInformation TokenIntegrityLevel -TokenHandle $TokenHandle | |
[PSCustomObject] @{ | |
Title = $ProcessInformation | |
ProcessName = $p.Name | |
SessionId = $p.SessionId | |
PID = $p.Id | |
TokenIntegrityLevel = $ProcessTokenIntegrityLevel | |
} | |
$Close = [TokenInformation.ProcessNativeMethods]::CloseHandle($TokenHandle) | |
$Close = [TokenInformation.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
} | |
} | |
function Get-TokenInformation { | |
<# | |
.SYNOPSIS | |
Gets token information given a specific process. | |
.DESCRIPTION | |
Get-TokenInformation will obtain information about a token's user. | |
.NOTES | |
Author: Jonathan Johnson (@jsecurity101) | |
Dependencies: None | |
References: PInvoke / https://gist.github.com/jaredcatkinson/17698b39efd72f976a6a846ec3a8eacd | |
#> | |
param ( | |
[Parameter(Mandatory=$true)] | |
[System.IntPtr] | |
$TokenHandle, | |
[Parameter(Mandatory= $true)] | |
[string] | |
$TokenInformation | |
) | |
$TokenLength = 0 | |
$Result = [TokenInformation.ProcessNativeMethods]::GetTokenInformation( | |
$TokenHandle, | |
[TokenInformation.TOKEN_INFORMATION_CLASS]::$TokenInformation, | |
[IntPtr]::Zero, | |
$TokenLength, | |
[Ref] $TokenLength | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
[IntPtr]$TokenPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TokenLength) | |
$Result = [TokenInformation.ProcessNativeMethods]::GetTokenInformation( | |
$TokenHandle, | |
[TokenInformation.TOKEN_INFORMATION_CLASS]::$TokenInformation, | |
$TokenPtr, | |
$TokenLength, | |
[Ref] $TokenLength | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($Result) { | |
switch ($TokenInformation) | |
{ | |
TokenIntegrityLevel | |
{ | |
$TokenIntegrityLevel = [System.Runtime.InteropServices.Marshal]::PtrToStructure($TokenPtr, [System.Type][TokenInformation.TOKEN_MANDATORY_LABEL]) | |
$StringPtr = [IntPtr]::Zero | |
$TokenSID = [TokenInformation.ProcessNativeMethods]::ConvertSidToStringSid( | |
$TokenIntegrityLevel.Label.Sid, | |
[ref]$StringPtr | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if(!$TokenSID) { | |
throw $LastError | |
} | |
$TokenIntegritySID = New-Object System.Security.Principal.SecurityIdentifier($StringPtr) | |
#Reference: https://docs.microsoft.com/en-US/windows/security/identity-protection/access-control/security-identifiers | |
if ($TokenIntegritySID -eq 'S-1-16-0') | |
{ | |
Write-Output "UNTRUSTED_MANDATORY_LEVEL" | |
} | |
if ($TokenIntegritySID -eq 'S-1-16-4096') | |
{ | |
Write-Output "LOW_MANDATORY_LEVEL" | |
} | |
if ($TokenIntegritySID -eq 'S-1-16-8192') | |
{ | |
Write-Output "MEDIUM_MANDATORY_LEVEL" | |
} | |
if ($TokenIntegritySID -eq 'S-1-16-8448') | |
{ | |
Write-Output "MEDIUM_PLUS_MANDATORY_LEVEL" | |
} | |
if ($TokenIntegritySID -eq 'S-1-16-12288') | |
{ | |
Write-Output "HIGH_MANDATORY_LEVEL" | |
} | |
if ($TokenIntegritySID -eq 'S-1-16-16384') | |
{ | |
Write-Output "SYSTEM_MANDATORY_LEVEL" | |
} | |
if ($TokenIntegritySID -eq 'S-1-16-20480') | |
{ | |
Write-Output "PROTECTED_PROCESS_MANDATORY_LEVEL" | |
} | |
if ($TokenIntegritySID -eq 'S-1-16-28672') | |
{ | |
Write-Output "SECURE_PROCESS_MANDATORY_LEVEL" | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment