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.
-Chris
FYI - you can simplify your code by using strings instead of enums - PowerShell will do the work for you. e.g.
ReplyDelete$importDLL::GetAsyncKeyState("LShiftKey")
Jeffrey Snover[MSFT]
Distinguished Engineer and Lead Architect for Windows Server and System Center Datacenter
Thanks for the tip! Certainly honored to have you checking out the PowerSploit project and the blog.
DeleteThe Script Works fine while initiate directly by the logged-on user.
ReplyDeleteBut I tried it with several methods of self-persistance that will re-start automatically after the original process termination and it wint work...
What methods did you try? As with most keyloggers, any method of persistence requires that the code be ran in the user's context. This could be accomplished with a registry key entry.
Delete