Ability to see when Keyboard or mouse were unplugged

PAC
Contributor

This idea/feature/request will seem odd to allot of people but i work in a school and we are seeing mice and keyboards been disconnected and moved or stolen

I will walk around the school at the ends of the day looking for issues with computers and when the keyboard is removed i see the message trying to set up the Bluetooth keyboard because no USB type is detected.

What would be awesome would be the ability to be able to do a smart group that looks for a certain error or event from the computer. I'm hoping then i could look up the event and time and see who was logged in at that time and try and track down the missing keyboard or mouse

Not sure if this is possible or not but thought i would ask

Regards
Pete

7 REPLIES 7

Look
Valued Contributor III

I would look at the console logs after a keyboard removal and see if there was anything unique there that you could look for with an EA, there is bound to be stopping or starting of something as a result. Only issue with an EA might be the delay until recon, so it might not be same day when you knew about it.

SimonLovett
New Contributor III

A possibility might be to compose a LaunchDaemon managed script which runs every few minutes on the machines and uses ioreg to detect if the keyboard or the mouse strings have disappeared from the output:

The command

ioreg -p IOUSB

outputs the following on my machine with a keyboard attached:

-o Root <class IORegistryEntry, id 0x100000100, retain 13> -o Root Hub Simulation Simulation@fa000000 <class AppleUSBRootHubDevice, id 0x10000028e, registered, matched, active, busy 0 (1 ms), retain 7> | -o IOUSBHostDevice@fa100000 <class AppleUSBDevice, id 0x10000028f, registered, matched, active, busy 0 (1 ms), retain 13> | -o BRCM20702 Hub@fa110000 <class AppleUSBDevice, id 0x1000002b2, registered, matched, active, busy 0 (0 ms), retain 12> | | -o Bluetooth USB Host Controller@fa113000 <class AppleUSBDevice, id 0x100000313, registered, matched, active, busy 0 (1 ms), retain 17> | -o USB Optical Mouse@fa120000 <class AppleUSBDevice, id 0x1000002d1, registered, matched, active, busy 0 (3 ms), retain 11> -o Root Hub Simulation Simulation@fd000000 <class AppleUSBRootHubDevice, id 0x100000294, registered, matched, active, busy 0 (2 ms), retain 7> -o IOUSBHostDevice@fd100000 <class AppleUSBDevice, id 0x100000295, registered, matched, active, busy 0 (2 ms), retain 13> -o IR Receiver@fd110000 <class AppleUSBDevice, id 0x1000002bb, registered, matched, active, busy 0 (52 ms), retain 14> -o Hub in Apple Extended USB Keyboard@fd120000 <class AppleUSBDevice, id 0x1000002d5, registered, matched, active, busy 0 (1 ms), retain 12> +-o Apple Extended USB Keyboard@fd123000 <class AppleUSBDevice, id 0x1000002f7, registered, matched, active, busy 0 (5 ms), retain 13>

As you can see, there is a keyboard string and a mouse string in there.

If I repeat the command with a sleep before it and then quickly pull the keyboard plug while the sleep is running....

sleep 5; ioreg -p IOUSB

then I get this output

-o Root <class IORegistryEntry, id 0x100000100, retain 13> -o Root Hub Simulation Simulation@fa000000 <class AppleUSBRootHubDevice, id 0x10000028e, registered, matched, active, busy 0 (1 ms), retain 7> | -o IOUSBHostDevice@fa100000 <class AppleUSBDevice, id 0x10000028f, registered, matched, active, busy 0 (1 ms), retain 13> | -o BRCM20702 Hub@fa110000 <class AppleUSBDevice, id 0x1000002b2, registered, matched, active, busy 0 (0 ms), retain 12> | | -o Bluetooth USB Host Controller@fa113000 <class AppleUSBDevice, id 0x100000313, registered, matched, active, busy 0 (1 ms), retain 17> | -o USB Optical Mouse@fa120000 <class AppleUSBDevice, id 0x1000002d1, registered, matched, active, busy 0 (3 ms), retain 11> -o Root Hub Simulation Simulation@fd000000 <class AppleUSBRootHubDevice, id 0x100000294, registered, matched, active, busy 0 (2 ms), retain 7> -o IOUSBHostDevice@fd100000 <class AppleUSBDevice, id 0x100000295, registered, matched, active, busy 0 (2 ms), retain 12> +-o IR Receiver@fd110000 <class AppleUSBDevice, id 0x1000002bb, registered, matched, active, busy 0 (52 ms), retain 14>

IE the keyboard string is missing from the output.

So it should be possible to write a script that periodically checks for the presence of the keyboard string in the output and then writes a local log file with time/date when the keyboard (or mouse) strings have disappeared from the output?

Failing that, physical security? We use commercial security cages ow, but we used to simply screw down the mouse and keyboard cables with a screw and a nylon cable clip, so the only way to steal them was by cutting the cable, (this rendering them useless), or bringing a tool kit into the lab :)

Hope that is helpful, sorry I haven't got time this minute to turn it into a prototype script...

mm2270
Legendary Contributor III

I was intrigued by this topic, so, taking what @SimonCU wrote above, here is a line that will clean up the ioreg output to give you each USB device or system it reports onto its own line, easy for grepping out what you want to look for.

ioreg -p IOUSB | awk -F'@' '{print $1}' | sed -e 's/|//g;s/+-o//g;s/^ *//g'

The output from my MBPr with no external keyboard/mouse attached looks like:

XHCI Root Hub SS Simulation
Card Reader
XHCI Root Hub USB 2.0 Simulation
Apple Internal Keyboard / Trackpad
BRCM20702 Hub
Bluetooth USB Host Controller
EHCI Root Hub Simulation
HubDevice
Apple Thunderbolt Display
Display Audio
FaceTime HD Camera (Display)

Running it again with a keyboard and mouse attached shows:

XHCI Root Hub SS Simulation
Card Reader
XHCI Root Hub USB 2.0 Simulation
Apple Internal Keyboard / Trackpad
BRCM20702 Hub
Bluetooth USB Host Controller
Generic USB Hub
Macally iKeySlim
Apple Optical USB Mouse
EHCI Root Hub Simulation
HubDevice
Apple Thunderbolt Display
Display Audio
FaceTime HD Camera (Display)

You can see the keyboard and mouse in the output. Yes, its a cheap MacAlly keyboard (only thing I had around to test with).

Taking this further, here's a script I put together that could be run on an interval by a LaunchDaemon. You can make this run once every 30 seconds for example, so it should be as real time as you can get. It will send you an email when a USB keyboard or mouse is detected missing. Right now its coded to look for the Macally keyboard I'm using so you'd need to adjust the two checks to make sure its correctly looking for the devices you want to track.
It will also write the data into a hidden file. The script checks to make sure that file is empty. If its not, it means it already sent an email alert and won't do it again (so you don't get spammed). If it sees all required devices attached, it checks to make sure that hidden file is empty, to get ready for the next event.

I also added an on screen alert that can pop up using cocoaDialog (could be swapped out for jamfHelper easily) so it can alert the user that the devices they just removed were recorded and their "administrator" has been alerted. That might help stop some of the incidents if they know their info was recorded and sent to you. If you set the warnUser flag to an empty string or something other than Yes it will skip sending up an on screen alert.

Here is the script:

#!/bin/bash

cdPath="/Library/Application Support/JAMF/bin/cocoaDialog.app/Contents/MacOS/cocoaDialog"

USBOutput=$(ioreg -p IOUSB | awk -F'@' '{print $1}' | sed -e 's/|//g;s/+-o//g;1d;s/^ *//g')

if [ ! -e "/private/var/usbtracker" ]; then
    touch "/private/var/usbtracker"
fi

## Set var below to "Yes" to send up notice on screen to the logged in user
## If left blank or at any other value than "Yes", it will skip the on screen notice
warnUser="Yes"

function sendAlertEmail ()
{

## Set the email recipient here, i.e, put your email address here
EMAILREC="your.email@company.com"

## Get Computer Name
COMPNAME=$(scutil --get ComputerName)

## Gather data from ioreg
IOREGDATA=$(ioreg -rd1 -c IOPlatformExpertDevice)
MODELNAME=$(awk -F'"' '/model/{print $4}' <<< "$IOREGDATA")
SERIALNUM=$(awk -F'"' '/IOPlatformSerialNumber/{print $4}' <<< "$IOREGDATA")
UUID=$(awk -F'"' '/IOPlatformUUID/{print $4}' <<< "$IOREGDATA")

## Get the logged in user
CURRUSER=$(stat -f%Su /dev/console)

## Build the subject and message variables
SUBJECT="USB Device detached from $COMPNAME"
MESSAGE="A USB device has been detached from the following system at $(date +"%D %T"):

Computer Name:      $COMPNAME
Model:          $MODELNAME
Serial Number:      $SERIALNUM
UUID:           $UUID

The user currently logged in was:
$CURRUSER"

check=$(cat "/private/var/usbtracker")

if [[ "$check" != "" ]]; then
    echo "Previous alert sent. Exiting..."
    exit 0
else
    ## Send off the alert email
    echo "${MESSAGE}" | mail -s "${SUBJECT}" ${EMAILREC}

    ## Create the alert sent file
    echo "$MESSAGE" > "/private/var/usbtracker"
fi

warnText="The USB device or devices just detached from this Mac have been recorded and information has been sent to your administrator. Your personal information has been sent to them as well.

Reattach the devices or this incident will be investigated."

if [ "$warnUser" == "Yes" ]; then
    "$cdPath" msgbox 
        --title "USB Device removal detected" 
        --text "Your information has been recorded" 
        --informative-text "$warnText" 
        --icon caution 
        --button1 "  OK  " 
        --quiet
else
    exit 0
fi

}

function checkAlert ()
{

check=$(cat "/private/var/usbtracker")

if [[ "$check" != "" ]]; then
    ## Remove previous alert data
    echo "" > "/private/var/usbtracker"
else
    exit 0
fi

}

## Edit these checks for the specific devices you want to track (add additional 'or' checks as needed)
if [[ $(echo "$USBOutput" | grep "Macally iKeySlim") == "" ]] || [[ $(echo "$USBOutput" | grep "Apple Optical USB Mouse") == "" ]]; then
    echo "Missing devices detected. Checking for previous alert"
    sendAlertEmail
else
    echo "No issues detected"
    checkAlert
    exit 0
fi

Hope the above helps get you on the right track with this. I've only done limited testing with the above, so hopefully it would work as designed under all cases.
Outside of something like this, it might be a good idea to look at physically securing the USB devices as suggested, which would avoid the entire issue.

SimonLovett
New Contributor III

That's a very tidy piece of code mm2270 - I figured there was going to be more goodies tucked away in the output and that reporting mechanism is very elegant indeed :)

SimonLovett
New Contributor III

@Look, yes the logs will show it as well in real time, but it might be harder to act on - this provides an email alert within minutes of a ....removal of the keyboard, and an on screen warning as well.

I think something similar is possible in Applescript based on keyboard events, but even then it would still end up quickest dropping to bash to post the email alert.

Does OS X still possess a syslog server out of interest does anyone know?

Good day sir

JAMESROY
New Contributor

Good day sir, How can i run this in windows OS?