Kextpocalyse 2: The Remediation [Blog post by our own @franton)

donmontalvo
Esteemed Contributor III

@franton how on earth will we ever repay you?! Apple and Jamf should shower you with Bitcoins.

Kextpocalyse 2: The Remediation

1e359e66375f4bc09a86eb1e7d32be3e

What a way to quickly/easily inventory KEXTs on a computer...whether an OOB (baseline) or one with a bunch of stuff installed (to grow list of TeamID/BundleIDs).

--
https://donmontalvo.com
90 REPLIES 90

franton
Valued Contributor III

I went a stage further since I wrote that. This script will scan for kexts (excluding certain folders like /System) and generate the whitelist plist for you.

Glad you found it useful @donmontalvo !

#!/bin/bash

# Script to scan a system for kexts and gather the information needed for Apple whitelisting
# richard at richard - purves dot com

plist="com.apple.syspolicy.kernel-extension-policy.plist"
output="$HOME/Desktop"
override="false"

# Stop IFS linesplitting on spaces
OIFS=$IFS
IFS=$'
'

# Scan the drive to find 3rd party kexts
# Excluding /System /private ./StagedExtensions and /dev

echo "Searching your drive for kext files"
echo "This may take a while. Please wait ..."
echo "(please enter your password if prompted)"
paths=($( sudo find / ( -type d -name "System" -prune ) -o ( -type d -name "private" -prune ) -o ( -type d -name "StagedExtensions" -prune ) -o ( -type d -name "dev" -prune ) -o ( -name "*.kext" -type d -print ) ))

echo ""

# Report the details of all found

if [ ${#paths[@]} != "0" ];
then
    for (( loop=0; loop<${#paths[@]}; loop++ ))
    do
        # Get the Team Identifier for the kext
        teamid[$loop]=$( codesign -d -vvvv ${paths[$loop]} 2>&1 | grep "Authority=Developer ID Application:" | cut -d"(" -f2 | tr -d ")" )

        # Get the CFBundleIdentifier for the kext
        bundid[$loop]=$( defaults read "${paths[$loop]}"/Contents/Info.plist CFBundleIdentifier )

        echo "Team ID: ${teamid[$loop]}    Bundle ID: ${bundid[$loop]}"
    done
fi

echo ""

# Start to generate a plist file
echo "Processing Team IDs into xml"
echo ""

if [ ${#paths[@]} != "0" ];
then
    # Prune the duplicate ID's from the array
    nodupes=($( echo "${teamid[@]}" | tr ' ' '
' | sort -u ))

    # Now write out the xml with what we've discovered
    # Header first

echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>' > /private/tmp/tmp.xml

    # Start with the User Override
echo "<key>AllowUserOverrides</key>
<$override/>" >> /private/tmp/tmp.xml

    # Now the Team IDs

echo '<key>AllowedTeamIdentifiers</key>
<array>' >> /private/tmp/tmp.xml

    for (( loop=0; loop<${#nodupes[@]}; loop++ ))
    do
        # Write the team identifier to the file
        echo "<string>"${nodupes[$loop]}"</string>" >> /private/tmp/tmp.xml
    done

    # Now for the Bundle IDs with the Team IDs

echo '</array>
<key>AllowedKernelExtensions</key>
<dict>' >> /private/tmp/tmp.xml

    for (( loop=0; loop<${#nodupes[@]}; loop++ ));
    do
        # Write the team identifier to the file
        echo "<key>"${nodupes[$loop]}"</key>" >> /private/tmp/tmp.xml
        echo '<array>' >> /private/tmp/tmp.xml

        # Parse collected data to write out captured bundle ids that match to the team id
        for (( loopint; loopint<${#teamid[@]}; loopint++ ));
        do      
            if [ "${nodupes[$loop]}" = "${teamid[$loopint]}" ];
            then        
                echo "<string>${bundid[$loopint]}</string>" >> /private/tmp/tmp.xml
            fi
        done

        # Reset internal loop variable and close tags
        loopint=0
        echo '</array>' >> /private/tmp/tmp.xml
    done

    # Close up, we're done

    echo '</dict>
</dict>
</plist>' >> /private/tmp/tmp.xml

fi

# Now format the file nicely and rename

cat /private/tmp/tmp.xml | xmllint -format - > "$output/$plist"
rm /private/tmp/tmp.xml
cat "$output"/"$plist"

# Reset IFS and quit
IFS=$OIFS

exit

donmontalvo
Esteemed Contributor III

57e6abf1c93c48e288a450d4051cfb42

--
https://donmontalvo.com

ChristopherGlov
New Contributor III

Thanks!

ChristopherGlov
New Contributor III

optional image ALT text

dubel
New Contributor III

I tried this with 10.13.4 Beta, but I still get prompted to allowing Kext, can anyone share their work flow if they been successful with 10.13.4? My main KEXT are mcafee ENS and Cisco AnyConnect.

Thanks.

franton
Valued Contributor III

How did you generate the profile? How was it deployed? Is the device DEP or was it manually approved mdm if not?

A multitude of things we need to know before we can advise. Apple hasn't made this easy.

dubel
New Contributor III

@franton Thanks.

  1. On a standard 10.13.3 build with all my standard software installed (including Cisco AnyConnect and Mcafee ) I ran the http://www.richard-purves.com/2017/11/12/kextpocalyse-2-the-remediation/
  2. I created KEXT config profile with this custom plist then scoped it to my 10.13.4 machines.
  3. Rebuilt a clean 10.13.3 machine, updated to 10.13.4 beta 3
  4. Enrolled the new 10.13.4 into JSS 9.101 and bound to AD, verified KEXT Profile is installed
  5. Approved the MDM
  6. Installed my standard software for Mcafee and Cisco AnyConnect, still prompted to open System Preferences and allow those kernel extensions.

Thanks for your help, please let me know if I can provide any more information.

franton
Valued Contributor III

Try using the script above in this post. Also can you post the plist it has generated?

davidhiggs
Contributor III

@dubel I don't think JSS 9.101 supports this type of config profile, I believe it needs to come from an MDM that supports it's deployment, ie. JAMF Pro 10.2.1. I could have my facts wrong, anyone that can confirm?

And good work @franton !

dubel
New Contributor III

Thanks, the script above seems to be working better. I'm going to do a fresh rebuild and apply 10.13.4 Beta and verify.

I am running JSS 9.101, and below is my profile. Thanks again for the assistance. 254bd6c2c6f6430fab1297e53fbe793f

donmontalvo
Esteemed Contributor III

@dubel curious what you get on a computer you pushed the KEXT whitelist to when you run:

Run this to look at the KextPolicy database on your 10.13.x Mac:

sqlite3 /var/db/SystemPolicyConfiguration/KextPolicy

Run this to view approved KEXTs in the sqlite3 database:

SELECT * FROM kext_policy;

CONTROL-C to exit.

This should show what KEXTs have been approved on your Mac.

--
https://donmontalvo.com

donmontalvo
Esteemed Contributor III

Another option, thanks to @henryxyz, if you don't want to dive in to sqlite3, but you want to get a list of the approved KEXTs on your computer:

$ sqlite3 -header -csv /var/db/SystemPolicyConfiguration/KextPolicy "select team_id,bundle_id from kext_policy" > ~/Desktop/KEXT_test.txt

@franton not sure if this is helpful for what you're creating...as a post approval check?

--
https://donmontalvo.com

franton
Valued Contributor III

@donmontalvo I'm just capturing the complete list of everything on the machine.

dubel
New Contributor III

@franton

Here is the list:

sqlite> SELECT * FROM kext_policy;
DE8Y96K9QP|com.cisco.kext.acsock|1|Cisco|1
6HB5Y2QTA3|com.hp.kext.io.enabler.compound|1|HP Inc.|0
TDNYQP7VRK|com.cisco.amp.fileop|1|Cisco Systems, Inc.|1
TDNYQP7VRK|com.cisco.amp.nke|1|Cisco Systems, Inc.|1
GT8P3H7SPW|com.McAfee.FMPSysCore|1|McAfee, Inc.|5
GT8P3H7SPW|com.McAfee.AVKext|1|McAfee, Inc.|5
GT8P3H7SPW|com.McAfee.SFKext|1|McAfee, Inc.|5
GT8P3H7SPW|com.intelsecurity.FileCore|1|McAfee, Inc.|1

bazcurtis
New Contributor III

This is a fantastic post and thanks to @franton for all his work.

I'm a little confused. I have added this Configuration Profile and the machine applies it without a problem. The Kext still shows up in the Preferences as needing to be approved.

6b9213bc99eb429d802e616591b1d469

Have I missed something? Do I need a plist as well?

I also see this when I enroll a machine. I believe this is expected and my understanding is Kext can't be approved by the Configuration Profile unless the user says yes to this.

f2ac5edadd0945cabca68bb6f3891d77

Is there anyway around this? I am not using DEP at the moment.

Any advice will be most welcome.

franton
Valued Contributor III

Ok your Jamf profile is to whitelist individual kext files and that's generating the plist and profile for you. However the screen grab is something else entirely, the user approved mdm profile. For safety sake, getting people to click "approve" or finding a way to grandfather in enrolled devices.

bazcurtis
New Contributor III

Thanks for the quick response. So to be clear. Once the user approves my kext Configuration Profile should work. Do you expect the kext to disappear from the Preference Pane? Thanks again.

franton
Valued Contributor III

Like I said, they're two different things. User Approved MDM isn't the User Approved KEXT issue.

Kexts are approved in System Preferences -> Security & Privacy.

You're looking at the MDM profile and the approve button.

bazcurtis
New Contributor III

Yes, totally get that. While I was researching this, I found this Centrify KBA - https://centrify.force.com/support/Article/KB-9652-User-Approval-of-MDM-enrollment-introduced-with-macOS-High-Sierra-10-13-2/

It says - As of 10.13.2, the only MDM functionality that will be unavailable to a un-approved MDM enrollment is the ability to install the new (to 10.13.2) "Secure Kernel Extension Loading" payload. Centrify does not do 'Secure Kernel Extension Loading' in the MDM profiles.

I was just checking that to test properly I have to say approved to the MDM enrollment part, then my kext Configuration Profile should work and the kext approval notice in System Preferences -> Security & Privacy should go away.

I should then use the commands above to check it has been approved. When I was testing yesterday, the kext was still asking to be approved in System Preferences -> Security & Privacy, I had approved the MDM functionality. I didn't run the commands above to check if they were approved or not.

Is it safe to trust the System Preferences -> Security & Privacy GUI? If the approval has gone, we are good?

alexjdale
Valued Contributor III

One thing I want to call out because I haven't seen anyone mention it: user approvals of kexts are persistent and will survive a re-image of a macOS device. If you are testing whitelisting you might want to reset the NVRAM first to clear them out, or you might think the whitelisting is working when in fact the system is simply using a previous approval.

I just reimaged a test system with 10.13.4 and was wondering why I had no kext approval messages, and nothing listed in Security prefs. After resetting the NVRAM, it prompted me to approve our security app and the kext was listed in Security prefs.

Also, it does appear that whitelisting at the MDM level doesn't stop the Security pane from saying the kext was blocked. It still offers user approval.

donmontalvo
Esteemed Contributor III

#clicksLikeOnAllFrantonPostsOnThisThread

--
https://donmontalvo.com

bazcurtis
New Contributor III

Thanks Alex. That is good information. I am testing with a Fusion VM. Sorry if this is a silly question, but does a VM have NVRAM?

BenL
New Contributor III
Also, it does appear that whitelisting at the MDM level doesn't stop the Security pane from saying the kext was blocked. It still offers user approval.

This drove me nuts today, glad to see someone else has experienced it.

donmontalvo
Esteemed Contributor III

@alexjdale wrote:

One thing I want to call out because I haven't seen anyone mention it: user approvals of kexts are persistent and will survive a re-image of a macOS device. If you are testing whitelisting you might want to reset the NVRAM first to clear them out, or you might think the whitelisting is working when in fact the system is simply using a previous approval.

Stumbled upon that one here too, works for us if only to get more data gathered through multiple wipes in QA. :)

Also, it does appear that whitelisting at the MDM level doesn't stop the Security pane from saying the kext was blocked. It still offers user approval.

Is this still the case if the whitelist includes AllowUserOverrides=False?

--
https://donmontalvo.com

cdev
Contributor III

in theory I have a valid config profile being passed through Jamf for this payload, but on my lab machines, macOS is ignoring the configured payload and still prompting for every additional kext (Wacom drivers, VPN, security tools, etc.). I thought I had tracked the issue down to one extra tag, but even after fixing that and verifying the payload looks correct on the client, I'm still not seeing the effect applied. Any thoughts as to why?

alexjdale
Valued Contributor III

@cdev, Are you using a custom MDM payload? I could not get a custom MDM payload to work with kext whitelisting, even though it would install correctly. It had to be a native payload for the kernel extension policy, which means you need a version of JAMF that supports it.

I know some people have said they got it to work, but I don't believe it personally.

donmontalvo
Esteemed Contributor III

If you decide to whitelist TeamID only (ten character vendor ID string), you shouldn't get any prompts once Wacom's TeamID is whitelisted.

But if use even one BundleID (com.vendor.application.etc.), that TeamID will require every BundleID to be included else prompts.

The configuration profile should have a Preference Domain of com.apple.syspolicy.kernel-extension-policy but pretty sure everyone knows that.

We created a TeamID whitelist that seems to work fine, not sure why anyone would want to add BundleIDs to the Custom Configuraiotn Profile (rabbithole).

KEXT inventory data

--
https://donmontalvo.com

franton
Valued Contributor III

As I've found, a custom payload doesn't work for 10.13.4 onwards now. Annoying. However it did for 10.13.3 backwards.

My suggestion is to use my script or other methods to find the info, then create the profile within Jamf Pro.

franton
Valued Contributor III

Also Erik Gomez on the macadmins' slack posted this google drive link: Kext Google Docs

It's a user compiled list of all the "fun" kext info you could possibly want.

LovelessinSEA
Contributor II

@franton I've built out the following based on the Kext info i gathered from using your script (Thank you!). I've ran this on 10.13.4 machines but the Kernals are still showing up as needing to be approved. I just want to make sure that I'm entering all of the information correctly. Does the config need to be deployed to User level or Computer level?
a9e4451aa5384fdda7204524a8c3dc74

franton
Valued Contributor III

@LovelessinSEA I'm deploying at the computer level.

LovelessinSEA
Contributor II

For some reason I can't get the extensions to approve. I tried using the whole .plist that was generated by the script and deploying it in a configuration profile. No change to the approvals. I tried using the Approved kernal Extensions payload and adding one approved Kernal Extension at a time and they still aren't being approved.

Is everyone else seeing that the extension approval button is going away after the config profile is pushed to the device?

For Example, I have a machine that needs to have Crowdstrike Approved. I created An Approved Kernal Extension Payload
4e27bd9b67a64782bd3f149df3e90080

It doesn't seem to do anything though.

20101b6dca0d44ec89cfb37f397055a4

Am i missing something?

alexjdale
Valued Contributor III

Are the kernel extensions loaded? In my experience, the prefs pane would offer user-level approval even if the kext was MDM-whitelisted and loaded. kextstat can help you there.

jalcorn
Contributor II

same for me @LovelessinSEA

mrbauer1
New Contributor

@LovelessinSEA and @jalcorn can contact support at CrowdStrike? We've seen some cases where the application of the MDM policy has caused the mdmclient process to crash leaving to an odd state. Having a sysdiagnose from your machines would be very helpful.

LovelessinSEA
Contributor II

@mrbauer1 Thanks for the reply, yeah we reached out to them last week and they suggested creating a configuration profile with an approved white list. Also gave us the workaround if you get the dreaded Black screen with cursor. they had us remove the crowdstrike launch daemon in a safe mode boot.

Thanks again!

jalcorn
Contributor II

@mrbauer1 Im seeing it with ESET, i do not use crowedstrike

macbentosh
New Contributor III

@LovelessinSEA Crowdstrike is kinda lost on this issue too. I am using these 4 without issues

(u'X9E956P446', u'com.crowdstrike.sensor', 1, u'CrowdStrike Inc.', 8)
(u'X9E956P446', u'com.crowdstrike.libreactos', 1, u'CrowdStrike Inc.', 8)
(u'X9E956P446', u'com.crowdstrike.platform', 1, u'CrowdStrike Inc.', 8)
(u'X9E956P446', u'com.crowdstrike.TDB', 1, u'CrowdStrike Inc.', 8)

LovelessinSEA
Contributor II

@macbentosh thanks for these! Are you including all of the bundle ID's or are you just using the main Team ID of X9E956P446 in the Config profile?