Detecting Command Line Interpreters Launched via Scheduled Tasks

KQL Queries:

KQL query to discover command line interpreters launched via scheduled tasks:

// Define patterns to identify command line interpreters
let CommandLineInterpreters = dynamic(["cmd.exe", "powershell.exe", "pwsh.exe", "wmic.exe", "mshta.exe", "cscript.exe", "wscript.exe"]);
// Query DeviceProcessEvents table
DeviceProcessEvents
| where ((InitiatingProcessFileName =~ "taskeng.exe") // For anything pre-Windows 10 version 1511
    or (InitiatingProcessFileName =~ "svchost.exe" and InitiatingProcessCommandLine has "Schedule")) // For anything post Windows 10 version 1511
| where FileName in~ (CommandLineInterpreters) // Match command line interpreters
| summarize
    Devices = make_set(DeviceName),
    NumberOfDevices = dcount(DeviceName),
    UniqueUsers = dcount(AccountName),
    TotalEvents = count()
    by ProcessCommandLine, FileName, FolderPath, InitiatingProcessFileName, bin(TimeGenerated, 1h)
| order by TotalEvents desc
| project TimeGenerated, ProcessCommandLine, FileName, FolderPath, InitiatingProcessFileName, Devices, NumberOfDevices, UniqueUsers, TotalEvents

Explanation:

  1. Pattern Matching: The CommandLineInterpreters dynamic array contains common command line interpreters.

  2. Filtering: The where clauses filter the DeviceProcessEvents table to retain only events where command line interpreters were launched via scheduled tasks.

  3. Summarisation: The summarise statement aggregates the data to count the number of devices and list the devices for each command line.

  4. Ordering: The results are ordered by the number of devices in descending order.

  5. Projection: The project statement selects the relevant columns for the final output.

Splunk Queries:

To detect Command Line Interpreters launched via Scheduled Tasks in Splunk using the sysmon index, you can use the following SPL (Search Processing Language) query. It leverages Sysmon Event IDs, processes commonly associated with command-line interpreters, and their execution context.

index=sysmon EventCode=1 
| eval is_scheduled_task=if((ParentImage="*\\taskeng.exe" OR ParentImage="*\\svchost.exe" OR CommandLine="schtasks*"), "true", "false")
| search is_scheduled_task="true"
| eval is_interpreter=if((Image="*\\cmd.exe" OR Image="*\\powershell.exe" OR Image="*\\wscript.exe" OR Image="*\\cscript.exe" OR Image="*\\pwsh.exe" OR Image="*\\bash.exe"), "true", "false")
| search is_interpreter="true"
| table _time ComputerName User Image ParentImage CommandLine
| rename Image as "Interpreter", ParentImage as "Parent Process"
| sort - _time

Explanation of the Query:

  1. Index and Event Filtering:

    • index=sysmon filters to only events within the sysmon index.

    • EventCode=1focuses on process creation events.

  2. Parent Process Check (Scheduled Tasks):

    • ParentImage="*\\taskeng.exe" or ParentImage="*\\svchost.exe" indicates the process is potentially related to Scheduled Tasks.

    • CommandLine="schtasks*"captures executions directly involving schtasks.

  3. Command-Line Interpreter Filtering:

    • Filters for commonly abused command-line interpreters, including cmd.exe, powershell.exe, wscript.exe, cscript.exe, pwsh.exe, and bash.exe.

  4. Conditional Evaluation and Final Filtering:

    • Uses eval to tag events based on parent process or interpreter usage.

    • Filters only events where is_scheduled_task and is_interpreter are both true.

  5. Tabular Results:

    • Displays relevant fields: Interpreter, Parent Process, CommandLine, User, ComputerName, and _time.

  6. Sorting:

    • Sort results by timestamp for analysis.

Last updated