Persistent Credential Theft with Authorization Plugins Archived: 2026-04-06 02:01:32 UTC Credential theft is often one of the first tactics leveraged by attackers once they’ve escalated privileges on a victim’s machine. Credential theft on OSX has become more difficult with the introduction of System Integrity Protection (SIP). Attackers can no longer use methods such as extracting the master keys from the securityd process and decrypting the victim’s login keychain. An example of this can be seen here. SIP prevents any user (even root) from modifying system files, directories, and processes. This might lead an attacker to use other methods for credential theft including keylogging, prompting the user for credentials, or triaging the local file system for plaintext credentials. However, there is another alternative called authorization plugins. Authorization plugins are used to extend the authorization services API and implement mechanisms that are not natively supported by the OS. A legitimate use case would be implementing multi-factor authentication with 3rd party software such as Duo. Each plugin can have several mechanisms, or functions contained within the plugin that implement custom logic to perform authorization. These mechanisms are also present in the policy database. This database contains definitions for various authorization rights. The definition for a particular authorization right can reference several mechanisms, each paired with their corresponding authorization plugin. Apple briefly describes how this works during the logon process here. Essentially, the loginwindow process tries to obtain the system.login.console right. The definition in the policy database lists several mechanisms that are executed when this happens. A custom plugin, along with its mechanism, can be inserted into this list. The position of the entry in this list will determine when it will be executed and should be determined based on how the plugin will interact with the OS during the logon process. Additionally, a plugin can be configured to run in a privileged or un-privileged context. This is indicated by the entry string within the policy database. For privileged execution, “,privileged” will need to be appended to the mechanism entry. An author may choose to use an unprivileged plugin if they wish to access the UI and present a prompt to the user. Additional information on plugin context issues can be found here. An interesting (especially for attackers) feature of authorization plugins is the ability to pass context values between plugins. These values contain important details about the user, including, the home directory, uid, and even the password in clear-text. This feature exists so that developers who wish to utilize both a privileged and un-privileged plugin, can share data between the two in a relatively easy way. Authorization plugins are an ideal credential theft and persistence mechanism for attackers. Persistent credential theft with the ability to execute code at any point during the login process is invaluable. Installing an authorization plugin is a relatively easy process, which we’ll cover in the next section. Installation Authorization plugins are comprised of two components; the bundle file that contains all of the plugins code, on disk, and an entry into the authorization database. The authorization database is used by the security server to authorize specific rights for a given user, based on rules/policies contained within the database. Applications may change the rules at any given time using the AuthorizationRightSet, AuthorizationRightGet, and https://xorrior.com/persistent-credential-theft/ Page 1 of 4 AuthorizationRightRemove API calls. When adding an entry to the database, the AuthorizationRightSet function should be called with a reference to a NSDictionary containing keys and values for each authentication mechanism. An example is shown in the Apple documentation here. Alternatively, the AuthorizationRightGet function can be used to obtain the NSDictionary value for an existing right. Then modify the dictionary and add an entry for the custom authorization plugin using the AuthorizationRightSet function. A python example of this can be seen here. The authorization database can also be modified via the security command line tool. If an attacker wanted to add a malicious plugin to the system.login.console policy, they would need to first read the policy from the authorization database into a plist file: security authorizationdb read system.login.console >> system.login.console.plist Then insert their bundle as one of the mechanisms in the following format: [Plugin Name]:auth,privileged PlistBuddy can also do this with the following command: /usr/libexec/PlistBuddy -c “add :mechanisms:[HomeDir Offset] string [bundlename]:login,privileged”