From 9e0c2a79127be15ea30548884b03db52c770eed9 Mon Sep 17 00:00:00 2001
From: Kostas
Date: Mon, 16 Dec 2024 22:17:28 -0800
Subject: [PATCH] Enhance Linux Telemetry with New Features and Improvements
(#99)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Uptycs addition
* Update EDR_telem.json
Updates based on evidence to be provided.
* Update EDR_telem.json
Minor correction to match evidence provided.
* Post-review update for Uptycs
* Update EDR_telem.json
Changes per updated evidence provided privately.
* Update EDR_telem.json: Update Process Access to "No"
* Initial commit for linux telemetry generator script.
* Refactor Linux telemetry generator script to include user account activities
* Remove unused imports from Linux telemetry generator script
* Add process hijack demo script using ptrace as suggested here: https://github.com/tsale/EDR-Telemetry/issues/21#issuecomment-2450048423
* Update raw_access_read function to read from /dev/sda in read-only mode and improve error handling
* Fix function name typo in process_hijack_demo.py and refactor network socket management in lnx_telem_gen.py
* Rename process_access to start_hijacking and update references; add network_connect method to NetworkSocketManager
* Remove commented-out main function and unused RemoteLibraryInjector class from lnx_telem_gen.py
* Refactor error handling in driver_load.py, scheduled_task.py, and process_tampering.py; add success messages and improve exception raising. Added README file.
* Add eBPF execution functionality via pamspy
* Update LINUX_TELEMETRY_GENERATOR_GUIDE.md
* Remove requirements.txt and correct apt installations for Debian in LINUX_TELEMETRY_GENERATOR_GUIDE.md
* Enhance Linux Telemetry Generator: Add PrettyTable dependency, improve process filtering, and implement execution summary logging
* Restore ProcessAccess event handling and reduce delay between events in lnx_telem_gen.py
* Add EDR telemetry configuration for process, file, user, network, and service activities
* Linux telem update
* Add Linux support to EDR telemetry scoring and enhance command line interface
* Refactor SentinelOne field in EDR telemetry configuration to remove redundancy
* No code changes made.
---------
Co-authored-by: Josh Lemon - Uptycs <116134008+joshlemon-uptycs@users.noreply.github.com>
Co-authored-by: SecurityAura
Co-authored-by: Ján Trenčanský
Co-authored-by: mthcht "
---
EDR_telem.json | 2 +-
EDR_telem_linux.json | 422 ++++++
EDR_telem_windows.json | 1168 +++++++++++++++++
README.md | 24 +-
.../Linux/LINUX_TELEMETRY_GENERATOR_GUIDE.md | 84 ++
.../Linux/complex/driver_load.py | 116 ++
.../Linux/complex/eBPF_exec.py | 52 +
.../Linux/complex/process_hijack_demo.py | 152 +++
.../Linux/complex/process_tampering.py | 161 +++
.../Linux/complex/scheduled_task.py | 86 ++
.../Linux/lnx_telem_gen.py | 390 ++++++
.../{ => Windows}/README.md | 0
.../{ => Windows}/config.json | 0
.../{ => Windows}/telemetry-generator.ps1 | 0
.../{ => Windows}/telemetry-mappings.csv | 0
Tools/compare.py | 158 ++-
partially_value_explanations_linux.json | 422 ++++++
17 files changed, 3154 insertions(+), 83 deletions(-)
create mode 100644 EDR_telem_linux.json
create mode 100644 EDR_telem_windows.json
create mode 100644 Tools/Telemetry-Generator/Linux/LINUX_TELEMETRY_GENERATOR_GUIDE.md
create mode 100644 Tools/Telemetry-Generator/Linux/complex/driver_load.py
create mode 100644 Tools/Telemetry-Generator/Linux/complex/eBPF_exec.py
create mode 100644 Tools/Telemetry-Generator/Linux/complex/process_hijack_demo.py
create mode 100644 Tools/Telemetry-Generator/Linux/complex/process_tampering.py
create mode 100644 Tools/Telemetry-Generator/Linux/complex/scheduled_task.py
create mode 100644 Tools/Telemetry-Generator/Linux/lnx_telem_gen.py
rename Tools/Telemetry-Generator/{ => Windows}/README.md (100%)
rename Tools/Telemetry-Generator/{ => Windows}/config.json (100%)
rename Tools/Telemetry-Generator/{ => Windows}/telemetry-generator.ps1 (100%)
rename Tools/Telemetry-Generator/{ => Windows}/telemetry-mappings.csv (100%)
create mode 100644 partially_value_explanations_linux.json
diff --git a/EDR_telem.json b/EDR_telem.json
index 4d78b80..a02aa95 100644
--- a/EDR_telem.json
+++ b/EDR_telem.json
@@ -1165,4 +1165,4 @@
"Uptycs":"Yes",
"WatchGuard":"No"
}
-]
+]
\ No newline at end of file
diff --git a/EDR_telem_linux.json b/EDR_telem_linux.json
new file mode 100644
index 0000000..f402c3c
--- /dev/null
+++ b/EDR_telem_linux.json
@@ -0,0 +1,422 @@
+[
+ {
+ "Telemetry Feature Category":"Process Activity",
+ "Sub-Category":"Process Creation",
+ "SentinelOne":"Yes",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Elastic":"Yes",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Process Termination",
+ "SentinelOne":"No",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"No",
+ "Elastic":"Yes",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"File Manipulation",
+ "Sub-Category":"File Creation",
+ "SentinelOne":"Yes",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"Yes",
+ "Elastic":"Yes",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"File Modification",
+ "SentinelOne":"Yes",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"Yes",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"File Deletion",
+ "SentinelOne":"Yes",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"No",
+ "Sysmon":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"Yes",
+ "Elastic":"Yes",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":"User Activity",
+ "Sub-Category":"User Logon",
+ "SentinelOne":"Yes",
+ "Qualys":"No",
+ "Uptycs":"Yes",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"Yes",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"User Logoff",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"Yes",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Logon Failed",
+ "SentinelOne":"Yes",
+ "Qualys":"No",
+ "Uptycs":"Yes",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"Script Activity",
+ "Sub-Category":"Script Content",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"Yes",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"Network Activity",
+ "Sub-Category":"Network Connection",
+ "SentinelOne":"Yes",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Elastic":"Yes",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Network Socket Listen",
+ "SentinelOne":"No",
+ "Qualys":"Partially",
+ "Uptycs":"No",
+ "CrowdStrike":"Yes",
+ "Sysmon":"No",
+ "LimaCharlie":"Partially",
+ "MDE":"No",
+ "Elastic":"Yes",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"DNS Query",
+ "SentinelOne":"Yes",
+ "Qualys":"Via EnablingTelemetry",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"No",
+ "LimaCharlie":"Yes",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"Scheduled Task Activity",
+ "Sub-Category":"Scheduled Task",
+ "SentinelOne":"Yes",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"User Account Activity",
+ "Sub-Category":"User Account Created",
+ "SentinelOne":"Yes",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"User Account Modified",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"User Account Deleted",
+ "SentinelOne":"Yes",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"Driver\/Module Activity",
+ "Sub-Category":"Driver Load",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Image Load",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"eBPF Event",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"Via EnablingTelemetry",
+ "CrowdStrike":"Yes",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"Access Activity",
+ "Sub-Category":"Raw Access Read",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"Via EnablingTelemetry",
+ "CrowdStrike":"No",
+ "Sysmon":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Process Access",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"Via EnablingTelemetry",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"Process Tampering Activity",
+ "Sub-Category":"Process Tampering",
+ "SentinelOne":"Yes",
+ "Qualys":"No",
+ "Uptycs":"Via EnablingTelemetry",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"Yes",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"Service Activity",
+ "Sub-Category":"Service Creation",
+ "SentinelOne":"Yes",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Service Modification",
+ "SentinelOne":"Yes",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Service Deletion",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"No"
+ },
+ {
+ "Telemetry Feature Category":"EDR SysOps",
+ "Sub-Category":"Agent Start",
+ "SentinelOne":"Yes",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"No",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Elastic":"Yes",
+ "Auditd":"No",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Agent Stop",
+ "SentinelOne":"Yes",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"No",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Elastic":"Yes",
+ "Auditd":"No",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":"Hash Algorithms",
+ "Sub-Category":"MD5",
+ "SentinelOne":"No",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Elastic":"Yes",
+ "Auditd":"No",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"SHA",
+ "SentinelOne":"Yes",
+ "Qualys":"Yes",
+ "Uptycs":"Yes",
+ "CrowdStrike":"Yes",
+ "Sysmon":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Elastic":"Yes",
+ "Auditd":"No",
+ "Carbon Black Cloud":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"IMPHASH",
+ "SentinelOne":"No",
+ "Qualys":"No",
+ "Uptycs":"No",
+ "CrowdStrike":"No",
+ "Sysmon":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Elastic":"No",
+ "Auditd":"No",
+ "Carbon Black Cloud":"Yes"
+ }
+]
\ No newline at end of file
diff --git a/EDR_telem_windows.json b/EDR_telem_windows.json
new file mode 100644
index 0000000..a02aa95
--- /dev/null
+++ b/EDR_telem_windows.json
@@ -0,0 +1,1168 @@
+[
+ {
+ "Telemetry Feature Category":"Process Activity",
+ "Sub-Category":"Process Creation",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Process Termination",
+ "Carbon Black":"Partially",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"No",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"No",
+ "Trend Micro":"Via EnablingTelemetry",
+ "Uptycs":"No",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Process Access",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Partially",
+ "Elastic":"Yes",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"No",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Image\/Library Loaded",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Remote Thread Creation",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Process Tampering Activity",
+ "Carbon Black":"Partially",
+ "Cortex XDR":"Partially",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Pending Response",
+ "ESET Inspect":"No",
+ "Elastic":"Yes",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"Partially",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"File Manipulation",
+ "Sub-Category":"File Creation",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Partially",
+ "Elastic":"Yes",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Partially"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"File Opened",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"No",
+ "CrowdStrike":"Partially",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Partially",
+ "MDE":"No",
+ "Qualys":"Yes",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EnablingTelemetry",
+ "Uptycs":"Yes",
+ "WatchGuard":"Partially"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"File Deletion",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"No",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EnablingTelemetry",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"File Modification",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"File Renaming",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Partially",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Partially"
+ },
+ {
+ "Telemetry Feature Category":"User Account Activity",
+ "Sub-Category":"Local Account Creation",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"Yes",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Via EventLogs",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Local Account Modification",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Partially",
+ "Cybereason":"No",
+ "ESET Inspect":"Yes",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Via EventLogs",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Via EventLogs",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Local Account Deletion",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"Yes",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Via EventLogs",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Via EventLogs",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EnablingTelemetry",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Account Login",
+ "Carbon Black":"Via EventLogs",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Partially",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Account Logoff",
+ "Carbon Black":"Via EventLogs",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Via EventLogs",
+ "MDE":"No",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":"Network Activity",
+ "Sub-Category":"TCP Connection",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"UDP Connection",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"No",
+ "Elastic":"Yes",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"URL",
+ "Carbon Black":"No",
+ "Cortex XDR":"No",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"Yes",
+ "Elastic":"Partially",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Via EnablingTelemetry",
+ "Symantec SES Complete":"Partially",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"No",
+ "Uptycs":"Yes",
+ "WatchGuard":"Partially"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"DNS Query",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"File Downloaded",
+ "Carbon Black":"No",
+ "Cortex XDR":"No",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Partially",
+ "ESET Inspect":"Partially",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"No",
+ "LimaCharlie":"Partially",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"Yes",
+ "Uptycs":"Partially",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":"Hash Algorithms",
+ "Sub-Category":"MD5",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"SHA",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"IMPHASH",
+ "Carbon Black":"No",
+ "Cortex XDR":"No",
+ "CrowdStrike":"No",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"Partially",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Qualys":"No",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"No",
+ "Sysmon":"Yes",
+ "Trellix":"No",
+ "Trend Micro":"No",
+ "Uptycs":"No",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"Registry Activity",
+ "Sub-Category":"Key\/Value Creation",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Partially",
+ "Cybereason":"Partially",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Key\/Value Modification",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Partially",
+ "Cybereason":"Partially",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Key\/Value Deletion",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"No",
+ "Cybereason":"Partially",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":"Schedule Task Activity",
+ "Sub-Category":"Scheduled Task Creation",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Via EventLogs",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Scheduled Task Modification",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"No",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Via EventLogs",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Scheduled Task Deletion",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Via EventLogs",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"Service Activity",
+ "Sub-Category":"Service Creation",
+ "Carbon Black":"Partially",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Yes",
+ "MDE":"Via EventLogs",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Yes",
+ "WatchGuard":"Partially"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Service Modification",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Partially",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Via EventLogs",
+ "LimaCharlie":"Yes",
+ "MDE":"No",
+ "Qualys":"Yes",
+ "SentinelOne":"Via EnablingTelemetry",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Yes",
+ "WatchGuard":"Partially"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Service Deletion",
+ "Carbon Black":"No",
+ "Cortex XDR":"No",
+ "CrowdStrike":"No",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"Via EventLogs",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"No",
+ "LimaCharlie":"Pending Response",
+ "MDE":"No",
+ "Qualys":"No",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"Driver\/Module Activity",
+ "Sub-Category":"Driver Loaded",
+ "Carbon Black":"No",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EnablingTelemetry",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"Yes",
+ "Trellix":"No",
+ "Trend Micro":"Via EnablingTelemetry",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Driver Modification",
+ "Carbon Black":"No",
+ "Cortex XDR":"No",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"No",
+ "LimaCharlie":"Yes",
+ "MDE":"No",
+ "Qualys":"Yes",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"No",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Driver Unloaded",
+ "Carbon Black":"No",
+ "Cortex XDR":"No",
+ "CrowdStrike":"No",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Qualys":"No",
+ "SentinelOne":"Partially",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"No",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"Device Operations",
+ "Sub-Category":"Virtual Disk Mount",
+ "Carbon Black":"No",
+ "Cortex XDR":"Partially",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"No",
+ "LimaCharlie":"Yes",
+ "MDE":"No",
+ "Qualys":"No",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"No",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"USB Device Unmount",
+ "Carbon Black":"No",
+ "Cortex XDR":"Partially",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"No",
+ "LimaCharlie":"Partially",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"Via EnablingTelemetry",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"No",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"USB Device Mount",
+ "Carbon Black":"Partially",
+ "Cortex XDR":"Partially",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"No",
+ "LimaCharlie":"Partially",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"Via EnablingTelemetry",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"No",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":"Other Relevant Events",
+ "Sub-Category":"Group Policy Modification",
+ "Carbon Black":"No",
+ "Cortex XDR":"No",
+ "CrowdStrike":"No",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"No",
+ "LimaCharlie":"No",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"No",
+ "Trend Micro":"No",
+ "Uptycs":"Via EventLogs",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"Named Pipe Activity",
+ "Sub-Category":"Pipe Creation",
+ "Carbon Black":"Partially",
+ "Cortex XDR":"No",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"Yes",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"Via EnablingTelemetry",
+ "Symantec SES Complete":"No",
+ "Sysmon":"Yes",
+ "Trellix":"No",
+ "Trend Micro":"Via EnablingTelemetry",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Pipe Connection",
+ "Carbon Black":"No",
+ "Cortex XDR":"No",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"No",
+ "SentinelOne":"Via EnablingTelemetry",
+ "Symantec SES Complete":"No",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EnablingTelemetry",
+ "Uptycs":"No",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"EDR SysOps",
+ "Sub-Category":"Agent Start",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Partially",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Via EventLogs",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"Yes",
+ "Trellix":"Pending Response",
+ "Trend Micro":"No",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Agent Stop",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"No",
+ "Elastic":"Yes",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Via EventLogs",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"Yes",
+ "Trellix":"Pending Response",
+ "Trend Micro":"No",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Agent Install",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"No",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"No",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Via EventLogs",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"No",
+ "Uptycs":"No",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Agent Uninstall",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Yes",
+ "Harfanglab":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Qualys":"No",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"No",
+ "Uptycs":"No",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Agent Keep-Alive",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"No",
+ "FortiEDR":"No",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Via EventLogs",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"No",
+ "Trellix":"Pending Response",
+ "Trend Micro":"No",
+ "Uptycs":"No",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"Agent Errors",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Yes",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Yes",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Yes",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Via EnablingTelemetry",
+ "Sysmon":"Yes",
+ "Trellix":"Pending Response",
+ "Trend Micro":"No",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"WMI Activity",
+ "Sub-Category":"WmiEventConsumerToFilter",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EnablingTelemetry",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Partially",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"WmiEventConsumer",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EnablingTelemetry",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Partially",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":null,
+ "Sub-Category":"WmiEventFilter",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EnablingTelemetry",
+ "CrowdStrike":"Yes",
+ "Cybereason":"Yes",
+ "ESET Inspect":"Yes",
+ "Elastic":"Yes",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"No",
+ "MDE":"Yes",
+ "Qualys":"Via EventLogs",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Partially",
+ "Sysmon":"Yes",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"Yes",
+ "WatchGuard":"Yes"
+ },
+ {
+ "Telemetry Feature Category":"BIT JOBS Activity",
+ "Sub-Category":"BIT JOBS Activity",
+ "Carbon Black":"No",
+ "Cortex XDR":"Via EnablingTelemetry",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"No",
+ "Elastic":"No",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"No",
+ "LimaCharlie":"No",
+ "MDE":"No",
+ "Qualys":"Yes",
+ "SentinelOne":"No",
+ "Symantec SES Complete":"No",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Via EventLogs",
+ "Uptycs":"No",
+ "WatchGuard":"No"
+ },
+ {
+ "Telemetry Feature Category":"PowerShell Activity",
+ "Sub-Category":"Script-Block Activity",
+ "Carbon Black":"Yes",
+ "Cortex XDR":"Via EventLogs",
+ "CrowdStrike":"Yes",
+ "Cybereason":"No",
+ "ESET Inspect":"Yes",
+ "Elastic":"No",
+ "FortiEDR":"Via EventLogs",
+ "Harfanglab":"Yes",
+ "LimaCharlie":"Via EventLogs",
+ "MDE":"Yes",
+ "Qualys":"Yes",
+ "SentinelOne":"Yes",
+ "Symantec SES Complete":"Yes",
+ "Sysmon":"No",
+ "Trellix":"Yes",
+ "Trend Micro":"Yes",
+ "Uptycs":"Yes",
+ "WatchGuard":"No"
+ }
+]
\ No newline at end of file
diff --git a/README.md b/README.md
index 91546dd..22f307d 100644
--- a/README.md
+++ b/README.md
@@ -56,27 +56,7 @@ For more details, you can refer to the [Pull Request #61](https://github.com/tsa
### EDR Scores
-| **No.** | **EDRs** | **Score** |
-|---------|-----------------------|-----------|
-| 1 | CrowdStrike | 37.45 |
-| 2 | SentinelOne | 34.25 |
-| 3 | MDE | 34.2 |
-| 4 | Uptycs | 33.85 |
-| 5 | Trellix | 30.6 |
-| 6 | Harfanglab | 30.45 |
-| 7 | Cortex XDR | 29.65 |
-| 8 | Elastic | 29.35 |
-| 9 | LimaCharlie | 29.25 |
-| 10 | Trend Micro | 28.85 |
-| 11 | ESET Inspect | 28.1 |
-| 12 | Qualys | 27.45 |
-| 13 | Cybereason | 25.65 |
-| 14 | Symantec SES Complete | 24.3 |
-| 15 | FortiEDR | 23.9 |
-| 16 | Sysmon | 23.2 |
-| 17 | Carbon Black | 22.7 |
-| 18 | WatchGuard | 20.9 |
-
+You can find the telemetry scores by visiting [the scores](https://www.edr-telemetry.com/scores.html) on the official website.
## EDR Telemetry Table
Below is information about the EDR table, including all values for each EDR and a description for each attribute.
@@ -185,4 +165,4 @@ Thanks to these amazing contributors:
## Current Primary Maintainers
-Kostas - [@kostastsale](https://twitter.com/Kostastsale)
+Kostas - [@kostastsale](https://twitter.com/Kostastsale)
\ No newline at end of file
diff --git a/Tools/Telemetry-Generator/Linux/LINUX_TELEMETRY_GENERATOR_GUIDE.md b/Tools/Telemetry-Generator/Linux/LINUX_TELEMETRY_GENERATOR_GUIDE.md
new file mode 100644
index 0000000..9a3111b
--- /dev/null
+++ b/Tools/Telemetry-Generator/Linux/LINUX_TELEMETRY_GENERATOR_GUIDE.md
@@ -0,0 +1,84 @@
+# Linux Telemetry Generator
+
+## Overview
+
+This script, `lnx_telem_gen.py`, is designed to generate various telemetry events for the EDR (Endpoint Detection and Response) telemetry project. The script performs a wide range of activities that are typically monitored by EDR solutions, such as file operations, network connections, process manipulation, and more. The goal is to help validate that the EDR solution is correctly capturing and reporting these events.
+
+## Features
+
+The script includes the following functionalities:
+
+1. **File Operations**: Create, modify, and delete files.
+2. **DNS Query**: Perform a DNS query.
+3. **Process Termination**: Create and terminate a process.
+4. **Image Load**: Load a shared library.
+5. **Process Access**: Hijack a process and manipulate its memory and registers.
+6. **Network Connections**: Establish TCP connections and create raw sockets.
+7. **Service Start/Stop**: Start and stop a service using system calls.
+8. **Raw Access Read**: Perform raw read access on a device.
+9. **Driver Load**: Write, compile, and load a Linux kernel module.
+10. **Process Tampering**: Tamper with the memory of a running process.
+11. **Scheduled Task**: Create and remove scheduled tasks using cron.
+12. **User Account Events**: Create, modify, and delete user accounts.
+13. **Network Listening**: Create a listening socket for incoming TCP connections.
+14. **eBPF Events**: Utilizing pamspy, a credential dumper, that is using eBPF thus generating the needed eBPF related events.
+
+## Usage
+
+To run the script, use the following command:
+
+```bash
+python3 lnx_telem_gen.py [Event1 Event2 ...]
+```
+If no events are specified, the script will run all available events. You can specify one or more events to run only those specific tests.
+
+**Example**
+
+```bash
+python3 lnx_telem_gen.py FileCreated DnsQuery NetworkConnect
+```
+
+This command will run the `FileCreated`, `DnsQuery`, and `NetworkConnect` events.
+
+## Event List
+
+- `FileCreated`
+- `FileModified`
+- `FileDelete`
+- `DnsQuery`
+- `ProcessTerminate`
+- `ImageLoad`
+- `ProcessAccess`
+- `NetworkConnect`
+- `ServiceStartStop`
+- `RawAccessRead`
+- `LoadDriver`
+- `TamperProcess`
+- `ScheduledTask`
+- `UserAccountEvents`
+- `NetworkListen`
+- `NetworkRawSocket`
+- `eBPFProgram`
+
+## Disclaimers
+
+- **Best Effort**: This script is provided on a best-effort basis. If you do not see telemetry events for a specific category, please refer to the official documentation for your EDR vendor.
+- **System Calls**: These tests are designed to avoid reliance on system binaries, which could allow the EDR to infer activity based on command line arguments or binaries executed on the host. Instead, this script uses system calls to perform the actions.
+
+## Logging
+The script logs the output of each function to a CSV file named `function_output_log.csv`. This file includes the function name, output, and any errors encountered during execution.
+
+## Requirements
+- Python 3.x
+- Required Python packages: `dbus-python`, `libuser`, `ctypes`
+
+## Installation
+To install the required packages on a Debian host, run:
+
+```bash
+sudo apt-get install -y python3-dbus python3-libuser git linux-headers-$(uname -r)
+pip install prettytable
+```
+
+## License
+This project is licensed under the MIT License.
\ No newline at end of file
diff --git a/Tools/Telemetry-Generator/Linux/complex/driver_load.py b/Tools/Telemetry-Generator/Linux/complex/driver_load.py
new file mode 100644
index 0000000..d8a7fd8
--- /dev/null
+++ b/Tools/Telemetry-Generator/Linux/complex/driver_load.py
@@ -0,0 +1,116 @@
+import os
+import ctypes
+import subprocess
+
+
+###
+ # This script writes, compiles, and loads a simple Linux kernel module.
+ # It performs the following steps:
+ # 1. Writes a C source file for a test kernel module.
+ # 2. Writes a Makefile to compile the kernel module.
+ # 3. Compiles the kernel module using the Makefile.
+ # 4. Loads the compiled kernel module into the kernel using the finit_module system call.
+###
+
+# Constants for system call numbers (Linux-specific)
+SYS_finit_module = 313 # On x86_64; this number may vary by architecture
+
+# Load the C library (libc) which contains system calls
+libc = ctypes.CDLL("libc.so.6")
+
+# Define finit_module prototype and parameters in ctypes
+# int finit_module(int fd, const char *param_values, int flags);
+libc.syscall.argtypes = [ctypes.c_long, ctypes.c_int, ctypes.c_char_p, ctypes.c_int]
+libc.syscall.restype = ctypes.c_int
+
+def write_test_driver():
+ """Write the test driver C code to a file."""
+ driver_code = """
+ #include // Needed by all kernel modules
+ #include // Needed for KERN_INFO
+ #include // Needed for __init and __exit macros
+
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Your Name");
+ MODULE_DESCRIPTION("A Simple Test Kernel Module");
+
+ // Function that runs when the module is loaded
+ static int __init test_driver_init(void) {
+ printk(KERN_INFO "Test Driver Loaded: Hello, Kernel!\\n");
+ return 0; // Return 0 means successful loading
+ }
+
+ // Function that runs when the module is unloaded
+ static void __exit test_driver_exit(void) {
+ printk(KERN_INFO "Test Driver Unloaded: Goodbye, Kernel!\\n");
+ }
+
+ // Macros that specify the initialization and cleanup functions
+ module_init(test_driver_init);
+ module_exit(test_driver_exit);
+ """
+
+ # Write to a file
+ with open("test_driver.c", "w") as f:
+ f.write(driver_code)
+ print("Test driver code written to 'test_driver.c'.")
+
+def write_makefile():
+ """Write the Makefile to compile the kernel module."""
+ makefile_content = """
+obj-m += test_driver.o
+
+all:
+\tmake -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+
+clean:
+\tmake -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
+ """
+ # Write the Makefile to the current directory
+ with open("Makefile", "w") as f:
+ f.write(makefile_content)
+ print("Makefile written.")
+
+def compile_driver():
+ """Compile the kernel module using the Makefile."""
+ try:
+ subprocess.run(["make"], check=True)
+ print("Kernel module compiled successfully.")
+ except subprocess.CalledProcessError:
+ print("Failed to compile the kernel module.")
+ raise Exception("Kernel module compilation failed") # Raise an exception instead
+
+def load_kernel_module(module_path, params=""):
+ """Load the kernel module using the finit_module system call."""
+ fd = os.open(module_path, os.O_RDONLY)
+
+ if fd < 0:
+ print(f"Failed to open module file: {module_path}")
+ return
+
+ # Make the finit_module system call
+ ret = libc.syscall(SYS_finit_module, fd, params.encode('utf-8'), 0)
+
+ # If ret == 0, the module was loaded successfully
+ if ret == 0:
+ print(f"Module {module_path} loaded successfully.")
+ else:
+ # Handle the case where finit_module fails
+ errno = ctypes.get_errno()
+ print(f"Failed to load module: {os.strerror(errno)}")
+
+ os.close(fd)
+
+def loadit():
+ # Write the driver C code and Makefile
+ write_test_driver()
+ write_makefile()
+
+ # Compile the kernel module
+ compile_driver()
+
+ # Load the kernel module using finit_module system call
+ module_path = "./test_driver.ko" # The compiled kernel module
+ load_kernel_module(module_path)
+
+ return "Driver loaded successfully."
\ No newline at end of file
diff --git a/Tools/Telemetry-Generator/Linux/complex/eBPF_exec.py b/Tools/Telemetry-Generator/Linux/complex/eBPF_exec.py
new file mode 100644
index 0000000..0f316d9
--- /dev/null
+++ b/Tools/Telemetry-Generator/Linux/complex/eBPF_exec.py
@@ -0,0 +1,52 @@
+import os
+import subprocess
+import urllib.request
+
+def download_pamspy():
+ """
+ Downloads the pamspy binary from the specified URL and saves it locally.
+ """
+ url = "https://github.com/citronneur/pamspy/releases/download/v0.3/pamspy"
+ local_path = "./pamspy"
+ try:
+ print(f"Downloading pamspy from {url}...")
+ urllib.request.urlretrieve(url, local_path)
+ os.chmod(local_path, 0o755) # Make the downloaded file executable
+ print("Download complete.")
+ except Exception as e:
+ print(f"Failed to download pamspy: {e}")
+ raise
+
+def execute_pamspy():
+ """
+ Executes the pamspy binary with the specified arguments.
+ Returns:
+ int: The return code of the executed command.
+ """
+ pam_path_command = "/usr/sbin/ldconfig -p | grep libpam.so | cut -d ' ' -f4"
+ try:
+ # Get the path to libpam.so
+ pam_path = subprocess.check_output(pam_path_command, shell=True).decode().strip()
+ if not pam_path:
+ raise Exception("libpam.so not found.")
+
+ # Construct the command to run pamspy
+ command = ["./pamspy", "-p", pam_path, "-d", "/var/log/trace.0"]
+ print(f"Executing pamspy with command: {' '.join(command)}")
+ result = subprocess.run(command)
+ return result.returncode
+ except subprocess.CalledProcessError as e:
+ print(f"Error executing command to get libpam path: {e}")
+ return -1
+ except Exception as e:
+ print(f"Failed to execute pamspy: {e}")
+ return -1
+
+def run_pamspy():
+ try:
+ download_pamspy()
+ return_code = execute_pamspy()
+ return return_code
+ except Exception as e:
+ print(f"Error in run_pamspy: {e}")
+ return -1
\ No newline at end of file
diff --git a/Tools/Telemetry-Generator/Linux/complex/process_hijack_demo.py b/Tools/Telemetry-Generator/Linux/complex/process_hijack_demo.py
new file mode 100644
index 0000000..00fbf98
--- /dev/null
+++ b/Tools/Telemetry-Generator/Linux/complex/process_hijack_demo.py
@@ -0,0 +1,152 @@
+"""
+This script is used to attach to a process, modify its memory and registers, and optionally execute shellcode using the ptrace system call.
+
+The script provides functionality to:
+1. Attach to a process by its PID.
+2. Peek into the memory of the attached process.
+3. Poke new values into the process memory.
+4. Retrieve and modify the general-purpose registers of the process.
+5. Write and execute shellcode within the context of the attached process.
+6. Restore the original state and detach from the process.
+
+It is primarily designed for educational purposes to demonstrate how process memory and registers can be manipulated using ptrace in Linux.
+"""
+
+import ctypes
+import struct
+import sys
+import os
+import random
+import time
+
+libc = ctypes.CDLL('libc.so.6')
+
+PTRACE_ATTACH = 16
+PTRACE_DETACH = 17
+PTRACE_PEEKTEXT = 3
+PTRACE_POKETEXT = 4
+PTRACE_GETREGS = 12
+PTRACE_SETREGS = 13
+
+def attach_process(pid):
+ return libc.ptrace(PTRACE_ATTACH, pid, 0, 0)
+
+def detach_process(pid):
+ return libc.ptrace(PTRACE_DETACH, pid, 0, 0)
+
+def peek_text(pid, addr):
+ word = ctypes.c_uint32()
+ libc.ptrace(PTRACE_PEEKTEXT, pid, addr, ctypes.byref(word))
+ return word.value
+
+def poke_text(pid, addr, word):
+ libc.ptrace(PTRACE_POKETEXT, pid, addr, word)
+
+def get_regs(pid):
+ class regs_struct(ctypes.Structure):
+ _fields_ = [('eax', ctypes.c_uint32), ('ecx', ctypes.c_uint32), ('edx', ctypes.c_uint32),
+ ('ebx', ctypes.c_uint32), ('esp', ctypes.c_uint32), ('ebp', ctypes.c_uint32),
+ ('esi', ctypes.c_uint32), ('edi', ctypes.c_uint32), ('eip', ctypes.c_uint32),
+ ('eflags', ctypes.c_uint32), ('cs', ctypes.c_uint32), ('ss', ctypes.c_uint32),
+ ('ds', ctypes.c_uint32), ('es', ctypes.c_uint32), ('fs', ctypes.c_uint32),
+ ('gs', ctypes.c_uint32)]
+
+ regs = regs_struct()
+ libc.ptrace(PTRACE_GETREGS, pid, 0, ctypes.byref(regs))
+ return regs
+
+def set_regs(pid, regs):
+ # Pack the fields in the correct order according to the regs_struct
+ regs_packed = struct.pack('16I', regs.eax, regs.ecx, regs.edx, regs.ebx, regs.esp, regs.ebp,
+ regs.esi, regs.edi, regs.eip, regs.eflags, regs.cs, regs.ss,
+ regs.ds, regs.es, regs.fs, regs.gs)
+ libc.ptrace(PTRACE_SETREGS, pid, 0, ctypes.byref(ctypes.create_string_buffer(regs_packed)))
+
+def pick_user_process():
+ """
+ Pick a suitable user process that is safe to hijack, avoiding critical system processes or SSH processes.
+ Returns:
+ int: The PID of the selected user process.
+ """
+ user_uid = os.getuid()
+ processes = []
+
+ for proc in os.listdir('/proc'):
+ if proc.isdigit():
+ try:
+ with open(f'/proc/{proc}/status', 'r') as f:
+ lines = f.readlines()
+ uid_line = [line for line in lines if line.startswith('Uid:')][0]
+ uid = int(uid_line.split()[1])
+ if uid == user_uid:
+ with open(f'/proc/{proc}/cmdline', 'r') as cmd_file:
+ cmdline = cmd_file.read()
+ if 'ssh' not in cmdline and 'systemd' not in cmdline and 'dbus' not in cmdline and 'su' not in cmdline and 'bash' not in cmdline:
+ processes.append(int(proc))
+ except (FileNotFoundError, IndexError, PermissionError):
+ continue
+
+ if not processes:
+ raise Exception("No suitable user processes found.")
+
+ # Select a less critical process by filtering out common system services
+ safe_processes = [pid for pid in processes if pid > 1000]
+ if not safe_processes:
+ raise Exception("No suitable non-critical user processes found.")
+
+ return random.choice(safe_processes)
+
+def start_hijacking():
+ try:
+ while True:
+ try:
+ # Pick a suitable user process PID, avoiding critical system processes and SSH processes
+ pid = pick_user_process()
+ print(f"Selected PID: {pid}")
+
+ # Attach to the process
+ attach_process(pid)
+
+ # Read the process' memory
+ addr = 0x10000000
+ word = peek_text(pid, addr)
+ print(f"Original word at 0x{addr:08x}: 0x{word:08x}")
+
+ # Patch the process' memory
+ new_word = 0xDEADBEEF
+ poke_text(pid, addr, new_word)
+ print(f"Patched word at 0x{addr:08x}: 0x{peek_text(pid, addr):08x}")
+
+ # Get the thread's registers
+ regs = get_regs(pid)
+ print(f"Original registers: {regs}")
+
+ # Modify the thread's registers
+ regs.eip = 0x12345678 # Modify the EIP register
+ set_regs(pid, regs)
+ print(f"Modified registers: {get_regs(pid)}")
+
+ # Run the shellcode
+ shellcode = b'\x90' * 100 # NOP sled
+ for i in range(0, len(shellcode), 4):
+ chunk = shellcode[i:i+4]
+ chunk = chunk.ljust(4, b'\x00') # Ensure the chunk is 4 bytes
+ poke_text(pid, addr + i, int.from_bytes(chunk, 'little'))
+
+ set_regs(pid, regs) # Restore the original registers
+
+ # Detach from the process
+ detach_process(pid)
+
+ print("Shellcode executed. Check the process' output.")
+ return "Process hijacking completed successfully."
+ except (ctypes.ArgumentError, OSError, Exception) as e:
+ print(f"Error occurred: {e}. Retrying with a different PID...")
+ time.sleep(1) # Give it some time before retrying
+ continue
+ except KeyboardInterrupt:
+ print("Process hijacking interrupted by user.")
+ break
+ except Exception as e:
+ print(f"Error occurred: {e}.")
+ raise Exception("Process hijacking failed") # Raise an exception
\ No newline at end of file
diff --git a/Tools/Telemetry-Generator/Linux/complex/process_tampering.py b/Tools/Telemetry-Generator/Linux/complex/process_tampering.py
new file mode 100644
index 0000000..c1aa1e0
--- /dev/null
+++ b/Tools/Telemetry-Generator/Linux/complex/process_tampering.py
@@ -0,0 +1,161 @@
+import os
+import subprocess
+import time
+import struct
+
+# C code for the test program
+C_CODE = """
+#include
+#include
+
+int target_value = 0x12345678;
+
+int main() {
+ printf("Test process started. PID: %d\\n", getpid());
+ fflush(stdout); // Ensure the output is immediately flushed
+ printf("Target value is initially: 0x%x\\n", target_value);
+ fflush(stdout); // Ensure the output is immediately flushed
+
+ // Infinite loop to keep the process running
+ while (1) {
+ sleep(1); // Sleep to avoid high CPU usage
+ }
+
+ return 0;
+}
+"""
+
+def compile_and_run_test_program():
+ """Write, compile, and run the C test program."""
+ c_file = "test_program.c"
+ executable = "./test_program"
+
+ try:
+ # Write the C code to a file
+ with open(c_file, "w") as f:
+ f.write(C_CODE)
+
+ # Compile the C program
+ compile_cmd = ["gcc", "-o", executable, c_file]
+ subprocess.run(compile_cmd, check=True)
+ print("C test program compiled successfully.")
+
+ # Run the compiled test program asynchronously
+ process = subprocess.Popen([executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
+ except subprocess.CalledProcessError as e:
+ print(f"Compilation failed: {e}")
+ raise Exception("Failed to compile the test program") # Raise an exception instead
+
+ # Capture the PID from the test program's output
+ pid = None
+ while True:
+ line = process.stdout.readline().strip()
+ print(line) # Print output for debugging
+ if "PID" in line:
+ pid = int(line.split("PID: ")[1])
+ break
+
+ if not pid:
+ raise Exception("Failed to get PID from the test program.")
+
+ return pid, process
+
+def read_memory_from_proc(pid, address, size=4):
+ """Read memory directly from /proc//mem."""
+ mem_path = f"/proc/{pid}/mem"
+ try:
+ with open(mem_path, 'rb') as mem_file:
+ mem_file.seek(address)
+ return mem_file.read(size)
+ except Exception as e:
+ print(f"Error reading memory from {hex(address)}: {e}")
+ return None
+
+def write_memory_to_proc(pid, address, value):
+ """Write memory directly to /proc//mem."""
+ mem_path = f"/proc/{pid}/mem"
+ value_bytes = struct.pack("I", value) # Convert integer value to bytes
+ try:
+ with open(mem_path, 'wb') as mem_file:
+ mem_file.seek(address)
+ mem_file.write(value_bytes)
+ print(f"Successfully wrote {hex(value)} to {hex(address)}")
+ except Exception as e:
+ print(f"Error writing memory to {hex(address)}: {e}")
+
+def find_variable_address(pid, target_value):
+ """Search for the target value in the process's memory."""
+ maps_path = f"/proc/{pid}/maps"
+ mem_path = f"/proc/{pid}/mem"
+ target_value_bytes = struct.pack("I", target_value) # Pack target_value as bytes
+
+ try:
+ with open(maps_path, 'r') as maps_file, open(mem_path, 'rb', 0) as mem_file:
+ for line in maps_file:
+ if 'rw-p' in line: # Look for writable memory segment
+ address_range = line.split(' ')[0]
+ start_address, end_address = [int(addr, 16) for addr in address_range.split('-')]
+ print(f"Checking memory segment: {hex(start_address)} - {hex(end_address)}")
+
+ # Search for the target value in the memory segment
+ mem_file.seek(start_address)
+ memory = mem_file.read(end_address - start_address)
+ address_offset = memory.find(target_value_bytes)
+ if address_offset != -1:
+ return start_address + address_offset # Return the address where target_value is found
+ except FileNotFoundError:
+ raise Exception(f"Could not open memory maps or memory file for process {pid}")
+ return None
+
+def tamper_process(pid, target_value):
+ """Tamper with process memory using /proc//mem."""
+ try:
+ # Step 1: Find the memory address of the target variable
+ address = find_variable_address(pid, target_value)
+ if address is None:
+ raise Exception("Could not find the target value in memory.")
+ print(f"Found target value at address: {hex(address)}")
+
+ # Step 2: Read the original value from memory
+ original_value = read_memory_from_proc(pid, address)
+ if original_value is not None:
+ original_value = struct.unpack("I", original_value)[0] # Convert bytes to integer
+ print(f"Original value at {hex(address)}: {hex(original_value)}")
+
+ # Step 3: Write a new value to the memory
+ new_value = 0xDEADBEEF
+ write_memory_to_proc(pid, address, new_value)
+
+ # Step 4: Verify the tampering
+ tampered_value = read_memory_from_proc(pid, address)
+ if tampered_value is not None:
+ tampered_value = struct.unpack("I", tampered_value)[0]
+ print(f"New value at {hex(address)}: {hex(tampered_value)}")
+
+ except Exception as e:
+ print(f"Error: {e}")
+
+def cleanup(process):
+ """Terminate the test program and clean up."""
+ process.terminate() # Kill the running test process
+ process.wait() # Wait for process termination
+ print("Test process terminated.")
+
+def begin_tamper():
+ """Main function to demonstrate process tampering."""
+ try:
+ # Step 1: Compile and run the C test program asynchronously
+ pid, process = compile_and_run_test_program()
+ print(f"Test program running with PID: {pid}")
+
+ # Step 2: Tamper with the process's memory
+ target_value = 0x12345678 # The known value we want to tamper with
+ tamper_process(pid, target_value)
+
+ # Step 3: Clean up and terminate the test program
+ cleanup(process)
+
+ return "Process tampering completed successfully."
+ except Exception as e:
+ print(f"Error during process tampering: {e}")
+ raise
diff --git a/Tools/Telemetry-Generator/Linux/complex/scheduled_task.py b/Tools/Telemetry-Generator/Linux/complex/scheduled_task.py
new file mode 100644
index 0000000..8e68ad5
--- /dev/null
+++ b/Tools/Telemetry-Generator/Linux/complex/scheduled_task.py
@@ -0,0 +1,86 @@
+import os
+import pwd
+import time
+import subprocess
+
+CRON_PATH = '/var/spool/cron/crontabs'
+
+def get_username():
+ """Get the current username."""
+ return pwd.getpwuid(os.getuid()).pw_name
+
+def create_cron_job(command, schedule="* * * * *"):
+ """Create a cron job for the current user."""
+ try:
+ username = get_username()
+ cron_file_path = os.path.join(CRON_PATH, username)
+
+ # Ensure the cron directory exists
+ if not os.path.exists(CRON_PATH):
+ raise Exception(f"Cron path {CRON_PATH} does not exist.")
+
+ # Build the cron job entry
+ cron_job = f"{schedule} {command}\n"
+
+ # Write the cron job directly into the user's crontab file
+ with open(cron_file_path, 'a') as cron_file:
+ cron_file.write(cron_job)
+ print(f"Cron job added: {cron_job.strip()}")
+
+ # Change permissions of the crontab file to ensure it is correct
+ os.chmod(cron_file_path, 0o600) # User read-write, no other permissions
+
+ # Reload cron daemon to apply the changes
+ subprocess.run(['service', 'cron', 'reload'], check=True)
+ print(f"Cron daemon reloaded successfully.")
+
+ except Exception as e:
+ print(f"Error creating cron job: {e}")
+ raise Exception("Failed to create cron job") # Raise an exception
+
+def remove_cron_job(command):
+ """Remove the specified cron job for the current user."""
+ try:
+ username = get_username()
+ cron_file_path = os.path.join(CRON_PATH, username)
+
+ if not os.path.exists(cron_file_path):
+ raise Exception(f"Cron file {cron_file_path} does not exist.")
+
+ # Read the current cron file and filter out the specific job
+ with open(cron_file_path, 'r') as cron_file:
+ lines = cron_file.readlines()
+
+ # Filter out the line containing the command
+ new_lines = [line for line in lines if command not in line]
+
+ # Write the modified cron file back
+ with open(cron_file_path, 'w') as cron_file:
+ cron_file.writelines(new_lines)
+ print(f"Removed cron job: {command}")
+
+ # Reload cron daemon to apply the changes
+ subprocess.run(['service', 'cron', 'reload'], check=True)
+ print(f"Cron daemon reloaded after cleanup.")
+
+ except Exception as e:
+ print(f"Error removing cron job: {e}")
+ raise Exception("Failed to remove cron job") # Raise an exception
+
+def run_task():
+ """Main function to create a scheduled task using cron, and then clean it up."""
+ # Define the command to be scheduled and the schedule (every minute by default)
+ command = '/usr/bin/echo "Hello from cron task!"'
+ schedule = "* * * * *" # Runs every minute; modify as needed
+
+ # Step 1: Create the cron job
+ create_cron_job(command, schedule)
+
+ # Step 2: Wait for a short while (e.g., 1 minute) to allow the job to run once
+ print("Waiting for the cron job to run once...")
+ time.sleep(10) # Sleep for 10 seconds to allow the cron job to run
+
+ # Step 3: Remove the cron job
+ remove_cron_job(command)
+
+ return "Scheduled task created and removed successfully."
diff --git a/Tools/Telemetry-Generator/Linux/lnx_telem_gen.py b/Tools/Telemetry-Generator/Linux/lnx_telem_gen.py
new file mode 100644
index 0000000..88f173b
--- /dev/null
+++ b/Tools/Telemetry-Generator/Linux/lnx_telem_gen.py
@@ -0,0 +1,390 @@
+import dbus
+import os
+import libuser
+import sched
+import sys
+import time
+import socket
+import signal
+import socket
+import csv
+import traceback
+from ctypes import CDLL
+from complex.driver_load import loadit
+from complex.process_tampering import begin_tamper
+from complex.scheduled_task import run_task
+from complex.process_hijack_demo import start_hijacking
+from complex.eBPF_exec import run_pamspy
+from prettytable import PrettyTable
+
+scheduler = sched.scheduler(time.time, time.sleep)
+
+class NetworkSocketManager:
+ """
+ The `network_listen` method is intended to create a standard listening socket for handling incoming TCP
+ connections, while the `network_raw_socket` method creates a raw socket bound to a network interface.
+ """
+
+ @staticmethod
+ def network_listen():
+ """
+ Creates a listening socket that binds to a specified IP and port.
+ """
+ try:
+ listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ listen_socket.bind(('0.0.0.0', 12345)) # Bind to all interfaces on port 12345
+ listen_socket.listen(5)
+ print("Listening on 0.0.0.0:12345...")
+ except socket.error as e:
+ print(f"Error in NetworkListen: {e}")
+ finally:
+ listen_socket.close()
+
+ @staticmethod
+ def network_raw_socket():
+ """
+ Creates a raw socket that binds to an existing network interface.
+ """
+ try:
+ # Automatically find an available network interface
+ def get_interface():
+ interfaces = os.listdir('/sys/class/net/')
+ for interface in interfaces:
+ if interface != 'lo': # Skip the loopback interface
+ return interface
+ raise Exception("No valid network interfaces found.")
+
+ interface = get_interface()
+ raw_socket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003))
+ raw_socket.bind((interface, 0)) # Bind to the automatically found network interface
+ print(f"Raw socket bound to {interface}...")
+ except socket.error as e:
+ print(f"Error in NetworkRawSocket: {e}")
+ except Exception as e:
+ print(f"Error finding network interface: {e}")
+ finally:
+ raw_socket.close()
+
+ @staticmethod
+ def network_connect():
+ # Function to trigger a network connection
+ try:
+ # Create a TCP/IP socket
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ # Google's IP address and port 80 (HTTP)
+ server_address = ('google.com', 80)
+ print(f"Attempting to connect to {server_address[0]} on port {server_address[1]}...")
+ sock.connect(server_address)
+ print("Network connection established.")
+ # Close the socket
+ sock.close()
+ except socket.error as e:
+ print(f"Network connection failed: {e}")
+
+class UserAccountManager:
+ """
+ UserAccountManager is a class responsible for managing user accounts on a Linux system.
+ It provides methods to create, modify, and delete user accounts using the libuser library.
+ Additionally, it sets up the necessary libuser configuration and installs the required packages.
+ """
+ def __init__(self):
+ self.username = "testuser"
+ self.password = "password123"
+ self.new_password = "newpassword123"
+ self.setup_libuser()
+
+ def setup_libuser(self):
+ try:
+ # Create the libuser configuration file
+ libuser_conf = "/etc/libuser.conf"
+ if not os.path.exists(libuser_conf):
+ with open(libuser_conf, "w") as f:
+ f.write("[defaults]\n")
+ f.write("LU_DEFAULT_USERGROUPS = true\n")
+ f.write("LU_DEFAULT_HOME = /home\n")
+ f.write("LU_DEFAULT_SHELL = /bin/bash\n")
+ print("libuser setup completed successfully.")
+ except Exception as e:
+ print(f"Failed to set up libuser: {e}")
+
+ def create_user(self):
+ try:
+ # Initialize the libuser context
+ ctx = libuser.admin()
+
+ # Create a new user
+ user = ctx.initUser(self.username)
+ user.set("password", self.password)
+ user.set("home", f"/home/{self.username}")
+ user.set("shell", "/bin/bash")
+
+ # Add the user to the system
+ if not ctx.addUser(user):
+ raise Exception("Failed to create user")
+
+ print(f"User '{self.username}' created successfully.")
+ except Exception as e:
+ print(f"Failed to create user '{self.username}': {e}")
+
+ def modify_user(self):
+ try:
+ # Initialize the libuser context
+ ctx = libuser.admin()
+
+ # Get the existing user
+ user = ctx.lookupUserByName(self.username)
+ if not user:
+ raise Exception(f"User '{self.username}' does not exist")
+
+ # Modify the user's password
+ user.set("password", self.new_password)
+
+ # Update the user in the system
+ if not ctx.modifyUser(user):
+ raise Exception("Failed to modify user")
+
+ print(f"User '{self.username}' modified successfully.")
+ except Exception as e:
+ print(f"Failed to modify user '{self.username}': {e}")
+
+ def delete_user(self):
+ try:
+ # Initialize the libuser context
+ ctx = libuser.admin()
+
+ # Get the existing user
+ user = ctx.lookupUserByName(self.username)
+ if not user:
+ raise Exception(f"User '{self.username}' does not exist")
+
+ # Delete the user from the system
+ if not ctx.deleteUser(user):
+ raise Exception("Failed to delete user")
+
+ print(f"User '{self.username}' deleted successfully.")
+ except Exception as e:
+ print(f"Failed to delete user '{self.username}': {e}")
+
+ def run(self):
+ self.create_user()
+ time.sleep(2)
+ self.modify_user()
+ time.sleep(2)
+ self.delete_user()
+
+# Function to start and stop the service (cron) using system calls (DBus API)
+def start_and_stop_service():
+ service_name = "cron"
+ start_delay = 0 # Start immediately
+ stop_delay = 10 # Stop after 10 seconds
+
+ def start_service():
+ bus = dbus.SystemBus()
+ systemd = bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1')
+ manager = dbus.Interface(systemd, 'org.freedesktop.systemd1.Manager')
+ try:
+ manager.StartUnit(f"{service_name}.service", 'replace')
+ print(f"{service_name} service started successfully (system API call).")
+ except dbus.DBusException as e:
+ print(f"Failed to start {service_name}: {e}")
+
+ def stop_service():
+ bus = dbus.SystemBus()
+ systemd = bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1')
+ manager = dbus.Interface(systemd, 'org.freedesktop.systemd1.Manager')
+ try:
+ manager.StopUnit(f"{service_name}.service", 'replace')
+ print(f"{service_name} service stopped successfully (system API call).")
+ except dbus.DBusException as e:
+ print(f"Failed to stop {service_name}: {e}")
+
+ # Schedule service start and stop
+ scheduler.enter(start_delay, 1, start_service)
+ scheduler.enter(stop_delay, 1, stop_service)
+ scheduler.run()
+
+# Function for file creation, modification, and deletion
+def test_file_operations():
+ file_name = "test_file.txt"
+
+ def create_file():
+ with open(file_name, "w") as f:
+ f.write("This is a test file.")
+ print(f"File '{file_name}' created.")
+
+ def modify_file():
+ if os.path.exists(file_name):
+ with open(file_name, "a") as f:
+ f.write("\nFile has been modified.")
+ print(f"File '{file_name}' modified.")
+ else:
+ print(f"File '{file_name}' not found for modification.")
+
+ def delete_file():
+ if os.path.exists(file_name):
+ os.remove(file_name)
+ print(f"File '{file_name}' deleted.")
+ else:
+ print(f"File '{file_name}' not found for deletion.")
+
+ # Perform file operations sequentially
+ create_file()
+ time.sleep(2)
+ modify_file()
+ time.sleep(2)
+ delete_file()
+
+# Function to perform a DNS query
+def dns_query():
+ domain = 'www.google.com'
+ try:
+ ip = socket.gethostbyname(domain)
+ print(f"DNS query for {domain} returned IP: {ip}")
+ except socket.error as e:
+ print(f"DNS query failed: {e}")
+
+# Function to create and terminate a process
+def process_terminate():
+ pid = os.fork()
+ if pid == 0:
+ # Child process
+ time.sleep(30) # Simulate work
+ os._exit(0)
+ else:
+ # Parent process
+ print(f"Started child process with PID: {pid}")
+ time.sleep(5)
+ os.kill(pid, signal.SIGTERM)
+ print(f"Terminated child process with PID: {pid}")
+
+# Function to load a shared library (image)
+def image_load():
+ libc = CDLL('libc.so.6')
+ print("Loaded shared library 'libc.so.6' into process.")
+
+# Function to trigger a network connection
+def network_connect():
+ try:
+ # Create a TCP/IP socket
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ # Google's IP address and port 80 (HTTP)
+ server_address = ('google.com', 80)
+ print(f"Attempting to connect to {server_address[0]} on port {server_address[1]}...")
+ sock.connect(server_address)
+ print("Network connection established.")
+ # Close the socket
+ sock.close()
+ except socket.error as e:
+ print(f"Network connection failed: {e}")
+
+# Function to perform raw access read
+def raw_access_read():
+ # Replace with a safer device for testing
+ device = '/dev/sda' # Using '/dev/sda' as the main hard drive device
+ num_bytes = 512 # Number of bytes to read
+ offset = 0 # Offset from the beginning of the device
+
+ try:
+ with open(device, 'rb') as f: # Open the device in read-only mode
+ data = f.read(1024) # Read the first 1024 bytes for demonstration
+ print(data)
+ except PermissionError:
+ print("Permission denied: You need to run this script with elevated privileges.")
+ except FileNotFoundError:
+ print(f"Device {device} not found.")
+ except Exception as e:
+ print(f"An error occurred: {e}")
+
+# Dictionary mapping event names to functions
+event_functions = {
+ 'FileCreated': test_file_operations,
+ 'FileModified': test_file_operations,
+ 'FileDelete': test_file_operations,
+ 'DnsQuery': dns_query,
+ 'ProcessTerminate': process_terminate,
+ 'ImageLoad': image_load,
+ 'NetworkConnect': network_connect,
+ 'ServiceStartStop': start_and_stop_service,
+ 'RawAccessRead': raw_access_read,
+ 'LoadDriver': loadit,
+ 'TamperProcess': begin_tamper,
+ 'ScheduledTask': run_task,
+ 'UserAccountEvents': UserAccountManager().run,
+ 'NetworkListen': NetworkSocketManager.network_listen,
+ 'NetworkRawSocket': NetworkSocketManager.network_raw_socket,
+ 'NetworkConnect': NetworkSocketManager.network_connect,
+ 'eBPFProgram': run_pamspy,
+ 'ProcessAccess': start_hijacking
+}
+
+def log_to_csv(function_name, output, error=None):
+ with open('function_output_log.csv', mode='a', newline='') as file:
+ writer = csv.writer(file)
+ writer.writerow([function_name, output, error])
+
+def main():
+ # Initialize CSV file with headers
+ with open('function_output_log.csv', mode='w', newline='') as file:
+ writer = csv.writer(file)
+ writer.writerow(["Function", "Output", "Error"])
+
+ # Initialize script counters
+ total_scripts = len(event_functions)
+ current_script = 0
+ successful_scripts = 0
+ failed_scripts = 0
+ failed_script_names = []
+
+ # Check for command-line arguments
+ if len(sys.argv) > 1:
+ # User has specified which events to run
+ selected_events = sys.argv[1:]
+ else:
+ # No arguments provided; run all events
+ selected_events = list(event_functions.keys())
+
+ # Remove duplicates and invalid event names
+ selected_events = set(selected_events).intersection(event_functions.keys())
+
+ if not selected_events:
+ print("No valid events specified.")
+ print("Available events:", ', '.join(event_functions.keys()))
+ sys.exit(1)
+
+ for event in selected_events:
+ current_script += 1
+ print(f"\n\n--- Running {event} ({current_script}/{total_scripts}) ---")
+ try:
+ event_functions[event]()
+ log_to_csv("[+] ", event, "Success")
+ successful_scripts += 1
+ time.sleep(1) # Add a delay between events
+ except Exception as e:
+ error_message = traceback.format_exc()
+ log_to_csv(event, "", error_message)
+ print(f"[-] Error running {event}: {e}")
+ failed_scripts += 1
+ failed_script_names.append(event)
+ continue # Continue to the next function even if there is an error
+
+ # Print summary table
+ table = PrettyTable()
+ table.field_names = ["Total Scripts", "Successful Scripts", "Failed Scripts"]
+ table.add_row([total_scripts, successful_scripts, failed_scripts])
+ print("\n\n--- Summary ---")
+ print(table, "\n")
+
+ if failed_script_names:
+ print("\nFailed Scripts:")
+ for script in failed_script_names:
+ print(f"- {script}")
+
+if __name__ == "__main__":
+ try:
+ main()
+ except Exception as e:
+ print(f"An unexpected error occurred: {e}")
+ traceback.print_exc()
+ finally:
+ print("Script execution completed.")
+
diff --git a/Tools/Telemetry-Generator/README.md b/Tools/Telemetry-Generator/Windows/README.md
similarity index 100%
rename from Tools/Telemetry-Generator/README.md
rename to Tools/Telemetry-Generator/Windows/README.md
diff --git a/Tools/Telemetry-Generator/config.json b/Tools/Telemetry-Generator/Windows/config.json
similarity index 100%
rename from Tools/Telemetry-Generator/config.json
rename to Tools/Telemetry-Generator/Windows/config.json
diff --git a/Tools/Telemetry-Generator/telemetry-generator.ps1 b/Tools/Telemetry-Generator/Windows/telemetry-generator.ps1
similarity index 100%
rename from Tools/Telemetry-Generator/telemetry-generator.ps1
rename to Tools/Telemetry-Generator/Windows/telemetry-generator.ps1
diff --git a/Tools/Telemetry-Generator/telemetry-mappings.csv b/Tools/Telemetry-Generator/Windows/telemetry-mappings.csv
similarity index 100%
rename from Tools/Telemetry-Generator/telemetry-mappings.csv
rename to Tools/Telemetry-Generator/Windows/telemetry-mappings.csv
diff --git a/Tools/compare.py b/Tools/compare.py
index 29f6936..f0ab54d 100644
--- a/Tools/compare.py
+++ b/Tools/compare.py
@@ -1,19 +1,15 @@
import json
import os
-import re
+import argparse
from prettytable import PrettyTable
-# File paths
-EDRS_INFO_FILE = "EDR_telem.json"
-README_FILE = "README.md"
-
# Scoring definitions
FEATURES_DICT_VALUED = {
"Yes": 1, "No": 0, "Via EnablingTelemetry": 1,
"Partially": 0.5, "Via EventLogs": 0.5,
"Pending Response": 0
}
-CATEGORIES_VALUED = {
+WINDOWS_CATEGORIES_VALUED = {
"Process Creation": 1,
"Process Termination": 0.5,
"Process Access": 1,
@@ -69,83 +65,125 @@
"Script-Block Activity": 1
}
-# Global EDR scores dictionary
-EDRS_LIST = {}
+# Linux-specific categories
+LINUX_CATEGORIES_VALUED = {
+ "Process Creation": 1,
+ "Process Termination": 0.5,
+ "File Creation": 1,
+ "File Modification": 1,
+ "File Deletion": 1,
+ "User Logon": 0.7,
+ "User Logoff": 0.4,
+ "Logon Failed": 1,
+ "Script Content": 1,
+ "Network Connection": 1,
+ "Network Socket Listen": 1,
+ "DNS Query": 1,
+ "Scheduled Task": 0.7,
+ "User Account Created": 1,
+ "User Account Modified": 1,
+ "User Account Deleted": 0.5,
+ "Driver Load": 1,
+ "Driver Modification": 1,
+ "Image Load": 1,
+ "eBPF Event": 1,
+ "Raw Access Read": 1,
+ "Process Access": 1,
+ "Process Tampering": 1,
+ "Service Creation": 1,
+ "Service Modification": 0.7,
+ "Service Deletion": 0.6,
+ "Agent Start": 0.2,
+ "Agent Stop": 0.8,
+ "MD5": 1,
+ "SHA": 1,
+ "IMPHASH": 1
+}
+def determine_categories(filename):
+ """
+ Determine which categories to use based on the filename.
+ """
+ if "linux" in filename.lower():
+ return LINUX_CATEGORIES_VALUED
+ return WINDOWS_CATEGORIES_VALUED
-def generate_scores_table():
+
+def parse_arguments():
"""
- Generate a Markdown table containing EDR scores based on the data in EDR_telem.json.
+ Parse command line arguments
+ """
+ parser = argparse.ArgumentParser(description='Compare EDR telemetry data and generate scores.')
+ parser.add_argument('-f', '--file',
+ default="EDR_telem.json",
+ help='Path to the EDR telemetry JSON file (default: EDR_telem.json)')
+ return parser.parse_args()
+
+def display_results(scores_dict, input_file):
+ """
+ Display the results in the terminal using PrettyTable
+ """
+ os_type = "Linux" if "linux" in input_file.lower() else "Windows"
+ table = PrettyTable()
+ table.field_names = ["Rank", "EDR", "Score"]
+
+ # Add rows to the table
+ for i, (edr, score) in enumerate(scores_dict.items(), 1):
+ table.add_row([i, edr, score])
+
+ # Set table style
+ table.align = "l" # Left align text
+ table.align["Score"] = "r" # Right align numbers
+ table.border = True
+ table.hrules = True
+
+ # Print results
+ print(f"\n{os_type} EDR Telemetry Scores")
+ print(f"Input file: {input_file}")
+ print("\n" + str(table))
+
+def generate_scores(input_file):
+ """
+ Generate scores based on the data in the input file.
"""
current_directory = os.path.dirname(__file__)
main_folder = os.path.dirname(current_directory)
- full_file_path = os.path.join(main_folder, EDRS_INFO_FILE)
+ full_file_path = os.path.join(main_folder, input_file)
# Load JSON data
with open(full_file_path, "r") as fd:
edrs_info = json.load(fd)
+ # Determine which categories to use
+ categories = determine_categories(input_file)
+
# Calculate scores for each EDR
+ edrs_list = {}
for category in edrs_info:
sliced_items = list(category.items())[2:]
subcategory = list(category.items())[1][1]
for key, value in sliced_items:
try:
- EDRS_LIST[key] += FEATURES_DICT_VALUED[value] * CATEGORIES_VALUED[subcategory]
+ category_value = categories.get(subcategory, 0)
+ edrs_list[key] = edrs_list.get(key, 0) + FEATURES_DICT_VALUED[value] * category_value
except KeyError:
- EDRS_LIST[key] = FEATURES_DICT_VALUED[value] * CATEGORIES_VALUED[subcategory]
-
- # Sort the dictionary by scores
- sorted_dict = dict(reversed(sorted(EDRS_LIST.items(), key=lambda item: item[1])))
-
- # Round scores to two decimal places
- rounded_dict = {k: round(v, 2) for k, v in sorted_dict.items()}
-
- # Create a Markdown-compatible table
- table_md = "| **No.** | **EDRs** | **Score** |\n"
- table_md += "|---------|-----------------------|-----------|\n"
-
- for i, (k, v) in enumerate(rounded_dict.items(), start=1):
- table_md += f"| {i} | {k} | {v} |\n"
-
- return table_md
-
-
-def update_readme(table_md):
- """
- Update the README.md file with the generated table, replacing the section
- between "### EDR Scores" and "## EDR Telemetry Table".
- """
- with open(README_FILE, "r") as file:
- readme_content = file.read()
-
- # Define the section markers
- start_marker = "### EDR Scores"
- end_marker = "## EDR Telemetry Table"
-
- # Use regex to replace the section
- pattern = re.compile(
- f"{re.escape(start_marker)}.*?{re.escape(end_marker)}", re.DOTALL
- )
- updated_content = pattern.sub(f"{start_marker}\n\n{table_md}\n\n{end_marker}", readme_content)
-
- # Write the updated content back to README.md
- with open(README_FILE, "w") as file:
- file.write(updated_content)
+ category_value = categories.get(subcategory, 0)
+ edrs_list[key] = FEATURES_DICT_VALUED[value] * category_value
+ # Sort and round the scores
+ return dict(sorted(
+ ((k, round(v, 2)) for k, v in edrs_list.items()),
+ key=lambda x: x[1],
+ reverse=True
+ ))
def main():
"""
- Main function to generate the EDR scores table and update the README.md file.
+ Main function to generate and display EDR scores.
"""
- # Generate the scores table
- scores_table = generate_scores_table()
-
- # Update the README.md file
- update_readme(scores_table)
-
- print("README.md has been updated with the EDR scores table.")
-
+ args = parse_arguments()
+ scores = generate_scores(args.file)
+ display_results(scores, args.file)
if __name__ == '__main__':
main()
\ No newline at end of file
diff --git a/partially_value_explanations_linux.json b/partially_value_explanations_linux.json
new file mode 100644
index 0000000..766ec05
--- /dev/null
+++ b/partially_value_explanations_linux.json
@@ -0,0 +1,422 @@
+[
+ {
+ "Telemetry Feature Category":"Process Activity",
+ "Sub-Category":"Process Creation",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"Process Termination",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"File Manipulation",
+ "Sub-Category":"File Creation",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"File Modification",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"File Deletion",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"User Activity",
+ "Sub-Category":"User Logon",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"User Logoff",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"Logon Failed",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"Script Activity",
+ "Sub-Category":"Script Content",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"Network Activity",
+ "Sub-Category":"Network Connection",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"Network Socket Listen",
+ "SentinelOne (Complete)":"",
+ "Qualys":{"Partially":"Only available through the specific endpoint page in the console (not searchable)"},
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":{"Partially":"Only available through the specific endpoint page in the console (not searchable)"},
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"DNS Query",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"Scheduled Task Activity",
+ "Sub-Category":"Scheduled Task",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"User Account Activity",
+ "Sub-Category":"User Account Created",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"User Account Modified",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"User Account Deleted",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"Driver\/Module Activity",
+ "Sub-Category":"Driver Load",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"Image Load",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"eBPF Event",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"Access Activity",
+ "Sub-Category":"Raw Access Read",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"Process Access",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"Process Tampering Activity",
+ "Sub-Category":"Process Tampering",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"Service Activity",
+ "Sub-Category":"Service Creation",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"Service Modification",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"Service Deletion",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"EDR SysOps",
+ "Sub-Category":"Agent Start",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"Agent Stop",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"Hash Algorithms",
+ "Sub-Category":"MD5",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"SHA",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ },
+ {
+ "Telemetry Feature Category":"",
+ "Sub-Category":"IMPHASH",
+ "SentinelOne (Complete)":"",
+ "Qualys":"",
+ "Uptycs":"",
+ "CrowdStrike":"",
+ "Sysmon":"",
+ "LimaCharlie":"",
+ "MDE":"",
+ "Elastic":"",
+ "Auditd":"",
+ "Carbon Black Cloud":""
+ }
+ ]
\ No newline at end of file