Its been over a year since I threw together the original Get-GPPPassword on a short flight and I was really having a hard time even looking at the code. In addition to a nagging bug, it needed to be rewritten and updated to include all the great recommendations from you guys. Its amazing how often I still see local passwords being enforced with Group Policy preferences. For some reason it actually feels like the problem is getting worse even with Microsoft's blatant warnings in Server 2012. The other issue that I have seen is that when administrators stop using preferences, the old XML file is not deleted. On more than one engagement I have found an old password which helped me guess the current one. We need to keep hammering at this poor practice.
Additionally, one of the things that jumped out at me while reworking this script is the simplicity of this task in PowerShell. Compared to accomplishing the same task in Ruby, PowerShell's XML parsing really gives it an edge. A lot of security professionals could benefit by spending a few days to learn it and Carlos Perez is teaching an awesome class at Derbycon!
Updates:
General flow, performance and bug fixes including better error handling and a fix for the problem with how the base64-encoded string was being padded.
Support for parsing not only groups.xml, but also scheduledtasks.xml, services.xml and datasources.xml. The original post that inspired me to write the function appears to be down, but there have been other posts that point out that passwords can be stored in other Group Policy preference files as well. I attempted to create each one of those XML files and created logic for the 4 that seem used.
Ryan Ries pointed out that the script could easily be pointed at the domain controller which removes the need for any parameters and makes the script easier to run:
I broke out the decryption function (Get-DecryptedCPassword) If you want to decrypt a password offline, you can use that.
As always, the most current version of the Get-GPPPassword is available from the PowerSploit Github page. Thanks for reading, keep the comments and recommendations coming and join Skip Duckwall and I at BlackHat where we will briefly discuss Group Policy preferences in relation to the Pass-the-Hash attack with practical mitigation techniques.
-Chris
Showing posts with label Group Policy Preferences. Show all posts
Showing posts with label Group Policy Preferences. Show all posts
Wednesday, July 3, 2013
Thursday, May 24, 2012
GPP Password Retrieval with PowerShell
Last week, I read a great post entitled "Exploiting Windows 2008 Group Policy Preferences" that I wish I saw sooner. The article included a nice Python script to accomplish the task of decrypting passwords that were set using the GPP feature in Windows 2008 domains. However, it looked like something that would be handy to have in a PowerShell script. Before I continue, I would like to point out the updated disclaimer, it certainly applies to this post.
You should read the original article, but the quick summary is that its possible for any authenticated user (this includes machine accounts) on the domain to decrypt passwords that are enforced with Windows 2008 Group Policy Preferences. From my experience, this practice is common for larger domains which need to set different local administrator ("500" account) passwords for different OUs.
Python is an excellent scripting language, but PowerShell has two notable advantages in this specific use-case. First, PowerShell does not require any additional libraries since it has access to the entire .NET framework. Second, PowerShell is installed by default on all modern Windows systems to include Windows Server 2008 so it can be used right from the machine you are on.
The following Get-GPPPassword PowerShell script can be used by penetration testers to elevate to local administrator privileges (on your way to Domain Admin) by downloading the "groups.xml" file from the domain controller and passing it to the script. The files are typically found in:
\\domain\SYSVOL\domain\Policies\{*}\Machine\Preferences\Groups\Groups.xml
Get-GPPPassword (Use Updated Version)
To run the function, just copy and paste the text into powershell and type 'Get-GPPPassword'. This will in effect bypass the ExecutionPolicy.
Writing this script ended up not being as easy as I originally thought mostly due to never dealing with .NET and crypto before. I would like to thank Matt Graeber for solving the null IV issue, Mike Santiago for general code improvements and of course Emilien Giraul (and the Sogeti ESEC Pentest team for their detailed writeup).
Try it out and let me know what you think.
***Update 26 May 2012***
You can also download the maintained version of the script from the PowerSploit repository on GitHub. It already has some great scripts for Windows post-exploitation on it!
***Update 16 June 2012***
Updated the script block with the improvements from Matt Graeber. Matt wrapped it into a function and apparently saved a puppy by creating a new object (avoiding the use of write-host).
***Update 3 July 2013***
I have reorganized and rewritten the script. You can find the updated version and read about it here.
-Chris
You should read the original article, but the quick summary is that its possible for any authenticated user (this includes machine accounts) on the domain to decrypt passwords that are enforced with Windows 2008 Group Policy Preferences. From my experience, this practice is common for larger domains which need to set different local administrator ("500" account) passwords for different OUs.
Python is an excellent scripting language, but PowerShell has two notable advantages in this specific use-case. First, PowerShell does not require any additional libraries since it has access to the entire .NET framework. Second, PowerShell is installed by default on all modern Windows systems to include Windows Server 2008 so it can be used right from the machine you are on.
The following Get-GPPPassword PowerShell script can be used by penetration testers to elevate to local administrator privileges (on your way to Domain Admin) by downloading the "groups.xml" file from the domain controller and passing it to the script. The files are typically found in:
\\domain\SYSVOL\domain\Policies\{*}\Machine\Preferences\Groups\Groups.xml
Get-GPPPassword (Use Updated Version)
To run the function, just copy and paste the text into powershell and type 'Get-GPPPassword'. This will in effect bypass the ExecutionPolicy.
Writing this script ended up not being as easy as I originally thought mostly due to never dealing with .NET and crypto before. I would like to thank Matt Graeber for solving the null IV issue, Mike Santiago for general code improvements and of course Emilien Giraul (and the Sogeti ESEC Pentest team for their detailed writeup).
Try it out and let me know what you think.
***Update 26 May 2012***
You can also download the maintained version of the script from the PowerSploit repository on GitHub. It already has some great scripts for Windows post-exploitation on it!
***Update 16 June 2012***
Updated the script block with the improvements from Matt Graeber. Matt wrapped it into a function and apparently saved a puppy by creating a new object (avoiding the use of write-host).
***Update 3 July 2013***
I have reorganized and rewritten the script. You can find the updated version and read about it here.
-Chris
Subscribe to:
Comments (Atom)

