Skip to content

Instantly share code, notes, and snippets.

@Brandon7CC
Last active February 14, 2024 02:13
Show Gist options
  • Save Brandon7CC/14cd97458629ca045774cb767d476e59 to your computer and use it in GitHub Desktop.
Save Brandon7CC/14cd97458629ca045774cb767d476e59 to your computer and use it in GitHub Desktop.
Hook the CoreAnalytics sendEvent function call made by endpointsecurityd to uncover event subscriptions.
/*
Author: Brandon Dalton (Red Canary Threat Research)
Date: 2023-12-07
Summary: This script attempts to instrument the `sendEvent:event:` method of the ESCoreAnalytics class.
- Download this script
- Target: You're targeting `endpointsecurityd`, so grab its PID: `sudo launchctl list | grep endpointsecurityd`
- To run: `sudo frida -p $PID -l es_coreanalytics_event_subs.js`
*/
const eventTypeMapping = {
// Complete mapping based on es_event_type_t enumeration
0: 'ES_EVENT_TYPE_AUTH_EXEC',
1: 'ES_EVENT_TYPE_AUTH_OPEN',
2: 'ES_EVENT_TYPE_AUTH_KEXTLOAD',
3: 'ES_EVENT_TYPE_AUTH_MMAP',
4: 'ES_EVENT_TYPE_AUTH_MPROTECT',
5: 'ES_EVENT_TYPE_AUTH_MOUNT',
6: 'ES_EVENT_TYPE_AUTH_RENAME',
7: 'ES_EVENT_TYPE_AUTH_SIGNAL',
8: 'ES_EVENT_TYPE_AUTH_UNLINK',
9: 'ES_EVENT_TYPE_NOTIFY_EXEC',
10: 'ES_EVENT_TYPE_NOTIFY_OPEN',
11: 'ES_EVENT_TYPE_NOTIFY_FORK',
12: 'ES_EVENT_TYPE_NOTIFY_CLOSE',
13: 'ES_EVENT_TYPE_NOTIFY_CREATE',
14: 'ES_EVENT_TYPE_NOTIFY_EXCHANGEDATA',
15: 'ES_EVENT_TYPE_NOTIFY_EXIT',
16: 'ES_EVENT_TYPE_NOTIFY_GET_TASK',
17: 'ES_EVENT_TYPE_NOTIFY_KEXTLOAD',
18: 'ES_EVENT_TYPE_NOTIFY_KEXTUNLOAD',
19: 'ES_EVENT_TYPE_NOTIFY_LINK',
20: 'ES_EVENT_TYPE_NOTIFY_MMAP',
21: 'ES_EVENT_TYPE_NOTIFY_MPROTECT',
22: 'ES_EVENT_TYPE_NOTIFY_MOUNT',
23: 'ES_EVENT_TYPE_NOTIFY_UNMOUNT',
24: 'ES_EVENT_TYPE_NOTIFY_IOKIT_OPEN',
25: 'ES_EVENT_TYPE_NOTIFY_RENAME',
26: 'ES_EVENT_TYPE_NOTIFY_SETATTRLIST',
27: 'ES_EVENT_TYPE_NOTIFY_SETEXTATTR',
28: 'ES_EVENT_TYPE_NOTIFY_SETFLAGS',
29: 'ES_EVENT_TYPE_NOTIFY_SETMODE',
30: 'ES_EVENT_TYPE_NOTIFY_SETOWNER',
31: 'ES_EVENT_TYPE_NOTIFY_SIGNAL',
32: 'ES_EVENT_TYPE_NOTIFY_UNLINK',
33: 'ES_EVENT_TYPE_NOTIFY_WRITE',
34: 'ES_EVENT_TYPE_AUTH_FILE_PROVIDER_MATERIALIZE',
35: 'ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_MATERIALIZE',
36: 'ES_EVENT_TYPE_AUTH_FILE_PROVIDER_UPDATE',
37: 'ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_UPDATE',
38: 'ES_EVENT_TYPE_AUTH_READLINK',
39: 'ES_EVENT_TYPE_NOTIFY_READLINK',
40: 'ES_EVENT_TYPE_AUTH_TRUNCATE',
41: 'ES_EVENT_TYPE_NOTIFY_TRUNCATE',
42: 'ES_EVENT_TYPE_AUTH_LINK',
43: 'ES_EVENT_TYPE_NOTIFY_LOOKUP',
44: 'ES_EVENT_TYPE_AUTH_CREATE',
45: 'ES_EVENT_TYPE_AUTH_SETATTRLIST',
46: 'ES_EVENT_TYPE_AUTH_SETEXTATTR',
47: 'ES_EVENT_TYPE_AUTH_SETFLAGS',
48: 'ES_EVENT_TYPE_AUTH_SETMODE',
49: 'ES_EVENT_TYPE_AUTH_SETOWNER',
50: 'ES_EVENT_TYPE_AUTH_CHDIR',
51: 'ES_EVENT_TYPE_NOTIFY_CHDIR',
52: 'ES_EVENT_TYPE_AUTH_GETATTRLIST',
53: 'ES_EVENT_TYPE_NOTIFY_GETATTRLIST',
54: 'ES_EVENT_TYPE_NOTIFY_STAT',
55: 'ES_EVENT_TYPE_NOTIFY_ACCESS',
56: 'ES_EVENT_TYPE_AUTH_CHROOT',
57: 'ES_EVENT_TYPE_NOTIFY_CHROOT',
58: 'ES_EVENT_TYPE_AUTH_UTIMES',
59: 'ES_EVENT_TYPE_NOTIFY_UTIMES',
60: 'ES_EVENT_TYPE_AUTH_CLONE',
61: 'ES_EVENT_TYPE_NOTIFY_CLONE',
62: 'ES_EVENT_TYPE_NOTIFY_FCNTL',
63: 'ES_EVENT_TYPE_AUTH_GETEXTATTR',
64: 'ES_EVENT_TYPE_NOTIFY_GETEXTATTR',
65: 'ES_EVENT_TYPE_AUTH_LISTEXTATTR',
66: 'ES_EVENT_TYPE_NOTIFY_LISTEXTATTR',
67: 'ES_EVENT_TYPE_AUTH_READDIR',
68: 'ES_EVENT_TYPE_NOTIFY_READDIR',
69: 'ES_EVENT_TYPE_AUTH_DELETEEXTATTR',
70: 'ES_EVENT_TYPE_NOTIFY_DELETEEXTATTR',
71: 'ES_EVENT_TYPE_AUTH_FSGETPATH',
72: 'ES_EVENT_TYPE_NOTIFY_FSGETPATH',
73: 'ES_EVENT_TYPE_NOTIFY_DUP',
74: 'ES_EVENT_TYPE_AUTH_SETTIME',
75: 'ES_EVENT_TYPE_NOTIFY_SETTIME',
76: 'ES_EVENT_TYPE_NOTIFY_UIPC_BIND',
77: 'ES_EVENT_TYPE_AUTH_UIPC_BIND',
78: 'ES_EVENT_TYPE_NOTIFY_UIPC_CONNECT',
79: 'ES_EVENT_TYPE_AUTH_UIPC_CONNECT',
80: 'ES_EVENT_TYPE_AUTH_EXCHANGEDATA',
81: 'ES_EVENT_TYPE_AUTH_SETACL',
82: 'ES_EVENT_TYPE_NOTIFY_SETACL',
83: 'ES_EVENT_TYPE_NOTIFY_PTY_GRANT',
84: 'ES_EVENT_TYPE_NOTIFY_PTY_CLOSE',
85: 'ES_EVENT_TYPE_AUTH_PROC_CHECK',
86: 'ES_EVENT_TYPE_NOTIFY_PROC_CHECK',
87: 'ES_EVENT_TYPE_AUTH_GET_TASK',
88: 'ES_EVENT_TYPE_AUTH_SEARCHFS',
89: 'ES_EVENT_TYPE_NOTIFY_SEARCHFS',
90: 'ES_EVENT_TYPE_AUTH_FCNTL',
91: 'ES_EVENT_TYPE_AUTH_IOKIT_OPEN',
92: 'ES_EVENT_TYPE_AUTH_PROC_SUSPEND_RESUME',
93: 'ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME',
94: 'ES_EVENT_TYPE_NOTIFY_CS_INVALIDATED',
95: 'ES_EVENT_TYPE_NOTIFY_GET_TASK_NAME',
96: 'ES_EVENT_TYPE_NOTIFY_TRACE',
97: 'ES_EVENT_TYPE_NOTIFY_REMOTE_THREAD_CREATE',
98: 'ES_EVENT_TYPE_AUTH_REMOUNT',
99: 'ES_EVENT_TYPE_NOTIFY_REMOUNT',
100: 'ES_EVENT_TYPE_AUTH_GET_TASK_READ',
101: 'ES_EVENT_TYPE_NOTIFY_GET_TASK_READ',
102: 'ES_EVENT_TYPE_NOTIFY_GET_TASK_INSPECT',
103: 'ES_EVENT_TYPE_NOTIFY_SETUID',
104: 'ES_EVENT_TYPE_NOTIFY_SETGID',
105: 'ES_EVENT_TYPE_NOTIFY_SETEUID',
106: 'ES_EVENT_TYPE_NOTIFY_SETEGID',
107: 'ES_EVENT_TYPE_NOTIFY_SETREUID',
108: 'ES_EVENT_TYPE_NOTIFY_SETREGID',
109: 'ES_EVENT_TYPE_AUTH_COPYFILE',
110: 'ES_EVENT_TYPE_NOTIFY_COPYFILE',
111: 'ES_EVENT_TYPE_NOTIFY_AUTHENTICATION',
112: 'ES_EVENT_TYPE_NOTIFY_XP_MALWARE_DETECTED',
113: 'ES_EVENT_TYPE_NOTIFY_XP_MALWARE_REMEDIATED',
114: 'ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOGIN',
115: 'ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOGOUT',
116: 'ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOCK',
117: 'ES_EVENT_TYPE_NOTIFY_LW_SESSION_UNLOCK',
118: 'ES_EVENT_TYPE_NOTIFY_SCREENSHARING_ATTACH',
119: 'ES_EVENT_TYPE_NOTIFY_SCREENSHARING_DETACH',
120: 'ES_EVENT_TYPE_NOTIFY_OPENSSH_LOGIN',
121: 'ES_EVENT_TYPE_NOTIFY_OPENSSH_LOGOUT',
122: 'ES_EVENT_TYPE_NOTIFY_LOGIN_LOGIN',
123: 'ES_EVENT_TYPE_NOTIFY_LOGIN_LOGOUT',
124: 'ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD',
125: 'ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_REMOVE',
126: 'ES_EVENT_TYPE_NOTIFY_PROFILE_ADD',
127: 'ES_EVENT_TYPE_NOTIFY_PROFILE_REMOVE',
128: 'ES_EVENT_TYPE_NOTIFY_SU',
129: 'ES_EVENT_TYPE_NOTIFY_AUTHORIZATION_PETITION',
130: 'ES_EVENT_TYPE_NOTIFY_AUTHORIZATION_JUDGEMENT',
131: 'ES_EVENT_TYPE_NOTIFY_SUDO',
132: 'ES_EVENT_TYPE_NOTIFY_OD_GROUP_ADD',
133: 'ES_EVENT_TYPE_NOTIFY_OD_GROUP_REMOVE',
134: 'ES_EVENT_TYPE_NOTIFY_OD_GROUP_SET',
135: 'ES_EVENT_TYPE_NOTIFY_OD_MODIFY_PASSWORD',
136: 'ES_EVENT_TYPE_NOTIFY_OD_DISABLE_USER',
137: 'ES_EVENT_TYPE_NOTIFY_OD_ENABLE_USER',
138: 'ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_VALUE_ADD',
139: 'ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_VALUE_REMOVE',
140: 'ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_SET',
141: 'ES_EVENT_TYPE_NOTIFY_OD_CREATE_USER',
142: 'ES_EVENT_TYPE_NOTIFY_OD_CREATE_GROUP',
143: 'ES_EVENT_TYPE_NOTIFY_OD_DELETE_USER',
144: 'ES_EVENT_TYPE_NOTIFY_OD_DELETE_GROUP',
145: 'ES_EVENT_TYPE_NOTIFY_XPC_CONNECT',
146: 'ES_EVENT_TYPE_LAST'
};
if (ObjC.available) {
try {
const ESCoreAnalytics = ObjC.classes.ESCoreAnalytics;
const sendEvent_event_ = ESCoreAnalytics['- sendEvent:event:'];
Interceptor.attach(sendEvent_event_.implementation, {
onEnter: function (args) {
console.log('[+] sendEvent:event: entered');
// Interpreting 'event' as an NSDictionary
const eventDict = new ObjC.Object(args[3]);
console.log(' Endpoint Security Event subscription details:');
const keys = eventDict.allKeys();
for (let i = 0; i < keys.count(); i++) {
const key = keys.objectAtIndex_(i);
const value = eventDict.objectForKey_(key);
if (value !== null && typeof value.toString === 'function') {
let valueString = value.toString();
// Resolve EventType to a readable format
if (key.toString() === 'EventType' && eventTypeMapping[valueString]) {
// `eventTypeMapping` is discussed below
valueString = eventTypeMapping[valueString] + ` (${valueString})`;
}
console.log(` ${key.toString()}: ${valueString}`);
} else {
console.log(` ${key.toString()}: <null or undefined>`);
}
}
}
});
} catch (e) {
console.error(e);
}
} else {
console.error('Objective-C runtime not found...');
}
@Brandon7CC
Copy link
Author

What does the end result look like? Notice that simply by pivoting off of the method's arguments with ObjC.Object(args[3]) we were able to read the dictionary being sent across to CoreAnalytics. In this case, we can see some incredible detail:

  • Type of client: sysext (System Extension)
  • The event subscription requested: ES_EVENT_TYPE_NOTIFY_AUTHORIZATION_PETITION in this case which has ID: 129
  • The bundle ID of the ESE: com.redcanary.agent.securityextension
  • The team ID of the ESE: UA6JCQGF3F
  • and the CDHash of the Mach-O: 1c2dc75b5d568ddf7981179a8482d7b1c383d5e
[+] sendEvent:event: entered
    Endpoint Security Event subscription details:
    ClientDisposition: sysext
    EventType: ES_EVENT_TYPE_NOTIFY_AUTHORIZATION_PETITION (129)
    BundleID: com.redcanary.agent.securityextension
    TeamID: UA6JCQGF3F
    CDHash: 1c2dc75b5d568ddf7981179a8482d7b1c383d5e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment