Skip to content

Instantly share code, notes, and snippets.

@knightsc
Last active March 24, 2020 22:20
Show Gist options
  • Save knightsc/4678757164b2c63a58856a1acb3dd17e to your computer and use it in GitHub Desktop.
Save knightsc/4678757164b2c63a58856a1acb3dd17e to your computer and use it in GitHub Desktop.
An example of using the libEndpointSecurity.dylib in Catalina
#import <Foundation/Foundation.h>
#import <EndpointSecurity/EndpointSecurity.h>
#import <os/log.h>
#import <bsm/libbsm.h>
/*
In the beta 1 seed it's not straight forward to create an EndpointSecurity extension.
You can use libEndpointSecurity.dylib directly as long as you set the following things:
1. Disable SIP
2. Give your app the com.apple.developer.endpoint-security.client entitlement
3. Run the application as root
This code works with Catalina beta 5
*/
void log_message(const es_message_t *message) {
pid_t pid = audit_token_to_pid(message->process->audit_token);
pid_t target_pid;
NSMutableString *log = [[NSMutableString alloc] init];
switch (message->event_type) {
case ES_EVENT_TYPE_AUTH_EXEC:
[log appendString:@"auth_exec: "];
break;
case ES_EVENT_TYPE_AUTH_OPEN:
[log appendString:@"auth_open: "];
break;
case ES_EVENT_TYPE_AUTH_KEXTLOAD:
[log appendString:@"auth_kextload: "];
break;
case ES_EVENT_TYPE_AUTH_MMAP:
[log appendString:@"auth_mmap: "];
break;
case ES_EVENT_TYPE_AUTH_MPROTECT:
[log appendString:@"auth_mprotect: "];
break;
case ES_EVENT_TYPE_AUTH_MOUNT:
[log appendString:@"auth_mount: "];
break;
case ES_EVENT_TYPE_AUTH_RENAME:
[log appendString:@"auth_rename: "];
break;
case ES_EVENT_TYPE_AUTH_SIGNAL:
[log appendString:[NSString stringWithFormat:@"%8d auth_signal: %d", pid, message->event.signal.sig]];
break;
case ES_EVENT_TYPE_AUTH_UNLINK:
[log appendString:@"auth_unlink: "];
break;
case ES_EVENT_TYPE_NOTIFY_EXEC:
[log appendString:[NSString stringWithFormat:@"%8d exec: %s", message->process->ppid, message->event.exec.target->executable->path.data]];
break;
case ES_EVENT_TYPE_NOTIFY_OPEN:
[log appendString:[NSString stringWithFormat:@"%8d open: %s", pid, message->event.open.file->path.data]];
break;
case ES_EVENT_TYPE_NOTIFY_FORK:
[log appendString:@"fork: "];
break;
case ES_EVENT_TYPE_NOTIFY_CLOSE:
[log appendString:[NSString stringWithFormat:@"%8d close: %s", pid, message->event.close.target->path.data]];
break;
case ES_EVENT_TYPE_NOTIFY_CREATE:
[log appendString:@"create: "];
break;
case ES_EVENT_TYPE_NOTIFY_EXCHANGEDATA:
[log appendString:@"exchangedata: "];
break;
case ES_EVENT_TYPE_NOTIFY_EXIT:
[log appendString:@"exit: "];
break;
case ES_EVENT_TYPE_NOTIFY_GET_TASK:
target_pid = audit_token_to_pid(message->event.get_task.target->audit_token);
[log appendString:[NSString stringWithFormat:@"%8d get_task: %d", pid, target_pid]];
break;
case ES_EVENT_TYPE_NOTIFY_KEXTLOAD:
[log appendString:@"kextload: "];
break;
case ES_EVENT_TYPE_NOTIFY_KEXTUNLOAD:
[log appendString:@"kextunload: "];
break;
case ES_EVENT_TYPE_NOTIFY_LINK:
[log appendString:@"link: "];
break;
case ES_EVENT_TYPE_NOTIFY_MMAP:
[log appendString:@"mmap: "];
break;
case ES_EVENT_TYPE_NOTIFY_MPROTECT:
[log appendString:@"mprotect: "];
break;
case ES_EVENT_TYPE_NOTIFY_MOUNT:
[log appendString:@"mount: "];
break;
case ES_EVENT_TYPE_NOTIFY_UNMOUNT:
[log appendString:@"unmount: "];
break;
case ES_EVENT_TYPE_NOTIFY_IOKIT_OPEN:
[log appendString:@"iokit_open: "];
break;
case ES_EVENT_TYPE_NOTIFY_RENAME:
[log appendString:@"rename: "];
break;
case ES_EVENT_TYPE_NOTIFY_SETATTRLIST:
[log appendString:@"setattrlist: "];
break;
case ES_EVENT_TYPE_NOTIFY_SETEXTATTR:
[log appendString:@"setextattr: "];
break;
case ES_EVENT_TYPE_NOTIFY_SETFLAGS:
[log appendString:@"setflags: "];
break;
case ES_EVENT_TYPE_NOTIFY_SETMODE:
[log appendString:@"setmode: "];
break;
case ES_EVENT_TYPE_NOTIFY_SETOWNER:
[log appendString:@"setowner: "];
break;
case ES_EVENT_TYPE_NOTIFY_SIGNAL:
[log appendString:@"signal: "];
break;
case ES_EVENT_TYPE_NOTIFY_UNLINK:
[log appendString:@"unlink: "];
break;
case ES_EVENT_TYPE_NOTIFY_WRITE:
[log appendString:@"write: "];
break;
case ES_EVENT_TYPE_AUTH_FILE_PROVIDER_MATERIALIZE:
[log appendString:@"auth_file_provider_materialize: "];
break;
case ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_MATERIALIZE:
[log appendString:@"file_provider_materialize: "];
break;
case ES_EVENT_TYPE_AUTH_FILE_PROVIDER_UPDATE:
[log appendString:@"auth_file_provider_update: "];
break;
case ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_UPDATE:
[log appendString:@"file_provider_update: "];
break;
case ES_EVENT_TYPE_AUTH_READLINK:
[log appendString:@"auth_readlink: "];
break;
case ES_EVENT_TYPE_NOTIFY_READLINK:
[log appendString:@"readlink: "];
break;
case ES_EVENT_TYPE_AUTH_TRUNCATE:
[log appendString:@"auth_truncate: "];
break;
case ES_EVENT_TYPE_NOTIFY_TRUNCATE:
[log appendString:@"truncate: "];
break;
case ES_EVENT_TYPE_AUTH_LINK:
[log appendString:@"auth_link: "];
break;
case ES_EVENT_TYPE_NOTIFY_LOOKUP:
[log appendString:@"lookup: "];
break;
case ES_EVENT_TYPE_LAST:
os_log_error(OS_LOG_DEFAULT, "impossible");
break;
}
const char *s = [log UTF8String];
os_log(OS_LOG_DEFAULT, "%s", s);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
os_log(OS_LOG_DEFAULT, "Starting endpoint security...");
es_client_t *client;
es_new_client_result_t res = es_new_client(&client, ^(es_client_t *client, const es_message_t *message) {
pid_t ppid = message->process->ppid;
// pid_t pid = audit_token_to_pid(message->proc.audit_token);
if (ppid != 1) {
// Ignore everything other than the process we're monitoring
// es_mute_process(client, message->proc.audit_token);
// return;
}
log_message(message);
// For now just auth everything
if (message->action_type == ES_ACTION_TYPE_AUTH) {
es_respond_result_t res = es_respond_auth_result(client, message, ES_AUTH_RESULT_ALLOW, false);
if (res != ES_RESPOND_RESULT_SUCCESS) {
os_log_error(OS_LOG_DEFAULT, "es_respond_auth_result failed: %d", res);
}
}
});
// es_new_client_result_t res = es_new_client(&client, ^(es_client_t *client, const es_message_t *message) {
// });
if (res != ES_NEW_CLIENT_RESULT_SUCCESS) {
os_log_error(OS_LOG_DEFAULT, "es_new_client failed: %d", res);
exit(1);
}
es_clear_cache_result_t cres = es_clear_cache(client);
if (cres != ES_CLEAR_CACHE_RESULT_SUCCESS) {
os_log_error(OS_LOG_DEFAULT, "es_clear_cache failed: %d", cres);
exit(1);
}
// 16 is the max? why?????!!!??!?
// Maybe if we split the request into two groups then it will work?
// es_event_type_t events[] = {
// ES_EVENT_TYPE_NOTIFY_EXEC,
// ES_EVENT_TYPE_NOTIFY_OPEN,
// ES_EVENT_TYPE_NOTIFY_FORK,
// ES_EVENT_TYPE_NOTIFY_CLOSE,
// ES_EVENT_TYPE_NOTIFY_CREATE,
// ES_EVENT_TYPE_NOTIFY_EXCHANGEDATA,
// ES_EVENT_TYPE_NOTIFY_EXIT,
// ES_EVENT_TYPE_NOTIFY_GET_TASK,
// ES_EVENT_TYPE_NOTIFY_KEXTLOAD,
// ES_EVENT_TYPE_NOTIFY_KEXTUNLOAD,
// ES_EVENT_TYPE_NOTIFY_LINK,
// ES_EVENT_TYPE_NOTIFY_MMAP,
// ES_EVENT_TYPE_NOTIFY_MPROTECT,
// ES_EVENT_TYPE_NOTIFY_MOUNT,
// ES_EVENT_TYPE_NOTIFY_UNMOUNT,
// ES_EVENT_TYPE_NOTIFY_IOKIT_OPEN,
// ES_EVENT_TYPE_NOTIFY_RENAME,
// ES_EVENT_TYPE_NOTIFY_SETATTRLIST,
// ES_EVENT_TYPE_NOTIFY_SETEXTATTR,
// ES_EVENT_TYPE_NOTIFY_SETFLAGS,
// ES_EVENT_TYPE_NOTIFY_SETMODE,
// ES_EVENT_TYPE_NOTIFY_SETOWNER,
// ES_EVENT_TYPE_NOTIFY_SIGNAL,
// ES_EVENT_TYPE_NOTIFY_UNLINK,
// ES_EVENT_TYPE_NOTIFY_WRITE,
// ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_MATERIALIZATION,
// ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_UPDATE
// };
es_event_type_t events[] = {
ES_EVENT_TYPE_NOTIFY_EXEC
};
es_return_t ret = es_subscribe(client, events, sizeof(events) / sizeof(events[0]));
if (ret != ES_RETURN_SUCCESS) {
os_log(OS_LOG_DEFAULT, "es_subscribe failed");
exit(1);
}
os_log(OS_LOG_DEFAULT, "Initialized");
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop run];
// Calling this will kernel panic! in b1 and b2 not sure about b3
// if (!es_delete_client(client)) {
// os_log_error(OS_LOG_DEFAULT, "es_delete_client failed");
// exit(1);
// }
}
return 0;
}
@bnbhuptani
Copy link

Hi,

Can we check event path is File_type or Folder_type ?

Thanks in advance.

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