Slide 1

Slide 1 text

Job(s) Bless Us! Privileged Operations on macOS

Slide 2

Slide 2 text

@aronskaya WWC Kyiv macOS Chapter Lead Software Engineer, Anti-malware team, Triage team iaronskaya

Slide 3

Slide 3 text

Agenda Intro to privileged operations API on macOS First CleanMyMac's security issue, reported by CleanMyMac on Comparison of privileged operations implementation on and Summary & Takeaways

Slide 4

Slide 4 text

Intro to privileged operations API on macOS Intro

Slide 5

Slide 5 text

High-level APIs SMJobBless() AuthorizationExecuteWithPrivileges() Intro

Slide 6

Slide 6 text

High-level APIs SMJobBless() AuthorizationExecuteWithPrivileges() Intro

Slide 7

Slide 7 text

High-level APIs SMJobBless() AuthorizationExecuteWithPrivileges() Intro

Slide 8

Slide 8 text

Intro There is no ‘UnBless’

Slide 9

Slide 9 text

Signing requirements Client Privileged Helper Client has requirements for Helper(s) Helper has requirements for Client(s) OS performs validation of the requirements ONLY on install & update of the Helper NO validation is performed on establishing XPC connection Intro

Slide 10

Slide 10 text

SMJobBless() 1. Client has the Privileged Helper executable in the bundle 2. Signing requirements are met • Both client and Helper are signed • Privileged Helper has a plist file for launchd embedded into __TEXT section • Privileged Helper has Info.plist embedded • Client has signing requirements listed in its Info.plist Intro

Slide 11

Slide 11 text

SMJobBless() 3. Obtain Authorization object: call AuthorizationCreate() 4. Call SMJobBless() with acquired Authorization object Intro

Slide 12

Slide 12 text

SMJobBless() 5. OS validates code signing requirements in client and helper’s Info.plist and copies the executable from the bundle to /Library/PrivilegedHelperTools Intro

Slide 13

Slide 13 text

SMJobBless() 5. Client can establish XPC connection to the Privileged Helper Intro

Slide 14

Slide 14 text

Apple’s Sample Code Intro

Slide 15

Slide 15 text

Apple’s Sample Code Intro

Slide 16

Slide 16 text

Apple’s Sample Code Intro

Slide 17

Slide 17 text

Issue #1 Intro

Slide 18

Slide 18 text

First security issue, reported by Talos

Slide 19

Slide 19 text

Zero-Day Reports • November 2018 Talos

Slide 20

Slide 20 text

Talos

Slide 21

Slide 21 text

Stumbled upon Talos’es Zero-Day reports Contacted Talos for details, they answer the same day We release a patched update v. 4.2.0 Talos reports insufficient fix We release a patch v. 4.3.0 Tyler Bohan (Talos) delivers a talk at OffenciveCon19 Timeline Talos 0 1

Slide 22

Slide 22 text

Tyler Bohan: ‘OSX XPC Revisited - 3rd Party Application Flaws’ at OffensiveCon19 https://www.youtube.com/watch?v=KPzhTqwf0bA Talos

Slide 23

Slide 23 text

Tyler Bohan: ‘OSX XPC Revisited - 3rd Party Application Flaws’ at OffensiveCon19 https://www.youtube.com/watch?v=KPzhTqwf0bA Talos

Slide 24

Slide 24 text

Fix Talos

Slide 25

Slide 25 text

Fix #1 Talos

Slide 26

Slide 26 text

on h1

Slide 27

Slide 27 text

Timeline March 2018 MacPaw launched a private h1 program for our other product Setapp May 2019 CleanMyMac desktop client is added to the scope h1

Slide 28

Slide 28 text

Client’s requirements { Bundle identifier Signing identity (team id) { h1

Slide 29

Slide 29 text

Client’s requirements Privileged helper’s executable can be replaced with old version { Bundle identifier Signing identity (team id) { h1

Slide 30

Slide 30 text

What’s the fuss about old versions? h1

Slide 31

Slide 31 text

What’s the fuss about old versions? El Capitan 10.11 Sierra 10.12 High Sierra 10.13 Mojave 10.14 Catalina 10.15 Hardened Runtime introduced in Mojave: • libraries signing validation == protect from dylib injection • remove get-task-allow from entitlements == protect from attaching with debugger (and other things) h1

Slide 32

Slide 32 text

Issue #2: steps Preconditions: Privileged Helper is not authorized yet. A malicious executable is present on the user’s computer. 1. Download an app version, vulnerable to dylib injection 2. Replace the Privileged Helper executable in the installed app with the vulnerable one 3. User authorizes the Helper 4. Perform a dylib injection into the Helper—it is run as root! h1

Slide 33

Slide 33 text

What about code signing? Replacing the Privileged Helper in the signed bundle doesn’t change anything, because OS validates the signature only when app is quarantined After the first launch no signature validation is performed on Mojave. Time-to-time signature checks were announced in Catalina. h1

Slide 34

Slide 34 text

Fix #2 h1 { Version check

Slide 35

Slide 35 text

Privileged Helper’s requirements { Signing identity (team id) h1

Slide 36

Slide 36 text

old client versions can connect Privileged Helper’s requirements { Signing identity (team id) h1

Slide 37

Slide 37 text

Issue #3: steps Preconditions: Privileged Helper is authorized. A malicious executable is present on the user’s computer. • Download an old app version, vulnerable to dylib injection • Launch client executable with a dylib injection • Call privileged helper’s methods from the injected code • In our case it leads to LPE to root h1

Slide 38

Slide 38 text

Issue #3: steps Preconditions: Privileged Helper is authorized. A malicious executable is present on the user’s computer. • Download an old app version, vulnerable to dylib injection • Launch client executable with a dylib injection • Call privileged helper’s methods from the injected code • In our case it leads to LPE to root Takeaway: Dylib injection does NOT break the code signature h1

Slide 39

Slide 39 text

Fix #3 h1

Slide 40

Slide 40 text

old client versions can connect other apps of the same vendor can connect Privileged Helper’s requirements { Signing identity (team id) h1

Slide 41

Slide 41 text

Fix #4 h1

Slide 42

Slide 42 text

Privileged Helper’s code h1

Slide 43

Slide 43 text

anyone can impersonate the client due to pid checks logic performed by OS Privileged Helper’s code h1

Slide 44

Slide 44 text

Issue #5: anyone can impersonate the client due to racy pid checks performed by OS h1

Slide 45

Slide 45 text

h1

Slide 46

Slide 46 text

Fix #5 h1

Slide 47

Slide 47 text

The APIs are private h1

Slide 48

Slide 48 text

Privileged operations implementation on and Setapp

Slide 49

Slide 49 text

SMJobBless() AuthorizationExecuteWithPrivileges() Application API # bugs reported* 5 Setapp * as for March 2020

Slide 50

Slide 50 text

SMJobBless() AuthorizationExecuteWithPrivileges() Application API # bugs reported* 5 0 * as for March 2020 Setapp

Slide 51

Slide 51 text

Summary & Takeaways Summary

Slide 52

Slide 52 text

Takeaways for developers 1. Think about security in your project/company. A good start is creating a security@yourcompany.com email handle. 2. Have one source of truth for Client’s signing requirements and one for Privileged Helper’s, e.g. put them in Preprocessor Macros and use it in: ℹ Info.plist file listener:shouldAcceptNewConnection: 3. In signing requirements check at least for: signing identity bundle identifier #⃣ minimum version 4. In SecCodeCopyGuestWithAttributes use audit token to obtain code reference for signature validation, not the pid 5. In order to be a good citizen remember to unregister the Privileged Helper via launchctl or SMJobRemove API, remove the executable from /Library/PrivilegedHelperTools and the auto generated .plist from /Library/LaunchDaemons Summary

Slide 53

Slide 53 text

Example set up requirements for Privileged Helper 1. Add User-Defined Build Settings: CLIENT_REQUIREMENTS="@\"anchor trusted and certificate leaf [subject.CN] = \\\"$(CLIENT_SIGNING_IDENTITY)\\\" and info[CFBundleShortVersionString] >= \\\"$CLIENT_MIN_VERSION\\\" and identifier \\\"$CLIENT_IDENTIFIER\\\"\"" 2. Use them to create a macro definition Summary

Slide 54

Slide 54 text

3. Use your Build Settings in Info.plist client requirements: 4. Use the Macro Definition from 2. in code to validate incoming connection: Example set up requirements for Privileged Helper Summary

Slide 55

Slide 55 text

Summary/Wishlist Summary

Slide 56

Slide 56 text

Summary/Wishlist 1. We need the documentation There is no easily available Apple’s documentation about securing XPC connection with Privileged Helpers 2. We need Code Samples Apple’s code samples are not secure 3. Using pid to check the signature of a process is not secure. It should be clearly stated in docs Checks by pid are racy by nature 4. Audit token should not be private It is the most secure way, but it is not available to 3rd party developers 5. There should be some Uninstallation API When the app is being removed, the Helpers are usually forgotten in /Library/PrivilegedHelperTools Summary

Slide 57

Slide 57 text

Further Reading 1. project-zero ‘Issue 1223: MacOS/iOS userspace entitlement checking is racy’ by Ian Beer 2. OffensiveCon19 'OSX XPC Revisited - 3rd Party Application Flaws' by Tyler Bohan 3. Apple Developer Forums 'XPC restricted to processes with the same code signing?' 4. Objective Development ‘The Story Behind CVE-2019-13013’ by Christian from Little Snitch 5. ‘No Privileged Helper Tool Left Behind’ by Erik Berglund Summary

Slide 58

Slide 58 text

Call to Action If I could ask you to do 1 thing, let it be: Summary

Slide 59

Slide 59 text

Call to Action Summary reporting to Apple, that audit tokens should be made available for 3rd party developers: If I could ask you to do 1 thing, let it be:

Slide 60

Slide 60 text

Thank you! iaronskaya