Using Squish to automate macOS applications built with the 'Hardened Runtime'

Last edited on

What is a Hardened Runtime AUT?

macOS 10.14 and Xcode 10 introduce a new features called ‘Hardened Runtime’. This is intended as enhancing the security of applications by disabling/disallowing various kinds of loading executable code into the AUT that has not been developed by the original authors of the application.

It effectively disables various features commonly exploited for security breaches.

The exact set of features (Apple calls them ‘entitlements’) is configured when compiling the application. See the Apple page on Hardened Runtime Entitlements on how to do this.

Which entitlements Squish needs

To make Squish work, two entitlements need to be checked:

This affects both Squish for Qt and Squish for macOS since they’re using the same mechanism for non-intrusive hooking. With Squish for Qt, an alternative may be using the builtin hook and code-signing all Squish libraries that are being loaded into the AUT with your own certificate.

How to tell if an AUT is hardened?

First, Squish will be unable to attach to your AUT. If you are unable to ask the developer, it is possible to check using command line tools provided by xCode. First, make sure xCode is installed with the command line tools, and issue the following command,using the path to your own AUT instead of TextEdit.app.

codesign -d -vv /Applications/TextEdit.app

This command produces an output that looks something like this:

Executable=/Applications/TextEdit.app/Contents/MacOS/TextEdit
Identifier=com.apple.TextEdit
Format=app bundle with Mach-O thin (x86_64)
CodeDirectory v=20100 size=1475 flags=0x0(none) hashes=39+5 location=embedded
Platform identifier=7
Signature size=4485
Authority=Software Signing
Authority=Apple Code Signing Certification Authority
Authority=Apple Root CA
Info.plist entries=33
TeamIdentifier=not set
Sealed Resources version=2 rules=13 files=479
Internal requirements count=1 size=68

In the output look for the line starting with ‘CodeDirectory’. The flags entry indicates which flags have been enabled. If the ‘runtime’ flag (0x10000) is present that means the application uses the hardened runtime feature. If it is not set - like in the example output above - the application does not use the hardened runtime.

To find out which entitlements are already enabled in your AUT, you can execute a command like this:

codesign -d --entitlement - /Applications/TextEdit.app

This produces output in the form of a plist file that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.application-identifier</key>
	<string>com.apple.TextEdit</string>
	<key>com.apple.developer.ubiquity-container-identifiers</key>
	<array>
		<string>com.apple.TextEdit</string>
	</array>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.files.user-selected.executable</key>
	<true/>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
	<key>com.apple.security.print</key>
	<true/>
</dict>
</plist>

In this output, check if the keys com.apple.security.cs.disable-library-validation and com.apple.security.cs.allow-dyld-environment-variables exist and are set to true. If they’re missing or set to false hooking with Squish will fail.

Code-Signing to add entitlements

With XCode, it is possible to sign an executable manually, with your own developer certificate, to give it new entitlements.The links below explain how: