From b39a5f75e245637a49dee18767654b77e63ba2b0 Mon Sep 17 00:00:00 2001 From: egieb <93350544+beigeworm@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:15:48 +0000 Subject: [PATCH] Update main.ps1 --- BadUSB-Detect-and-Protect/main.ps1 | 253 +++++++++++++++-------------- 1 file changed, 127 insertions(+), 126 deletions(-) diff --git a/BadUSB-Detect-and-Protect/main.ps1 b/BadUSB-Detect-and-Protect/main.ps1 index 18e3986..68c7d9b 100644 --- a/BadUSB-Detect-and-Protect/main.ps1 +++ b/BadUSB-Detect-and-Protect/main.ps1 @@ -1,22 +1,22 @@ -<# ================ BAD USB DETECTION AND PROTECTION =================== - -SYNOPSIS -This script runs passively in the background waiting for any new usb devices. -When a new USB device is connected to the machine this script monitors keypresses for 30 seconds. -If there are 15 or more keypresses detected within 200 milliseconds it will attempt to disable the most recently connected USB device - -USAGE -1. Run the script and follow instructions -2. A pop up will appear when monitoring is active and if a 'BadUSB' device is detected -3. logs are found in 'usblogs' folder in the temp directory. - -REQUIREMENTS -Admin privlages are required for removing any suspected devices (you can re-enable devices too) - -#> - +<# ================ BAD USB DETECTION AND PROTECTION =================== + +SYNOPSIS +This script runs passively in the background waiting for any new usb devices. +When a new USB device is connected to the machine this script monitors keypresses for 30 seconds. +If there are 13 or more keypresses detected within 200 milliseconds it will pause all input for 10 seconds and attempt to disable the most recently connected USB device + +USAGE +1. Run the script and follow instructions +2. A pop up will appear when monitoring is active and if a 'BadUSB' device is detected +3. logs are found in 'usblogs' folder in the temp directory. + +REQUIREMENTS +Admin privlages are required for removing any suspected devices (you can re-enable devices too) + +#> + Add-Type -AssemblyName System.Drawing -Add-Type -AssemblyName System.Windows.Forms +Add-Type -AssemblyName System.Windows.Forms Write-Host "Checking User Permissions.." -ForegroundColor DarkGray If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) { Write-Host "Admin privileges needed for this script..." -ForegroundColor Red @@ -29,11 +29,12 @@ else{ Write-Host "This script is running as Admin!" -ForegroundColor Green New-Item -ItemType Directory -Path "$env:TEMP\usblogs\" cls - $enable = Read-Host "Re-enable All Devices? (y/n) " - $hidden = Read-Host "Hide This Window (y/n) " -} - - + $enable = Read-Host "Re-enable All Devices? [y/n] " + $hidden = Read-Host "Hide This Window [y/n] " + $DisableOnDetect = Read-Host "Disable detected devices (input will still be blocked) [y/n] " +} + + If ($hidden -eq 'y'){ Write-Host "Hiding the Window.." -ForegroundColor Red sleep 1 @@ -49,18 +50,18 @@ If ($hidden -eq 'y'){ $hwnd = $Proc.MainWindowHandle $Type::ShowWindowAsync($hwnd, 0) } -} - -$usbDevices = Get-WmiObject -Query "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB%'" -$currentUSBDevices = @() -$newUSBDevices = @() -foreach ($device in $usbDevices) { - $deviceID = $device.DeviceID - $newUSBDevices += $deviceID -} -$currentUSBDevices = $newUSBDevices - - +} + +$usbDevices = Get-WmiObject -Query "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB%'" +$currentUSBDevices = @() +$newUSBDevices = @() +foreach ($device in $usbDevices) { + $deviceID = $device.DeviceID + $newUSBDevices += $deviceID +} +$currentUSBDevices = $newUSBDevices + + function EnableDevices { param ( [string[]]$deviceIDs @@ -92,35 +93,34 @@ if ($enable -eq 'y'){ } pause exit -} -else{ - "" | Out-File -FilePath "$env:TEMP\usblogs\ids.log" - "" | Out-File -FilePath "$env:TEMP\usblogs\monon.log" - Write-Host "Monitoring for devices.." -ForegroundColor Green - sleep 1 -} - - -$monitor = { - -Add-Type -AssemblyName System.Drawing -Add-Type -AssemblyName System.Windows.Forms - -$API = @' -[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] -public static extern short GetAsyncKeyState(int virtualKeyCode); -[DllImport("user32.dll", CharSet=CharSet.Auto)] -public static extern int GetKeyboardState(byte[] keystate); -[DllImport("user32.dll", CharSet=CharSet.Auto)] -public static extern int MapVirtualKey(uint uCode, int uMapType); -[DllImport("user32.dll", CharSet=CharSet.Auto)] -public static extern int ToUnicode(uint wVirtKey, uint wScanCode, byte[] lpkeystate, System.Text.StringBuilder pwszBuff, int cchBuff, uint wFlags); -'@ -$API = Add-Type -MemberDefinition $API -Name 'Win32' -Namespace API -PassThru - - -$balloon = { +} +else{ + "" | Out-File -FilePath "$env:TEMP\usblogs\ids.log" + "" | Out-File -FilePath "$env:TEMP\usblogs\monon.log" + Write-Host "Monitoring for devices.." -ForegroundColor Green + sleep 1 +} + +$monitor = { + +Add-Type -AssemblyName System.Drawing +Add-Type -AssemblyName System.Windows.Forms + +$API = @' +[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] +public static extern short GetAsyncKeyState(int virtualKeyCode); +[DllImport("user32.dll", CharSet=CharSet.Auto)] +public static extern int GetKeyboardState(byte[] keystate); +[DllImport("user32.dll", CharSet=CharSet.Auto)] +public static extern int MapVirtualKey(uint uCode, int uMapType); +[DllImport("user32.dll", CharSet=CharSet.Auto)] +public static extern int ToUnicode(uint wVirtKey, uint wScanCode, byte[] lpkeystate, System.Text.StringBuilder pwszBuff, int cchBuff, uint wFlags); +'@ +$API = Add-Type -MemberDefinition $API -Name 'Win32' -Namespace API -PassThru + + +$balloon = { Add-Type -AssemblyName System.Drawing Add-Type -AssemblyName System.Windows.Forms $notify = New-Object System.Windows.Forms.NotifyIcon @@ -129,9 +129,16 @@ $notify.Visible = $true $balloonTipTitle = "WARNING" $balloonTipText = "Bad USB Device Intercepted!" $notify.ShowBalloonTip(30000, $balloonTipTitle, $balloonTipText, [System.Windows.Forms.ToolTipIcon]::WARNING) +} + +$pausejob = { +$s='[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]public static extern bool BlockInput(bool fBlockIt);' +Add-Type -MemberDefinition $s -Name U -Namespace W +[W.U]::BlockInput($true) +sleep 10 +[W.U]::BlockInput($false) +} -} - function DisableDevices { param ([string[]]$deviceIDs) foreach ($deviceID in $deviceIDs) { @@ -148,45 +155,43 @@ function DisableDevices { "Error disabling device with ID: $deviceID. $_" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append } } -} - -function MonitorKeys { - - $startTime = $null - $keypressCount = 0 - $initTime = Get-Date - while ($MonitorTime -lt $initTime.AddSeconds(30)) { - $stopjob = Get-Content "$env:TEMP\usblogs\monon.log" - if ($stopjob -eq 'true'){"killed monitoring for: $deviceID" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append ;exit} - $MonitorTime = Get-Date - Start-Sleep -Milliseconds 10 - for ($i = 8; $i -lt 256; $i++) { - $keyState = $API::GetAsyncKeyState($i) - if ($keyState -eq -32767) { - if (-not $startTime) { - $startTime = Get-Date - } - $keypressCount++ - } - } - - if ($startTime -and (New-TimeSpan -Start $startTime).TotalMilliseconds -ge 200) { - if ($keypressCount -gt 14) { +} + +function MonitorKeys { + $startTime = $null + $keypressCount = 0 + $initTime = Get-Date + while ($MonitorTime -lt $initTime.AddSeconds(30)) { + $stopjob = Get-Content "$env:TEMP\usblogs\monon.log" + if ($stopjob -eq 'true'){"killed monitoring for: $deviceID" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append ;exit} + $MonitorTime = Get-Date + Start-Sleep -Milliseconds 10 + for ($i = 8; $i -lt 256; $i++) { + $keyState = $API::GetAsyncKeyState($i) + if ($keyState -eq -32767) { + if (-not $startTime) { + $startTime = Get-Date + } + $keypressCount++ + } + } + if ($startTime -and (New-TimeSpan -Start $startTime).TotalMilliseconds -ge 200) { + if ($keypressCount -gt 12) { $script:newUSBDeviceIDs = Get-Content "$env:TEMP\usblogs\ids.log" + Start-Job -ScriptBlock $pausejob -Name PauseInput Start-Job -ScriptBlock $balloon -Name BallonIcon - DisableDevices -deviceIDs $script:newUSBDeviceIDs - - } - $startTime = $null - $keypressCount = 0 - - } - } - -} -MonitorKeys -} - + if ($DisableOnDetect -eq 'y'){ + DisableDevices -deviceIDs $script:newUSBDeviceIDs + } + } + $startTime = $null + $keypressCount = 0 + } + } +} +MonitorKeys +} + function CheckNew { $usbDevices = Get-WmiObject -Query "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB%'" $newUSBDevices = @() @@ -200,34 +205,30 @@ function CheckNew { $newUSBDeviceIDs += $deviceID -split "," | Out-File -FilePath "$env:TEMP\usblogs\ids.log" -Append } } - $global:currentUSBDevices = $newUSBDevices $global:newUSBDeviceIDs = $newUSBDeviceIDs -} - +} + $notify = New-Object System.Windows.Forms.NotifyIcon $notify.Icon = [System.Drawing.SystemIcons]::Shield $notify.Visible = $true $balloonTipTitle = "USB Monitoring" $balloonTipText = "BadUSB Monitoring Active.." -$notify.ShowBalloonTip(30000, $balloonTipTitle, $balloonTipText, [System.Windows.Forms.ToolTipIcon]::Info) - -while ($true) { - - CheckNew - if ($match){ - Write-Host "Monitoring Keys" - $jobon = Get-Job -Name Monitor - if ($jobon){ - "true" | Out-File -FilePath "$env:TEMP\usblogs\monon.log" - sleep -Milliseconds 500 - } - $script:match = $false - "false" | Out-File -FilePath "$env:TEMP\usblogs\monon.log" - Start-Job -ScriptBlock $monitor -Name Monitor - } - - sleep -Milliseconds 500 - -} - +$notify.ShowBalloonTip(30000, $balloonTipTitle, $balloonTipText, [System.Windows.Forms.ToolTipIcon]::Info) + +while ($true) { + + CheckNew + if ($match){ + Write-Host "Monitoring Keys" + $jobon = Get-Job -Name Monitor + if ($jobon){ + "true" | Out-File -FilePath "$env:TEMP\usblogs\monon.log" + sleep -Milliseconds 500 + } + $script:match = $false + "false" | Out-File -FilePath "$env:TEMP\usblogs\monon.log" + Start-Job -ScriptBlock $monitor -Name Monitor + } + sleep -Milliseconds 500 +}