!!! A Reliable Solution!!! for managing EFI Firmware Password on Mac Devices

kishoth_p
New Contributor II

Hi All,

After multiple research from GitHub's, stack overflow, JAMF nation blogs I was still unable to find a method to manage, verify & delete the EFI passwords on mac devices.

Not a Shell Script Expert, But still tried creating a in-house script with logical functions and finally achieved the desired result.

To all the admins out there who is seeking a seamless solution on EFI Firmware password management.

"Here goes your answer"

Step 1 - Setting a Random EFI Password on Intel based Mac
Set Random EFI Password.sh


#!/bin/bash

function logresult()    {
if [ $? = "0" ] ; then
echo "$1"
else
echo "$2"
exit 1
fi
}

# verify whether a firmware password is set
echo "Checking for existing firmware password"
checkFirmwarePassword=$( /usr/sbin/firmwarepasswd -check )

# if a firmware password is already set, stop the script and report failure in Jamf Pro
if [ "$checkFirmwarePassword" != "Password Enabled: No" ] | [ -d /private/tmp/.fp ]; then
    echo "A firmware password is already set. Doing nothing."
    exit 0
else
    echo "No firmware password set"
fi

# create obscure directory
fpdirectory="/private/var/.fp"
/bin/mkdir -p "$fpdirectory"
logresult "Creating "$fpdirectory" directory" "Failed creating "$fpdirectory" directory"

# generate random password
randpassword=$( /usr/bin/openssl rand -hex 6 )
logresult "Generating 8-character firmware passcode: $randpassword" "Failed generating 8-character firmware passcode."

# write random password to temporary file
/usr/bin/touch "$fpdirectory/$randpassword"
logresult "Writing password to file "$fpdirectory/$randpassword"" "Failed writing password to file "$fpdirectory/$randpassword""

# update Jamf Pro computer record with firmware password and set only if inventory was updated
/usr/local/bin/jamf recon && /usr/local/bin/jamf setOFP -mode command -password "$randpassword"

# set the firmware password only after a successful inventory update to Jamf Pro
if [ $? = "0" ]; then
echo "Updating Jamf Pro inventory to upload firmware password"
echo "Setting firmware password"
exit 0
else
echo "Failed setting firmware password"
exit 1
fi

Step 2 - Create a Policy and include Restart Options with "Restart Immediately" trigger for the changes to take effect post successful run of Set Random EFI Password.sh

Step 3 - Create a EA to display the EFI password applied

#!/bin/bash
echo "<result>$( ls /private/var/.fp | sort -V )</result>"
exit 0

Note:- Once the EFI password is set, it will write the set EFI password to the following directory /private/var/.fp where .fp is hidden folder


Decommissioning Process - (During unenrollment, ownership transfers & hardware replacements)

Step 1 - Automated EFI Password Deletion Script
EFI Password Deletion.sh


#!/bin/bash

#For Loop to Fetch all the passwords stored in /private/var/.fp folder
if [ -d "/private/var/.fp" ]; then
efipasswordslist=$(ls /private/var/.fp)
for i in $(ls /private/var/.fp)
do
/usr/bin/expect<<EOF
#This removes the current EFI password set on a mac    
spawn firmwarepasswd -delete
expect {
"Enter password:" {
send "$i
"
expect -re {
(S+orrect)}
set result $expect_out(1,string)
}
}
EOF
done
#Removes the .fp folder and its associated old passwords
rm -r /private/var/.fp

#Jamf Inventory Update
jamf recon

else echo "Folder doesn't exist"
fi
exit 0

Step 2 - Create a Policy and include Restart Options with "Restart Immediately" trigger for the changes to take effect post successful run of EFI Password Deletion.sh


Verification Process (This is to avoid duplicate passwords stored during failed/reattempted run of **Set Random EFI Password.sh** Script)

Step 1 - Automated EFI Password Verification Script
EFI Password Verification.sh


#!/bin/bash

EFIVerified=""

# This will verify the EFI password {Correct | Incorrect}
function verifyEFIPassword(){
arg=$1
export efiPwd=$arg

EFIVerified="$(expect <<'Done'
log_user 0
spawn firmwarepasswd -verify
expect "Enter password:"
send -- $env(efiPwd)
send -- "
"
expect -re {
(S+orrect)}
set result $expect_out(1,string)
log_user 1
puts $result    
)"
}
# Looping through EFI passwords located at /private/var/.fp/ hidden folder
for i in $(ls /private/var/.fp)
do
# Calling verifyEFIPassword function by providing each password    
verifyEFIPassword $i
if [ "$EFIVerified" = "Incorrect" ]; then
echo "Deleting Incorrect EFIPassword $i"
# This will remove the incorrect passwords located at /private/var/.fp/ hidden folder           
rm /private/var/.fp/$i
fi
if [ "$EFIVerified" = "Correct" ]; then
echo "Verified the Correct EFIPassword $i"
fi
done

#Jamf Inventory Update
jamf recon

exit 0

Note:- This entire solution works seamlessly if you have set the EFI password by using **Set Random EFI Password.sh** script. It doesn't work on any customised environment where the EFI passwords are set differently.

I would recommended to apply this seamless solution in your environment and give me a thumbs up if it works as expected without any failures.

Do post me if you have any queries, I will be happy to answer those.

Regards,
Kishoth P
Stay Safe! Stay Healthy!

3 REPLIES 3

sdagley
Honored Contributor II

@kishoth.p If you use the Code Block tag of ``` (triple back-tick) before and after your script it will prevent the forum software from mangling it.

kishoth_p
New Contributor II

@sdagley - Noted! I was not aware it will cause crumple. I will be rest assured next time to update correctly. Thanks!!!

bradtchapman
Valued Contributor

Your scripts are awesome and you clearly put a lot of effort into this. You should also consider that this method of setting and storing a firmware password might not pass security review because it fails a principle known as “security through obscurity.” Hiding the file doesn’t mean people won’t find it (or try), and then the data is compromised.

At minimum, you should use chmod 000 /path/to/.hiddenfile to ensure that no one can casually find or read it. (technically root / sudo can overwrite and read it anyway, which would be defeated by a local admin).

Another technique to secure data is “obfuscation.” If you encode the password using a known secret, such as hashing it with the computer serial number, it can be stored safely without anyone guessing what it might be. edit: sorry, I was looking at this on mobile and the code window was so narrow I couldn’t see the random line.

One way to vastly improve the security of this password is to not store it on the device, and instead use the Jamf API to read / write the contents of an EA.

It would be even more awesome if Jamf had a way to restrict visibility of this EA, so be advised that the firmware password might be visible to anyone in the Jamf Console that is allowed to read EA’s and computer records.

I would also love to put the idea out there that it would be great if Jamf had a “restricted” flag for extension attributes that required a higher level of privilege to view. The only data that have this level of protection right now are filevault keys and activation lock bypass codes.