Since Mojave (10.14), Hardened Runtime has been introduced to bring global Library Validation enforcement, which prohibits dynamic libraries without valid code signature from the same developer or Apple from being loaded.
Some entitlements can mark an executable as an exception.
So when an executable has any one of these entitlements, it implies that this process is designed to load third-party libraries. This leads me to these interesting persistence vectors on macOS.
This daemon (/usr/libexec/dspluginhelperd) is for loading 3rd-party DirectoryService plugins. It launches on each system boot, and automatically reloads after crash.
In function CPluginHandler::LoadPlugins, it scans bundles that match
/Library/DirectoryServices/PlugIns/*.dsplug and execute them. Since this process has root privilege and no sandbox at all, it is a powerful place to put persistence payload.
/Library/DirectoryServices/Plugins requires root privilege to write. The malware must either trick user to input administrator password or exploit a privilege escalation bug.
ObjectiveSee’s KnockKnock v2.1 has introduced detection for this persistence vector.
You must be familiar with it because this service has just been exploited in this year’s TyphoonPwn for userspace sandbox escape on iOS.
It loads plugins (recursively search for child directories) from three locations:
- /Library/Audio/MIDI Drivers/**/*.plugin
- ~/Library/Audio/MIDI Drivers/**/*.plugin
This agent does not set
YES, and system built-in LaunchAgents is readonly, so we need to write a new launch agent entry in
~/Library/LaunchAgents/whatever.plist. Since launchd also supports setting environment string in the plist, we can use an alternative path for HOME directory. This vector does not require root privilege.
It can not hide itself from persistence detection softwares like KnockKnock. But after all, this executable is 100% valid signed by Apple.
Since we’ve talked about the recent bug reports for MIDIServer:
Could this be a persistence method on iOS?
AMFI on iOS is slightly different than macOS. Actually, iOS does not care about
com.apple.security.cs.disable-library-validation at all :(
On the other hand, Apple has introduced a new sandbox profile on iOS 13 to reduce its attack surface. But on macOS, sandbox profile named MIDIServer is nowhere to be found. Then it is like:
So this executable has one entitlement that does not work on iOS, and another one does not work on macOS 😢
On 10.15.1 there are about 30+ executables possessing this entitlement. I only analyzed some of them and found these two nice example.
You may also refer to other vectors like QuickLook plugins: https://github.com/theevilbit/macos/tree/master/PersistentQL
Less ideal because they are sandboxed.