Sunday, June 30, 2013

Logging Keys with PowerShell: Get-Keystroke

I was recently inspired by Matt Graeber's series of posts on Microsoft's "Hey, Scripting Guy! Blog" to go back and look at old scripts and implement reflection. One of the scripts that I use regularly and mentioned in a previous post is a keylogger. Generally, I use keyloggers in one of two ways. The first way is to keep a record of every key I press with a timestamp for logging purposes during pentests or incident response activities. The other is to collect password credentials in a post-exploitation scenario. Both of these scenarios require a script that has a minimal forensic footprint.

There are a lot of keyloggers out there that make use of GetAsyncKeyState, GetKeyboardState and VirtualKeyCode and if you have ever written or used one, you know it isn't an exact science. There are even examples of other PowerShell keyloggers. A preferred method would be to hook each window with SetWindowsHookEx but there are several security products that flag on that behavior, so I avoided it.

In the script that originally wrote early last year, I made use of Add-Type to interact with user32.dll (it was included in the Invoke-TwitterBot presentation ). If you have read Matt's posts, then you understand why that is not ideal. A few requirements that I had were tracking of special characters such as [Shift] and [Caps Lock] which are really important. VirtualKeyCode doesn't track all common characters so I had to map the other ones:

I also needed to capture the window title and a date time group which is really simple once you load GetForegroundWindow:

Ultimately, the exercise of properly using reflection proved too much of a challenge for me and I reached out to the professional. Matt made short work of it and together we have a script that meets the standards for inclusion in the PowerSploit project:

The full script is available on the PowerSploit Github page. We hope you find the script useful.