Service Registry Permissions Weakness Check
title: Service Registry Permissions Weakness Check
id: 95afc12e-3cbb-40c3-9340-84a032e596a3
status: test
description: |
Adversaries may execute their own malicious payloads by hijacking the Registry entries used by services.
Adversaries may use flaws in the permissions for registry to redirect from the originally specified executable to one that they control, in order to launch their own code at Service start.
Windows stores local service configuration information in the Registry under HKLM\SYSTEM\CurrentControlSet\Services
references:
- https://github.com/redcanaryco/atomic-red-team/blob/f339e7da7d05f6057fdfcdd3742bfcf365fee2a9/atomics/T1574.011/T1574.011.md#atomic-test-1---service-registry-permissions-weakness
- https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/get-acl?view=powershell-7.2
author: frack113
date: 2021/12/30
tags:
- attack.persistence
- attack.t1574.011
logsource:
product: windows
category: ps_script
definition: 'Requirements: Script Block Logging must be enabled'
detection:
selection:
ScriptBlockText|contains|all:
- 'get-acl'
- 'REGISTRY::HKLM\SYSTEM\CurrentControlSet\Services\'
condition: selection
falsepositives:
- Legitimate administrative script
level: medium
Original Analytic Scoring
Application (A) |
User-mode (U) |
Kernel-mode (K) |
|
---|---|---|---|
Core to (Sub-) Technique (5) |
|||
Core to Part of (Sub-) Technique (4) |
|||
Core to Pre-Existing Tool (3) |
|||
Core to Adversary-brought Tool (2) |
EventID: 4104
ScriptBlockText|contains|all:
- ‘get-acl’
- ‘REGISTRY::HKLM\SYSTEM\CurrentControlSet\Services\’
|
||
Ephemeral (1) |
Improved Analytic Scoring
Application (A) |
User-mode (U) |
Kernel-mode (K) |
|
---|---|---|---|
Core to (Sub-) Technique (5) |
EventID: 4663
TargetObject: “*SYSTEM\CurrentControlSet\Services\*”
|
||
Core to Part of (Sub-) Technique (4) |
|||
Core to Pre-Existing Tool (3) |
|||
Core to Adversary-brought Tool (2) |
|||
Ephemeral (1) |
This analytic uses the Windows PowerShell logging Event ID 4104 and detects on specific
values in the ScriptBlockText field 1. While the specified registry key is core to
the subtechnique 2, the actual observable is the string representation of that
registry key inside the script text. It is relatively easy for an attacker to obfuscate
keywords or values in a PowerShell script. For example, the cmdlet get-acl
is
defined and included in the Microsoft.PowerShell.Security module, but equivalent
functionality can be accomplished with a renamed or custom cmdlet that doesn’t require
get-acl
exist in the script text. The registry key string can be obfuscated in other
ways 3, several of which are shown below. Since the adversary can modify their
tools and associated scripts before deployment to evade this analytic, it is 2A.
# Let’s start with a simple example:
function Invoke-Malware {
Write-Host ‘Malware!’;
}
# Simple signature: if script contains “Write-Host ‘Malware’” → Malicious
# Simple bypass:
function Invoke-Malware {
Write-Host "Malware!";
}
# Simple signature: if re.findall(“Write-Host .Malware.”, script) → Malicious
# Simple bypass:
function Invoke-Malware {
Write-Host (“Mal” + “ware!”);
}
# Let’s start being a little more sophisticated (just a bit):
function Invoke-NotMalware {
$malware_base64 = "V3JpdGUtSG9zdCAiTWFsd2FyZSEi";
$malware = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($malware_base64));
IEX ($malware);
}
# Simple signature:
# if script contains “V3JpdGUtSG9zdCAiTWFsd2FyZSEi” → Malicious
# Simple bypass:
function Invoke-NotMalware {
$malware_base64 = "VwByAGkAdABlAC0ASABvAHMAdAAgACIATQBhAGwAdwBhAHIAZQAhACIA";
$malware = [System.Text.Encoding]::UNICODE.GetString([System.Convert]::FromBase64String($malware_base64));
IEX ($malware);
}
# Security solutions are able to emulate base64 decoding
# So malware authors move to algorithm based obfuscation such as XOR:
$key = 0x64
$encodedMalware = "M2QWZA1kEGQBZElkLGQLZBdkEGREZEZkKWQFZAhkE2QFZBZkAWRFZEZk";
$bytes = [Convert]::FromBase64String($encodedMalware)
$decodedBytes = foreach ($byte in $bytes) {$byte -bxor $key}
$decodedMalware = [System.Text.Encoding]::Unicode.GetString($decodedBytes)
IEX ($decodedMalware)
A more robust way of detecting the original behavior involves setting a Security Access
Control List (SACL) on the registry key. Setting a SACL on the registry key enables
using a kernel-mode data source to detect the get-acl
behavior of a script without
looking at the contents of the script itself. Once the SACL is set and configured, an
EventID 4663 will be generated whenever an attempt is made to access the registry key.
Note
SACLs have configuration options which can change the accuracy of an analytic. One
configuration option is to log the “Full Control” set of activity and get a complete
view of registry key activity, and then query those results for when the registry
key is read (when the AccessMask
field has the corresponding value
READ_CONTROL
4). However, this approach could generate a large amount of
benign noise. As an alternative, the SACL can be configured to generate an event
only when the key is read.
References