skills/smithery.ai/splunk-rule-conversion

splunk-rule-conversion

SKILL.md

Splunk Rule Conversion

Overview

Convert Splunk SPL detection rules to Microsoft Sentinel KQL, Google SecOps YARA-L 2.0, and CrowdStrike CQL. Includes field mappings, syntax patterns, and detection quality improvements.

Quick Reference

Source Target Key Differences
Splunk SPL Microsoft KQL Pipe vs chained operators, different aggregation syntax
Splunk SPL Google YARA-L Declarative rules vs procedural queries, UDM schema
Splunk SPL CrowdStrike CQL Similar pipe syntax, different field names

SPL to Microsoft Sentinel KQL

Syntax Mapping

SPL KQL
index=windows SecurityEvent table
sourcetype=WinEventLog:Security SecurityEvent
search field=value where field == "value"
stats count by user summarize count() by user
eval field=value extend field = value
table field1, field2 project field1, field2
rename old AS new project-rename new = old
dedup field summarize take_any(*) by field
sort -count order by count desc
rex field=x "(?<name>pattern)" parse x with * "pattern" name or extract()
mvexpand field mv-expand field
earliest=-24h TimeGenerated > ago(24h)
| where count > 5 | where count_ > 5
transaction summarize makeset() + correlation logic

Data Table Mapping

Splunk Source Sentinel Table
Windows Security Events SecurityEvent
Syslog Syslog
Network/Firewall CommonSecurityLog
DNS DnsEvents
Azure AD Sign-ins SigninLogs
Azure AD Audit AuditLogs
M365 Activity OfficeActivity
Defender for Endpoint DeviceEvents, DeviceProcessEvents
Azure Activity AzureActivity

Windows EventID Reference

EventID Description KQL Filter
4624 Successful logon EventID == 4624
4625 Failed logon EventID == 4625
4648 Explicit credential logon EventID == 4648
4672 Special privileges assigned EventID == 4672
4688 Process creation EventID == 4688
4698 Scheduled task created EventID == 4698
4720 User account created EventID == 4720
4732 Member added to local group EventID == 4732

KQL Detection Quality Guidelines

When converting, enhance detections with:

  1. Avoid Low-and-Slow Blindness

    // Create complementary rules with different thresholds
    // High threshold for immediate alert
    // Low threshold for hunting/investigation
    
  2. Address Distributed Attacks

    // Aggregate by user across ALL devices, not per-device
    SecurityEvent
    | where EventID == 4625
    | summarize FailedLogons = count() by TargetUserName, bin(TimeGenerated, 1h)
    | where FailedLogons > 10
    
  3. Correlate Failures with Success

    // Failed attempts followed by success = potential compromise
    let failures = SecurityEvent | where EventID == 4625;
    let successes = SecurityEvent | where EventID == 4624;
    failures
    | join kind=inner (successes) on TargetUserName
    | where TimeGenerated1 between (TimeGenerated .. TimeGenerated + 1h)
    
  4. Cover Cloud Identity

    // Include non-interactive sign-ins (often missed)
    union SigninLogs, AADNonInteractiveUserSignInLogs
    | where ResultType != 0
    
  5. Device Management Context

    // CRITICAL: Use LEFT OUTER JOIN for device tables (not all devices managed)
    SecurityEvent
    | join kind=leftouter (DeviceInfo) on DeviceId
    
  6. Geographic Anomaly Detection

    SigninLogs
    | extend Country = tostring(LocationDetails.countryOrRegion)
    | summarize Countries = make_set(Country) by UserPrincipalName, bin(TimeGenerated, 1h)
    | where array_length(Countries) > 1
    

Example Conversion: Brute Force Detection

Original SPL:

index=windows sourcetype=WinEventLog:Security EventCode=4625
| stats count as failed_attempts by Account_Name, src_ip
| where failed_attempts > 5

Converted KQL:

let timeframe = 1h;
let threshold = 5;
SecurityEvent
| where TimeGenerated > ago(timeframe)
| where EventID == 4625
| extend AccountName = TargetUserName
| extend SourceIP = IpAddress
| summarize FailedAttempts = count() by AccountName, SourceIP, bin(TimeGenerated, 5m)
| where FailedAttempts > threshold
| project TimeGenerated, AccountName, SourceIP, FailedAttempts

SPL to Google SecOps YARA-L 2.0

YARA-L 2.0 Rule Structure

rule rule_name {
  meta:
    author = "Security Team"
    description = "Rule description"
    severity = "HIGH"  // INFO, LOW, MEDIUM, HIGH, CRITICAL
    mitre_attack_tactic = "Tactic Name"
    mitre_attack_technique = "TXXXX"

  events:
    // Event matching conditions
    $event.metadata.event_type = "PROCESS_LAUNCH"
    $event.principal.process.file.full_path = /pattern/i

  match:
    // Grouping for aggregation (optional)
    $event.principal.user.userid over 5m

  outcome:
    // Calculated fields (optional)
    $count = count($event)

  condition:
    // Rule trigger conditions
    $event and $count > 5
}

CRITICAL YARA-L Requirements

  1. Risk Score MUST be static integer

    // CORRECT
    risk_score = 85
    
    // WRONG - will fail
    risk_score = $severity * 10
    
  2. No if() in aggregation functions

    // WRONG
    $count = count_distinct(if($e.severity > 5, $e.user))
    
    // CORRECT - use separate rules or filter in events section
    
  3. Match section indentation: exactly 2 spaces

    match:
      $user over 5m  // 2 spaces, not tab
    
  4. Placeholder variables use $ prefix

    $e.metadata.event_type  // event variable
    $user over 5m           // match variable
    

UDM Field Mapping

Splunk Field UDM Path
user / Account principal.user.userid
src_ip principal.ip
dest_ip target.ip
src_port principal.port
dest_port target.port
process principal.process.file.full_path
command_line principal.process.command_line
parent_process principal.process.parent_process.file.full_path
host / hostname principal.hostname
EventCode metadata.product_event_type
action security_result.action
severity security_result.severity
file_hash target.file.sha256
url target.url
domain network.dns.questions.name

UDM Event Types

Type Description
PROCESS_LAUNCH Process execution
PROCESS_TERMINATE Process termination
NETWORK_CONNECTION Network connection
NETWORK_DNS DNS query
FILE_CREATION File created
FILE_MODIFICATION File modified
FILE_DELETION File deleted
USER_LOGIN Authentication
USER_LOGOUT Session end
REGISTRY_CREATION Registry key created
REGISTRY_MODIFICATION Registry value changed

Example Conversion: Suspicious PowerShell

Original SPL:

index=windows sourcetype=WinEventLog:Security EventCode=4688
| search New_Process_Name="*powershell.exe"
| search (Process_Command_Line="*-enc*" OR Process_Command_Line="*-encodedcommand*")
| stats count by Account_Name, Workstation_Name

Converted YARA-L:

rule suspicious_encoded_powershell {
  meta:
    author = "Security Team"
    description = "Detects encoded PowerShell execution"
    severity = "HIGH"
    mitre_attack_tactic = "Execution"
    mitre_attack_technique = "T1059.001"

  events:
    $process.metadata.event_type = "PROCESS_LAUNCH"
    $process.metadata.product_event_type = "4688"
    $process.principal.process.file.full_path = /powershell\.exe$/i
    $process.principal.process.command_line = /\-[eE]nc|\-[eE]ncodedCommand/
    $user = $process.principal.user.userid
    $host = $process.principal.hostname

  match:
    $user, $host over 5m

  outcome:
    $execution_count = count($process)
    $risk_score = 75

  condition:
    $process
}

SPL to CrowdStrike CQL

CQL Syntax Mapping

SPL CQL
index=main Select event source/repository
sourcetype= event_simpleName=
search field=value field=value
stats count by field | groupBy([field])
eval newfield=expr | eval(newfield=expr)
table fields | select([fields])
sort -field | sort(field, order=desc)
dedup field | groupBy([field]) | head(1)
rex | regex()
where count > 5 | test(count > 5)

CrowdStrike Event Types

event_simpleName Description
ProcessRollup2 Process execution with full context
SyntheticProcessRollup2 Synthetic process events
NetworkConnectIP4 IPv4 network connection
NetworkConnectIP6 IPv6 network connection
DnsRequest DNS query
FileWritten File creation/modification
UserLogon Authentication event
AsepValueUpdate Persistence mechanism

Platform Filtering

// Windows only
event_platform=Win

// macOS only
event_platform=Mac

// Linux only
event_platform=Lin

CQL Field Reference

Splunk Equivalent CQL Field
hostname ComputerName
user UserName
process FileName
command_line CommandLine
parent_process ParentBaseFileName
src_ip LocalAddressIP4
dest_ip RemoteAddressIP4
dest_port RemotePort
file_hash SHA256HashData
pid TargetProcessId
parent_pid ParentProcessId

Example Conversion: Network Beaconing

Original SPL:

index=firewall sourcetype=pan:traffic
| stats count by src_ip, dest_ip, dest_port
| where count > 100
| sort -count

Converted CQL:

event_simpleName=NetworkConnectIP4
| groupBy([LocalAddressIP4, RemoteAddressIP4, RemotePort])
| count(aid, as=connection_count)
| test(connection_count > 100)
| sort(connection_count, order=desc)
| select([LocalAddressIP4, RemoteAddressIP4, RemotePort, connection_count])

Conversion Workflow

Step 1: Analyze Source Rule

  1. Identify data sources (index, sourcetype)
  2. Map fields to target schema
  3. Understand aggregation logic
  4. Note time windows and thresholds

Step 2: Translate Core Logic

  1. Convert search conditions
  2. Map aggregation functions
  3. Adapt field names
  4. Adjust time syntax

Step 3: Enhance Detection Quality

  1. Add complementary low-threshold variants
  2. Include distributed attack patterns
  3. Add success correlation for auth failures
  4. Cover cloud identity sources
  5. Add geographic anomaly detection

Step 4: Validate and Test

  1. Syntax validation
  2. Test with sample data
  3. Tune thresholds
  4. Document false positive patterns

MITRE ATT&CK Mapping Reference

Include MITRE mapping in converted rules:

Tactic Common Techniques
Initial Access T1566 (Phishing), T1190 (Exploit Public-Facing)
Execution T1059 (Command/Scripting), T1204 (User Execution)
Persistence T1547 (Boot/Logon Autostart), T1053 (Scheduled Task)
Privilege Escalation T1548 (Abuse Elevation), T1134 (Access Token)
Defense Evasion T1070 (Indicator Removal), T1036 (Masquerading)
Credential Access T1003 (OS Credential Dumping), T1110 (Brute Force)
Discovery T1082 (System Info), T1083 (File/Directory Discovery)
Lateral Movement T1021 (Remote Services), T1570 (Lateral Tool Transfer)
Collection T1005 (Data from Local System), T1114 (Email Collection)
Exfiltration T1041 (Exfil Over C2), T1048 (Exfil Over Alt Protocol)
Impact T1486 (Data Encrypted), T1489 (Service Stop)

Common Conversion Patterns

Authentication Monitoring

SPL:

index=windows EventCode=4625 | stats count by Account_Name | where count > 10

KQL:

SecurityEvent
| where EventID == 4625
| summarize FailedCount = count() by TargetUserName
| where FailedCount > 10

YARA-L:

rule brute_force_detection {
  meta:
    severity = "MEDIUM"
  events:
    $fail.metadata.event_type = "USER_LOGIN"
    $fail.security_result.action = "BLOCK"
    $user = $fail.target.user.userid
  match:
    $user over 10m
  outcome:
    $fail_count = count($fail)
  condition:
    $fail and $fail_count > 10
}

CQL:

event_simpleName=UserLogon LogonType=10
| groupBy([UserName])
| count(aid, as=logon_attempts)
| test(logon_attempts > 10)

Confidence Scoring

When converting rules, assess confidence:

Score Meaning
0.90-1.00 Perfect conversion, all fields mapped
0.75-0.89 Good conversion, minor assumptions made
0.60-0.74 Moderate conversion, some logic simplified
0.40-0.59 Partial conversion, manual review needed
<0.40 Significant gaps, major rework required

Factors affecting confidence:

  • Field availability in target platform
  • Aggregation complexity
  • Multi-event correlation
  • Custom field extractions
  • Platform-specific features
Weekly Installs
1
First Seen
7 days ago
Installed on
claude-code1