mirror of
https://github.com/google/santa.git
synced 2026-04-24 03:00:12 -04:00
santad/SNTEventLog: log original path of translocated apps (#194)
* log original path of translocated apps * made handle a local variable & fixed capitalization * Removed superfluous CFError
This commit is contained in:
committed by
Tom Burgin
parent
ff095bc53d
commit
79662d0dcf
@@ -14,6 +14,7 @@
|
||||
|
||||
#import "SNTEventLog.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <grp.h>
|
||||
#include <libproc.h>
|
||||
#include <pwd.h>
|
||||
@@ -208,6 +209,12 @@
|
||||
message.gid, [self nameForGID:message.gid],
|
||||
mode, [self sanitizeString:@(message.path)]];
|
||||
|
||||
// Check for app translocation by GateKeeper, and log original path if the case.
|
||||
NSString *originalPath = [self originalPathForTranslocation:message];
|
||||
if (originalPath) {
|
||||
[outLog appendFormat:@"|origpath=%@", [self sanitizeString:originalPath]];
|
||||
}
|
||||
|
||||
if (logArgs) {
|
||||
[self addArgsForPid:message.pid toString:outLog];
|
||||
}
|
||||
@@ -497,4 +504,49 @@
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**
|
||||
Uses the executable path, uid, and gid from a given santa_message_t to determine if the path
|
||||
has been translocated by GateKeeper and if so, returns the original path of the executable. This
|
||||
requires macOS 10.12 or higher. We use dlopen to access the functions we need in
|
||||
Security.framework so that we can still build against the 10.11 SDK. If the path has not been
|
||||
translocated or if running on macOS prior to 10.12, this method returns nil.
|
||||
*/
|
||||
- (NSString *)originalPathForTranslocation:(santa_message_t)message {
|
||||
// The first time this function is called, we attempt to find the addresses of
|
||||
// SecTranslocateIsTranslocatedURL and SecTranslocateCreateOriginalPathForURL inside of the
|
||||
// Security.framework library. If we were successful, handle will be non-NULL and is never
|
||||
// closed.
|
||||
static Boolean (*IsTranslocatedURL)(CFURLRef, bool *, CFErrorRef *) = NULL;
|
||||
static CFURLRef __nullable (*CreateOriginalPathForURL)(CFURLRef, CFErrorRef *) = NULL;
|
||||
static dispatch_once_t token;
|
||||
dispatch_once(&token, ^{
|
||||
void *handle = dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY);
|
||||
if (handle) {
|
||||
IsTranslocatedURL = dlsym(handle, "SecTranslocateIsTranslocatedURL");
|
||||
CreateOriginalPathForURL = dlsym(handle, "SecTranslocateCreateOriginalPathForURL");
|
||||
if (!IsTranslocatedURL || !CreateOriginalPathForURL) {
|
||||
IsTranslocatedURL = NULL;
|
||||
CreateOriginalPathForURL = NULL;
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// If we couldn't open the library or find the functions we need, don't do anything.
|
||||
if (!IsTranslocatedURL || !CreateOriginalPathForURL) return nil;
|
||||
|
||||
// Determine if the executable URL has been translocated or not.
|
||||
CFURLRef cfExecURL = (__bridge CFURLRef)[NSURL fileURLWithPath:@(message.path)];
|
||||
bool isTranslocated = false;
|
||||
if (!IsTranslocatedURL(cfExecURL, &isTranslocated, NULL) || !isTranslocated) return nil;
|
||||
|
||||
// SecTranslocateCreateOriginalPathForURL requires that our uid be the same as the user who
|
||||
// launched the executable. So we temporarily drop from root down to this uid, then reset.
|
||||
pthread_setugid_np(message.uid, message.gid);
|
||||
NSURL *origURL = CFBridgingRelease(CreateOriginalPathForURL(cfExecURL, NULL));
|
||||
pthread_setugid_np(KAUTH_UID_NONE, KAUTH_GID_NONE);
|
||||
|
||||
return [origURL path]; // this will be nil if there was an error
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user