← SYSREF
HYLAS // PORTMONREF
PORTMON — SERIAL & PARALLEL PORT MONITOR REFERENCE
HARDWARE IMPLANTS
// OVERVIEW
PortMon is a serial and parallel port monitor — it captures all I/O requests sent to serial (COM) and parallel (LPT) ports in real time. Originally designed for debugging hardware peripherals and printer drivers, it has significant relevance in security contexts for detecting rogue hardware implants, BadUSB devices presenting as COM ports, and keyloggers communicating over serial.

Note: PortMon is an older Sysinternals tool and may have driver compatibility issues on Windows 10/11 with Secure Boot or Driver Signature Enforcement enabled. Running on a test system without DSE enforcement, or in a VM, is recommended for forensic use.
// HYLAS SECURITY NOTE — PortMon is uniquely relevant to hardware-based security testing. BadUSB devices (Rubber Ducky, O.MG Cable, DIY ESP32/Pico payloads) that present as HID + CDC Serial will appear as a COM port. PortMon can capture the serial data stream from such a device, exposing the C2 channel or exfiltration path.
// GUI OPERATION
PortMon is GUI-only (no CLI mode). Key operations:

ActionMenu / MethodDescription
Connect to local portsComputer → Connect LocalMonitor all COM/LPT ports on the current machine
Connect to remote portsComputer → Connect Remote → [hostname]Monitor ports on a remote machine (requires portmon driver on remote)
Start / stop captureCapture menu → Capture EventsToggle real-time capture on/off
Filter by portFilter → Filter...Focus on specific COM port — useful to isolate one device
Filter by IRP typeFilter → Highlight...Show only READ, WRITE, or specific IOCTL requests
Save logFile → SaveExport captured events to file for analysis
Clear displayEdit → ClearReset the event list to start a fresh capture
// OUTPUT FIELDS
FieldDescription
TimeTimestamp of the I/O request (microsecond precision)
ProcessProcess making the request — KEY for identifying which process communicates with the device
RequestIRP (I/O Request Packet) type: IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_DEVICE_CONTROL, etc.
PortCOM or LPT port identifier (e.g. \Device\Serial0 = COM1)
LengthNumber of bytes in the request
DataHex dump + ASCII of the actual bytes sent or received
OtherIOCTL codes, baud rate changes, flow control, line state changes
// SERIAL IOCTL REFERENCE
IRP / IOCTLMeaningSecurity relevance
IRP_MJ_CREATEPort opened by a processIdentifies when a process connects to the COM device
IRP_MJ_READData read from port (incoming from device)See what the implant is sending to the host
IRP_MJ_WRITEData written to port (outgoing to device)See what the host is sending to the implant (commands)
IRP_MJ_CLOSEPort closedConnection lifecycle tracking
IOCTL_SERIAL_SET_BAUD_RATEBaud rate configurationBadUSB/implants typically use 115200 baud
IOCTL_SERIAL_SET_LINE_CONTROLData bits, stop bits, parityStandard: 8N1 (8 data, no parity, 1 stop)
IOCTL_SERIAL_SET_TIMEOUTSRead/write timeout configurationVery short timeouts suggest polling behaviour (beacon)
IOCTL_SERIAL_WAIT_ON_MASKWaiting for specific events (data arrival)Common in drivers that poll for incoming data
// BADUSB & HARDWARE IMPLANT DETECTION
BadUSB devices (ESP32, Raspberry Pi Pico, Rubber Ducky, O.MG Cable) that present as both HID keyboard and USB CDC serial (composite USB device) will show up as:

Device Manager: Human Interface Devices → USB Input Device (HID keyboard) Ports (COM & LPT) → USB Serial Device (COMx) ← PortMon captures this Registry location: HKLM\SYSTEM\CurrentControlSet\Enum\USB\ HKLM\SYSTEM\CurrentControlSet\Services\usbser\Enum\
What PortMon reveals about a BadUSB serial channel:
1. IRP_MJ_CREATE from a process (which process opened the COM port?) - Legitimate: Arduino IDE, PuTTY, device driver host - Suspicious: cmd.exe, powershell.exe, python.exe, unknown binary 2. IRP_MJ_WRITE data — commands sent to the device - Check the Data column for ASCII commands - Base64 encoded strings suggest obfuscated C2 commands 3. IRP_MJ_READ data — data sent FROM the device to the host - Keylog data, exfiltrated files, beaconing responses 4. IOCTL_SERIAL_SET_BAUD_RATE - BadUSB typically: 9600, 115200, or 1000000 baud - USB CDC virtual COM ignores actual baud — the rate is cosmetic
Rogue COM port audit via PowerShell (no PortMon needed):
Get-WMIObject Win32_SerialPort | Select Name, DeviceID, PNPDeviceID, Description Get-PnpDevice | Where-Object{$_.Class -eq "Ports"} | Format-List ; Cross-reference VID/PID of found COM devices against known-good hardware inventory ; Suspicious VID:PID combinations: ; VID_2341 (Arduino), VID_2E8A (Raspberry Pi), VID_10C4 (Silicon Labs CP2102) ; VID_1A86 (CH340 — common in cheap clones)
// RED TEAM
Use HID-only — avoid CDC serial channel if stealth is required. HID-only devices don't appear in COM ports and won't be captured by PortMon.
Spoof VID/PID — configure USB device to present as known-good hardware (e.g. Dell keyboard VID) to evade hardware inventory checks.
Encrypt serial channel — base64 + XOR minimum; ensure PortMon data capture reveals nothing useful in plaintext.
Use short burst comms — open COM port, send/receive, close immediately. Minimises the window for process-to-port association.
// BLUE TEAM
USB device whitelisting — use Windows Defender Device Control or a MDM policy to whitelist approved USB VID/PID combinations. Block unknown COM devices.
Audit COM port processes — periodic check: which processes have COM ports open? handle64.exe \Device\Serial
Physical USB port control — epoxy unused USB ports, enforce port-locking hardware in high-security environments.
PortMon remote monitoring — deploy as part of a hardware implant detection sweep when a new USB device is found connected to an asset.