Skip to main content

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



Kextpocalyse 2: The Remediation





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).

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


Thanks!


optional image ALT text


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.


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.


@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.


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


@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 !


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.


@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.


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?


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


@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


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.





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.





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



Any advice will be most welcome.


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.


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.


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.


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?


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.


#clicksLikeOnAllFrantonPostsOnThisThread


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?


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.


@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?


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?