Login Hook
Adversaries may use a Login Hook to establish persistence executed upon user logon on macOS. A login hook is a plist file that points to a specific script to execute with root privileges upon user logon. The plist file is located at /Library/Preferences/com.apple.loginwindow.plist and can be modified using the defaults command-line utility. Login hooks (LoginHook key) and logout hooks (LogoutHook key) both require administrator permissions to modify. Adversaries insert a path to a malicious script into the plist, which executes upon the next user login. Only one login and one logout hook can exist on a system at a time. Note: Login hooks were deprecated in macOS 10.11 in favor of Launch Daemons and Launch Agents, but they continue to function on newer systems.
// Detection for T1037.002 - macOS Login Hook via Syslog/CommonSecurityLog ingested into Sentinel
// Covers: defaults write to loginwindow plist, direct plist modification, and suspicious script execution at login
let LoginHookPaths = dynamic([
"/Library/Preferences/com.apple.loginwindow.plist",
"com.apple.loginwindow"
]);
let LoginHookKeys = dynamic([
"LoginHook",
"LogoutHook"
]);
// Detection 1: Process events showing 'defaults' command modifying loginwindow plist
let DefaultsModification = Syslog
| where TimeGenerated > ago(24h)
| where SyslogMessage has "defaults" and SyslogMessage has "com.apple.loginwindow"
| where SyslogMessage has_any ("LoginHook", "LogoutHook")
| extend CommandLine = extract(@"defaults\s+.+", 0, SyslogMessage)
| extend HookType = iff(SyslogMessage has "LoginHook", "LoginHook", "LogoutHook")
| extend ScriptPath = extract(@"(LoginHook|LogoutHook)\s+([/\w\-.]+)", 2, SyslogMessage)
| project TimeGenerated, Computer, SyslogMessage, CommandLine, HookType, ScriptPath,
HostName, ProcessName
| extend DetectionType = "defaults_write_loginwindow";
// Detection 2: Direct file write to loginwindow plist
let PlistFileWrite = Syslog
| where TimeGenerated > ago(24h)
| where SyslogMessage has "/Library/Preferences/com.apple.loginwindow.plist"
| where SyslogMessage has_any ("write", "open", "create", "truncate", "rename")
| project TimeGenerated, Computer, SyslogMessage, HostName, ProcessName
| extend DetectionType = "plist_file_modification"
| extend HookType = "unknown"
| extend ScriptPath = ""
| extend CommandLine = SyslogMessage;
// Detection 3: CommonSecurityLog (CEF) from macOS endpoint agents
let CEFLoginHook = CommonSecurityLog
| where TimeGenerated > ago(24h)
| where DeviceEventClassID in ("process_create", "file_write", "file_create")
| where RequestURL has_any (LoginHookPaths) or Message has_any (LoginHookKeys)
| extend CommandLine = RequestURL
| extend HookType = iff(Message has "LoginHook", "LoginHook", iff(Message has "LogoutHook", "LogoutHook", "unknown"))
| extend ScriptPath = extract(@"(LoginHook|LogoutHook)[\s=]+([/\w\-.]+)", 2, Message)
| project TimeGenerated, Computer = DeviceName, SyslogMessage = Message, CommandLine,
HookType, ScriptPath, HostName = DeviceName, ProcessName = SourceProcessName
| extend DetectionType = "cef_endpoint_agent";
// Union all detections
DefaultsModification
| union CEFLoginHook
| union PlistFileWrite
| sort by TimeGenerated desc Data Sources
Required Tables
False Positives
- MDM solutions (Jamf Pro, Mosyle, Kandji) legitimately writing LoginHook entries as part of managed configuration profiles and onboarding workflows
- IT administrators manually configuring login scripts for legitimate enterprise purposes such as drive mapping or authentication setup
- Security software or compliance agents that use login hooks for startup checks on older macOS versions (pre-10.11)
- Migration scripts or imaging tools that configure loginwindow plist as part of macOS system setup or re-imaging processes
References (9)
- https://attack.mitre.org/techniques/T1037/002/
- https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CustomLogin.html
- https://developer.apple.com/documentation/devicemanagement/loginwindowscripts
- https://www.sentinelone.com/blog/how-malware-persists-on-macos/
- https://taomm.org/PDFs/vol1/CH%200x02%20Persistence.pdf
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1037.002/T1037.002.md
- https://objective-see.org/blog.html
- https://ss64.com/osx/defaults.html
- https://support.apple.com/en-us/HT203539
Unlock Pro Content
Get the full detection package for T1037.002 including response playbook, investigation guide, and atomic red team tests.