Using Osquery for USB device monitoring.

Zercurity
4 min readAug 20, 2020

--

I briefly touched on USB device monitoring on Mac OSX via Osquery during my Osquery Con 2019 talk last year. However, I though I’d explore in more detail how to setup device monitoring on Osquery from start to finish. Including some more example queries.

Prerequisites

This article is written using Osquery 4.2.0. If you’re looking for help on installing Osquery please see our guide here.

Example of USB device monitoring with FIM on Osquery

Why monitor USB devices?

There are three main reasons I can think of — off the top of my head as to why you’d want to monitor your devices USB devices.

Data loss prevention

Removable media can be used as a medium to exfiltrate data from corporate networks. Most companies will block access to online file sharing services in favor of corporate file sharing services. Which will provide audit-able events for compliance. With restrictions on email attachment types and sizes, USB devices become a fast medium of file exchange between systems. Amusing of course USB ports aren’t blocked either. Nevertheless, files left on USB devices can become a potential source of a data breach. Given their size, these devices are typically misplaced or re-purposed. Even if deleted files can still be recovered from USB devices. Having an audit-able log of files copied to USB devices can help mitigate risk.

Compliance & Auditing

As with the use case above. Many security framework and compliance standards require some form of USB device monitoring and auditing. In the event of a data breach, having a strong reference point can massively help aid investigations. Thereby, potentially minimising any damage to the business operations.

Security

USB devices can be a potential source of malicious files being introduced to a system or network. Being able to identify those files — understanding whether they’re known or unknown by the organisation can help minimise damage to the business.

Setting up File Integrity Monitoring (FIM)

FIM uses FSEvents(Mac OS X) to monitor files and directories for changes. As files and directories are written, read and deleted events are created. Osquery can update its FIM configuration on the fly via the remote API. Wildcards for directories can also be used.

When a USB device if plugged into a Mac, its automatically mounted into the /Volumes/ directory. The following Osquery FIM configuration will create an event as files are created, modified and deleted within the /Volumes/<device> directory.

An important note is that this configuration is done for simplicity. In some cases, secondary system volumes may be mounted within /Volumes/ leading to a large number of events being generated, just something to bear in mind.

The following is a simple JSON file called osq.conf which will be loaded by Osquery.

{
"options": {
},
"file_paths": {
"homes": [
"/Volumes/%%"
]
}
}

Fire up the osqueryi like so providing our new config file:

sudo osqueryi --disable_audit=false --verbose --disable_events=false --config_path ./osq.conf

USB devices

The first query you can run is as follows:

SELECT vendor, model FROM usb_devices WHERE removable = 1;

This will provide you with a list of all the removable USB devices currently attached to your system.

+---------+--------------+
| vendor | model |
+---------+--------------+
| SanDisk | Cruzer Glide |
+---------+--------------+

There are two tables we need for this next part disk_events and mounts this will help us find the mount path for our newly inserted USB device.

SELECT action, DATETIME(time, 'unixepoch') AS datetime, vendor, mounts.path FROM disk_events LEFT JOIN mounts ON mounts.device = disk_events.device;

Which will yield the following:

+--------+---------------------+---------+------------------+
| action | datetime | vendor | path |
+--------+---------------------+---------+------------------+
| add | 2020-08-19 16:16:10 | SanDisk | |
| add | 2020-08-19 16:16:10 | SanDisk | /Volumes/SanDisk |
| add | 2020-08-19 16:16:10 | SanDisk | |
+--------+---------------------+---------+------------------+

When the USB device is removed, the action will change to a remove event. The path column refers to where the USB device has been mounted on your system.

To check to see what files have been created, modified or removed on the device we can use the file_events table in conjunction with the target_path column.

SELECT action, uid, SUBSTR(target_path, 18) AS path, SUBSTR(md5, 0, 8) AS hash, time FROM file_events WHERE sha1 <> '' AND target_path NOT LIKE '%DS_Store';

When I copy the Zercurity.png over to the USB device, the following file events are generated:

+---------+-----+---------------+---------+------------+
| action | uid | path | hash | time |
+---------+-----+---------------+---------+------------+
| CREATED | 99 | | 43cf614 | 1597853771 |
| CREATED | 99 | Zercurity.png | 8894958 | 1597853800 |
| CREATED | 99 | Zercurity.png | 8894958 | 1597853800 |
| UPDATED | 99 | Zercurity.png | 8894958 | 1597853800 |
| UPDATED | 99 | Zercurity.png | 8894958 | 1597853800 |
+---------+-----+---------------+---------+------------+

The query above will grab all file events from all configured file_paths. We’ll link those file events to a device after the fact. However, to do this in one single query for a given device. We can join both the mounts table and the file_events table together like so:

SELECT mounts.path FROM disk_events 
INNER JOIN mounts ON mounts.device = disk_events.device
WHERE vendor IN (
SELECT vendor FROM usb_devices
WHERE removable = 1
)

This query will provide us with a list of mount paths:

+--------------------+
| path |
+--------------------+
| /Volumes/Zercurity |
+--------------------+

Then, whilst using the above query in a WITH statement we can use this to query your file_events table.

WITH target_paths AS (
SELECT mounts.path FROM disk_events
INNER JOIN mounts ON mounts.device = disk_events.device
WHERE vendor IN (
SELECT vendor FROM usb_devices
WHERE removable = 1
)
)
SELECT * FROM file_events WHERE target_path LIKE (SELECT path || '%' FROM target_paths);

This will then give you a complete dump of all the file changes made on any attached USB devices.

You’ll also automatically get the user making the change and hash of the file too. Which you can use to wash against known files within your organisation.

Hopefully that helps. Please feel free to get in touch if you need any help. Or join us on the #zercurity Osquery Slack channel.

--

--

Zercurity

Real-time security and compliance delivered.