stihl не предоставил(а) никакой дополнительной информации.
TL;DR Microsoft will be introducing Administrator Protection into Windows 11, so I wanted to have an understanding of how this technology works and how it interacts with existing offensive tooling. While this technology is just a thin wrapper around a separate account, there are a few nuances such as who is permitted to access these accounts, as well as existing UAC bypasses which are still effective against the new “backdoorless” Administrator Protection. This post explores these nuances in detail.
I started researching Administrator Protection a few months back, but I must admit that I never really believed that it would ever make it to a release build of Windows in its current form.
Then I saw a post on BlueSky announcing that it is in-fact coming to Windows 11, and soon:
Для просмотра ссылки Войди или ЗарегистрируйсяIn this post, I’ll be dumping my research into Windows Administrator Protection. There isn’t anything too groundbreaking here as I only touched this technology on a surface level for tooling compatibility testing, but the hope is that anyone else diving into this area will find the content useful.
Note: Administrator Protection is still in active development and everything shown in this post is subject to change as this feature develops.
So other than the removal of backdoors, what else separates Administrator Protection from UAC?
Well, the big one is that split tokens are (mostly) gone. Previously under UAC, there were two distinct token states. An administrative user would have a token in medium integrity with all administrative privileges and security groups stripped away. After the user consents to a UAC prompt (e.g., consent.exe) the system grants a high integrity token that restores all privileges and groups. The caveat here is in the filtering, as both tokens belonged to the same user account. In Admin Protection mode, you now have a completely separate admin account with a prefix of admin_. In the case of my Windows system, xpn has a corresponding admin_xpn account when I need the admin privileges and security groups typically granted to a high integrity token. In the Admin Protection world, this is called a Shadow Admin account.
или Зарегистрируйся that I found and it covered Administrator Protection back in October 2024 in a lot of detail.
The reason that I continued beyond this post was because I wanted to understand the operational limitations and our tooling requirements for engagements (we like to be prepared). But I wanted to make it clear that Rudy’s post set the pace and is recommended reading.
Additionally, Microsoft released a detailed post called “Для просмотра ссылки Войдиили Зарегистрируйся”.
There are sections from Microsoft’s post where “bypasses” were called out which were bugging me, mainly because I wanted to understand why known vulnerabilities still existed.
The reason that I also reference this is because it actually dives into a lot of details of the new functionality, including gaps in its implementation. Kudos for Microsoft being upfront about their design process.
It is actually the ShadowAccountBackLink key which links to the security identifier (SID) of the regular user account which determines if an account is classed as a shadow admin or not. Without this key being set, the account is just another admin account and is subject to token filtering.
We can see that this is the case in samsrv.dll - SamrIsShadowAdminAccount, which checks if this registry value is present:
We can use samlib.dll - SamiIsShadowAdminAccount programmatically to determine if a SID is a Shadow Admin account:
To do this, Rudy Ooms notes that the ShadowAdmin::CreateShadowAdminAccount method is called from samsrv.dll.
From an RPC perspective, the entry method called is SamrFindOrCreateShadowAdminAccount and can be invoked with the samlib.dll - SamiFindOrCreateShadowAdminAccount API method:
From within lsass.exe, lsasrv.dll is responsible for validating that the LogonUserExExW is coming from a permitted process. Within the LsapCanLogonShadowAdmin function, a check is first completed to make sure that the incoming request is from a process with a token set to SYSTEM integrity:
Next, the calling process needs to be in a allowlist. This is done in the LsapIsProcessOnShadowAdminAllowList:
At the time of checking, only Consent.exe is present in the list. This is a nice set of checks because, if you were SYSTEM, you could generate your own access to the admin_ account.
The corresponding Shadow Admin account will have a ShadowAccountBackLinkSid registry value pointing to the SID of the account:
As a fun experiment, you can actually update the ShadowAccountForwardLinkSid to point to any account Shadow Admin SID. You will need to reboot the system as the SID is cached in the local security authority subsystem service (LSASS); however, upon elevation, you’ll find that elevated processes spawn as another account.
Below we can see this in action, where build2 spawns an elevated process as admin_build as we switch out the SID:
This will only work for other Shadow Admin accounts, as the LogonUserExExW uses a blank password.
But even if we allow this, we will get an Access Denied warning:
If we remove the ShadowAccountBackLinkSid registry value and enable the ability for passwordless login, we can login fine with a blank password:
Obviously, this means that LogonUserW will work as:
или Зарегистрируйся. So, if things are so locked down, why does this work?
The two bypasses Microsoft called out are James Forshaws’s “Для просмотра ссылки Войдиили Зарегистрируйся” and SplinterCode’s “Для просмотра ссылки Войди или Зарегистрируйся” techniques.
These both have one thing in common: they take advantage of LocalAccountTokenFilterPolicy.
If we pull apart lsasrv.dll, we find the referenced LsaISetSupplimentalTokenInfo function referenced in James’ post. This is called by the msv1_0 - SsprHandleAuthenticationMessage function upon establishing a connection:
This function is responsible for determining if our network access is downgraded to use the medium integrity token.
This area of code doesn’t look like it has been updated with the introduction of Administrator Protection, which means that existing “bypasses” still exist. The reason I put that in quotes is because you actually end up in a state where the token created is just a high integrity token for the user; not the admin_ shadow admin account.
For example, if we access the ADMIN$ share using a domain admin account over a remote SMB connection, we see that access is on behalf of the user, not the Shadow Admin account:
Similarly, if we use something likeДля просмотра ссылки Войдиили Зарегистрируйся to spawn a new process, that process will end up running with High Integrity within its own user account; not as a Shadow Admin account:
So, actually, what we have now are three states with the introduction of Administrator Protection:
We can see this is the case by adding a new registry key:
On reboot and login, we get a Shadow Admin shell:
This works using the existing RaiProcessRunOnce RPC method invoked from explorer.exe’s AicProcessRunOnce:
This RPC method is exposed via AppInfo service as it always was in UAC. The parameters passed to this method do not unfortunately influence the command executed, meaning that we would need admin access to write to the RunOnce registry key.
A good example is theДля просмотра ссылки Войдиили Зарегистрируйся from R41N3RZUF477. We need to modify the OskSupport dynamic-link library (DLL) to send keys, but we see that this works just fine:
If the admin user has never authenticated to the host, you’ll just get the regular Access Denied error:
This, of course, also means that if (for some reason) blank passwords are allowed on the host, then you have the ability to authenticate to the host remotely as the admin account without a password:
For example, if we use smbclient.py, we can access the server without a password:
However, and unfortunately, our token is going to be filtered
Essentially, we have separate Admin accounts now for elevated actions. We also still have a weird scenario in which UAC elevated tokens do exist for admin sessions, but this feels like an unfinished feature at the moment. It will be interesting to see what happens when this rolls out in release.
What will also be interesting is that now files written to the users profile locations such as Desktop, Downloads etc., will belong to separate accounts depending on if the CreateFile was completed as an elevated user or not.
Для просмотра ссылки Войдиили Зарегистрируйся
I started researching Administrator Protection a few months back, but I must admit that I never really believed that it would ever make it to a release build of Windows in its current form.
Then I saw a post on BlueSky announcing that it is in-fact coming to Windows 11, and soon:

Note: Administrator Protection is still in active development and everything shown in this post is subject to change as this feature develops.
What is Admin Protection and Why Not Use UAC?
You can play around with Admin Protection on the canary build of Windows 11. I warn you in advance, you’ll see those elevation prompts more than before! And that’s by design; Microsoft created Administrator Protection to explicitly eliminate UAC backdoors, which means:- No EXE autoelevate backdoors
- No COM elevate backdoors
So other than the removal of backdoors, what else separates Administrator Protection from UAC?
Well, the big one is that split tokens are (mostly) gone. Previously under UAC, there were two distinct token states. An administrative user would have a token in medium integrity with all administrative privileges and security groups stripped away. After the user consents to a UAC prompt (e.g., consent.exe) the system grants a high integrity token that restores all privileges and groups. The caveat here is in the filtering, as both tokens belonged to the same user account. In Admin Protection mode, you now have a completely separate admin account with a prefix of admin_. In the case of my Windows system, xpn has a corresponding admin_xpn account when I need the admin privileges and security groups typically granted to a high integrity token. In the Admin Protection world, this is called a Shadow Admin account.
Existing Research
Before I dig too deep into this, I wanted to give a shoutout to Rudy Ooms at Call4Cloud. When I started looking into Shadow Admin accounts, Для просмотра ссылки ВойдиThe reason that I continued beyond this post was because I wanted to understand the operational limitations and our tooling requirements for engagements (we like to be prepared). But I wanted to make it clear that Rudy’s post set the pace and is recommended reading.
Additionally, Microsoft released a detailed post called “Для просмотра ссылки Войди
There are sections from Microsoft’s post where “bypasses” were called out which were bugging me, mainly because I wanted to understand why known vulnerabilities still existed.
The reason that I also reference this is because it actually dives into a lot of details of the new functionality, including gaps in its implementation. Kudos for Microsoft being upfront about their design process.
What Makes a Shadow Admin Account?
Administrator Protection revolves around the concept of a Shadow Admin account. If we take a look in the service account manager (SAM) hive, we see that the Shadow Admin is just a standard administrator account with a few additional attributes set against it:It is actually the ShadowAccountBackLink key which links to the security identifier (SID) of the regular user account which determines if an account is classed as a shadow admin or not. Without this key being set, the account is just another admin account and is subject to token filtering.
We can see that this is the case in samsrv.dll - SamrIsShadowAdminAccount, which checks if this registry value is present:
We can use samlib.dll - SamiIsShadowAdminAccount programmatically to determine if a SID is a Shadow Admin account:
Код:
typedef NTSYSAPI NTSTATUS(*p_SamIsShadowAdminAccount)(
PSID sid,
void* out1,
void* out2,
void* out3
);
void *modHandle = (void*)LoadLibraryA("samlib.dll");
p_SamIsShadowAdminAccount _SamIsShadowAdminAccount;
_SamIsShadowAdminAccount = (p_SamIsShadowAdminAccount)GetProcAddress((HMODULE)modHandle, "SamiIsShadowAdminAccount");
if (_SamIsShadowAdminAccount == NULL)
{
std::cout << "Failed to get address of SamIsShadowAdminAccount\n";
return 1;
}
void* out1 = NULL;
void* out2 = NULL;
void* out3 = NULL;
PSID sid;
// SID to check
if (ConvertStringSidToSidA("S-1-5-21-1524884646-3830121960-1456475082-1003", &sid) == 0) {
std::cout << "ConvertStringSidToSid failed\n";
return 1;
}
NTSTATUS status = _SamIsShadowAdminAccount(sid, &out1, &out2, &out3);
if (status != 0) {
printf("Cannot find SID\n");
return;
}
if (out1 != (void*)0) {
printf("This is a shadow admin account\n");
} else {
printf("Not a shadow admin account\n");
}
How are Shadow Admin Accounts Created?
Shadow Admin accounts are actually created on first use. If we have a user named build, then admin_build will actually be created upon elevation.To do this, Rudy Ooms notes that the ShadowAdmin::CreateShadowAdminAccount method is called from samsrv.dll.
From an RPC perspective, the entry method called is SamrFindOrCreateShadowAdminAccount and can be invoked with the samlib.dll - SamiFindOrCreateShadowAdminAccount API method:
Код:
typedef NTSYSAPI NTSTATUS(*p_SamiFindOrCreateShadowAdminAccount) (
void* DomainHandle,
void **out1,
void** out2
);
void *modHandle = (void*)LoadLibraryA("samlib.dll");
p_SamiFindOrCreateShadowAdminAccount _SamFindOrCreateShadowAdminAccount;
_SamFindOrCreateShadowAdminAccount = (p_SamiFindOrCreateShadowAdminAccount)GetProcAddress((HMODULE)modHandle, "SamiFindOrCreateShadowAdminAccount");
if (_SamFindOrCreateShadowAdminAccount == NULL) {
return 1;
}
void *modHandle = (void*)LoadLibraryA("samlib.dll");
if (modHandle == NULL) {
return 1;
}
// SID to create ShadowAdmin account for
if (ConvertStringSidToSidA("S-1-5-21-3889136333-1358944941-3928491093-1001", &sid) == 0) {
return 1;
}
void* arg1 = NULL;
void* arg2 = NULL;
NTSTATUS status = _SamFindOrCreateShadowAdminAccount((void*)(sid), &arg1, &arg2);
if (status != 0) {
printf("SamiFindOrCreateShadowAdminAccount returned: %x\n", status3);
}
How Do Users Get a Shadow Account Token?
As with UAC, Consent.exe is responsible for creating an access token for the Shadow Admin account. This is done via LogonUserExExW. And, as seen below, no password is passed:From within lsass.exe, lsasrv.dll is responsible for validating that the LogonUserExExW is coming from a permitted process. Within the LsapCanLogonShadowAdmin function, a check is first completed to make sure that the incoming request is from a process with a token set to SYSTEM integrity:
Next, the calling process needs to be in a allowlist. This is done in the LsapIsProcessOnShadowAdminAllowList:
At the time of checking, only Consent.exe is present in the list. This is a nice set of checks because, if you were SYSTEM, you could generate your own access to the admin_ account.
How Does LSASS Know Which Shadow Admin Account to Use?
Within the SAM hive, there is a registry value of ShadowAccountForwardLinkSid associated with the SID of the Shadow Admin user account:The corresponding Shadow Admin account will have a ShadowAccountBackLinkSid registry value pointing to the SID of the account:
As a fun experiment, you can actually update the ShadowAccountForwardLinkSid to point to any account Shadow Admin SID. You will need to reboot the system as the SID is cached in the local security authority subsystem service (LSASS); however, upon elevation, you’ll find that elevated processes spawn as another account.
Below we can see this in action, where build2 spawns an elevated process as admin_build as we switch out the SID:
This will only work for other Shadow Admin accounts, as the LogonUserExExW uses a blank password.
Logging In As a Shadow Admin
If the account is determined to be a Shadow Admin, we cannot log in as this account using methods such as runas /user:admin_test due to the default blank password requirement:But even if we allow this, we will get an Access Denied warning:
If we remove the ShadowAccountBackLinkSid registry value and enable the ability for passwordless login, we can login fine with a blank password:
Obviously, this means that LogonUserW will work as:
Код:
LogonUser(L"admin_build", L".", L"", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken)
Noted Bypasses – LocalAccountTokenFilterPolicy
There are still bypasses for Admin Protection, as Microsoft noted in their blog post Для просмотра ссылки ВойдиThe two bypasses Microsoft called out are James Forshaws’s “Для просмотра ссылки Войди
These both have one thing in common: they take advantage of LocalAccountTokenFilterPolicy.
If we pull apart lsasrv.dll, we find the referenced LsaISetSupplimentalTokenInfo function referenced in James’ post. This is called by the msv1_0 - SsprHandleAuthenticationMessage function upon establishing a connection:
This function is responsible for determining if our network access is downgraded to use the medium integrity token.
This area of code doesn’t look like it has been updated with the introduction of Administrator Protection, which means that existing “bypasses” still exist. The reason I put that in quotes is because you actually end up in a state where the token created is just a high integrity token for the user; not the admin_ shadow admin account.
For example, if we access the ADMIN$ share using a domain admin account over a remote SMB connection, we see that access is on behalf of the user, not the Shadow Admin account:
Similarly, if we use something likeДля просмотра ссылки Войди
So, actually, what we have now are three states with the introduction of Administrator Protection:
- The typical UAC style medium integrity token
- The admin_ Shadow Account high integrity token
- The old UAC type high integrity token
Noted Bypasses – RunOnce
Microsoft also noted RunOnce as an auto-elevate method for Admin Protection.We can see this is the case by adding a new registry key:
On reboot and login, we get a Shadow Admin shell:
This works using the existing RaiProcessRunOnce RPC method invoked from explorer.exe’s AicProcessRunOnce:
This RPC method is exposed via AppInfo service as it always was in UAC. The parameters passed to this method do not unfortunately influence the command executed, meaning that we would need admin access to write to the RunOnce registry key.
UIAccess Bypasses
As noted in Microsoft’s documentation, UIAccess Bypasses are partially prevented as current “UAC” based UIAccess elevations use auto-elevation of privileged processes before hijacking the UI. If, however, a legitimate app has been elevated, UIAccess can still be used to interact with the Window.A good example is theДля просмотра ссылки Войди
Fingerprinting Users & Blank Passwords
Shadow Admins give us a shot at anonymously enumerating if an admin has previously authenticated to a host:If the admin user has never authenticated to the host, you’ll just get the regular Access Denied error:
This, of course, also means that if (for some reason) blank passwords are allowed on the host, then you have the ability to authenticate to the host remotely as the admin account without a password:
For example, if we use smbclient.py, we can access the server without a password:
However, and unfortunately, our token is going to be filtered

Reflections and Conclusions
So, what do we have (other than a trail of “out of scope” UAC bypasses now being used to create a feature based off the hard work of researchers)?Essentially, we have separate Admin accounts now for elevated actions. We also still have a weird scenario in which UAC elevated tokens do exist for admin sessions, but this feels like an unfinished feature at the moment. It will be interesting to see what happens when this rolls out in release.
What will also be interesting is that now files written to the users profile locations such as Desktop, Downloads etc., will belong to separate accounts depending on if the CreateFile was completed as an elevated user or not.
Для просмотра ссылки Войди