Three ways to escalate privileges (and steal credentials) in Windows

Read how our red team used different attack techniques to hack AppLocker restrictions by implementing escalated privileges and reusing the Credentials Manager to extract stored data and Azure information.

During an internal penetration test earlier this year, we got ourselves access to a couple of Windows workstations. Fully patched Windows 10 machines, from which we had to try and find a way to escalate our privileges to a user with higher privileges.

Our goal was to escalate our access all the way to Domain Admin, so that we could achieve the objective for this project as set out by the customer. We tried working our way through the internal network by identifying alive hosts, enumerating potential exploitable network services and obtaining credentials but with no luck. We found ourselves stuck on this one host, so decided to dive all the way into the rabbit hole.

This story is based on an internal pentest, but screenshots, names and references are taken from our research lab.

escalate privileges and steal credentials

A story worth telling

The first step was to gather Active Directory data using Bloodhound and try to find attack paths we would be able to infiltrate. During the enumeration and exploitation phases we landed on a vulnerable Windows machine. From this machine we were able to extract the SAM and retrieve the password NLTM hash for various users. Using a derivative local admin password hash, we found our way to a Windows workstation that was part of the domain and appeared to be extremely well protected, prohibiting us to execute even using CMD or running PowerShell scripts.

Having nothing special in our hands to continue, we took a step back and started digging around for something that we may have missed during enumeration. Further down the rabbit hole we go…

Steal credentials

Hacking into vulnerable workstations

Making use of the valid users’ credentials that we discovered and extracted from various vulnerable workstations, our first objective was to identify the nature of the Windows machine (ARROW-Win10) and try to find out what the system is running on and what we might be able to leverage in further attacks. We started with verifying our credentials and checking if we can access the Windows machine through SMB protocol and what kind of permissions our user has.

Steal credentials

Unfortunately, our user was not able to access the C$ drive which may mean that the user is not part of the local group Administrators or extra security layers are applied on top through local GPO policies. Taking into consideration the outcome of Bloodhound we noticed that a certain user can RDP to the remote host.

Steal credentials

In a Windows environment, each domain and local user, group and other security objects are assigned to a unique identifier – Security Identifier called SID. A security identifier is a unique value of variable length that is used to identify a security principal (such as a security group) in Windows operating systems and is used to control access to different resources such as network shared folders, registry keys, file system objects, etc.

There are multiple ways to convert the above SID to an actual username. For our convenience and as we are having access to a workstation joined to the domain, we used the following PowerShell commands to convert the SID:

$objSID = New-Object System.Security.Principal.SecurityIdentifier(“S-1-5-21-2914800294-3420094760-3837107029-1006”)

escalate privileges and steal credentials

Taking advantage of the above information, we managed to get access to the remote workstation (ARROW-Win10) through RDP with the Pass-The-Hash technique by running the following command from our Kali machine.

xfreerdp /u:aliceland /d:. /pth:9a1a8b1dc3a4996ffa48b6e9a617b6cc /v:ARROW-Win10

Pass-the-Hash technique involves a user logging in using a username and password hash instead of a password in clear text format. Microsoft, in their quest to mitigate the “Pass-the-Hash” techniques, introduced the “Restricted Admin” mode which allows admins to easily connect to remote systems to locally administer them without having to worry about exposing their credentials to that weaker/less secure system.

Being able to access the affected workstation using the remote desktop through Restricted Admin mode, we established that our user has Administrator privileges on the remote host. As described in MS KB article 951916, Microsoft introduced this feature as part of UAC. Although this might be a little-known feature, UAC remote restrictions effectively filters the access token for connections made with local user accounts or Microsoft accounts. As described by Microsoft:

“When a local user who is a member of the local Administrators group on the target remote computer establishes a remote administrative connection they won’t connect as a full administrator. The user has no elevation potential on the remote computer, and the user cannot perform administrative tasks. If the user wants to administer the workstation with a Security Account Manager (SAM) account, the user must interactively log on to the computer that is to be administered with Remote Assistance or Remote Desktop, if these services are available.”

This means we had access to ARROW-Win10 Workstation through RDP, but we are severely limited. So, we need to look for alternative ways to expand our privileges.

Our next attempt was to execute Mimikatz so we could dump the memory and retrieve any valuable information. Unfortunately, local security policy was enforced prohibiting us to debug privileges and interact with the LSASS etc even using the local administrator user. Bypassing the AppLocker policy using the MsBuild technique, also did not get us any further.

Note: Having admin privileges we had the opportunity to enable the execution of Mimikatz, but as this requires a reboot to take effect, we may lose data that is stored in memory.

Pulling rabbits from a hat called Credential Manager

Then we went for something truly magical: Credential Manager! Credential Manager is the “digital vault” where Windows stores log-in credentials such as usernames, passwords, and network addresses. This information can be saved by Windows for use on your local computer, on other computers in the same network, servers, or Internet locations. This data can be used by Windows itself or by apps and programs. Credentials are split into several categories, such as Windows credentials, generic credentials, and certificate credentials. In this blogpost, our focus will be the first category: Windows credentials.

Windows credentials are used only by Windows and its services. For example, Windows can use these credentials to automatically log you into the shared folders of another computer on your network. It can also store the password of the Homegroup you have joined and uses it automatically each time you access what is being shared in that particular Homegroup.

Reviewing the Credential Manager window shown below, we quickly realized that this may be our golden ticket to getting Domain Admin or at least another step of privilege escalation.

Steal credentials

As we can’t run our trusty tools Mimikatz, nor on its more obscure cousins Pypikatz, we had to find another way to abuse this built-in goldmine called Windows Credentials. As the user is part of the Domain and part of a group with interesting (read: elevated) permissions… We were determined to not let this opportunity pass by unused!

We attempted to recon the Active Directory for that user (puppet_user) using ADSI (Active Directory Service Interfaces) without triggering AMSI or leaving artifacts in the event logger of the compromised host.

Active Directory Service Interfaces (ADSI) is a set of COM interfaces used to access the features of directory services from different network providers. It works by abstracting the capabilities of directory services to present a single set of interfaces for managing network resources in a distributed computing network. LDAP query examples can be found under the following link (selfADSI).

([ADSISearcher]'(&(objectCategory=user)(memberOf=CN=SQLGroup,OU=Users,OU=Lab,DC=flame,DC=delos,DC=lab))’).FindAll() | foreach {[ADSI]$_.path} | Select -Property sAMAccountName,memberOf | Format-List

escalate privileges and steal credentials

One (legitimate) way to reveal Windows Credential information through command lines is to use the cmdkey command and running the following to list all stored credentials on the local machine’s Credential Manager:

cmdkey /list 

escalate privileges and steal credentials

Great, we see through the commandline and the information we want gets revealed… But how do we take advantage of this? How can we reveal the actual credentials or otherwise re-use the information that is dangling right in front of us?

Digging around further, we discovered that you can indeed use the command option runas /savecred and specify the user. In doing so, Windows will use the credentials that are stored for that user in Credentials Manager. Using the saved user credentials, along with our MSBuild command allow us to bypass the AppLocker restrictions policy and connect to the remote host.

runas /savecred /user:FLAMEpuppet_user “C:WindowsMicrosoft.NETFrameworkv4.0.30319MSBuild.exe C:TempMSBuildPS.csproj”
Get-WmiObject -Class win32_operatingsystem -ComputerName ORCHID-SQL

escalate privileges and steal credentials
escalate privileges and steal credentials

The above information was a crucial stepping stone for our red team engagement and at the end of this project would eventually give us access to the Workstation where “puppet_user” had local administrative access and the SQL Server is installed. This gave us not only valuable information, but also allowed us to escalate our privileges by simply abusing built in Windows tooling and slip between the cracks in an otherwise secure configuration and laterally move through to other systems in further pursuit of our objectives.

Catching an invisible cat

Sqldumper.exe is an existing (and trusted) Microsoft tool that can be used to generate a dump file on demand for any Microsoft Windows application. For example, we can generate a dump file for debugging an application when a computer that is running a SQL Server Application is not responding. A dump file can be a mini-dump file, a full dump file, or a filtered dump file. Taking advantage of this information, we established a PowerShell remote connection to the Server where ‘puppet_user’ had local admin rights and SQL instance was running on it.

PS C:WINDOWSsystem32> $session = New-Pssession -ComputerName ORCHID-SQL
PS C:WINDOWSsystem32> Enter-PSSession -Session $session

To generate a specific kind of a dump file, we needed to type the corresponding command followed by the process ID and the DumpType. Using the 0x01100:40 flag whichcreates a Mimikatz compatible dump file, for example:

sqldumper.exe <PID> 0 0x01100:40

escalate privileges and steal credentials

After having established a PSRemote session using the ‘puppet_user‘ account, we used the SQLDumper tool to dump the LSASS process. Then by invoking Mimikatz and using the dumped file on our local machine, we can extract the dumped info, which included the SQLAdmin’s NTLM hash.

PS C:Temp> Invoke-Command -FilePath .Invoke-Mimikatz.ps1 -Session $session
PS C:Temp> Enter-PSSession -Session $session

[ORCHID-SQL]: PS C:Temp> Invoke-Mimikatz -Command ‘”sekurlsa::minidump C:TempSQLDmpr0001.mdmp” “sekurlsa::logonPasswords full”‘


  .#####.   mimikatz 2.1.1 (x64) built on Nov 29 2018 12:37:56
.## ^ ##.  “A La Vie, A L’Amour” – (oe.eo) ** Kitten Edition **
## / ##  /*** Benjamin DELPY `gentilkiwi` ( )
## / ##       >
‘## v ##’       Vincent LE TOUX             ( )
‘#####’        > /   ***/


mimikatz(powershell) # sekurlsa::minidump C:TempSQLDmpr0001.mdmp
Switch to MINIDUMP : ‘C:TempSQLDmpr0001.mdmp’


mimikatz(powershell) # sekurlsa::logonPasswords full
Opening : ‘C:TempSQLDmpr0001.mdmp’ file for minidump…




Authentication Id : 0 ; 2119563 (00000000:0020578b)
Session           : Interactive from 0
User Name         : SQLAdmin
>Domain            : FLAME
Logon Server      : DHARMA-DC
Logon Time        : 3/30/2021 3:04:39 PM
SID               : S-1-5-21-3814968796-4193774654-733324460-1109
msv :
[00000003] Primary
* Username : sqladmin
* Domain   : FLAME
* NTLM     : 91ff8d675a9a348b6416b7c76bc5ba8e
* SHA1     : 90ef8dcb01e594c22c7adbcf62b438ef6ff4d6fd
* DPAPI    : ca5425a189a847f19e992dc8f95396af



The nature of the ORCHID-SQL server was to perform the AzureAD synchronization and handle Windows updates through WSUS configuration. Having all this information in the table we started digging into the server to find any useful information for our next step. Furthermore, checking closely the Bloodhound queries we made to the following results which indicates that the internal infrastructure is Azure Domain joined.

escalate privileges and steal credentials

Azure AD Connect creates the account, an account is created that follows the naming convention resulting in a name starting with MSOL_, followed by the first 8 bytes of the Azure AD Connect installation ID (a version 4 UUID) and the server name. It is placed in the Users container per Active Directory domain in scope.

Since we had admin rights in the Windows machine, we were able to retrieve the Azure access token(s) for the user ‘sqladmin’

escalate privileges and steal credentials

The next step was to make use of the Azure token(s) and connect to the company’s tenant to extract any valuable information if possible.

We copied the files “TokenCache.dat” and “AzureRmContext.json” back to our Windows machine and by adding the Az module we had to manipulate the stolen .dat and .json file so we can import them into our PowerShell session.

PS C:Temp> $token_bytes = Get-Content “C:Userslabuser.FLAMEDesktopTokenCache.dat” -Encoding byte
PS C:Temp> $token_b64 = [Convert]::ToBase64String($token_bytes)
PS C:Temp> Add-Content “C:TempAzure-token.txt” $token_b64

To accomplish this, we had to add the content of the Azure-token.txt into the AzureRmContext.json file by replacing the null string from the “CachData” option and by running the following command to import the new token:

PS C:Temp> Import-AzContext -Profile “C:TempAzureRmContext.json”

escalate privileges and steal credentials

Since we had successfully connected to the company Azure tenant, this gave us further information to continue our escalation and find any possible way to compromise the entire infrastructure by also using the Azure services.

escalate privileges and steal credentials

Happy ever after and advice

The above story is a short story about an attack path we have uncovered during a recent Red team assessment. The purpose of this story is to introduce different attack techniques and tools that can be used to bypass AppLocker restrictions, escalate privileges either by derivate local admin credentials or reusing the Credentials Managers credentials and by taking advantage of the trusted built-in tools to dump the essential processes and extract stored and Azure info.

About Ghost Labs

ghost labs logo

Ghost Labs is the specialist security unit within Outpost24 working in partnership with our clients to meet their penetration testing needs and objectives. Our experienced Offensive Security team offers enhanced and bespoke penetration testing security services such as advanced network penetration testing, (web)application testing, Red Teaming assessments and complex web application exploitation to help organizations have a true picture of their cyber risk. In addition, the Ghost Labs team is an active contributor to the security community with vulnerability research and coordinated responsible disclosure program.

Ghost Labs performs hundreds of successful penetration tests for its customers ranging from global enterprises to SMEs. Our team consists of highly skilled ethical hackers, covering a wide range of advanced testing services to help companies keep up with evolving threats and new technologies. To help businesses drive security maturity and mitigate risks posed by the evolving threat and techniques of the modern day hacker.