diff --git a/.github/workflows/appinspect.yml b/.github/workflows/appinspect.yml index 6eaf1a1025..063bfb4add 100644 --- a/.github/workflows/appinspect.yml +++ b/.github/workflows/appinspect.yml @@ -18,7 +18,13 @@ jobs: - name: Install Python Dependencies and ContentCTL and Atomic Red Team run: | - pip install contentctl==${{ vars.CONTENTCTL_VERSION }} + if [ -n "${{ vars.CONTENTCTL_VERSION }}" ]; then + echo "Installing contentctl version ${{ vars.CONTENTCTL_VERSION }}" + pip install contentctl==${{ vars.CONTENTCTL_VERSION }} + else + echo "Installing latest contentctl version" + pip install contentctl + fi git clone --depth=1 --single-branch --branch=master https://github.com/redcanaryco/atomic-red-team.git external_repos/atomic-red-team git clone --depth=1 --single-branch --branch=master https://github.com/mitre/cti external_repos/cti diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9cbfcabf7c..75a1011555 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,8 +19,13 @@ jobs: - name: Install Python Dependencies and ContentCTL and Atomic Red Team run: | - echo "CONTENTCTL_VERSION is ${{ vars.CONTENTCTL_VERSION }}" - pip install contentctl==${{ vars.CONTENTCTL_VERSION }} + if [ -n "${{ vars.CONTENTCTL_VERSION }}" ]; then + echo "Installing contentctl version ${{ vars.CONTENTCTL_VERSION }}" + pip install contentctl==${{ vars.CONTENTCTL_VERSION }} + else + echo "Installing latest contentctl version" + pip install contentctl + fi git clone --depth=1 --single-branch --branch=master https://github.com/redcanaryco/atomic-red-team.git external_repos/atomic-red-team git clone --depth=1 --single-branch --branch=master https://github.com/mitre/cti external_repos/cti diff --git a/.github/workflows/unit-testing.yml b/.github/workflows/unit-testing.yml index 7efa46679f..3071d016f9 100644 --- a/.github/workflows/unit-testing.yml +++ b/.github/workflows/unit-testing.yml @@ -23,7 +23,13 @@ jobs: - name: Install Python Dependencies and ContentCTL run: | python -m pip install --upgrade pip - pip install contentctl==${{ vars.CONTENTCTL_VERSION }} + if [ -n "${{ vars.CONTENTCTL_VERSION }}" ]; then + echo "Installing contentctl version ${{ vars.CONTENTCTL_VERSION }}" + pip install contentctl==${{ vars.CONTENTCTL_VERSION }} + else + echo "Installing latest contentctl version" + pip install contentctl + fi # Running contentctl test with a few arguments, before running the command make sure you checkout into the current branch of the pull request. This step only performs unit testing on all the changes against the target-branch. In most cases this target branch will be develop # Make sure we check out the PR, even if it actually lives in a fork diff --git a/contentctl.yml b/contentctl.yml index 1bd5b72e03..c1a4789702 100644 --- a/contentctl.yml +++ b/contentctl.yml @@ -71,9 +71,9 @@ apps: - uid: 833 title: Splunk Add-on for Unix and Linux appid: Splunk_TA_nix - version: 9.2.0 + version: 10.0.0 description: description of app - hardcoded_path: https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/splunk-add-on-for-unix-and-linux_920.tgz + hardcoded_path: https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/splunk-add-on-for-unix-and-linux_1000.tgz - uid: 5579 title: Splunk Add-on for CrowdStrike FDR appid: Splunk_TA_CrowdStrike_FDR diff --git a/data_sources/linux_auditd_add_user.yml b/data_sources/linux_auditd_add_user.yml index c1d4736a2e..d8604f8794 100644 --- a/data_sources/linux_auditd_add_user.yml +++ b/data_sources/linux_auditd_add_user.yml @@ -10,7 +10,7 @@ configuration: https://github.com/Neo23x0/auditd/blob/master/audit.rules supported_TA: - name: Splunk Add-on for Unix and Linux url: https://splunkbase.splunk.com/app/833 - version: 9.2.0 + version: 10.0.0 fields: - msg - type @@ -30,4 +30,6 @@ fields: - UID - AUID - ID -example_log: 'type=ADD_USER msg=audit(1722950859.266:6994): pid=1788 uid=0 auid=1000 ses=1 subj=unconfined msg=''op=adding user id=1002 exe="/usr/sbin/useradd" hostname=ar-linux1 addr=? terminal=pts/1 res=success''UID="root" AUID="ubuntu" ID="unknown(1002)"' +example_log: 'type=ADD_USER msg=audit(1722950859.266:6994): pid=1788 uid=0 auid=1000 + ses=1 subj=unconfined msg=''op=adding user id=1002 exe="/usr/sbin/useradd" hostname=ar-linux1 + addr=? terminal=pts/1 res=success''UID="root" AUID="ubuntu" ID="unknown(1002)"' diff --git a/data_sources/linux_auditd_execve.yml b/data_sources/linux_auditd_execve.yml index 0752725a0f..04f7bb6c35 100644 --- a/data_sources/linux_auditd_execve.yml +++ b/data_sources/linux_auditd_execve.yml @@ -10,10 +10,11 @@ configuration: https://github.com/Neo23x0/auditd/blob/master/audit.rules supported_TA: - name: Splunk Add-on for Unix and Linux url: https://splunkbase.splunk.com/app/833 - version: 9.2.0 + version: 10.0.0 fields: - msg - type - msg - argc -example_log: 'type=EXECVE msg=audit(1723044684.257:15795): argc=3 a0="sudo" a1="LD_PRELOAD=./myfopen.so" a2="./prog"' +example_log: 'type=EXECVE msg=audit(1723044684.257:15795): argc=3 a0="sudo" a1="LD_PRELOAD=./myfopen.so" + a2="./prog"' diff --git a/data_sources/linux_auditd_path.yml b/data_sources/linux_auditd_path.yml index 03703ad47b..9ff6f3cdef 100644 --- a/data_sources/linux_auditd_path.yml +++ b/data_sources/linux_auditd_path.yml @@ -10,7 +10,7 @@ configuration: https://github.com/Neo23x0/auditd/blob/master/audit.rules supported_TA: - name: Splunk Add-on for Unix and Linux url: https://splunkbase.splunk.com/app/833 - version: 9.2.0 + version: 10.0.0 fields: - msg - type @@ -30,4 +30,6 @@ fields: - cap_frootid - OUID - OGID -example_log: 'type=PATH msg=audit(1723043687.149:14898): item=1 name="/etc/ssh/ssh_config~" inode=1292 dev=103:01 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=DELETE cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0 OUID="root" OGID="root"' +example_log: 'type=PATH msg=audit(1723043687.149:14898): item=1 name="/etc/ssh/ssh_config~" + inode=1292 dev=103:01 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=DELETE cap_fp=0 + cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0 OUID="root" OGID="root"' diff --git a/data_sources/linux_auditd_proctitle.yml b/data_sources/linux_auditd_proctitle.yml index 4831ba4585..b20cf3036c 100644 --- a/data_sources/linux_auditd_proctitle.yml +++ b/data_sources/linux_auditd_proctitle.yml @@ -10,7 +10,7 @@ configuration: https://github.com/Neo23x0/auditd/blob/master/audit.rules supported_TA: - name: Splunk Add-on for Unix and Linux url: https://splunkbase.splunk.com/app/833 - version: 9.2.0 + version: 10.0.0 fields: - proctitle - msg diff --git a/data_sources/linux_auditd_service_stop.yml b/data_sources/linux_auditd_service_stop.yml index 151da0bdca..f58756c5ae 100644 --- a/data_sources/linux_auditd_service_stop.yml +++ b/data_sources/linux_auditd_service_stop.yml @@ -10,7 +10,7 @@ configuration: https://github.com/Neo23x0/auditd/blob/master/audit.rules supported_TA: - name: Splunk Add-on for Unix and Linux url: https://splunkbase.splunk.com/app/833 - version: 9.2.0 + version: 10.0.0 fields: - msg - type @@ -28,4 +28,6 @@ fields: - res - UID - AUID -example_log: 'type=SERVICE_STOP msg=audit(1722957155.494:4802): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=unconfined msg=''unit=atd comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success''UID="root" AUID="unset"' +example_log: 'type=SERVICE_STOP msg=audit(1722957155.494:4802): pid=1 uid=0 auid=4294967295 + ses=4294967295 subj=unconfined msg=''unit=atd comm="systemd" exe="/usr/lib/systemd/systemd" + hostname=? addr=? terminal=? res=success''UID="root" AUID="unset"' diff --git a/data_sources/linux_auditd_syscall.yml b/data_sources/linux_auditd_syscall.yml index 73a300e2be..6246b98eaf 100644 --- a/data_sources/linux_auditd_syscall.yml +++ b/data_sources/linux_auditd_syscall.yml @@ -10,7 +10,7 @@ configuration: https://github.com/Neo23x0/auditd/blob/master/audit.rules supported_TA: - name: Splunk Add-on for Unix and Linux url: https://splunkbase.splunk.com/app/833 - version: 9.2.0 + version: 10.0.0 fields: - msg - type @@ -20,7 +20,7 @@ fields: - success - exit - a1 -- a2 +- a2 - a3 - items - ppid @@ -51,4 +51,9 @@ fields: - EGID - SGID - FSGID -example_log: 'type=SYSCALL msg=audit(1723035666.627:3663): arch=c000003e syscall=59 success=yes exit=0 a0=556a6d697a58 a1=556a6d68ad00 a2=556a6d69c980 a3=0 items=2 ppid=1300 pid=1301 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm="lsmod" exe="/usr/bin/kmod" subj=unconfined key="rootcmd" ARCH=x86_64 SYSCALL=execve AUID="ubuntu" UID="root" GID="root" EUID="root" SUID="root" FSUID="root" EGID="root" SGID="root" FSGID="root"' +example_log: 'type=SYSCALL msg=audit(1723035666.627:3663): arch=c000003e syscall=59 + success=yes exit=0 a0=556a6d697a58 a1=556a6d68ad00 a2=556a6d69c980 a3=0 items=2 + ppid=1300 pid=1301 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 + tty=pts1 ses=1 comm="lsmod" exe="/usr/bin/kmod" subj=unconfined key="rootcmd" ARCH=x86_64 + SYSCALL=execve AUID="ubuntu" UID="root" GID="root" EUID="root" SUID="root" FSUID="root" + EGID="root" SGID="root" FSGID="root"' diff --git a/detections/endpoint/system_user_discovery_with_query.yml b/detections/endpoint/system_user_discovery_with_query.yml index 249c62b457..cd0788aeb9 100644 --- a/detections/endpoint/system_user_discovery_with_query.yml +++ b/detections/endpoint/system_user_discovery_with_query.yml @@ -1,7 +1,7 @@ name: System User Discovery With Query id: ad03bfcf-8a91-4bc2-a500-112993deba87 -version: 4 -date: '2024-11-13' +version: 5 +date: '2025-02-05' author: Mauricio Velazco, Splunk status: production type: Hunting @@ -17,9 +17,8 @@ data_source: - Windows Event Log Security 4688 - CrowdStrike ProcessRollup2 search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) - as lastTime from datamodel=Endpoint.Processes where (Processes.process_name="query.exe") - (Processes.process=*user*) by Processes.dest Processes.user Processes.parent_process - Processes.process_name Processes.process Processes.process_id Processes.parent_process_id + as lastTime from datamodel=Endpoint.Processes where (Processes.process_name="query.exe" OR Processes.original_file_name="query.exe") + AND Processes.process="*user*" AND ((NOT Processes.process="*/server*") OR Processes.process IN ("*/server:localhost*", "*/server:127.0.0.1*")) by Processes.dest Processes.user Processes.parent_process Processes.process_name Processes.process Processes.process_id Processes.parent_process_id | `drop_dm_object_name(Processes)` | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `system_user_discovery_with_query_filter`' how_to_implement: The detection is based on data that originates from Endpoint Detection diff --git a/detections/endpoint/windows_system_remote_discovery_with_query.yml b/detections/endpoint/windows_system_remote_discovery_with_query.yml new file mode 100644 index 0000000000..58b97c3df7 --- /dev/null +++ b/detections/endpoint/windows_system_remote_discovery_with_query.yml @@ -0,0 +1,64 @@ +name: Windows System Remote Discovery With Query +id: 94859172-a521-474f-97ac-4cf4b09634a3 +version: 1 +date: '2025-02-05' +author: Steven Dick +status: production +type: Anomaly +description: The following analytic detects the execution of `query.exe` with command-line arguments aimed at discovering data on remote devices. It leverages data from Endpoint Detection and Response (EDR) agents, focusing on process names and command-line executions. This activity is significant as adversaries may use `query.exe` to gain situational awareness and perform Active Directory discovery on compromised endpoints. If confirmed malicious, this behavior could allow attackers to identify various details about a system, aiding in further lateral movement and privilege escalation within the network. +data_source: +- Sysmon Event ID 1 +- Windows Security Event ID 4688 +- CrowdStrike ProcessRollup2 +search: |- + | tstats `security_content_summariesonly` values(Processes.process_current_directory) as Processes.process_current_directory values(Processes.process_id) as Processes.process_id values(Processes.process) as Processes.process values(Processes.parent_process_id) as Processes.parent_process_id values(Processes.parent_process) as Processes.parent_process count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where (Processes.process_name="query.exe" OR Processes.original_file_name="query.exe") AND (Processes.process="*/server*") AND NOT Processes.process IN ("*/server:localhost*", "*/server:127.0.0.1*") by Processes.dest Processes.user Processes.process_name Processes.parent_process_name + | `drop_dm_object_name(Processes)` + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `windows_system_remote_discovery_with_query_filter` +how_to_implement: The detection is based on data that originates from Endpoint Detection and Response (EDR) agents. These agents are designed to provide security-related telemetry from the endpoints where the agent is installed. To implement this search, you must ingest logs that contain the process GUID, process name, and parent process. Additionally, you must ingest complete command-line executions. These logs must be processed using the appropriate Splunk Technology Add-ons that are specific to the EDR product. The logs must also be mapped to the `Processes` node of the `Endpoint` data model. Use the Splunk Common Information Model (CIM) to normalize the field names and speed up the data modeling process. +known_false_positives: Administrators or power users may use this command for troubleshooting. +references: +- https://attack.mitre.org/techniques/T1033/ +drilldown_searches: +- name: View the detection results for - "$dest$" and "$user$" + search: '%original_detection_search% | search dest = "$dest$" user = "$user$"' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: View risk events for the last 7 days for - "$dest$" and "$user$" + search: '| from datamodel Risk.All_Risk | search normalized_risk_object IN ("$dest$","$user$") starthoursago=168 | stats count min(_time) as firstTime max(_time) as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk Message" values(analyticstories) as "Analytic Stories" values(annotations._all) as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics" by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +- name: Investigate processes on $dest$ + search: '| from datamodel:Endpoint.Processes | search dest=$dest$ process_name = $process_name|s$' + earliest_offset: $info_min_time$ + latest_offset: $info_max_time$ +rba: + message: The user $user$ ran the Query command to enumerate the remote system $dest$ + risk_objects: + - field: user + type: user + score: 25 + - field: dest + type: system + score: 25 + threat_objects: + - field: process_name + type: process_name +tags: + analytic_story: + - Active Directory Discovery + asset_type: Endpoint + mitre_attack_id: + - T1033 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + security_domain: endpoint +tests: +- name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1033/query_remote_usage/query_remote_usage.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: XmlWinEventLog