joshua-d-miller / macOSLAPS

Swift binary that will change a local administrator password to a random generated password. Similar behavior to LAPS for Windows
MIT License
387 stars 58 forks source link

Unable to unlock Filevault with LAPS Admin #106

Open mruepp opened 4 months ago

mruepp commented 4 months ago

We try to roll out LAPS Admin & macOSLAPS on our Intune Managed Machines. We create a Smartcard enforced config but we exclude unmapped users.

So the flow is: Local User enrollment -> LAPS Admin created through MDM with random password -> macLAPS gets installed MDM -> Custom Attribute should show LAPS Password

Our enrollment User is the first to be assigned the Secure Token and the only one to login interactively. The LAPS Admin gets created later in the process. Never would someone interactively login to the LAPS Admin account except breaking glass is necessary.

We can not unlock Filevault in the Bootprocess with the LAPS Admin, even if we manually rotate the password using sudo /usr/local/laps/macOSLAPS -resetPassword

Our macLAPS Config looks like this:

    <key>DaysTillExpiration</key>
    <integer>30</integer>
    <key>LocalAdminAccount</key>
    <string>lapsadmin</string>
    <key>PasswordLength</key>
    <integer>14</integer>
    <key>PasswordGrouping</key>
    <integer>6</integer>
    <key>PasswordSeparator</key>
    <string>-</string>
    <key>RemovePassChars</key>
    <string>{}[]|</string>
    <key>Method</key>
    <string>Local</string>
    <key>PasswordRequirements</key>
        <dict>
            <key>Lowercase</key>
            <integer>1</integer>
            <key>Uppercase</key>
            <integer>1</integer>
            <key>Number</key>
            <integer>1</integer>
            <key>Symbol</key>
            <integer>1</integer>
        </dict>

Our initial Password creation snippet looks like this, we create a random password and we use this script to create Admin through MDM

echo "Creating new local admin account [$adminaccountname]"
p=`cat /dev/urandom | base64 | tr -dc '0-9a-zA-Z' | head -c14 | base64`

We use this script to record the password as custom attribute.

#!/bin/zsh
: '
-------------------------
| macOSLAPS EA Combined |
-------------------------
| Captures the Password and Expiration from the files
| outputted to the filesystem and sends the results
| to jamf in the following format:
|     | Password: PasswordHere | Expiration: ExpirationHere |
------------------------------------------------------------
| Created: James Smith - https://github.com/smithjw
| Last Update By: Joshua D. Miller - josh.miller@outlook.com
| Last Update Date: January 29, 2023
------------------------------------------------------------
'
### -------------------- ###
### | Global Variables | ###
### -------------------- ###
## Path to macOSLAPS binary ##
LAPS=/usr/local/laps/macOSLAPS
## Path to Password File ##
PW_FILE="/var/root/Library/Application Support/macOSLAPS-password"
## Path to Expiration File ##
EXP_FILE="/var/root/Library/Application Support/macOSLAPS-expiration"
## Local Admin Account ##
LOCAL_ADMIN=$(/usr/bin/defaults read \
    "/Library/Managed Preferences/edu.psu.macoslaps.plist" LocalAdminAccount)
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #
### ----------------------- ###
### | Verify Requirements | ###
### ----------------------- ###
verify_requirements () {
    ## Does the binary exist ##
    if [ ! -e $LAPS ]
    then
        /bin/echo "macOSLAPS Not Installed"
        return
    fi
    ## Verify Local Admin Specified Exists ##
    if id "$1" &> /dev/null
    then
        /bin/echo "Yes"
    else
        /bin/echo "Account Not Found"
    fi
    return
}
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #
### ----------------- ###
### | Main Function | ###
### ----------------- ###
## Determine if macOSLAPS itself exits and the local admin account is present ##
VERIFIED=$(verify_requirements "$LOCAL_ADMIN")
## If we have verified LAPS and the Account ##
if [[ "$VERIFIED" == "Yes" ]]
then
    ## Ask macOSLAPS to write out the current password to the system keychain
    $LAPS -getPassword > /dev/null
    SERVICE_NAME=$(/bin/cat /var/root/.GeneratedLAPSServiceName)
    CURRENT_PASSWORD=$(/usr/bin/security find-generic-password -s "$SERVICE_NAME" -w 2&> /dev/null)
    CURRENT_EXPIRATION=$(/usr/bin/security find-generic-password -s "$SERVICE_NAME" | /usr/bin/grep -Eo "\d{4}-\d{2}-\d{2}.*\d")
    ## Test $current_password to ensure there is a value
    if [ -z "$CURRENT_PASSWORD" ]
    then
        ## Don't Write anything to jamf as it might overwrite an
        ## old password in place that might still be needed
        exit 0
    else
        /bin/echo "Password: $CURRENT_PASSWORD | Expiration: $CURRENT_EXPIRATION"
        ## Run macOSLAPS a second time to remove the password export entry from the system keychain
        $LAPS > /dev/null
    fi
## Otherwise ##
else
    echo "<result>Not Installed</result>"
fi

exit 0

Is there something I miss? So the goal would be to have a breaking glass local admin user with regular password rotation write back as custom attribute to our MDM which allows us to circumvent the Smartcard only login on boot with File Vault.

Thanks,

Michael

joshua-d-miller commented 4 months ago

Hello @mruepp,

Due to the way you are creating your account it may or may not have what is called a secureToken. That particular piece is vital to being able to unlock FileVault. Accounts created with Setup Assistant receive this automatically. Since you are creating outside of Setup Assistant you may not have a secureToken or be listed as a volume owner. You can verify that on the device with this command. sysadminctl -secureTokenStatus usernamehere which will produce the following if enabled.

2024-07-25 08:53:24.446 sysadminctl[35601:822344] Secure token is ENABLED for user Joshua D. Miller

If that shows as DISABLED then your account does not have the ability to unlock FileVault. I'm not too familiar with the way Setup Assistant works for macOS in InTune but I believe you can create a local admin account with InTune which during Setup Assistant would give the account a secureToken. Let me know if this information was helpful.

Thanks!

GPAEALandon commented 3 months ago

@joshua-d-miller Intune unfortunately does not currently create an Admin account during ADE like other MDMs do, although it is on the roadmap. They've got it partly implemented as now the username and full name fields can be auto populated and aren't editable.

@mruepp I haven't found any solution I especially like yet in my environment (education). The least headache: I have staff come in for white-gloved enrollment with user affinity. I create the first user for admin and securetoken, then create their account.

I've tried letting some staff enroll themselves zero-touch and delayed enabling FileVault until after the admin account was created by script. I was also demoting the staff accounts to standard which was a fun headache. A standard user with securetoken can't grant it to another account, it has to be an admin with securetoken.

joshua-d-miller commented 4 weeks ago

So from what I can tell this appears to be a known issue with InTune and the way it creates the account as it does not grant the user a secureToken. While I'm not sure how we can work around this at this time I'm thinking for now we can at least note this in the Wiki. I'm gonna write some pages about InTune hopefully this week.