Skip to content

Commit a725a4c

Browse files
authored
Add logging support for ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME (#883)
Add full support for logging process suspend/resume events: - updated the proto to add a `ProcSuspendResume` message with instigator, target, and Type enum - updated enriched types and serializers - updated the Telemetry map with a new key `kProcSuspendResume` - updated notifier subscriptions to include the `NOTIFY_PROC_SUSPEND_RESUME` event - updated metrics - updated tests
1 parent 6becb3e commit a725a4c

29 files changed

Lines changed: 853 additions & 2 deletions

Source/common/TelemetryEventMap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ enum class TelemetryEvent : uint64_t {
4949
kLaunchItem = 1 << 21,
5050
kTCCModification = 1 << 22,
5151
kXProtect = 1 << 23,
52+
kProcSuspendResume = 1 << 24,
5253
kEverything = ~0ULL,
5354
};
5455
// clang-format on

Source/common/TelemetryEventMap.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static inline TelemetryEvent EventNameToMask(std::string_view event) {
5050
{"launchitem", TelemetryEvent::kLaunchItem},
5151
{"tccmodification", TelemetryEvent::kTCCModification},
5252
{"xprotect", TelemetryEvent::kXProtect},
53+
{"procsuspendresume", TelemetryEvent::kProcSuspendResume},
5354
// IMPORTANT: When adding new keys to the map, keep the set of keys in
5455
// `docs/src/lib/santaconfig.ts` in sync.
5556

@@ -114,6 +115,7 @@ TelemetryEvent ESEventToTelemetryEvent(es_event_type_t event) {
114115
#if HAVE_MACOS_15_4
115116
case ES_EVENT_TYPE_NOTIFY_TCC_MODIFY: return TelemetryEvent::kTCCModification;
116117
#endif // HAVE_MACOS_15_4
118+
case ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME: return TelemetryEvent::kProcSuspendResume;
117119
default: return TelemetryEvent::kNone;
118120
}
119121
}

Source/common/TelemetryEventMapTest.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ - (void)testTelemetryConfigToBitmask {
6060
{"LaunchItem", TelemetryEvent::kLaunchItem},
6161
{"TCCModification", TelemetryEvent::kTCCModification},
6262
{"XProtect", TelemetryEvent::kXProtect},
63+
{"ProcSuspendResume", TelemetryEvent::kProcSuspendResume},
6364

6465
// special cases
6566
{"none", TelemetryEvent::kNone},
@@ -112,6 +113,7 @@ - (void)testESEventToTelemetryEvent {
112113
{ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_REMOVE, TelemetryEvent::kLaunchItem},
113114
{ES_EVENT_TYPE_NOTIFY_XP_MALWARE_DETECTED, TelemetryEvent::kXProtect},
114115
{ES_EVENT_TYPE_NOTIFY_XP_MALWARE_REMEDIATED, TelemetryEvent::kXProtect},
116+
{ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME, TelemetryEvent::kProcSuspendResume},
115117
#if HAVE_MACOS_15
116118
{ES_EVENT_TYPE_NOTIFY_GATEKEEPER_USER_OVERRIDE, TelemetryEvent::kGatekeeperOverride},
117119
#endif // HAVE_MACOS_15

Source/common/es/EnrichedTypes.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,23 @@ class EnrichedCSInvalidated : public EnrichedEventType {
344344
EnrichedCSInvalidated(const EnrichedCSInvalidated& other) = delete;
345345
};
346346

347+
class EnrichedProcSuspendResume : public EnrichedEventType {
348+
public:
349+
EnrichedProcSuspendResume(Message&& es_msg, EnrichedProcess&& instigator,
350+
std::optional<EnrichedProcess>&& target)
351+
: EnrichedEventType(std::move(es_msg), std::move(instigator)),
352+
target_(std::move(target)) {}
353+
354+
EnrichedProcSuspendResume(EnrichedProcSuspendResume&&) = default;
355+
356+
EnrichedProcSuspendResume(const EnrichedProcSuspendResume& other) = delete;
357+
358+
const std::optional<EnrichedProcess>& target() const { return target_; }
359+
360+
private:
361+
std::optional<EnrichedProcess> target_;
362+
};
363+
347364
// Note: All EnrichedLoginWindowSession* classes currently have the same
348365
// data and implementation. To improve maintainability but still provide
349366
// individual types, an internal EnrichedLoginWindowSession base class is
@@ -780,7 +797,8 @@ using EnrichedType = std::variant<
780797
EnrichedLoginLogout, EnrichedAuthenticationOD,
781798
EnrichedAuthenticationTouchID, EnrichedAuthenticationToken,
782799
EnrichedAuthenticationAutoUnlock, EnrichedClone, EnrichedCopyfile,
783-
EnrichedLaunchItem, EnrichedXProtectDetected, EnrichedXProtectRemediated
800+
EnrichedProcSuspendResume, EnrichedLaunchItem, EnrichedXProtectDetected,
801+
EnrichedXProtectRemediated
784802
#if HAVE_MACOS_15
785803
,
786804
EnrichedGatekeeperOverride

Source/common/es/Enricher.mm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@
188188
std::move(es_msg), Enrich(*es_msg->process), Enrich(es_msg->event.tcc_modify->instigator),
189189
Enrich(es_msg->event.tcc_modify->responsible)));
190190
#endif // HAVE_MACOS_15_4
191+
case ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME: {
192+
std::optional<EnrichedProcess> target;
193+
if (es_msg->event.proc_suspend_resume.target) {
194+
target.emplace(Enrich(*es_msg->event.proc_suspend_resume.target));
195+
}
196+
return std::make_unique<EnrichedMessage>(EnrichedProcSuspendResume(
197+
std::move(es_msg), Enrich(*es_msg->process), std::move(target)));
198+
}
191199
default:
192200
// This is a programming error
193201
LOGE(@"Attempting to enrich an unhandled event type: %d", es_msg->event_type);

Source/common/santa.proto

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,24 @@ message NetworkActivity {
12301230
repeated Process processes = 1;
12311231
}
12321232

1233+
// Information about a process suspend/resume event
1234+
message ProcSuspendResume {
1235+
// The process initiating the suspend/resume
1236+
optional ProcessInfoLight instigator = 1;
1237+
1238+
// The target process being suspended/resumed
1239+
optional ProcessInfo target = 2;
1240+
1241+
// The type of suspend/resume action
1242+
enum Type {
1243+
TYPE_UNKNOWN = 0;
1244+
TYPE_SUSPEND = 1;
1245+
TYPE_RESUME = 2;
1246+
TYPE_SHUTDOWN_SOCKETS = 3;
1247+
}
1248+
optional Type type = 3;
1249+
}
1250+
12331251
// A message encapsulating a single event
12341252
message SantaMessage {
12351253
// Machine ID of the host emitting this log
@@ -1273,6 +1291,7 @@ message SantaMessage {
12731291
TCCModification tcc_modification = 32;
12741292
XProtect xprotect = 33;
12751293
NetworkActivity network_activity = 34;
1294+
ProcSuspendResume proc_suspend_resume = 35;
12761295
}
12771296
}
12781297

Source/santad/EventProviders/SNTEndpointSecurityRecorder.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ - (void)enable {
223223
ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_REMOVE,
224224
ES_EVENT_TYPE_NOTIFY_XP_MALWARE_DETECTED,
225225
ES_EVENT_TYPE_NOTIFY_XP_MALWARE_REMEDIATED,
226+
ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME,
226227
};
227228

228229
#if HAVE_MACOS_15

Source/santad/EventProviders/SNTEndpointSecurityRecorderTest.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ - (void)setUp {
101101
ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD,
102102
ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_REMOVE,
103103
ES_EVENT_TYPE_NOTIFY_XP_MALWARE_DETECTED,
104-
ES_EVENT_TYPE_NOTIFY_XP_MALWARE_REMEDIATED};
104+
ES_EVENT_TYPE_NOTIFY_XP_MALWARE_REMEDIATED,
105+
ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME};
105106

106107
#if HAVE_MACOS_15
107108
if (@available(macOS 15.0, *)) {

Source/santad/Logs/EndpointSecurity/Serializers/BasicString.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class BasicString : public Serializer {
5151
std::vector<uint8_t> SerializeMessage(const santa::EnrichedCSInvalidated&) override;
5252
std::vector<uint8_t> SerializeMessage(const santa::EnrichedClone&) override;
5353
std::vector<uint8_t> SerializeMessage(const santa::EnrichedCopyfile&) override;
54+
std::vector<uint8_t> SerializeMessage(const santa::EnrichedProcSuspendResume&) override;
5455
std::vector<uint8_t> SerializeMessage(const santa::EnrichedLoginWindowSessionLogin&) override;
5556
std::vector<uint8_t> SerializeMessage(const santa::EnrichedLoginWindowSessionLogout&) override;
5657
std::vector<uint8_t> SerializeMessage(const santa::EnrichedLoginWindowSessionLock&) override;

Source/santad/Logs/EndpointSecurity/Serializers/BasicString.mm

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,30 @@ static inline void AppendSocketAddress(std::string& str, es_address_type_t type,
520520
return FinalizeString(str);
521521
}
522522

523+
std::vector<uint8_t> BasicString::SerializeMessage(const EnrichedProcSuspendResume& msg) {
524+
std::string str = CreateDefaultString();
525+
526+
str.append("action=PROC_SUSPEND_RESUME");
527+
528+
switch (msg->event.proc_suspend_resume.type) {
529+
case ES_PROC_SUSPEND_RESUME_TYPE_SUSPEND: str.append("|type=SUSPEND"); break;
530+
case ES_PROC_SUSPEND_RESUME_TYPE_RESUME: str.append("|type=RESUME"); break;
531+
case ES_PROC_SUSPEND_RESUME_TYPE_SHUTDOWN_SOCKETS: str.append("|type=SHUTDOWN_SOCKETS"); break;
532+
default: str.append("|type=UNKNOWN"); break;
533+
}
534+
535+
if (msg->event.proc_suspend_resume.target) {
536+
str.append("|targetpid=");
537+
str.append(std::to_string(Pid(msg->event.proc_suspend_resume.target->audit_token)));
538+
str.append("|targetpath=");
539+
str.append(FilePath(msg->event.proc_suspend_resume.target->executable).Sanitized());
540+
}
541+
542+
AppendInstigator(str, msg);
543+
544+
return FinalizeString(str);
545+
}
546+
523547
std::vector<uint8_t> BasicString::SerializeMessage(const EnrichedLoginWindowSessionLogin& msg) {
524548
std::string str = CreateDefaultString();
525549

0 commit comments

Comments
 (0)