Skip to content
This repository has been archived by the owner on Feb 5, 2025. It is now read-only.

Add Support for CS_INVALIDATED Events #1210

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Source/common/santa.proto
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,11 @@ message Unlink {
optional FileInfo target = 2;
}

// Information about a processes codesigning invalidation event
message CodesigningInvalidated {
optional ProcessInfoLight instigator = 1;
}

// Information about a link event
message Link {
// The process performing the link
Expand Down Expand Up @@ -529,6 +534,7 @@ message SantaMessage {
Bundle bundle = 19;
Allowlist allowlist = 20;
FileAccess file_access = 21;
CodesigningInvalidated codesigning_invalidated = 22;
};
}

Expand Down
12 changes: 11 additions & 1 deletion Source/santad/EventProviders/EndpointSecurity/EnrichedTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,19 @@ class EnrichedUnlink : public EnrichedEventType {
EnrichedFile target_;
};

class EnrichedCSInvalidated : public EnrichedEventType {
public:
EnrichedCSInvalidated(Message &&es_msg, EnrichedProcess &&instigator)
: EnrichedEventType(std::move(es_msg), std::move(instigator)) {}
EnrichedCSInvalidated(EnrichedCSInvalidated &&other)
: EnrichedEventType(std::move(other)) {}
EnrichedCSInvalidated(const EnrichedCSInvalidated &other) = delete;
};

using EnrichedType =
std::variant<EnrichedClose, EnrichedExchange, EnrichedExec, EnrichedExit,
EnrichedFork, EnrichedLink, EnrichedRename, EnrichedUnlink>;
EnrichedFork, EnrichedLink, EnrichedRename, EnrichedUnlink,
EnrichedCSInvalidated>;

class EnrichedMessage {
public:
Expand Down
3 changes: 3 additions & 0 deletions Source/santad/EventProviders/EndpointSecurity/Enricher.mm
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@
case ES_EVENT_TYPE_NOTIFY_UNLINK:
return std::make_unique<EnrichedMessage>(EnrichedUnlink(
std::move(es_msg), Enrich(*es_msg->process), Enrich(*es_msg->event.unlink.target)));
case ES_EVENT_TYPE_NOTIFY_CS_INVALIDATED:
return std::make_unique<EnrichedMessage>(
EnrichedCSInvalidated(std::move(es_msg), Enrich(*es_msg->process)));
default:
// This is a programming error
LOGE(@"Attempting to enrich an unhandled event type: %d", es_msg->event_type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class BasicString : public Serializer {
const santa::santad::event_providers::endpoint_security::EnrichedRename &) override;
std::vector<uint8_t> SerializeMessage(
const santa::santad::event_providers::endpoint_security::EnrichedUnlink &) override;
std::vector<uint8_t> SerializeMessage(
const santa::santad::event_providers::endpoint_security::EnrichedCSInvalidated &) override;

std::vector<uint8_t> SerializeFileAccess(
const std::string &policy_version, const std::string &policy_name,
Expand Down
14 changes: 14 additions & 0 deletions Source/santad/Logs/EndpointSecurity/Serializers/BasicString.mm
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
using santa::santad::event_providers::endpoint_security::EnrichedProcess;
using santa::santad::event_providers::endpoint_security::EnrichedRename;
using santa::santad::event_providers::endpoint_security::EnrichedUnlink;
using santa::santad::event_providers::endpoint_security::EnrichedCSInvalidated;
using santa::santad::event_providers::endpoint_security::Message;
using santa::santad::logs::endpoint_security::serializers::Utilities::MountFromName;
using santa::santad::logs::endpoint_security::serializers::Utilities::NonNull;
Expand Down Expand Up @@ -412,6 +413,19 @@ static inline void AppendUserGroup(std::string &str, const audit_token_t &tok,
return FinalizeString(str);
}

std::vector<uint8_t> BasicString::SerializeMessage(const EnrichedCSInvalidated &msg) {
const es_message_t &esm = msg.es_msg();
std::string str = CreateDefaultString();

str.append("action=CODESIGNING_INVALIDATED");
AppendProcess(str, esm.process);
AppendUserGroup(str, esm.process->audit_token, msg.instigator().real_user(),
msg.instigator().real_group());
str.append("|codesigning_flags=");
str.append([NSString stringWithFormat:@"0x%08x", esm.process->codesigning_flags].UTF8String);
return FinalizeString(str);
pmarkowsky marked this conversation as resolved.
Show resolved Hide resolved
}

std::vector<uint8_t> BasicString::SerializeFileAccess(const std::string &policy_version,
const std::string &policy_name,
const Message &msg,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,20 @@ - (void)testSerializeMessageUnlink {
XCTAssertCppStringEqual(got, want);
}

- (void)testSerializeMessageCSInvalidated {
es_file_t procFile = MakeESFile("foo");
es_process_t proc = MakeESProcess(&procFile, MakeAuditToken(12, 34), MakeAuditToken(56, 78));
es_message_t esMsg = MakeESMessage(ES_EVENT_TYPE_NOTIFY_CS_INVALIDATED, &proc);

std::string got = BasicStringSerializeMessage(&esMsg);
std::string want =
"action=CODESIGNING_INVALIDATED"
"|pid=12|ppid=56|process=foo|processpath=foo"
"|uid=-2|user=nobody|gid=-1|group=nogroup|codesigning_flags=0x00000000|machineid=my_id\n";

XCTAssertCppStringEqual(got, want);
}

- (void)testGetAccessTypeString {
std::map<es_event_type_t, std::string> accessTypeToString = {
{ES_EVENT_TYPE_AUTH_OPEN, "OPEN"}, {ES_EVENT_TYPE_AUTH_LINK, "LINK"},
Expand Down
2 changes: 2 additions & 0 deletions Source/santad/Logs/EndpointSecurity/Serializers/Empty.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class Empty : public Serializer {
const santa::santad::event_providers::endpoint_security::EnrichedRename &) override;
std::vector<uint8_t> SerializeMessage(
const santa::santad::event_providers::endpoint_security::EnrichedUnlink &) override;
std::vector<uint8_t> SerializeMessage(
const santa::santad::event_providers::endpoint_security::EnrichedCSInvalidated &) override;

std::vector<uint8_t> SerializeFileAccess(
const std::string &policy_version, const std::string &policy_name,
Expand Down
5 changes: 5 additions & 0 deletions Source/santad/Logs/EndpointSecurity/Serializers/Empty.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Source/santad/Logs/EndpointSecurity/Serializers/Empty.h"

using santa::santad::event_providers::endpoint_security::EnrichedClose;
using santa::santad::event_providers::endpoint_security::EnrichedCSInvalidated;
using santa::santad::event_providers::endpoint_security::EnrichedExchange;
using santa::santad::event_providers::endpoint_security::EnrichedExec;
using santa::santad::event_providers::endpoint_security::EnrichedExit;
Expand Down Expand Up @@ -65,6 +66,10 @@
return {};
}

std::vector<uint8_t> Empty::SerializeMessage(const EnrichedCSInvalidated &msg) {
return {};
}

std::vector<uint8_t> Empty::SerializeFileAccess(const std::string &policy_version,
const std::string &policy_name, const Message &msg,
const EnrichedProcess &enriched_process,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ - (void)testAllSerializersReturnEmptyVector {
XCTAssertEqual(e->SerializeMessage(*(es::EnrichedLink *)&fake).size(), 0);
XCTAssertEqual(e->SerializeMessage(*(es::EnrichedRename *)&fake).size(), 0);
XCTAssertEqual(e->SerializeMessage(*(es::EnrichedUnlink *)&fake).size(), 0);
XCTAssertEqual(e->SerializeMessage(*(es::EnrichedCSInvalidated *)&fake).size(), 0);

XCTAssertEqual(e->SerializeAllowlist(*(es::Message *)&fake, "").size(), 0);
XCTAssertEqual(e->SerializeBundleHashingEvent(nil).size(), 0);
Expand Down
2 changes: 2 additions & 0 deletions Source/santad/Logs/EndpointSecurity/Serializers/Protobuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class Protobuf : public Serializer {
const santa::santad::event_providers::endpoint_security::EnrichedRename &) override;
std::vector<uint8_t> SerializeMessage(
const santa::santad::event_providers::endpoint_security::EnrichedUnlink &) override;
std::vector<uint8_t> SerializeMessage(
const santa::santad::event_providers::endpoint_security::EnrichedCSInvalidated &) override;

std::vector<uint8_t> SerializeFileAccess(
const std::string &policy_version, const std::string &policy_name,
Expand Down
12 changes: 12 additions & 0 deletions Source/santad/Logs/EndpointSecurity/Serializers/Protobuf.mm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
using santa::common::NSStringToUTF8StringView;
using santa::santad::event_providers::endpoint_security::EndpointSecurityAPI;
using santa::santad::event_providers::endpoint_security::EnrichedClose;
using santa::santad::event_providers::endpoint_security::EnrichedCSInvalidated;
using santa::santad::event_providers::endpoint_security::EnrichedEventType;
using santa::santad::event_providers::endpoint_security::EnrichedExchange;
using santa::santad::event_providers::endpoint_security::EnrichedExec;
Expand Down Expand Up @@ -600,6 +601,17 @@ static inline void EncodeCertificateInfo(::pbv1::CertificateInfo *pb_cert_info,
return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeMessage(const EnrichedCSInvalidated &msg) {
Arena arena;
::pbv1::SantaMessage *santa_msg = CreateDefaultProto(&arena, msg);

::pbv1::CodesigningInvalidated *pb_cs_invalidated = santa_msg->mutable_codesigning_invalidated();
EncodeProcessInfoLight(pb_cs_invalidated->mutable_instigator(), msg.es_msg().version,
pmarkowsky marked this conversation as resolved.
Show resolved Hide resolved
msg.es_msg().process, msg.instigator());

return FinalizeProto(santa_msg);
}

std::vector<uint8_t> Protobuf::SerializeFileAccess(const std::string &policy_version,
const std::string &policy_name,
const Message &msg,
Expand Down
10 changes: 10 additions & 0 deletions Source/santad/Logs/EndpointSecurity/Serializers/ProtobufTest.mm
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ JsonPrintOptions DefaultJsonPrintOptions() {
case ES_EVENT_TYPE_NOTIFY_LINK: return @"link.json";
case ES_EVENT_TYPE_NOTIFY_RENAME: return @"rename.json";
case ES_EVENT_TYPE_NOTIFY_UNLINK: return @"unlink.json";
case ES_EVENT_TYPE_NOTIFY_CS_INVALIDATED: return @"cs_invalidated.json";
default: XCTFail(@"Unhandled event type: %d", eventType); return nil;
}
}
Expand Down Expand Up @@ -145,6 +146,7 @@ bool CompareTime(const Timestamp &timestamp, struct timespec ts) {
case ::pbv1::SantaMessage::kBundle: return santaMsg.bundle();
case ::pbv1::SantaMessage::kAllowlist: return santaMsg.allowlist();
case ::pbv1::SantaMessage::kFileAccess: return santaMsg.file_access();
case ::pbv1::SantaMessage::kCodesigningInvalidated: return santaMsg.codesigning_invalidated();
case ::pbv1::SantaMessage::EVENT_NOT_SET:
XCTFail(@"Protobuf message SantaMessage did not set an 'event' field");
OS_FALLTHROUGH;
Expand Down Expand Up @@ -668,6 +670,14 @@ - (void)testSerializeMessageUnlink {
json:NO];
}

- (void)testSerializeMessageCodesigningInvalidated {
[self serializeAndCheckEvent:ES_EVENT_TYPE_NOTIFY_CS_INVALIDATED
messageSetup:^(std::shared_ptr<MockEndpointSecurityAPI> mockESApi,
es_message_t *esMsg) {
}
json:NO];
}

- (void)testGetAccessType {
std::map<es_event_type_t, ::pbv1::FileAccess::AccessType> eventTypeToAccessType = {
{ES_EVENT_TYPE_AUTH_CLONE, ::pbv1::FileAccess::ACCESS_TYPE_CLONE},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class Serializer {
const santa::santad::event_providers::endpoint_security::EnrichedRename &) = 0;
virtual std::vector<uint8_t> SerializeMessage(
const santa::santad::event_providers::endpoint_security::EnrichedUnlink &) = 0;
virtual std::vector<uint8_t> SerializeMessage(
const santa::santad::event_providers::endpoint_security::EnrichedCSInvalidated &) = 0;

virtual std::vector<uint8_t> SerializeFileAccess(
const std::string &policy_version, const std::string &policy_name,
Expand Down Expand Up @@ -95,6 +97,8 @@ class Serializer {
const santa::santad::event_providers::endpoint_security::EnrichedRename &);
std::vector<uint8_t> SerializeMessageTemplate(
const santa::santad::event_providers::endpoint_security::EnrichedUnlink &);
std::vector<uint8_t> SerializeMessageTemplate(
const santa::santad::event_providers::endpoint_security::EnrichedCSInvalidated &);

bool enabled_machine_id_ = false;
std::string machine_id_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,8 @@
std::vector<uint8_t> Serializer::SerializeMessageTemplate(const es::EnrichedUnlink &msg) {
return SerializeMessage(msg);
}
std::vector<uint8_t> Serializer::SerializeMessageTemplate(const es::EnrichedCSInvalidated &msg) {
return SerializeMessage(msg);
}

}; // namespace santa::santad::logs::endpoint_security::serializers
35 changes: 35 additions & 0 deletions Source/santad/testdata/protobuf/v1/cs_invalidated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"instigator": {
"id": {
"pid": 12,
"pidversion": 34
},
"parent_id": {
"pid": 56,
"pidversion": 78
},
"original_parent_pid": 56,
"group_id": 111,
"session_id": 222,
"effective_user": {
"uid": -2,
"name": "nobody"
},
"effective_group": {
"gid": -1,
"name": "nogroup"
},
"real_user": {
"uid": -2,
"name": "nobody"
},
"real_group": {
"gid": -1,
"name": "nogroup"
},
"executable": {
"path": "foo",
"truncated": false
}
}
}
35 changes: 35 additions & 0 deletions Source/santad/testdata/protobuf/v2/cs_invalidated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"instigator": {
"id": {
"pid": 12,
"pidversion": 34
},
"parent_id": {
"pid": 56,
"pidversion": 78
},
"original_parent_pid": 56,
"group_id": 111,
"session_id": 222,
"effective_user": {
"uid": -2,
"name": "nobody"
},
"effective_group": {
"gid": -1,
"name": "nogroup"
},
"real_user": {
"uid": -2,
"name": "nobody"
},
"real_group": {
"gid": -1,
"name": "nogroup"
},
"executable": {
"path": "foo",
"truncated": false
}
}
}
35 changes: 35 additions & 0 deletions Source/santad/testdata/protobuf/v4/cs_invalidated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"instigator": {
"id": {
"pid": 12,
"pidversion": 34
},
"parent_id": {
"pid": 56,
"pidversion": 78
},
"original_parent_pid": 56,
"group_id": 111,
"session_id": 222,
"effective_user": {
"uid": -2,
"name": "nobody"
},
"effective_group": {
"gid": -1,
"name": "nogroup"
},
"real_user": {
"uid": -2,
"name": "nobody"
},
"real_group": {
"gid": -1,
"name": "nogroup"
},
"executable": {
"path": "foo",
"truncated": false
}
}
}
35 changes: 35 additions & 0 deletions Source/santad/testdata/protobuf/v5/cs_invalidated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"instigator": {
"id": {
"pid": 12,
"pidversion": 34
},
"parent_id": {
"pid": 56,
"pidversion": 78
},
"original_parent_pid": 56,
"group_id": 111,
"session_id": 222,
"effective_user": {
"uid": -2,
"name": "nobody"
},
"effective_group": {
"gid": -1,
"name": "nogroup"
},
"real_user": {
"uid": -2,
"name": "nobody"
},
"real_group": {
"gid": -1,
"name": "nogroup"
},
"executable": {
"path": "foo",
"truncated": false
}
}
}
Loading