Whenever an attacker is trying to persist the access on a compromised machine, the first offensive approach usually involves the creation of a new identity. Nevertheless, this may not work with ease under hardened environments with diverse detection mechanisms against common attack vectors.
What if we "suborn" Windows to create our own hidden account that will grant us total access to a victim while impersonating any account we want without triggering any alerts?
Now it is possible with Suborner.
This technique will dynamically create an invisible machine account with custom credentials and custom properties without calling any user management Win32 APIs (e.g., netapi32.dll::netuseradd) and therefore evading detection mechanisms (e.g., Event IDs 4720, 4741). By "suborning" Windows, we can also impersonate any desired account to keep our stealthiness even after a successful authentication/authorization.
As far as I know, there is currently no public solution that crafts local users as the legitimate OS without calling APIs specifically designed for this purpose. Recently, some security researchers (like Ben Ten) have pinpointed ways to leverage the dollar sign $ to create "hidden accounts". Nevertheless, these approaches use the netuseradd API either through a call to net user /add or by directly invoking the API function. This results in partial stealthiness, but still noise because:
This is why I decided to create the Suborner Attack.
The attack is simple: Persist the access on a compromised machine by creating a hidden account without triggering any alert on the victim. Moreover, by suborning the Windows victim, this new stealthy account can also impersonate any existing enabled/disabled local account after each authentication.
All this magic is done by:
As far as I can tell, this attack works for every Windows version since NT. This attack has been tested across multiple Windows versions: manually tested for XP, 7, Server 2008R2 and automatically on Windows 10, 11 and Server 2019.
To show the attack effectiveness, we will use the suborner technique to create a local account that will be considered as a machine account, and will by default impersonate the disabled Administrator built-in account (500). Yes, disabled. Meaning that there is no need to add the invisible account to any group with high privileges to become an admin.
For this purpose, I have developed a C# program called Suborner: The Invisible Account Forger that will implement the attack automatically for us. At the time of the release of this entry, the program dynamically creates an invisible account by using an existent account as a template. In the future, I will update Suborner to allow the customization of all possible attributes (and use this to try new different attacks >:) )
The Suborner C# program currently accepts 5 possible arguments to craft the values needed to forge the invisible account and its attributes:
You can download the latest module from my GitHub repository.
First things first. This is the initial state of the victim machine: An up to date Windows 11 with the default built-in accounts and only a custom account named user. We can see from here that the local administrators are only this user custom account and the default Administrator. We can notice as well that there are currently no logs regarding user account creations.
We can use any username we want. By default, the program that automatizes the attack will use the
hostname value to create this invisible account, but we will stick to the
suborner$ name just for the sake of learning.
We will create this
suborner$ account as a machine account with the super complex password
Password.1. The account will impersonate the built-in Administrator every time we log in with its credentials, but remember that we can decide what account we want to impersonate... And yes, including the "useless" Guest (501) or any other custom account.
From a privileged powershell prompt, we run our Suborner C# assembly specifying the username and the password we want (remember this can be "filelessly" loaded through stuff like reflection if you don't want to deal with the .exe on disk ;) ).
After we successfully created the invisible account, we first look if there is any particular change that may raise an alert. However, this new account does not appear either on the output of , the local user manager , nor the default account management interface for Windows 11. The attack does not log any account creation, which is always good for our nefarious purposes >:)
Now from a remote attacking machine we try to access to the victim machine through the Impacket's version of PSExec, and dump the LSA secrets with the amazing . This is possible because we are impersonating the built-in Administrator, even if we are authenticating with the credentials.
DEFAULT SCENARIO: A SUBORNER MACHINE ACCOUNT
The Suborner attack allows to create any type of local account, including one that assigns the username as the victim's hostname, as if it were the legitimate machine account of the victim. Although this setup does not overwrite the default machine account hash (preventing possible problems for domain-joined machines), it is possible to authenticate with the credentials we set even without changing the original machine account hash.
In order to successfully craft an account with all the attributes I wanted, I tried again to study how the authentication process works. I have spent many long nights reversing, analyzing and poking on the internet to barely improve my understanding about it. After all that crazy work, I eventually could forge an account “almost” from scratch without calling the Windows APIs.
This is an attack that leverages the way the MSV1_0 authentication package works. At this moment, I am not going to explain all the authentication models that Windows systems encompass, but instead, I will focus on what I am doing with this piece of software. In the future, I will include more details about how each key is crafted.
The current version of the program (1.0.1) has the following schema:
I believe this is an introduction to a new world of user-mode persistence on Windows machines. Right now, there are many solutions to detect uncommon identities with weird attributes like the dollar sign (which made me think about the bribery thing lol) or detecting new account creations. If we do not rely on the operating system to do the nasty stuff, but instead we manually craft the things we need just as we want, we surpass the limits imposed by the OS and its restricted APIs.
Suborner can be the origin of a new way for attackers to create new accounts in a stealthy manner. Now it is just a neat persistence technique I am really proud to release, though am sure it can be leveraged to practically forge any account with any attribute we want, opening the door to a myriad of attacks that are waiting to be unveiled.
This is only the beginning...