Menu Close

CrowdStrike Falcon Kickstart (0.0.2)

(Hopefully) automate the remediation of sideways Falcon installations

Background

During the initial phases of our CrowdStrike Falcon pilot, we discovered a surprising number of sideways installations which were reporting the seemingly dreaded: Error while accessing Falcon service.

As we developed a “kickstart” script to (hopefully) automate the remediation, we’d occasionally observe the following error:

falconBinary="/Applications/Falcon.app/Contents/Resources/falconctl"
$falconBinary stats agent_info | awk '/Sensor operational:/{print $3}'
/Applications/Falcon.app/Contents/Resources/falconctl: line 5: 20933 Killed: 9 ../MacOS/Falcon --ctl $PARAMS

We enhanced our kickstart script to first validate the Configuration Profile-defined ccid and working with CrowdStrike Support, we also added a licensing step for good measure.

Results

If there’s any silver lining in the sideways installation cloud, it’s that a Maintenance Token doesn’t appear to be required to uninstall via ${falconBinary} uninstall -verbose.

In less than 18 hours, we were able to reduce the number of sideways installations from 13 percent to well less than 1 percent. (This exercise also helped us to better detect sideways MDM enrollments.)

Script

The following script presumes:

  • Prior implementation of the CrowdStrike Falcon Tags script
  • Prior implementation of the bonus hack (since Falcon doesn’t store its preferences in the standard /Library/Preferences/ directory)
  • A Jamf Pro Policy to re-install CrowdStrike Falcon with a Custom Trigger of crowdStrikeFalcon
csf-Kickstart.bash
#!/bin/bash

####################################################################################################
#
#   CrowdStrike Falcon Kickstart
#
#   Purpose: Load CrowdStrike Falcon's Sensor
#
####################################################################################################
#
# HISTORY
#
# Version 0.0.1, 28-Feb-2023, Dan K. Snelson (@dan-snelson)
#   Original version
#
# Version 0.0.2, 10-Mar-2023, Dan K. Snelson (@dan-snelson)
#   Added licensing step
#
####################################################################################################



####################################################################################################
#
# Variables
#
####################################################################################################

scriptVersion="0.0.2"
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin/
falconBinary="/Applications/Falcon.app/Contents/Resources/falconctl"
scriptLog="${4:-"/var/log/com.company.log"}"    # Parameter 4: Full path to your company's client-side log
exitCode="0"



####################################################################################################
#
# Pre-flight Checks
#
####################################################################################################

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Client-side Logging
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ ! -f "${scriptLog}" ]]; then
    touch "${scriptLog}"
fi



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Client-side Script Logging Function
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

function updateScriptLog() {
    echo -e "$( date +%Y-%m-%d\ %H:%M:%S ) - ${1}" | tee -a "${scriptLog}"
}



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Logging Preamble
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

updateScriptLog "\n\n###\n# CrowdStrike Falcon Kickstart (${scriptVersion})\n###\n"
updateScriptLog "PRE-FLIGHT CHECK: Initiating …"



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Confirm script is running as root
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ $(id -u) -ne 0 ]]; then
    updateScriptLog "PRE-FLIGHT CHECK: This script must be run as root; exiting."
    exit 1
fi



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Confirm CrowdStrike Falcon is installed
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ -f "${falconBinary}" ]]; then
    updateScriptLog "PRE-FLIGHT CHECK: CrowdStrike Falcon installed; proceeding …"
else
    updateScriptLog "PRE-FLIGHT CHECK: CrowdStrike Falcon NOT found; exiting."
    exit 1
fi



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Confirm CrowdStrike Falcon CCID
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

ccidTest=$( defaults read "/Library/Preferences/com.crowdstrike.falcon.plist" ccid 2>&1 )
if [[ "${ccidTest}" == *"does not exist"* ]]; then
    updateScriptLog "PRE-FLIGHT CHECK: CrowdStrike Falcon CCID NOT found; exiting."
    exit 1
else
    updateScriptLog "PRE-FLIGHT CHECK: CrowdStrike Falcon CCID found; proceeding …"
fi



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Confirm CrowdStrike Falcon System Extension is running
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

systemExtensionTest=$( systemextensionsctl list | grep -o "com.crowdstrike.falcon.Agent.*" | cut -f2- -d" " )
if [[ -n "${systemExtensionTest}" ]]; then
    systemExtensionStatus="${systemExtensionTest}"
else
    systemExtensionStatus="Not Found"
fi

updateScriptLog "PRE-FLIGHT CHECK: CrowdStrike Falcon System Extension Status:"
updateScriptLog "${systemExtensionStatus}"



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Pre-flight Check: Complete
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

updateScriptLog "PRE-FLIGHT CHECK: Complete"



####################################################################################################
#
# Program
#
####################################################################################################

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Process CrowdStrike Falcon System Extension Status
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

updateScriptLog "Processing System Extension Status …"

case ${systemExtensionStatus} in

    *"[activated enabled]"* )
        updateScriptLog "CrowdStrike Falcon System Extension enabled"

        updateScriptLog "Validating Sensor Operation …"
        sensorOperationalStatus=$( $falconBinary stats agent_info | awk '/Sensor operational:/{print $3}' )

        if [[ "${sensorOperationalStatus}" == "true" ]]; then

            updateScriptLog "Falcon Sensor Operational: ${sensorOperationalStatus}"
            updateScriptLog "Updating inventory …"
            jamf recon
            exitCode="0"

        else

            updateScriptLog "Attempting to kickstart Falcon Sensor …"

            falconKickStartLicense=$( ${falconBinary} license "$( defaults read /Library/Managed\ Preferences/com.crowdstrike.falcon.plist ccid )" --noload --verbose)
            updateScriptLog "Falcon Kickstart License Result: ${falconKickStartLicense}"

            falconKickStartLoad=$( ${falconBinary} load -verbose )
            updateScriptLog "Falcon Kickstart Load Result: ${falconKickStartLoad}"

            if [[ "${falconKickStartLoad}" == "Falcon sensor is loaded" ]]; then

                sensorOperationalStatus=$( $falconBinary stats agent_info | awk '/Sensor operational:/{print $3}' )

                if [[ "${sensorOperationalStatus}" == "true" ]]; then

                    updateScriptLog "Falcon Sensor Operational: ${sensorOperationalStatus}"
                    updateScriptLog "Updating inventory …"
                    jamf recon
                    exitCode="0"

                fi

            else

                exitCode="1"

            fi

            exitCode="0"

        fi
        ;;

    "Not Found" )

        updateScriptLog "CrowdStrike Falcon System Extension NOT found"

        updateScriptLog "Attempting re-installation …"
        falconKickStartUninstall=$( ${falconBinary} uninstall -verbose )
        updateScriptLog "Falcon Kickstart Uninstall Result: ${falconKickStartUninstall}"

        updateScriptLog "Updating computer inventory …"
        jamf recon

        updateScriptLog "Re-installing CrowdStrike Falcon …"
        jamf policy -trigger crowdStrikeFalcon

        exitCode="1"
        ;;

    * )
        updateScriptLog "Code for 'Catch-all' goes here"
        exitCode="1"
        ;;

esac



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Exit
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

updateScriptLog "Exit Code: ${exitCode}"

exit "${exitCode}"
Posted in CrowdStrike Falcon, Jamf Pro, Scripts, Tips & Tricks

Related Posts