New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
santad: add critical system binaries #296
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,9 @@ | |
#import <MOLCertificate/MOLCertificate.h> | ||
#import <MOLCodesignChecker/MOLCodesignChecker.h> | ||
|
||
#import "SNTCachedDecision.h" | ||
#import "SNTConfigurator.h" | ||
#import "SNTFileInfo.h" | ||
#import "SNTLogging.h" | ||
#import "SNTRule.h" | ||
|
||
|
@@ -31,6 +33,7 @@ @interface SNTRuleTable () | |
@property NSString *santadCertSHA; | ||
@property NSString *launchdCertSHA; | ||
@property NSDate *lastTransitiveRuleCulling; | ||
@property NSDictionary *criticalSystemBinaries; | ||
@end | ||
|
||
@implementation SNTRuleTable | ||
|
@@ -64,7 +67,8 @@ - (uint32_t)initializeDatabase:(FMDatabase *)db fromVersion:(uint32_t)version { | |
// Save hashes of the signing certs for launchd and santad. | ||
// Used to ensure rules for them are not removed. | ||
self.santadCertSHA = [[[[MOLCodesignChecker alloc] initWithSelf] leafCertificate] SHA256]; | ||
self.launchdCertSHA = [[[[MOLCodesignChecker alloc] initWithPID:1] leafCertificate] SHA256]; | ||
MOLCodesignChecker *launchdCSInfo = [[MOLCodesignChecker alloc] initWithPID:1]; | ||
self.launchdCertSHA = launchdCSInfo.leafCertificate.SHA256; | ||
|
||
// Ensure the certificates used to sign the running launchd/santad are whitelisted. | ||
// If they weren't previously and the database is not new, log an error. | ||
|
@@ -87,6 +91,31 @@ - (uint32_t)initializeDatabase:(FMDatabase *)db fromVersion:(uint32_t)version { | |
self.launchdCertSHA, @(SNTRuleStateWhitelist), @(SNTRuleTypeCertificate)]; | ||
} | ||
|
||
// Setup critical system binaries | ||
// TODO(tburgin): Add the Santa components to this feature and remove the santadCertSHA rule. | ||
NSMutableDictionary *bins = [NSMutableDictionary dictionary]; | ||
for (NSString *path in @[ @"/usr/libexec/trustd" ]) { | ||
SNTFileInfo *binInfo = [[SNTFileInfo alloc] initWithPath:path]; | ||
MOLCodesignChecker *csInfo = [binInfo codesignCheckerWithError:NULL]; | ||
|
||
// Make sure the critical system binary is signed by the same chain as launchd. | ||
if ([csInfo signingInformationMatches:launchdCSInfo]) { | ||
SNTCachedDecision *cd = [[SNTCachedDecision alloc] init]; | ||
|
||
cd.decision = SNTEventStateAllowBinary; | ||
cd.decisionExtra = @"critical system binary"; | ||
cd.sha256 = binInfo.SHA256; | ||
|
||
// Not needed, but nice for logging. | ||
cd.certSHA256 = csInfo.leafCertificate.SHA256; | ||
cd.certCommonName = csInfo.leafCertificate.commonName; | ||
|
||
bins[binInfo.SHA256] = cd; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. log error if signing info doesn't match? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good idea |
||
} | ||
|
||
self.criticalSystemBinaries = bins; | ||
|
||
return newVersion; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -116,21 +116,28 @@ - (void)validateBinaryWithMessage:(santa_message_t)message { | |
} | ||
|
||
// Get codesigning info about the file but only if it's a Mach-O. | ||
// If the binary is a critical system binary, don't check its signiture. The binary was validated | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo: signiture -> signature There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oops |
||
// by santad at startup. | ||
SNTCachedDecision *cd = self.ruleTable.criticalSystemBinaries[binInfo.SHA256]; | ||
MOLCodesignChecker *csInfo; | ||
if (binInfo.isMachO) { | ||
if (!cd && binInfo.isMachO) { | ||
NSError *csError; | ||
csInfo = [[MOLCodesignChecker alloc] initWithBinaryPath:binInfo.path | ||
fileDescriptor:binInfo.fileHandle.fileDescriptor | ||
error:&csError]; | ||
|
||
// Ignore codesigning if there are any errors with the signature. | ||
if (csError) csInfo = nil; | ||
} | ||
|
||
// Actually make the decision (and refresh rule access timestamp). | ||
SNTCachedDecision *cd = [self.policyProcessor decisionForFileInfo:binInfo | ||
// If needed, actually make the decision (and refresh rule access timestamp). | ||
if (!cd) { | ||
cd = [self.policyProcessor decisionForFileInfo:binInfo | ||
fileSHA256:nil | ||
certificateSHA256:csInfo.leafCertificate.SHA256]; | ||
cd.certCommonName = csInfo.leafCertificate.commonName; | ||
cd.certCommonName = csInfo.leafCertificate.commonName; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this might be easier to follow if it were structured as
instead of having two separate checks for !cd There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
cd.vnodeId = message.vnode_id; | ||
|
||
// Formulate an initial action from the decision. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this fail the right way if there's no file at path? I'm guessing csInfo will end up nil and then the call to signingInformationMatches: will return NO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, if csInfo is nil, sending any message to it will return nil.