Trying to setup EA for CrowdStrike

janzaldua
Contributor

Hello. I wanted to setup some EAs for CrowdStrike, regarding the Version / agentID / customerID. The command to put in Terminal to gather this info is:

sudo /Applications/Falcon.app/Contents/Resources/falconctl stats agent_info

I want to get this info into an EA, if possible. There was a script someone posted earlier this year, but it is not working for me for some reason. It was in this thread. When I deploy it via Jamf, the field for the EA remains blank. Although if I run the script directly from my Mac, it displays the customerID stat just fine.

Any help is appreciated.

24 REPLIES 24

pbenware1
Release Candidate Programs Tester

There is a script from somewhere that used to get a sort of health state (connected, running, extensions loaded, etc), but it has been unreliable for me for a while, and didn't get some of the same info you're looking for. I've been actively creating new EA scripts for each data point that I need, which has been working, but I'm getting a little concerned about too many scripted EA's running @ recon, so I'm thinking about a better way to handle it.

There is also a script that can be run as a policy rather than an EA that presents the output in a user friendly manner, and only runs on demand, so no hits from running an EA on every recon.

For the policy based script, check out Dan Snelsons excellent CrowdStrike Falcon Inspector.

Its not an EA, so won't appear in the inventory record, but the field techs have found it very useful, since it can be run from Self Service.

 

For Agent version EA, check out this and a bunch of others from Zach Thompson:

https://github.com/MLBZ521/MacAdmin/blob/master/Jamf%20Pro/Extension%20Attributes/jamf_ea_CrowdStrik...

For Agent ID, a very simple script that I use:

#!/bin/sh

###################################################################################################
# Script Name:  jamf_ea_CrowdStrikeAgentID.sh
# Description:  This script gets the AgentID of Crowd Strike agent_info section of a falconctl stats query, if installed.
#
###################################################################################################

result="Not Installed or Running"

if [ -e /Applications/Falcon.app/Contents/MacOS/Falcon ]; then
    agentID=$(/Applications/Falcon.app/Contents/Resources/falconctl stats | awk '/agentID:/ {print $2}')
    result=$(echo "$agentID" | tr -d - )

fi

echo "<result>$result</result>"

 

And this, modified from Zach's Agent Version script:

** Note: We have 2 CID's in use here, was well as devices from other orgs with their own CID's. The very last section of this script converts the 2 CID values into a more human recognizable format.  Makes searching and sorting in Jamf must easier. If you use this, be careful to enter your own CID(s) and the associated names that they align to.

#!/bin/bash

###################################################################################################
# 
#
#	This script was modified from Zach Thompsons excellent CrowdstrikeVersionVersion EA script.  Get it here:
# 	https://github.com/MLBZ521/MacAdmin/blob/master/Jamf%20Pro/Extension%20Attributes/jamf_ea_CrowdStrikeVersion.sh
#	Script Name:  jamf_ea_CrowdStrikeCustomerID.sh
# 	Description:  This script gets the CustomerID of Crowd Strike, if installed.
# 
# 	October 2022
# 	Harvard Medical School - Information Technology
# 	Phil Benware
# 	modified from jamf_ea_CrowdStrikeAgentID.sh to collect the Customer ID license key used during install.
# 	15-NOV-22 Added additional functionality to make the results Human readable in Jamf by defining the CID as either "CID1" or "CID2".
# 	If neither of those CID's is recognized then show the reported CID.
###################################################################################################

echo "Checking if Crowd Strike is installed..."

##################################################
# Possible falconctl binary locations
falconctl_app_location="/Applications/Falcon.app/Contents/Resources/falconctl"
falconctl_old_location="/Library/CS/falconctl"

#############################################n#####
# Functions

get_falconctl_version() {
	
	csAgentInfo=$( sudo "${1}" stats agent_info --plist )
	#echo $csAgentInfo
	
	cs_customerID=$( /usr/libexec/PlistBuddy -c "Print :agent_info:customerID" /dev/stdin <<< "${csAgentInfo}" 2> /dev/null )
	plistBuddy_exit_code=$?
	
	if [[ $plistBuddy_exit_code -ne 0 ]]; then
		
		# Get the Crowd Strike version from sysctl for versions prior to v5.36.
		cs_customerID=$( /usr/sbin/sysctl -n cs.agentID )
		cs_customerID_exit_code=$?
		
		if [[ $cs_customerID_exit_code -ne 0 ]]; then
			
			cs_customerID="Not Running"
			
		fi
		
	fi
	
	echo "${cs_customerID}"
	
}

##################################################
# Bits staged, collect the information...

if  [[ -e "${falconctl_app_location}" && -e "${falconctl_old_location}" ]]; then
	
	# The new and old verisons appear to both be installed.  This is bad.
	cs_customerID="ERROR:  Multiple CS Versions installed"
	
elif  [[ -e "${falconctl_app_location}" ]]; then
	# this is the new version of falcon
	cs_customerID=$( get_falconctl_version "${falconctl_app_location}" )
	
elif  [[ -e "${falconctl_old_location}" ]]; then
	# this is the old version of falcon
	cs_customerID=$( get_falconctl_version "${falconctl_old_location}" )
	
else
	# falcon does not appear to be installed
	cs_customerID="Not Installed"
	
fi

# Convert the CID value to something human readable, if its known to <my company>, otherwise show the reported CID.
if [ "${cs_customerID}" == "CID1" ]; then
	cs_customerID="My Company CID"
elif [ "${cs_customerID}" == "CID2" ]; then
	cs_customerID="An UNKNOWN CID"
else
	echo "<result>${cs_customerID}</result>"
fi

echo "<result>${cs_customerID}</result>"

exit 0

 

sdagley
Esteemed Contributor II

@janzaldua I posted that EA that you linked to, and it's still working in my environment, so not sure why it's not working for you. Can you try creating a Script with the EA script then run that as a Policy payload to see what the full output is? 

Sorry for the late reply here! If I run the script via a Policy, it shows the version successfully. Here is the full output:

~ % sudo jamf policy -event csversiontest -verbose
verbose: JAMF binary already symlinked
verbose: Checking for an existing instance of this application...
Checking for policies triggered by "csversiontest" for user "*****"...
verbose: Checking for active ethernet connection...
verbose: No active ethernet connection found...
verbose: Removing any cached policies for this trigger.
verbose: Parsing servers...
verbose: Parsing Policy Crowdstrike Version [Test] (372)...
verbose: The Management Framework Settings are up to date.
verbose: Found 1 matching policies.
Executing Policy Crowdstrike Version [Test]
verbose: Copying script to temp directory...
verbose: Determining script type...
Running script Crowdstrike Version...
Script exit code: 0
Script result: <result>6.57.17003.0</result>
verbose: Removing local copy...
Submitting log to https://****.jamfcloud.com/

Again, this works great via a Policy. It also works fine if I run the script through Terminal locally on my MacBook.. But for some reason if I put it into an EA, it just stays BLANK, even after an inventory update.

sdagley
Esteemed Contributor II

@janzaldua Can you post the script of the EA you're running? Based on the "Script result: <result>6.57.17003.0</result>" output from you running the EA as a policy script it should be a valid EA result so we need to look for some other explanation of why it isn't working.

Sure. I believe it is the same one you posted on the other thread, but I changed the 'customerID' to 'version' instead.

#!/bin/sh

# Reports back the version: result from the agent_info section of a falconctl stats query

result="Not Installed or Running"

if [ -e /Applications/Falcon.app/Contents/MacOS/Falcon ]; then
	syextNum=$(systemextensionsctl list | awk '/com.crowdstrike.falcon.Agent/ {print $7,$8}' | wc -l) 
	if [ $syextNum -gt 0 ]; then
		result=$(/Applications/Falcon.app/Contents/Resources/falconctl stats | awk '/version:/ {print $2}')
	fi
fi

echo "<result>$result</result>"

sdagley
Esteemed Contributor II

@janzaldua You don't really need to determine if the Falcon Extension is running to query the version, so you could try removing that check, but I'd recommend you you use the version check EA that @mm2270 posted because it will report "Not Installed" if the falconctl stats call doesn't return a version number.

I got it working as a string, but I wanted to set it as an integer. If I set it as integer, it will allow for a Smart Group to fit criteria as 'more than' or 'less than', but the problem is, the Version shows up as invalid. Check out these screenshots.

Screenshot 2023-08-10 at 3.41.41 PM.png

Screenshot 2023-08-10 at 3.41.34 PM.png

The EA is working fine and shows the Crowdstrike Version, but apparently Smart Groups see that integer as invalid?

mm2270
Legendary Contributor III

That's because 6.57.17003.0 is not an integer. Integers are basically whole numbers (positive or negative). Even if the version was something like 6.57, that is still not an integer, it's a decimal.

I suggest just using it as a string for now. Unfortunately Jamf doesn't have Crowdstrike in their list of patch management titles or you would be able to use that to build smart groups to give you the less than or greater than function. You could consider submitting a feature request / idea to have them include that in the future.

Alternatively, you could look into Jamf's Title Editor to create your own patch title if you really really want that type of version check functionality.

Yeah this makes sense. Thank you. What is the best way to check if the CS Agent is installed? Using only the Applications path doesn't seem reliable, as that is what we were using before but it was inaccurate. I figured returning a version back would be good enough, in which I could use the Version EA as a way to tell if CS Agent is installed. I was then going to try and create a Smart Group to say version is "more than" 6, but I couldn't do it.

sdagley
Esteemed Contributor II

@janzaldua You can use a regular expression to have Jamf Pro evaluate a semantic version number like 6.57.17003.0, and the script make_ge_version_regexp.sh will create those expressions for you. You can use the "matches regex" or "does not match regex" operators in a Smart Group to determine if the version of CrowdStrike is older or newer than what you're looking for.

That said I would not recommend trying to use Jamf Pro to keep the CrowdStrike Falcon agent up to date, and leave updates to the agent itself. For my org the install of CrowdStrike Falcon is triggered if the agent isn't detected, not what version is installed.

And a side note on installing CS - you really should think about using the script described in @franton 's Crowdstrike Falcon API For Fun and Profit to install if you aren't already.

Oh for sure, I agree. I am not using Jamf Pro to keep the agent up to date. As stated above to mm2270, I was going to use the EA as a way to show if the agent is installed/present. Which EA is best to only show whether or not the CS Agent is installed/present, and not just the Applications folder path.

sdagley
Esteemed Contributor II

I prefer to check the agent status and the last connection date to verify compliance

And how would you make a Smart Group based on these EA's? 

Screenshot 2023-08-11 at 8.54.09 AM.png

I was going to make a Smart Group based on the version. That if a version does not show blank, and does not show 'Not Installed', it should be installed. As it will show a version number.

mm2270
Legendary Contributor III

What you have there should work, if your goal is to show devices that do not have CS installed.

@mm2270 - Maybe how I did it is confusing, but my goal is quite the opposite. I want to show devices that DO have CS installed. Which is why the Operator is set to "is not" 'Not Installed' - A double negative, meaning, IS Installed.

mm2270
Legendary Contributor III

OK, yeah, I see that now. If you're using my "status" EA, it would show something like "connected" or "connecting" for devices with CS installed and it making connections back to the server. Maybe you could use that as a criteria. 

mm2270
Legendary Contributor III

The Crowdstrike EAs we use:

Crowdstrike Status:

#!/bin/sh

## Path to the falconctl binary
falconctl_path="/Applications/Falcon.app/Contents/Resources/falconctl"

if [ -e "$falconctl_path" ]; then
    cs_state=$("$falconctl_path" stats | awk '/State:/{print $NF}')
    echo "<result>${cs_state}</result>"
else
    echo "<result>Not Installed</result>"
fi

 

Crowdstrike Last Connection Date:

#!/bin/zsh

## Path to the falconctl binary
falconctl_path="/Applications/Falcon.app/Contents/Resources/falconctl"

## If the falconctl binary cannot be found, set result to Not Installed
if [ ! -e "$falconctl_path" ]; then
    /bin/echo "No falconctl located. Crowdstrike Falcon may not be installed"
    result="Not Installed"
fi

## Use the falconctl binary to get the last connection (Last Established) 
last_successful_checkin_raw=$("$falconctl_path" stats | awk '/Last Established At/{print $4,$5,$6,$8,$9}')

if [[ ! -z "$last_successful_checkin_raw" ]]; then
    last_successful_checkin_formatted=$(date -jf "%b %d, %Y %r" "$last_successful_checkin_raw" +"%Y-%m-%d %T")
    if [[ $? == "0" ]]; then
        result="$last_successful_checkin_formatted"
    else
        result="1970-01-01 00:00:00"
    fi
else
    result="1970-01-01 00:00:00"
fi

echo "<result>$result</result>"

 

Crowdstrike Customer ID:

#!/bin/zsh

## Path to falconctl
falconctl_path="/Applications/Falcon.app/Contents/Resources/falconctl"

if [ -e "$falconctl_path" ]; then
	customer_id=$("$falconctl" stats | awk '/customerID:/{print $NF}' 2>/dev/null)
else
	customer_id="unknown"
fi

/bin/echo "<result>$customer_id</result>"

 

Crowdstrike Version:

#!/bin/sh

## Path to falconctl
falconctl_path="/Applications/Falcon.app/Contents/Resources/falconctl"

if [ -e "$falconctl_path" ]; then
	cs_version=$("$falconctl_path" stats | awk '/version:/{print $NF}')
fi

if [ ! -z "$cs_version" ]; then
	echo "<result>$cs_version</result>"
else
	echo "<result>Not Installed</result>"
fi

 

These are probably about the same as some of the other ones posted on other threads. These, or the other ones should all work to my knowledge. These assume you're using a relatively up to date version of CS. A while back they used a different location for the binary to gather this information, but they moved on from that a while ago.

 

sdagley
Esteemed Contributor II

@mm2270 FYI you can request a specific subsection of the falconctl stats output (e.g. the labels with a === prefix and postfix), so to get the Communications specific data where you will find State: you can use:

/Applications/Falcon.app/Contents/Resources/falconctl stats Communications

 

Sorry for replying in two spots, but I just wanted to say that the Version EA that mm2270 posted is working for me! But for whatever reason yours (sdagley) did not work. I posted the script I was using of yours in a reply above.

 

Unfortunately this doesn't work. As stated above in a reply to user 'sdagley' - it works via a script through a policy, but not as an EA. 

mm2270
Legendary Contributor III

Thanks for that tip @sdagley ! I wasn't aware of that.

Hi @mm2270 - Your version and last connection date work quite well. But I am curious as to what the 'Status' EA is doing exactly? Is it showing whether or not the software is installed, or is checking for something else? I wanted a different EA that only shows whether it is installed or not. I needed to create a smart group to show Installed or Not installed based on some EA. I don't think I can use your Version one, because I'm not sure if it works through an integer or a string? Right now I have it set to string.

fotofojo
New Contributor III

I think I am in the same boat as you. We have several machines that CS is not seeing and I want to cross reference that with a Jamf Pro query that renders a installed/not installed value. While you state that you had luck with @mm2270 EA script, I have not. Most of the results I see this community page are very old, so probably aren't applicable any longer. Would love to know what I am doing wrong. Thanks

sdagley
Esteemed Contributor II

@mm2270 FYI it looks like CrowdStrike changed the subsection where connection status is displayed in version 6.58, and it's now under CloudInfo instead of Communications.