Skip to content

Instantly share code, notes, and snippets.

@jsecurity101
Last active May 11, 2023 05:54
Show Gist options
  • Save jsecurity101/5ef14a0b537af36ce448b28c707c6976 to your computer and use it in GitHub Desktop.
Save jsecurity101/5ef14a0b537af36ce448b28c707c6976 to your computer and use it in GitHub Desktop.
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