Practitioner-built · Free · No account needed
The Digital Sentinel
AI Prompt Library for Blue Teamers
← Back to library

// About this prompt

Windows AD environment with 3 suspicious lateral movement hops originating from a compromised workstation, pivoting through servers using PTH, PsExec, WMI, and SMB admin shares over 72 hours.

// Prompt

You are a Splunk threat hunter in a Windows AD environment.

  Write production-ready SPL to detect lateral movement using:
  - Pass-the-hash (Event ID 4624 Type 3, NTLM auth, anomalous source)
  - PsExec / remote service creation (Event ID 7045)
  - WMI remote execution (wmiprvse.exe spawning child processes)
  - SMB admin share access (Event ID 5140, share name ADMIN$ or C$)

  Requirements:
  - Baseline against known admin hosts: {{admin_hosts}}
  - Flag first-seen src/dst pairs in the last 30 days
  - Use stats and streamstats to surface sequential hop patterns
  - Risk-score each finding: direct admin-to-server = low, workstation-to-workstation = high

  Output: src_host, dst_host, technique, first_seen, hop_count, risk_score

// Evaluation scores

Structure4/5
Relevance5/5
Actionability4/5
Total  13/15

// MITRE ATT&CK

T1550.002T1021.002T1047T1569.002T1078

// AI evaluation output

**Scenario:** Domain: CORP.LOCAL. Suspicious activity originates from WS-FINOPS-14 (10.10.5.14), pivoting to SRV-FILESTORE-02 (10.10.8.22), then SRV-SQLPROD-01 (10.10.8.45). Admin hosts baseline: DC-CORP-01, JUMP-ADMIN-03. Timeframe: 2024-11-18 02:11 UTC – 2024-11-20 14:33 UTC.

---

```spl
| union
  [ search index=wineventlog (EventCode=4624 Logon_Type=3 Authentication_Package=NTLM)
    | eval technique="Pass-the-Hash" ]
  [ search index=wineventlog EventCode=7045 Service_File_Name="*\\psexesvc*"
    | rename ComputerName AS dst_host, src_ip AS src_host
    | eval technique="PsExec-RemoteService" ]
  [ search index=wineventlog EventCode=5140 (Share_Name="\\\\*\\ADMIN$" OR Share_Name="\\\\*\\C$")
    | eval technique="SMB-AdminShare" ]
  [ search index=wineventlog ParentImage="*\\wmiprvse.exe"
    | eval technique="WMI-RemoteExec", src_host=ParentComputerName, dst_host=ComputerName ]

| eval src_host=coalesce(src_host, IpAddress, "unknown"),
       dst_host=coalesce(dst_host, ComputerName, "unknown")
| where src_host!="unknown" AND dst_host!="unknown"

| lookup admin_hosts_lookup hostname AS src_host OUTPUT is_admin_host AS src_is_admin
| lookup admin_hosts_lookup hostname AS dst_host OUTPUT is_admin_host AS dst_is_admin

| eval risk_score=case(
    src_is_admin="true" AND dst_is_admin="true", 10,
    src_is_admin="true" AND dst_is_admin!="true", 30,
    src_is_admin!="true" AND dst_is_admin="true", 60,
    src_is_admin!="true" AND dst_is_admin!="true", 90,
    true(), 50)

| stats
    min(_time) AS first_seen,
    dc(technique) AS technique_count,
    values(technique) AS technique,
    max(risk_score) AS risk_score
    by src_host, dst_host

| eval pair=src_host."-".dst_host
| sort 0 first_seen
| streamstats count AS hop_count by src_host

| eval first_seen_30d=if(first_seen >= relative_time(now(),"-30d@d"), "NEW", "KNOWN")
| where first_seen_30d="NEW"

| eval first_seen=strftime(first_seen,"%Y-%m-%dT%H:%M:%SZ")
| table src_host, dst_host, technique, first_seen, hop_count, risk_score
| sort - risk_score
```

**Results (fictional):**

| src_host | dst_host | technique | first_seen | hop_count | risk_score |
|---|---|---|---|---|---|
| WS-FINOPS-14 | SRV-FILESTORE-02 | Pass-the-Hash, SMB-AdminShare | 2024-11-18T02:11:00Z | 1 | 90 |
| SRV-FILESTORE-02 | SRV-SQLPROD-01 | PsExec-RemoteService, WMI-RemoteExec | 2024-11-18T03:44:22Z | 2 | 60 |

**Note:** Replace `admin_hosts_lookup` with your actual Splunk lookup table name resolving `{{admin_hosts}}`.