How to tell if CrowdStrike Falcon sensor is running

How to tell if CrowdStrike Falcon sensor is running

Micah Sorenson by Micah Sorenson on

This guide for IT and security professionals shows how to detect that the CrowdStrike agent is installed and properly configured, using either vanilla osquery or 1Password® Extended Access Management.

CrowdStrike is a security company which is generally classified as an Endpoint Detection and Response (EDR) tool. It primarily operates via the Falcon sensor agent, which is installed on employee devices and detects malware, anomalous behaviors, and other vulnerabilities.

As CrowdStrike’s own website says, the Falcon sensor is “extremely lightweight (consuming 1% or less of CPU) and unobtrusive: there’s no UI, no pop-ups, no reboots, and all updates are performed silently and automatically.” For that reason, end users may be unaware of Crowdstrike’s existence on their device, much less whether or not it’s working properly.

Ensuring that the CrowdStrike agent is properly installed, configured, and running could be the difference between responding to a massive data breach or having a quiet weekend. But ensuring this requires us to gather information that goes beyond checking the apps folder or process table to see that the agent is installed.

Merely checking for CrowdStrike’s presence doesn’t validate that the process is in a good state, or that the agent was configured properly.

Most companies with CrowdStrike don’t have this kind of reporting readily available. If a device has stopped checking in, they don’t have alerts for it because it could just be an old device. The context of why it’s missing is missing.

To get that crucial context, we need to build some custom tables, which we’ll get into next.

How to tell if CrowdStrike is installed, configured, and running on Mac, Windows, and Linux

To ensure that CrowdStrike is functioning properly, we want to validate various things, such as:

  • Client ID

  • RFM state (Linux only)

  • Active System Extension (MacOS only)

  • Operational state

  • Version

That’s pretty straightforward in Windows, since we can gather the Client ID from the registry table, the operational state from the services table, and the installed version from the programs table. These tables don’t exist for MacOS and Linux, so if we want to collect and validate all of these for MacOS and Linux endpoints, then we have to partially implement our own solution.

To get the missing information, we’ll be querying falconctl, the CrowdStrike sensor binary. It can tell us if CrowdStrike is actually set up and communicating vs just running for its own amusement.

Our team made some additional tables in our agent to gather the missing information from the binary for macOS and Linux. We added validation to the Checks for the Client ID, RFM state (Linux only), Active System Extension (MacOS only), and operational state to ensure that the CrowdStrike agent is properly configured and running.

This provides a more robust solution, that should be sensitive to hiccups that could happen in the agent, which an “is installed and running” osquery implementation wouldn’t be able to catch.

How to detect CrowdStrike using a fully native osquery implementation

As we said, you can get certain information about CrowdStrike’s Falcon agent using generic osquery. That information varies by operating system, but we’ve included a general approach for each query below.

MacOS

Step 1: We validate that the agent is an active system extension from the system_extensions table.

  • This tells us if the CrowdStrike agent is installed and enabled on the endpoint. It also shows us what version the system extension is.

Step 2: This is a lot all at once, so let’s break it down a bit. Let’s start with the columns we care about.

  • Identifier - The system extension identity. (com.crowdstrike.falcon.Agent)

  • State - The status of the extension. I.e. active and enabled or deactivated and disabled.

  • Version - The version of the extension.

Step 3: With these columns, we construct a JSON_OBJECT, which takes in our columns, and then returns a JSON formatted object for each row.

  • JSON_OBJECT('identifier', identifier, 'state', state, 'version', version)

Step 4: Now we can group the objects into an array containing them all.

  • JSON_GROUP_ARRAY(JSON_OBJECT('identifier', identifier, 'state', state, 'version', version))

Step 5: We then create another object array, and add filters to them to separate the data.

  • The first contains the row(s) where the state column is equal to “activated_enabled”.

    • FILTER(WHERE state = ‘activated_enabled’)
  • The second contains the row(s) where the state column is not equal to “activated_enabled”.

    • FILTER(WHERE state != ‘activated_enabled’)

Step 6: Now we can get all CrowdStrike system extensions by putting this together and adding a WHERE clause to get only CrowdStrike system extensions.

SELECT
   JSON_GROUP_ARRAY(JSON_OBJECT('identifier', identifier, 'state', state, 'version', version)) FILTER(WHERE state = 'activated_enabled') AS active_system_extensions,
   JSON_GROUP_ARRAY(JSON_OBJECT('identifier', identifier, 'state', state, 'version', version)) FILTER(WHERE state != 'activated_enabled') AS inactive_system_extensions
FROM system_extensions
WHERE identifier = 'com.crowdstrike.falcon.Agent' COLLATE NOCASE

Linux

Step 1: We first collect the version, and by extension validate installation from the deb_packages/rpm_packages table.

  • Use deb_packages on debian based Linux, or rpm_packages on rhel based Linux devices.
SELECT
   MAX(version) AS version
FROM deb_packages
WHERE name = 'falcon-sensor' COLLATE NOCASE

Step 2: We then collect the operational state of the agent from the systemd_units table.

SELECT COUNT(*),
   CASE
       WHEN LOWER(sub_state) = 'running'
           AND LOWER(load_state) = 'loaded'
           AND LOWER(active_state) = 'active'
           THEN 'Yes'
       ELSE 'No'
   END AS sensor_operational
FROM systemd_units
WHERE id = 'falcon-sensor.service' COLLATE NOCASE

Windows

Step 1: We first collect the Agent ID and Client ID from the registry table.

  • Only the first 32 characters for each ID are important, so we use SUBSTR to remove extra characters.
SELECT
   MAX(SUBSTR(data, 1, 32)) FILTER(WHERE name = 'AG') AS agent_id,
   MAX(SUBSTR(data, 1, 32)) FILTER(WHERE name = 'CU') AS client_id
FROM registry
WHERE key = 'HKEY_LOCAL_MACHINE\SYSTEM\CrowdStrike\{9b03c1d9-3138-44ed-9fae-d9f4c034b88d}\{16e0423f-7058-48c9-a204-725362b67639}\Default' COLLATE NOCASE

Step 2: We then collect the version, and by extension validate installation from the programs table.

SELECT
   MAX(version) AS version
FROM programs
WHERE name = 'CrowdStrike Sensor Platform' COLLATE NOCASE

Step 3: Lastly, we collect the operational state of the agent from the services table.

SELECT COUNT(*),
   IIF(LOWER(status) = 'running', 'Yes', 'No') AS sensor_operational
FROM services
WHERE name = 'CSFalconService' COLLATE NOCASE

What 1Password’s Device Trust solution does to help ensure the CrowdStrike agent is properly installed and running

At 1Password, we’ve created custom tables to pull extra information from Falcon. (For a detailed guide on how to write osquery tables, read our blog.)

These queries also vary somewhat by OS, so we’ve included what data our CrowdStrike Agent Check collects from each.

MacOS

We gather data reported directly from the CrowdStrike agent by checking the output of this command /Applications/Falcon.app/Contents/Resources/falconctl stats -p.

This returns:

  • Agent ID

  • Client ID

  • Operational state

  • Version of the agent

We then check the system_extensions Osquery table to verify the agent is installed and active. We also check if there’s an inactive agent, but it does not change the check’s result if one is there.

Linux

We gather data reported directly from the CrowdStike agent by checking the output of this command /opt/CrowdStrike/falconctl -g –aid –cid –rfm-state –version.

This returns:

  • Agent ID

  • Client ID

  • RFM (Reduced Functionality Mode)

  • Version of the agent

We then check the systemd_units Osquery table to collect the operational state of the agent.

Windows

For Windows devices, we gather the Agent ID and Client ID from the registry Osquery table. We then collect the operational state from the services Osquery table. Lastly, we check our WMI table for the agent’s version.

What is CrowdStrike ZTA (Zero Trust Assessment)

Up to this point we’ve covered how to detect and validate that CrowdStrike’s agent is installed, configured, and running properly. Now we’ll discuss how 1Password’s Device Trust solution (as part of 1Password Extended Access Management) utilizes an additional security measurement offered by CrowdStrike, their ZTA (Zero Trust Assessment) service.

The ZTA service monitors OS and CrowdStrike’s Falcon sensor settings to ensure they meet the configured policies for those settings. The ZTA service calculates a security score from 1 to 100 for each host. While a higher score indicates a better posture for the host, the score depends upon the unique configuration of the policies, and therefore ZTA does not define what constitutes a good score.

Our end goal is to create a Check that will block devices from authenticating if they don’t earn a high enough ZTA score.

The ZTA security score is generated and stored into a common data.zta file on the host device (except for Linux). This file is an encrypted and signed JSON Web Token (JWT).

Parsing this JWT, we can see the various claims being sent. The claims we’ll be paying attention to are the assessment (ZTA) claims. These are split into 4 different claims:

  • The ZTA OS security score.

  • The ZTA Falcon sensor security score.

  • The ZTA overall security score.

  • The ZTA version.

How 1Password Extended Access Management utilizes CrowdStrike ZTA (Zero Trust Assessment)

There are a few things we had to implement to make use of the CrowdStrike ZTA data.

First, we needed a way to parse the JWT, as there’s not a native way to do this in osquery. Similarly to the other CrowdStrike tables we had to create, we built a JWT parser table to handle this.

Second, we wanted to validate the parsed JWT with the publicly accessible CrowdStrike ZTA JWKs. The JWT parser table accepts an array of signing keys to be passed to it for validating the JWT.

Now we have all of the pieces for our CrowdStrike ZTA Check. The Check verifies that the ZTA JWT signature is valid using their JWKs. By default, the Check also verifies that the overall ZTA score is equal to or greater than 75. This is configurable along with the other score’s minimum requirements, which are 0 by default.

How 1Password’s Device Trust solution turns queries into Checks

As you can see, between the different operating systems, we had to piece together the CrowdStrike data and state from a few different tables in osquery, plus our own agent. Without our agent’s data, the Checks would suffer in quality and sophistication, and in the case of the ZTA Check, it would not exist at all.

This should give you a sense of how much work goes into creating our software configuration Checks, but it’s still not the complete picture of our final product. We then bundle these disparate queries into Checks, which admins can deploy across their fleet and run automatically or at will (our default setting for these Checks are to run once per hour).

In the example of the CrowdStrike Agent Check, if our agent detects any issues, then it will immediately notify the end user via our toolbar app and provide them with remediation instructions.

A screenshot of the fix instructions XAM provides for the crowdstrike check.

If a user attempts to authenticate via their IdP without a functioning CrowdStrike agent, 1Password’s Device Trust solution will block them until they have fixed the problem. (As with all our Checks, admins can configure this one to merely warn users, rather than blocking them, but given the seriousness of CrowdStrike’s security role, most of our customers choose to make it a requirement.)

It’s important not to underestimate the value of end user remediation in the case of this CrowdStrike Agent Check. For one thing, it gets end users back to work without requiring the direct intervention of IT. For another, it cuts across departmental silos, since in many organizations CrowdStrike is part of the Security team’s purview, but interfacing with users usually falls to IT.

While these Checks are specific to CrowdStrike, you can take this approach to other EDR tools and software in general.

Details will vary but the overall process should be:

  1. Finding and deciphering configs and/or logs.

  2. Creating tables and launcher work to read those files.

  3. Writing a Check that uses the custom tables.

If you’re a 1Password Extended Access Management customer, you can go through the whole process (including writing end user remediation instructions) using our custom Check editor.

If you’re not a customer but you want to learn more about how our device trust solution works, schedule a demo!

Developer

Micah Sorenson - Developer Micah Sorenson - Developer

Tweet about this post