As user-driven security expands, the need for securing user-managed systems grows. Disk encryption is an essential and straightforward way to shore up user security.
In this tutorial, we’ll look at how osquery can assess the state of disk encryption on different operating systems.
Let’s start with the disk_encryption table. The first thing to note is that it only captures information on Linux and macOS-based systems. We’ll get to Windows in a moment.
Here’s the query:
SELECT * FROM disk_encryption;
Here are the query results:
Notice the output isn’t super useful. Yes, the encryption_status
field tells us if the partition is encrypted, but which partition matters? What needs to be encrypted? The name
column refers to the hardware device of the partition, but investigators don’t generally have those memorized. We’re going to need information from another table:
SELECT * FROM mounts;
The results:
The mounts
table shows every disk device that’s mounted to a computer, but looking at the output, there’s some noise. Let’s filter this a bit:
SELECT * FROM mounts WHERE device LIKE '/dev/%';
Results:
That’s better. We’ve filtered the table to only show addressable disk devices. The path
column shows where the device is mounted in the system. Notice how the device_alias
column looks a lot like the name
column from the previous table? That means we can link these two queries together with a JOIN
!
SELECT m.device, m.device_alias, m.path, m.type, de.encryption_status
FROM mounts m
LEFT JOIN disk_encryption de ON de.name = m.device_alias
WHERE m.device LIKE '/dev/%'
ORDER BY m.device;
Results:
That query went from 0-100 really fast. Let’s break it down:
SELECT m.device, m.device_alias, m.path, m.type, de.encryption_status
The JOIN
mashes all the columns from both tables into one giant table. The result is a lot harder to read and there’s much that just isn’t important to an investigation. This SELECT
statement pulls out only the column names we care about.
But what’s the deal with the “m.
” and “de.
”? That indicates which table the column is from and that’s defined in the JOIN
syntax:
FROM mounts m
LEFT JOIN disk_encryption de ON de.name = m.device_alias
Here we are joining information from the disk_encryption
table to the output of the mounts
table. For this to work, you need a column in each with the same data in it. As we noted above, the device_alias
column from the mounts
table has the same information in it as the name
field in the disk_encryption
table.
Notice we are doing a LEFT JOIN
. The reason is a little outside the scope of this piece, but check out “Understanding SQL Joins” if you want more information.
WHERE m.device LIKE '/dev/%'
ORDER BY m.device;
These last two lines are filtering the results like we did above and ordering the output to be a bit more readable.
Now you may notice that some partitions aren’t encrypted. In Linux and macOS systems, not everything needs to be encrypted. For example, in Linux systems, the /boot
partition might not be and that’s normal. What’s important will depend on your organization’s requirements, but generally, look for root partitions (“/
”) and other paths mounted off root
, like /home
, /var
, or /System/Volumes/Data
. Those should be encrypted.
Everything outlined above doesn’t apply to Windows, but that’s a good thing! The Windows query is a lot simpler:
SELECT * FROM bitlocker_info;
If protection_status
> 0, then the mounted drive is encrypted.
Photo by Linus Nylund on Unsplash