Skip to Main Content
September 23, 2020

Azure Account Hijacking using mimikatz’s lsadump::setntlm

Written by Hans Lakhan
Application Security Assessment Penetration Testing Security Testing & Analysis

Not long ago, I was on an engagement where the client made use of a hybrid Office 365 environment. In their setup, authentication credentials were managed by the on-premises Active Directory (AD) Domain Controller and then synced to Azure AD via Azure AD Connect.

We were tasked with gaining access to sensitive customer information. And while we were able to obtain domain administrative privileges, we had a difficult time finding exactly where the target information resided. Normally in these instances, we research the employees of the organization, attempt to understand who they are, what roles they play, and how they operate from a day to day perspective. And while we were able to identify several key employees, we ran into two (2) problems: 1) the users did not store client data on their assigned working device and 2) the organization used cloud-based Office products to store client data, such as OneDrive, SharePoint, etc.

Unfortunately, the users I targeted had chosen strong passwords, and their NTLM hash was not cracking. And while I had privileges to reset the users' passwords, they would be aware of such a change the next time they tried to log in. It seemed like this path was going to be a dead end until Carlos Perez, TrustedSec's Research Practice Lead, reminded me of two (2) underutilized features in Mimikatz—lsadump::setntlm and lsadump::changentlm.

Five Steps

Starting with lsadump::changentlm, this feature is similar to when a user changes their own password. You must either know the user’s original password or NTLM hash, and then you can set a new password (or NTLM hash) for the account. A few things to note though, you are restricted to any password complexity and minimum password age requirements set by the domain.

The second feature, lsadump::setntlm, acts similarly to the ‘set user password’ in ‘active directory users and computers.’ You need privileged access over the desired account, but you do not need to know the original password. You are also not restricted by any password complexity or minimum password age requirements.

What is important to note is that with both features, you can set/change the user's password OR NTLM hash. (You can use Rubeus to generate a valid NTLM hash: Rubeus.exe hash /password:myawesomepassword.)

So how do we use this to hijack an account? Well, if we have Domain Admin access (really ‘Replicating Directory Changes All’ and ‘Replicating Directory Changes’), we can extract the current user's NTLM hash (dcsync). This means that when the user has gone home at night, we can change their password to something we know and then use lsadump::setntlm to change it back before they arrive the next morning. This change will be synced to the Domain Controller but will not update client/apps that are configured to authenticate on the user's behalf. For example, if the user has the Outlook app on their phone, they are going to get a failed authentication message during this attack.

Step 1) Extract user's current NTLM hash (dcysnc)

Step 2) Set user's password (lsadump::setntlm)

Step 3) Wait 30 minutes for changes to be replicated to Azure AD

Step 4) Access the desired Azure/Microsoft Online resource [1].

Step 5) Set users NTLM hash back to the original hash found in step 1.

The screenshots below show the attack performed in a lab setting:

Step 1) Extracting target users current NTLM hash
Step 2) Setting users password using lsadump::setntlm
Step 3) Waiting 30 minutes for credentials to replicate and Step 4) Accessing desired resources
Step 5) Setting users NTLM hash back to the original hash found in step 1

This process does generate a few indicators of compromise (IoCs). First off, both Mimikatz functions will generate a Windows event:

Lsadump::changentlm generates an event id 4724

Ladump::setntlm generates an event id 4738

Secondly, the user's password history will now include the NTLM hash of the password used to take over the account. If you really wanted to, you could generate a bunch of password changes to fill up this table, but it is probably not worth the extra events.

Changed password hash found in hash history

Closing Thoughts

This attack does work well, but it can be mitigated. Enabling Azure's Conditional Access policies that require multi-factor authentication (MFA) as well as restricting logins to originate from a trusted network segment will effectively restrict this attack. Additional controls such as ensuring that the connection comes from an approved device will also help. However, rumor has it that if you can obtain access to the user's Office 365 bearer token, all of the above can be achieved regardless of the controls suggested. But that’s for another post.

Obtaining Azure PRT for Cloud Access

Last but not least, many thanks are owed to Carlos Perez. If you have not already, I highly recommend checking out his class, 'Mastering Mimikatz, Kekeo and More.'

After writing this blog we found that, like many things, we were not the first to cover this topic.

[1]  On-premises resources like file shares and desktops can also be accessed during this time.