Detection rules › Splunk

Executable File Written to Disk (Windows Event Log)

Group by
_time, host, target_filename
Source
github.com/anvilogic-forge/armory

Detects when a potentially malicious file is written to the disk

MITRE ATT&CK coverage

TacticTechniques
Command & ControlT1105 Ingress Tool Transfer

References

Event coverage

Rule body yaml

id: '1040.1061'
title: Executable File Written to Disk
description: 'Detects when a potentially malicious file is written to the disk. -
  Threat Actor Association: Alloy Taurus/Gallium, Andariel, APT28 (aka.Fancy Bear,
  Fighting Ursa, Forest Blizzard, Pawn Storm, TA422, STRONTIUM), APT29/Nobelium/Cozy
  Bear, APT34/OilRig, APT37, APT41, Arid Viper/APT C-23, Babuk, Carbanak, Evilnum,
  FIN6, FIN7, FIN8, Gamaredon (aka. Armageddon, UAC-0010), Kimsuky, Lazarus, MalKamak,
  Memento Team, Mustang Panda, Night Spider, TA2541, TA,505, TA551, Prophet Spider,
  Phosphorus/Magic Hound/APT35, SaintBear (aka UAC-0056, UNC2589, TA471), Scatter
  Swine, TA576, Wizard Spider -- Software Association: BadHatch, Bazar, Black Basta,
  BlackByte, Clop, Conti, Cring, Emotet, GhostShell, Hancitor, Harvester, IcedID,
  Lapsus$, MirrorBlast, PYSA/Mespinoza, QakBot, Ransom Cartel, Remcos, Ryuk, SquirrelWaffle,
  TargetCompany, Trickbot, Vidar Stealer, WhisperGate, XingLocker, Yanluowang, Zloader'
logic_format: Splunk
logic: '`get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=4656) OR
  "<EventID>4656<") (Accesses="*write*" OR Accesses="*add*" OR AccessList="*%%4417*"
  OR AccessList="*%%4418*") (TERM("bat") OR TERM("bin") OR TERM("cmd") OR TERM("com")
  OR TERM("e_e") OR TERM("ex_") OR TERM("exe") OR TERM("hta") OR TERM("jar") OR TERM("js")
  OR TERM("out") OR TERM("plx") OR TERM("ps1") OR TERM("py") OR TERM("pyc") OR TERM("rgs")
  OR TERM("script") OR TERM("sct") OR TERM("server") OR TERM("vb") OR TERM("ws") OR
  TERM("docm") OR TERM("dotm") OR TERM("xlm") OR TERM("xlsm") OR TERM("xltm") OR TERM("xla")
  OR TERM("xlam") OR TERM("xll") OR TERM("otm") OR TERM("pptm") OR TERM("potm") OR
  TERM("ppsm") OR TERM("sldm")) | rename Object_Name as file_path | regex file_path="\.(bat|bin|cmd|com|e_e|ex_|exe|hta|jar|js|out|plx|ps1|py|pyc|rgs|script|sct|server|vb|ws|docm|dotm|xlm|xlsm|xltm|xla|xlam|xll|otm|pptm|potm|ppsm|sldm)$"
  | table _time, host, user, event_id, file_path, process_name, process_path, signature_id,
  tag | bin span=1s | stats values(*) as * by _time, host, file_path '
techniques:
- command-and-control:ingress tool transfer
technique_id: 
- T1105
data_category:
- Windows event logs
references:
- https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4656

Stages and Predicates

Stage 1: search

`get_endpoint_data` `get_endpoint_data_winevent` (TERM(EventCode=4656) OR "<EventID>4656<") (Accesses="*write*" OR Accesses="*add*" OR AccessList="*%%4417*" OR AccessList="*%%4418*") (TERM("bat") OR TERM("bin") OR TERM("cmd") OR TERM("com") OR TERM("e_e") OR TERM("ex_") OR TERM("exe") OR TERM("hta") OR TERM("jar") OR TERM("js") OR TERM("out") OR TERM("plx") OR TERM("ps1") OR TERM("py") OR TERM("pyc") OR TERM("rgs") OR TERM("script") OR TERM("sct") OR TERM("server") OR TERM("vb") OR TERM("ws") OR TERM("docm") OR TERM("dotm") OR TERM("xlm") OR TERM("xlsm") OR TERM("xltm") OR TERM("xla") OR TERM("xlam") OR TERM("xll") OR TERM("otm") OR TERM("pptm") OR TERM("potm") OR TERM("ppsm") OR TERM("sldm"))

Stage 2: rename

| rename Object_Name as file_path

Stage 3: regex

| regex file_path="\.(bat|bin|cmd|com|e_e|ex_|exe|hta|jar|js|out|plx|ps1|py|pyc|rgs|script|sct|server|vb|ws|docm|dotm|xlm|xlsm|xltm|xla|xlam|xll|otm|pptm|potm|ppsm|sldm)$"

Stage 4: table

| table _time, host, user, event_id, file_path, process_name, process_path, signature_id, tag

Stage 5: bucket

| bin span=1s

Stage 6: stats

| stats values(*) as * by _time, host, file_path

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
AccessListeq
  • "*%%4417*" corpus 11 (sigma 8, elastic 2, splunk 1)
  • "*%%4418*" corpus 3 (sigma 1, splunk 1, kusto 1)
Accesseseq
  • "*add*"
  • "*write*"
EventCodeeq
  • 4656 corpus 19 (splunk 15, kusto 4)
file_pathregex_match
  • ".(bat|bin|cmd|com|e_e|ex_|exe|hta|jar|js|out|plx|ps1|py|pyc|rgs|script|sct|server|vb|ws|docm|dotm|xlm|xlsm|xltm|xla|xlam|xll|otm|pptm|potm|ppsm|sldm)$"

Search terms

Bare-string tokens in the SPL search body. Splunk matches each token against _raw (the untyped raw event text) anywhere it appears, not against a specific field. These don't surface in the Indicators table because they aren't predicates on a known field.

StageTerm
1TERM
1"<EventID>4656<"
1"bat"
1"bin"
1"cmd"
1"com"
1"e_e"
1"ex_"
1"exe"
1"hta"
1"jar"
1"js"
1"out"
1"plx"
1"ps1"
1"py"
1"pyc"
1"rgs"
1"script"
1"sct"
1"server"
1"vb"
1"ws"
1"docm"
1"dotm"
1"xlm"
1"xlsm"
1"xltm"
1"xla"
1"xlam"
1"xll"
1"otm"
1"pptm"
1"potm"
1"ppsm"
1"sldm"