…or why you should ensure all Windows machines are domain joined.
This is my first non-web post on my blog. I’m traditionally a web developer, and that is where my first interest in infosec came from. However, since I have managed to branch into penetration testing, Active Directory testing has become my favourite type of penetration test.
This post is regarding an internal network test I undertook some years back. This client’s network is a tough nut to crack, and one I’ve tested before so I was kind of apprehensive of going back to do this test for them in case I came away without having “hacked in”. We had only just managed it the previous time.
The first thing I run on an internal is the Responder tool. This will grab Windows hashes from LLMNR or NetBIOS requests on the local subnet. However, this client was wise to this and had LLMNR & NetBIOS requests disabled. Despite already knowing this fact from the previous engagement, one of the things I learned during my OSCP course was to always try the easy things first - there’s no point in breaking in through a skylight if the front door is open.
So I ran Responder, and I was surprised to see the following hash captured:
Note of course, that I would never reveal client confidential information on my blog, therefore everything you see here is anonymised and recreated in the lab with details changed.
Here we can see the host
172.16.157.133 has sent us the NETNTLMv2 hash for the account
Checking this host’s NetBIOS information with Crack Map Exec (other tools are available), we can check whether this is a local account hash. If it is, the “domain” part of the username:
[SMBv2] NTLMv2-SSP Username : 2-FD-87622\FRONTDESK
2-FD-87622 should match the host’s NetBIOS name if this is the case. Looking up the IP with CME we can see the name of the host matches:
So the next port of call we try to crack this hash and gain the plaintext password. Hashcat was loaded against rockyou.txt and rules, and quickly cracked the password.
hashcat -m 5600 responder /usr/share/wordlists/rockyou.txt -r /usr/share/rules/d3adhob0.rule
Now we have a set of credentials for the front desk machine. Hitting the machine again with CME but this time passing the cracked credentials:
cme smb 172.16.157.133 -u FRONTDESK -p 'Winter2018!' --local-auth
We can see
Pwn3d! in the output showing us this is a local administrator account. This means we have the privileges required to dump the local password hashes:
cme smb 172.16.157.133 -u FRONTDESK -p 'Winter2018!' --local-auth --sam
Note we can see
This time we are seeing the NTLM hash of the password, rather than the NETNTLMv2 “challenge/response” hash that Responder caught earlier. Responder catches hashes over the wire, and these are different to the format that Windows stores in the SAM.
The next step was to try the local administrator hash and spray it against the client’s server range. Note that we don’t even have to crack this administrator password, we can simply “pass-the-hash”:
cme smb 172.16.157.0/24 -u administrator -H 'aad3b435b51404eeaad3b435b51404ee:5509de4ff0a6eed7048d9f4a61100e51' --local-auth
We can only pass-the-hash using the stored NTLM format, not the NETNTLMv2 network format (unless you look to execute an “SMB relay” attack instead).
To our surprise, it got a hit, the local administrator password had been reused on the STEWIE machine. Querying this host’s NetBIOS info:
$ cme smb 172.16.157.134 SMB 172.16.157.134 445 STEWIE [*] Windows Server 2008 R2 Foundation 7600 x64 (name:STEWIE) (domain:MACFARLANE) (signing:False) (SMBv1:True)
We can see it is a member of the MACFARLANE domain, the main domain of the client’s Active Directory.
So the non-domain machine had a local administrator password which was reused on the internal servers. We can now use Metasploit to PsExec onto the machine, using the NTLM as the password which will cause Metasploit to pass-the-hash.
Once ran, our shell is gained:
We can load the Mimikatz module and read Windows memory to find passwords:
Looks like we have the DA (Domain Admin) account details. And to finish off, we use CME to execute commands on the Domain Controller to add ourselves as a DA (purely for a POC, in real life or to remain more stealthy we could just use the discovered account).
cme smb 172.16.157.135 -u administrator -p 'October17' -x 'net user markitzeroda hackersPassword! /add /domain /y && net group "domain admins" markitzeroda /add'
Note the use of the undocumented
/y function to suppress the prompt Windows gives you for adding a password longer than 14 characters.
A screenshot of Remote Desktop to the Domain Controller can go into the report as proof of exploitation:
So if this front desk machine had been joined to the domain, it would have had LLMNR disabled (from their Group Policy setting) and we wouldn’t have gained the initial access to it and leveraged its secrets in order to compromise the whole domain. Of course there are other mitigations such as using LAPS to manage local administrator passwords and setting
FilterAdministratorToken to prevent SMB logins using the local RID 500 account (great post on this here).