Update main.ps1
This commit is contained in:
+215
-143
@@ -6,17 +6,36 @@ When a new USB device is connected to the machine this script monitors keypresse
|
||||
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
|
||||
1. Edit Options below (optional) and Run the script
|
||||
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.
|
||||
4. Re-enable any devices with the Re-enable option below.
|
||||
5. Close the monitor in the system tray
|
||||
|
||||
REQUIREMENTS
|
||||
Admin privlages are required for removing any suspected devices (you can re-enable devices too)
|
||||
Admin privlages are required for removing any suspected devices
|
||||
|
||||
#>
|
||||
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
# Hide the console after monitor starts
|
||||
$hidden = 'y'
|
||||
|
||||
# Enable all devices
|
||||
$enable = 'n'
|
||||
|
||||
# Disable Detected Devices
|
||||
$DisableOnDetect = 'n'
|
||||
|
||||
$Host.UI.RawUI.BackgroundColor = "Black"
|
||||
Clear-Host
|
||||
[Console]::SetWindowSize(80, 35)
|
||||
[Console]::Title = "BadUSB Detection Setup"
|
||||
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
Add-Type -AssemblyName Microsoft.VisualBasic
|
||||
[System.Windows.Forms.Application]::EnableVisualStyles()
|
||||
|
||||
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,39 +48,27 @@ 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] "
|
||||
$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
|
||||
$Async = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
|
||||
$Type = Add-Type -MemberDefinition $Async -name Win32ShowWindowAsync -namespace Win32Functions -PassThru
|
||||
$hwnd = (Get-Process -PID $pid).MainWindowHandle
|
||||
if($hwnd -ne [System.IntPtr]::Zero){
|
||||
$Type::ShowWindowAsync($hwnd, 0)
|
||||
}
|
||||
else{
|
||||
$Host.UI.RawUI.WindowTitle = 'hideme'
|
||||
$Proc = (Get-Process | Where-Object { $_.MainWindowTitle -eq 'hideme' })
|
||||
$hwnd = $Proc.MainWindowHandle
|
||||
$Type::ShowWindowAsync($hwnd, 0)
|
||||
Function HideConsole{
|
||||
If ($hidden -eq 'y'){
|
||||
Write-Host "Hiding the Window.." -ForegroundColor Red
|
||||
sleep 1
|
||||
$Async = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
|
||||
$Type = Add-Type -MemberDefinition $Async -name Win32ShowWindowAsync -namespace Win32Functions -PassThru
|
||||
$hwnd = (Get-Process -PID $pid).MainWindowHandle
|
||||
if($hwnd -ne [System.IntPtr]::Zero){
|
||||
$Type::ShowWindowAsync($hwnd, 0)
|
||||
}
|
||||
else{
|
||||
$Host.UI.RawUI.WindowTitle = 'hideme'
|
||||
$Proc = (Get-Process | Where-Object { $_.MainWindowTitle -eq 'hideme' })
|
||||
$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
|
||||
|
||||
|
||||
function EnableDevices {
|
||||
param (
|
||||
[string[]]$deviceIDs
|
||||
@@ -97,16 +104,28 @@ if ($enable -eq 'y'){
|
||||
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
|
||||
}
|
||||
|
||||
$DeviceMonitor = {
|
||||
|
||||
$monitor = {
|
||||
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
$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
|
||||
|
||||
$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);
|
||||
@@ -117,118 +136,171 @@ 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
|
||||
$notify.Icon = [System.Drawing.SystemIcons]::Warning
|
||||
$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) {
|
||||
try {
|
||||
"Attempting to disable device with ID: $deviceID" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append
|
||||
$pnpDevice = Get-PnpDevice -InstanceId $deviceID -ErrorAction Stop
|
||||
if ($pnpDevice.Status -eq 'OK') {
|
||||
Disable-PnpDevice -InstanceId $deviceID -Confirm:$false -ErrorAction Stop
|
||||
"Successfully disabled device with ID: $deviceID" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append
|
||||
} else {
|
||||
"Device with ID: $deviceID is not in an 'OK' state and cannot be disabled." | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append
|
||||
}
|
||||
} catch {
|
||||
"Error disabling device with ID: $deviceID. $_" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append
|
||||
$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
|
||||
$notify.Icon = [System.Drawing.SystemIcons]::Warning
|
||||
$notify.Visible = $true
|
||||
$balloonTipTitle = "WARNING"
|
||||
$balloonTipText = "Bad USB Device Intercepted!"
|
||||
$notify.ShowBalloonTip(30000, $balloonTipTitle, $balloonTipText, [System.Windows.Forms.ToolTipIcon]::WARNING)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
if ($DisableOnDetect -eq 'y'){
|
||||
DisableDevices -deviceIDs $script:newUSBDeviceIDs
|
||||
|
||||
$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) {
|
||||
try {
|
||||
"Attempting to disable device with ID: $deviceID" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append
|
||||
$pnpDevice = Get-PnpDevice -InstanceId $deviceID -ErrorAction Stop
|
||||
if ($pnpDevice.Status -eq 'OK') {
|
||||
Disable-PnpDevice -InstanceId $deviceID -Confirm:$false -ErrorAction Stop
|
||||
"Successfully disabled device with ID: $deviceID" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append
|
||||
} else {
|
||||
"Device with ID: $deviceID is not in an 'OK' state and cannot be disabled." | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append
|
||||
}
|
||||
} catch {
|
||||
"Error disabling device with ID: $deviceID. $_" | Out-File -FilePath "$env:TEMP\usblogs\log.log" -Append
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function MonitorKeys {
|
||||
$startTime = $null
|
||||
$keypressCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
MonitorKeys
|
||||
}
|
||||
|
||||
function CheckNew {
|
||||
$usbDevices = Get-WmiObject -Query "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB%'"
|
||||
$newUSBDevices = @()
|
||||
$newUSBDeviceIDs = @()
|
||||
foreach ($device in $usbDevices) {
|
||||
$deviceID = $device.DeviceID
|
||||
$newUSBDevices += $deviceID
|
||||
if ($currentUSBDevices -notcontains $deviceID) {
|
||||
Write-Host "New USB device added: $($device.Name) ID: $($deviceID)"
|
||||
$script:match = $true
|
||||
$newUSBDeviceIDs += $deviceID -split "," | Out-File -FilePath "$env:TEMP\usblogs\ids.log" -Append
|
||||
$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
|
||||
if ($DisableOnDetect -eq 'y'){
|
||||
DisableDevices -deviceIDs $script:newUSBDeviceIDs
|
||||
}
|
||||
}
|
||||
$startTime = $null
|
||||
$keypressCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
MonitorKeys
|
||||
}
|
||||
$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
|
||||
|
||||
function CheckNew {
|
||||
$usbDevices = Get-WmiObject -Query "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB%'"
|
||||
$newUSBDevices = @()
|
||||
$newUSBDeviceIDs = @()
|
||||
foreach ($device in $usbDevices) {
|
||||
$deviceID = $device.DeviceID
|
||||
$newUSBDevices += $deviceID
|
||||
if ($currentUSBDevices -notcontains $deviceID) {
|
||||
Write-Host "New USB device added: $($device.Name) ID: $($deviceID)"
|
||||
$script:match = $true
|
||||
$newUSBDeviceIDs += $deviceID -split "," | Out-File -FilePath "$env:TEMP\usblogs\ids.log" -Append
|
||||
}
|
||||
}
|
||||
$script:match = $false
|
||||
"false" | Out-File -FilePath "$env:TEMP\usblogs\monon.log"
|
||||
Start-Job -ScriptBlock $monitor -Name Monitor
|
||||
$global:currentUSBDevices = $newUSBDevices
|
||||
$global:newUSBDeviceIDs = $newUSBDeviceIDs
|
||||
}
|
||||
sleep -Milliseconds 500
|
||||
|
||||
$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(3000, $balloonTipTitle, $balloonTipText, [System.Windows.Forms.ToolTipIcon]::Info)
|
||||
|
||||
while ($true) {
|
||||
CheckNew
|
||||
$global:CurrentStatus = 'Waiting For Devices'
|
||||
if ($match){
|
||||
Write-Host "Monitoring Keys"
|
||||
$global:CurrentStatus = 'Monitoring Inputs..'
|
||||
$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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cls
|
||||
Write-Host "Monitor Started!" -ForegroundColor Green
|
||||
sleep 1
|
||||
Write-Host "Setting Window To Background.."
|
||||
Write-Host "
|
||||
===================================================
|
||||
**YOU CAN CLOSE THE MONITOR FROM THE SYSTEM TRAY**
|
||||
===================================================" -ForegroundColor Blue
|
||||
sleep 2
|
||||
HideConsole
|
||||
Start-Job -ScriptBlock $DeviceMonitor -Name DeviceMonitor
|
||||
|
||||
$Systray_Tool_Icon = New-Object System.Windows.Forms.NotifyIcon
|
||||
$Systray_Tool_Icon.Text = "BadUSB Monitor"
|
||||
$Systray_Tool_Icon.Icon = [System.Drawing.SystemIcons]::Shield
|
||||
$Systray_Tool_Icon.Visible = $true
|
||||
|
||||
$contextmenu = New-Object System.Windows.Forms.ContextMenuStrip
|
||||
$traytitle = $contextmenu.Items.Add("BadUSB Detection");
|
||||
|
||||
$Menu_Exit = $contextmenu.Items.Add("Close Monitor");
|
||||
$Menu_Exit_Picture =[System.Drawing.Icon]::ExtractAssociatedIcon("C:\Windows\System32\DFDWiz.exe")
|
||||
$Menu_Exit.Image = $Menu_Exit_Picture
|
||||
|
||||
$Systray_Tool_Icon.ContextMenuStrip = $contextmenu
|
||||
$appContext = New-Object System.Windows.Forms.ApplicationContext
|
||||
|
||||
$traytitle.add_Click({
|
||||
|
||||
Start-Process msedge.exe 'https://github.com/beigeworm'
|
||||
|
||||
})
|
||||
|
||||
$Menu_Exit.add_Click({
|
||||
|
||||
$notify = New-Object System.Windows.Forms.NotifyIcon
|
||||
$notify.Icon = [System.Drawing.SystemIcons]::Shield
|
||||
$notify.Visible = $true
|
||||
$balloonTipTitle = "USB Monitoring"
|
||||
$balloonTipText = "BadUSB Monitor Stopped"
|
||||
$notify.ShowBalloonTip(3000, $balloonTipTitle, $balloonTipText, [System.Windows.Forms.ToolTipIcon]::Error)
|
||||
|
||||
Stop-Job -Name DeviceMonitor
|
||||
$Systray_Tool_Icon.Visible = $false
|
||||
$appContext.ExitThread()
|
||||
exit
|
||||
|
||||
})
|
||||
|
||||
[void][System.Windows.Forms.Application]::Run($appContext)
|
||||
|
||||
Reference in New Issue
Block a user