Blog Zscaler

Ricevi gli ultimi aggiornamenti dal blog di Zscaler nella tua casella di posta

Best Practices

Better know a data source: Process integrity levels

image
JONNY JOHNSON
dicembre 09, 2021 - 13 min read

Impossible to spoof, process integrity levels dictate trust between securable objects, offering defenders great visibility into privilege escalation.

Editor’s note: We updated the supported integrity levels table in this article to better describe “Protected Process” and to remove “Secure Process”, an integrity level that is rarely referenced in documentation that we’ve never encountered in the wild.

In this second installment of our Better know a data source series, we’re showcasing process integrity levels. Integrity levels define the trust between process/thread and another object (files, processes, threads) and help control what that object can or can’t do on a system. A sudden change in a process’s integrity level might be a sign that an adversary has obtained system privileges.

While an adversary might be able to obtain a higher integrity level, they have no control over its metadata, meaning they can’t masquerade, hide, or otherwise fake it. Process integrity level is a kernel attribute from a kernel object, making it a reliable data point for defenders seeking to weed out malicious activity.

What are process integrity levels?

Before diving into integrity levels, it’s important to understand the basics of access tokens. Access tokens serve to identify the security context (user security identifier, security identifier, group memberships, and privileges) of a process or thread. Unless a token is explicitly assigned to a thread, all threads will inherit the token of the primary thread (i.e., the first thread started in a process), which is also known as the primary token. All actions the process takes will fall under the security context of that token.

Every token is tied to a logon session. Any time a user logs in, a new token is generated and then applied to any process that user spawns during its logon lifecycle. When a local administrator logs in, two separate logon sessions are created: one for the unelevated token (medium integrity level) and one with the elevated token (high integrity level). These logon sessions are bound to one another and are referred to as a “split token.”

process integrity level MITRE ATT@CK data source

The image above shows a logon session in which two LogonIDs are specified and tied to the appropriate token. Although this is the same user, there will be another logon session for the elevated token with different LogonID values and a higher integrity level.

Because every token is tied to a logon session, identity logs associated with logon sessions can serve as a link between process events when privilege escalation is performed. You can see an example of this in the Detection opportunities section below.

By default, child processes will inherit a copy of their parent’s token, meaning that all processes running under a logon session will have the same token. Token attributes include:

  • user
  • groups the user is associated with
  • token type
  • token ID
  • user’s privileges
  • integrity level

Integrity levels help define the trust between a process/thread and a securable object (processes, threads, tokens, files, etc.—any object that can have a security descriptor). Because access tokens can be tied to a process or thread, integrity levels can be tied to either of these as well. The only time a thread’s token will be different from the primary token is when a token is explicitly set on a target thread.

Integrity levels are stored as security identifiers (SID) but can be converted to a human readable string that defenders can more easily interpret.

Below are the integrity level SIDs defined by Microsoft:

 

Supported Integrity Levels
SIDDisplay name (mandatory level)Description

S-1-16-0

Untrusted

Anonymous logged on processes. Write access is mostly blocked. Seen with Chrome.

S-1-16-4096

Low

Used for AppContainers, browsers that access the internet and prevent most write access to objects on the system—specifically the registry and filesystem

S-1-16-8192

Medium

Default for most processes. For authenticated users.

S-1-16-8448

Medium Plus

Unable to find a resource or reference to this

S-1-16-12288

High

Administrator-level processes. (Elevated) process with UAC.

S-1-16-16384

System

Reserved for system services/processes

S-1-16-20480

Protected Process

Not seen to be used by default. Windows Internals book says it can be set by a kernel-mode caller.

Note: Although the level Medium Plus doesn’t include a description due to a lack of references, you should still look out for these SIDs.

Why focus on process integrity level?

Integrity levels can be applied to securable objects as a way of evaluating the level of access that a source object has to a target object. Monitoring processes spawning from a lower integrity level into a higher integrity level can tip defenders off when a process is about to perform a task that requires higher privileges or when sensitive privileges have been co-opted.

Each integrity level comes with a set of system privileges. By default, the higher integrity level you are, the more system privileges you have on a host and the more access you have to securable objects. This is one of the primary drivers that compels adversaries to find ways to escalate their integrity level. The following example from James Forshaw’s NtObjectManager PowerShell module shows the default privileges given to a process of medium integrity level and then again of high integrity level.

Medium integrity level:

process integrity level detection data source

High integrity level:

process integrity level detection data source

These token privileges dictate what you can and can’t do on a machine from a system operations perspective, such as loading drivers, changing the host’s time, impersonating a client, creating a primary token, etc.

As we noted earlier, when an admin logs in, a split token is generated. Unless you explicitly set the process token to a high integrity level, the process will default to the lowest group the user/token is associated with, which for most users will be a medium integrity level. Users must specify when they want to use their administrative privileges, and in most circumstances, User Account Control (UAC) kicks in to either allow that elevation or not. If the elevation request is successful, the elevated token is granted to that process and the appropriate privileges are applied.

What users can obtain a high integrity level token?

By default, users who are a part of the Administrators groups can obtain a high integrity level token. However, a high integrity level token can still be applied to a user outside of the Administrators group if a sensitive privilege is explicitly granted to that user.

Adversaries have been known to gain access to SeImpersonatePrivilege. This privilege allows an attacker to impersonate different clients—such as named pipe clients, RPC clients, and COM clients— to act with the security context of a targeted token.

This privilege is given to users within the Administrators group by default. Admins can grant this privilege to a user outside of that group using the User Rights Assignments (URA) within Group Policy Object - Computer Configuration\Windows Settings\Security Settings\Local Policies\User Rights Assignment. To do so, the admins would need to add the user to the “impersonate a client after authentication” assignment and start a new logon session with that user.

If the user starts a normal process, they will not have a token that possesses that sensitive privilege. In the screenshot below, I granted SeImpersonatePrivilege to TargetUser, but when I started a normal PowerShell process, I didn’t have that sensitive privilege. The integrity level of TargetUser is “medium.” The examples below are using whoami /groups.

process integrity level detection data souce

To apply the sensitive privilege SeImpersonatePrivilege, the user has to run as an elevated prompt. After doing so, the sensitive privilege and corresponding high integrity level are applied.

To my knowledge, there is no easy way to determine what token privileges should be considered sensitive —other than by looking at how the privileges are used for sensitive system operations. Knowing this, adversaries prefer to set their sights on processes with specific sensitive privileges granted to their token, or, alternatively, by simply targeting accounts in the Administrators group.

How do adversaries leverage access token process integrity levels?

T1134.002: Create Process With Token is a MITRE ATT&CK technique that describes when an adversary targets access tokens of higher integrity levels and creates a process with a copy of the targeted token. This allows attackers to operate under the security context of the targeted user and run a program, access resources, or establish persistence where they otherwise wouldn’t have been able to.

Adversaries will also impersonate another user either by obtaining a copy of the target token or by obtaining the handle to the target token and setting it to a thread within their running process, in turn changing the integrity level for that thread (T1134.001: Token Impersonation/Theft). By default this will only work with a token that has a high integrity level process, because that’s the level required to abuse SeImpersonatePrivilege.

In general, it is unusual to see a newly spawned process go from a lower integrity level to a higher one (outside of normal UAC elevation)—it could mean that an adversary has obtained a token of a higher integrity level process or has logged in as another user who is of higher integrity level and is using that logon session token. It could also mean that an administrator is using Start-Process as a normal everyday activity.

As we explained earlier, it’s impossible for an adversary to directly manipulate integrity level metadata. Therefore, if you’re able to gather integrity level-related telemetry, it can serve as a reliable data source.

What data sources are available to retrieve process integrity level?

There are a couple of data sources that you can use to gain insight into a process’s integrity level.

Win32 API:

Data source: GetTokenInformation Relevant field(s): IntegrityLevel

One way to view the integrity level of a process/thread is to use the GetTokenInformation Win32 API and pass in the TokenIntegrityLevel value into the TokenInformationClass parameter. This will specify that you want to enumerate the TokenIntegrityLevel attribute within the TOKEN_INFORMATION_CLASS enum. The TokenIntegrityLevel attribute is backed by the TOKEN_MANDATORY_LABEL structure, which has an attribute within it called Label. Label is backed by the SID_AND_ATTRIBUTES structure that identifies the mandatory integrity level of the token. The SID attribute can be translated to one of the values seen in the table above.

Here is an example of what this can look like:

 PS > Get-IntegrityLevel Title : Displaying Process/Primary Information ProcessName : powershell SessionId : 1 PID : 2800 TokenIntegrityLevel : MEDIUM_MANDATORY_LEVEL 

 

Windows Process Auditing:

Data source: Windows Security Log Event ID 4688 Relevant field(s): Mandatory Label Example data:

Creator Subject: Security ID: [REDACTED]\thor Account Name: thor Account Domain: [REDACTED] Logon ID: 0x2FC7277 Target Subject: Security ID: NULL SID Account Name: - Account Domain: - Logon ID: 0x0 Process Information: New Process ID: 0x1b54 New Process Name:	C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe Token Elevation Type:	%%1938 Mandatory Label: Mandatory Label\Medium Mandatory Level Creator Process ID:	0x16b0 Creator Process Name:	C:\Windows\explorer.exe Process Command Line: 

 

Sysmon:

Data source: Event ID 1: Process creation Relevant field[s]: IntegrityLevel Example data:

Relevant Field[s]: IntegrityLevel Example Data: UtcTime: 2021-10-28 01:19:37.643 ProcessGuid: {68e97739-faa9-6179-9394-0f0300000000} ProcessId: 6996 Image: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe FileVersion: 10.0.17134.1 (WinBuild.160101.0800) Description: Windows PowerShell Product: Microsoft® Windows® Operating System Company: Microsoft Corporation OriginalFileName: PowerShell.EXE CommandLine: 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' CurrentDirectory: C:\Users\thor\ User: [REDACTED]\thor LogonGuid: {68e97739-fa73-6179-7772-fc0200000000} LogonId: 0x2FC7277 TerminalSessionId: 2 IntegrityLevel: Medium Hashes: SHA1=1B3B40FBC889FD4C645CC12C85D0805AC36BA254,MD5=95000560239032BC68B4C2FDFCDEF913,SHA256=D3F8FADE829D2B7BD596C4504A6DAE5C034E789B6A3DEFBE013BDA7D14466677,IMPHASH=741776AACCFC5B71FF59832DCDCACE0F ParentProcessGuid: {68e97739-fa75-6179-1c86-fd0200000000} ParentProcessId: 5808 ParentImage: C:\Windows\explorer.exe ParentCommandLine: C:\Windows\Explorer.EXE 

 

Microsoft Defender for Endpoint (MDE):

Data source: DeviceProcessEvents Relevant field[s]: ProcessIntegrityLevel, InitiatingProcessIntegrityLevel Example data:

Timestamp:	2021-10-28T01:19:37.7098154Z DeviceId:	4444706065525f7093e60eeca71e8a48d2e8448f DeviceName:	asgard-wrkstn.REDACTED.local ActionType:	ProcessCreated FileName:	powershell.exe FolderPath:	C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe SHA1:	1b3b40fbc889fd4c645cc12c85d0805ac36ba254 SHA256:	d3f8fade829d2b7bd596c4504a6dae5c034e789b6a3defbe013bda7d14466677 MD5:	95000560239032bc68b4c2fdfcdef913 FileSize:	447488 ProcessVersionInfoCompanyName:	Microsoft Corporation ProcessVersionInfoProductName:	Microsoft® Windows® Operating System ProcessVersionInfoProductVersion:	10.0.17134.1 ProcessVersionInfoInternalFileName:	POWERSHELL ProcessVersionInfoOriginalFileName:	PowerShell.EXE ProcessVersionInfoFileDescription:	Windows PowerShell ProcessId:	6996 ProcessCommandLine:	'powershell.exe' ProcessIntegrityLevel:	Medium ProcessTokenElevation:	TokenElevationTypeLimited ProcessCreationTime:	2021-10-28T01:19:37.6431454Z AccountDomain:	REDACTED AccountName:	thor AccountSid:	S-1-5-21-3637186843-3378876361-2759896766-1104 AccountUpn: AccountObjectId: LogonId:	0 InitiatingProcessAccountDomain:	REDACTED InitiatingProcessAccountName:	thor InitiatingProcessAccountSid	: S-1-5-21-3637186843-3378876361-2759896766-1104 InitiatingProcessAccountUpn: InitiatingProcessAccountObjectId: InitiatingProcessLogonId:	null InitiatingProcessIntegrityLevel:	Medium InitiatingProcessTokenElevation:	TokenElevationTypeLimited InitiatingProcessSHA1:	e4d846417f2836d1a2c2a8f25c61620fddb4893b InitiatingProcessSHA256:	a6327254f8808e99e3378d16bbf8e564d733879f55b3461acd9a036fc46f5aea InitiatingProcessMD5:	ea043f4a77826199143350288dad220c InitiatingProcessFileName:	explorer.exe InitiatingProcessFileSize:	4098912 InitiatingProcessVersionInfoCompanyName:	Microsoft Corporation InitiatingProcessVersionInfoProductName:	Microsoft® Windows® Operating System InitiatingProcessVersionInfoProductVersion:	10.0.17134.1098 InitiatingProcessVersionInfoInternalFileName:	explorer InitiatingProcessVersionInfoOriginalFileName:	EXPLORER.EXE InitiatingProcessVersionInfoFileDescription:	Windows Explorer InitiatingProcessId:	5808 InitiatingProcessCommandLine:	Explorer.EXE InitiatingProcessCreationTime:	2021-10-28T01:18:45.9993865Z InitiatingProcessFolderPath	: c:\windows\explorer.exe InitiatingProcessParentId:	4256 InitiatingProcessParentFileName:	userinit.exe InitiatingProcessParentCreationTime:	2021-10-28T01:18:45.8917635Z InitiatingProcessSignerType	Unknown: InitiatingProcessSignatureStatus:	Unknown ReportId:	6685 AppGuardContainerId: AdditionalFields:	

 

How do I generate integrity level metadata for sensor and detection validation?

Within the AtomicTestHarnesses PowerShell module, there is a function called Invoke-ATHCreateProcessWithToken that generates telemetry to test optics, detection gaps, and technique knowledge. This module will simulate the behavior of targeting a token then creating a process with a duplicated copy of that targeted token. It will terminate all processes created and close any handles that were opened as a result of this activity. It will then print out an accessible view of data that relates to the activity so that it can easily be tested against the optics available to the users/analysts.

PS > Invoke-ATHCreateProcessWithToken TechniqueID : T1134.002 TestSuccess : True TestGuid : a8e88199-1036-4ceb-9845-c556bc09ded9 TestCommand : Invoke-ATHCreateProcessWithToken SourceUser : REDACTED\thor SourceExecutableFilePath : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe SourceExecutableFileHash : D3F8FADE829D2B7BD596C4504A6DAE5C034E789B6A3DEFBE013BDA7D14466677 SourceProcessId : 8952 GrantedRights : QueryLimitedInformation ImpersonatedUser : NT AUTHORITY\SYSTEM LogonType : TargetExecutableFilePath : C:\Windows\system32\winlogon.exe TargetExecutableFileHash : 10098BBE7EFD4B16014493F7D26E593E06910CC36D4BA4A3E59FCF8C15E4F1D7 TargetProcessId : 588 NewProcessExecutablePath : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe NewProcessCommandline : powershell.exe -nop -Command Write-Host a8e88199-1036-4ceb-9845-c556bc09ded9; Start-Sleep -Seconds 2; exit NewProcessExecutableHash : D3F8FADE829D2B7BD596C4504A6DAE5C034E789B6A3DEFBE013BDA7D14466677 NewProcessId : 5828 

 

Detection opportunities

The following Microsoft Defender for Endpoint (MDE) queries identify when lower integrity level processes spawn a higher integrity level process or a potentially impersonated login. These will only work for instances where a new process is spawned. Currently, we aren’t aware of any scalable optics or analytics that would give insight into times when token impersonation happens on a thread level. See Access Token Manipulation: Token Impersonation/Theft for more.

Detecting parent-child process integrity level disparities

This MDE query looks for high integrity level processes spawning a system integrity level process and/or low integrity level process spawning high or system integrity level process.

DeviceProcessEvents | where InitiatingProcessIntegrityLevel != ProcessIntegrityLevel and (InitiatingProcessIntegrityLevel == 'Low' or InitiatingProcessIntegrityLevel == 'High') | project Timestamp, DeviceName, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessIntegrityLevel, AccountName, FileName, ProcessIntegrityLevel, InitiatingProcessParentId 

 

Detecting login impersonation

As in the previous MDE query, this detection logic looks for integrity level disparities between parent and child processes. However, here we’re also looking for a corresponding command line with the seclogon (secondary logon) string. The seclogon string is a good indication of logging on as another user and abusing their security context. This logic will show when a process was spawned with CreateProcessWithLogon.

DeviceProcessEvents | where (InitiatingProcessIntegrityLevel != ProcessIntegrityLevel and (InitiatingProcessIntegrityLevel == 'Low' or InitiatingProcessIntegrityLevel == 'High')) or (InitiatingProcessAccountName != AccountName and ProcessIntegrityLevel == 'Medium' and InitiatingProcessCommandLine contains 'seclogon') | project Timestamp, DeviceName, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessIntegrityLevel, AccountName, FileName, ProcessIntegrityLevel 

 

Another way to detect login impersonation

You can also use identity events to look for logins where the InitiatingProcessCommandLine tag has seclogon (secondary logon). This telemetry also suggests the use of CreateProcessWithLogon.

DeviceLogonEvents | where Protocol == 'Negotiate' and InitiatingProcessCommandLine contains 'seclogon' | project InitiatingProcessAccountName, AccountName, Protocol, LogonType, InitiatingProcessId, LogonId | join ( DeviceProcessEvents | project InitiatingProcessId, InitiatingProcessLogonId, AccountName, FileName ) on InitiatingProcessId, AccountName | project-rename TargetProcessId = InitiatingProcessId1 | project-rename TargetUser = AccountName1 | project InitiatingProcessAccountName, Protocol, LogonType, TargetUser, LogonId, TargetProcessId, FileName 

 

References

form submtited
Grazie per aver letto

Questo post è stato utile?

Esclusione di responsabilità: questo articolo del blog è stato creato da Zscaler esclusivamente a scopo informativo ed è fornito "così com'è", senza alcuna garanzia circa l'accuratezza, la completezza o l'affidabilità dei contenuti. Zscaler declina ogni responsabilità per eventuali errori o omissioni, così come per le eventuali azioni intraprese sulla base delle informazioni fornite. Eventuali link a siti web o risorse di terze parti sono offerti unicamente per praticità, e Zscaler non è responsabile del relativo contenuto, né delle pratiche adottate. Tutti i contenuti sono soggetti a modifiche senza preavviso. Accedendo a questo blog, l'utente accetta le presenti condizioni e riconosce di essere l'unico responsabile della verifica e dell'uso delle informazioni secondo quanto appropriato per rispondere alle proprie esigenze.

Ricevi gli ultimi aggiornamenti dal blog di Zscaler nella tua casella di posta

Inviando il modulo, si accetta la nostra Informativa sulla privacy.