Upon reading Mandiant’s “North Korea Leverages SaaS Provider in a Targeted Supply Chain Attack”, one of the artifacts that stood out to me was the usage of XProtect’s Behavior Service DB. Until now, I had assumed all XProtect detections were signature based, but it sounds like Apple may be testing some behavioral-based rules to flag suspicious process executions in newer versions of MacOS.
Examining the DB locally using sqlite3
If you’d like to take a look at the DB on your own system, you can simply run
sudo sqlite3 /var/protected/xprotect/XPdb:
SQLite version 3.39.5 2022-10-14 20:58:05 Enter ".help" for usage hints. sqlite> .mode line sqlite> select * from events; id = 298 violated_rule = BastionRule-1 exec_path = /usr/sbin/lsof exec_cdhash = 62c8e638c90f2fe3672d89cb134f37a010561e29 exec_signing_id = com.apple.lsof exec_team_id = exec_sha256 = f8a6987f682de1174ece536deaa9da730b5103ef4af086a45c9c533068296709 exec_is_notarized = 0 responsible_path = /Users/user/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/Helpers/GoogleSoftwareUpdateAgent.app/Contents/MacOS/GoogleSoftwareUpdateAgent responsible_cdhash = 8c87d6eb2d85e5b18d68088ebc7d1a36d28c1930 responsible_signing_id = com.google.Keystone.Agent responsible_team_id = EQHXZ8M8AV responsible_sha256 = e89dbda1bbdcfca7a9d559fb92bf0d7d9d275a0ad74a9e27098329dd766e3d34 responsible_is_notarized = 1 reported = 1 profile_hash = 5998098849390627319 dt = 2023-06-30 06:34:28 ... <snip>
From this entry, we can see XProtect flagged the
GoogleSoftwareUpdateAgent binary (signed with team_id
EQHXZ8M8AV) because it executed the
/usr/sbin/lsof binary. Something about this execution caused it to trigger the
BastionRule-1 rule. I have a bunch of entries in my DB, and all of them appear to be false positives, but it’s quite clear how this could be a useful place to check for suspicious process executions. It clearly paid off for Mandiant!
Examining the XPDB at scale
One of the lesser known features of osquery is called Automatic Table Creation or “ATC” for short. Kolide has a pretty good write up on what the feature is and how to use it. Assuming you’re using some sort of osquery management tool like FleetDM or Kolide, you’ll be able to leverage ATC to query the XPDB on all of your hosts.
I personally use the open source version of FleetDM, so I added an entry to my config that looks like this:
overrides: platforms: darwin: auto_table_construction: xpdb: columns: - id - violated_rule - exec_path - exec_cdhash - exec_signing_id - exec_team_id - exec_sha256 - exec_is_notarized - responsible_path - responsible_cdhash - responsible_signing_id - responsible_team_id - responsible_sha256 - responsible_is_notarized - reported - profile_hash - dt path: /var/protected/xprotect/XPdb query: SELECT * FROM events WHERE responsible_team_id NOT IN (<list of team_ids I trust>) AND exec_team_id NOT IN (<list of team_ids I trust>)
If you’re less trusting of certain organizations than I am, you could of course just
SELECT * without any
After adding this to the config,
xpdb is exposed as a table like any other osquery table. I set up a scheduled query that basically runs
SELECT * FROM xpdb and logs any additions (ignores removals) to the database on all my hosts across the fleet.
Other ATC Considerations
There’s quite a bit of valuable information stored in SQLite databases on MacOS, so consider monitoring things like your users’ TCC system and user entries, quarantine events, and maybe some application settings that are stored in sqlite databases.