PowerShell Share Enumeration Script

Detects PowerShell scripts that use ShareFinder functions (Invoke-ShareFinder/Invoke-ShareFinderThreaded) or Windows share enumeration APIs (shi1_netname/shi1_remark with NetShareEnum/NetApiBufferFree). Attackers use share enumeration to map accessible network shares for collection, lateral movement, or ransomware targeting.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2022/08/17"
  3integration = ["windows"]
  4maturity = "production"
  5updated_date = "2026/09/18"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Detects PowerShell scripts that use ShareFinder functions (Invoke-ShareFinder/Invoke-ShareFinderThreaded) or Windows
 11share enumeration APIs (shi1_netname/shi1_remark with NetShareEnum/NetApiBufferFree). Attackers use share enumeration to
 12map accessible network shares for collection, lateral movement, or ransomware targeting.
 13"""
 14from = "now-9m"
 15index = ["logs-windows.powershell*", "winlogbeat-*"]
 16language = "kuery"
 17license = "Elastic License v2"
 18name = "PowerShell Share Enumeration Script"
 19references = [
 20    "https://www.advintel.io/post/hunting-for-corporate-insurance-policies-indicators-of-ransom-exfiltrations",
 21    "https://thedfirreport.com/2022/04/04/stolen-images-campaign-ends-in-conti-ransomware/",
 22    "https://github.com/atc-project/atc-data/blob/master/docs/Logging_Policies/LP_0109_windows_powershell_script_block_log.md",
 23]
 24risk_score = 73
 25rule_id = "4c59cff1-b78a-41b8-a9f1-4231984d1fb6"
 26severity = "high"
 27tags = [
 28    "Domain: Endpoint",
 29    "OS: Windows",
 30    "Use Case: Threat Detection",
 31    "Tactic: Discovery",
 32    "Resources: Investigation Guide",
 33    "Data Source: PowerShell Logs",
 34    "Noise: Low",
 35    "Performance: Normal",
 36    "Rule Type: Custom Query (KQL)",
 37    "Platform: Windows",
 38]
 39timestamp_override = "event.ingested"
 40type = "query"
 41
 42query = '''
 43event.category:process and host.os.type:windows and
 44  powershell.file.script_block_text:(
 45    "Invoke-ShareFinder" or
 46    "Invoke-ShareFinderThreaded" or
 47    (
 48      "shi1_netname" and
 49      "shi1_remark"
 50    ) or
 51    (
 52      "NetShareEnum" and
 53    "NetApiBufferFree"
 54    )
 55  ) and not user.id : "S-1-5-18"
 56'''
 57
 58note = """## Triage and analysis
 59
 60### Investigating PowerShell Share Enumeration Script
 61
 62#### Possible investigation steps
 63
 64- Does the reconstructed script block show active share enumeration or only helper code loading?
 65  - Why: PowerView-style modules can define functions before invocation, so a function name alone is weaker than target selection, loops, output handling, or access checks.
 66  - Focus: reconstruct the script with `powershell.file.script_block_id` + `powershell.sequence` + `powershell.total` on the same `host.id`, then inspect `powershell.file.script_block_text` for ShareFinder calls, NetShareEnum wrappers, and share result fields such as "shi1_netname" or "shi1_remark". $investigate_0
 67  - Implication: escalate when reconstruction shows active enumeration, target lists, loops, share output, or access testing; lower concern when it only defines helper code and no later invocation appears. Missing fragments keep intent unresolved, not benign.
 68
 69- Can the PowerShell launch context be recovered?
 70  - Why: script block events preserve code; command line and parentage require a matching process event.
 71  - Focus: when endpoint process telemetry exists, recover the matching process via `host.id` + `process.pid` before using `process.*` or `process.parent.*`; review `process.command_line`, `process.parent.executable`, and session type. $investigate_1
 72  - Hint: anchor returned process starts to `@timestamp`; empty, multiple, or distant PID matches keep launch context unresolved.
 73  - Implication: escalate when the launcher is a document, script host, remote session, scheduled task, or user-writable path; lower concern when launcher, arguments, and session type match the same script path, target scope, and user/host anchors for a recurring inventory or storage-audit job. If endpoint process telemetry is missing, continue with script content, source path, user/host anchors, and related-alert scope instead of closing.
 74
 75- Does the script widen discovery with broad targets, threading, or access checks?
 76  - Focus: reconstructed `powershell.file.script_block_text` for threading, host/domain lists, access-check options, ADMIN$ testing, ping suppression, delay/jitter, credential objects, or loops over many hosts or shares.
 77  - Implication: escalate when the script uses threading, access checks, alternate credentials, broad domain or host-list discovery, or ADMIN$ testing; lower concern when the target set is tightly bounded to one recognized inventory, access-review, or storage-audit task.
 78
 79- Are source or output artifacts risky?
 80  - Focus: source path when present, fileless execution, output redirection/export, target/share arrays or excluded-share logic, and same-host/user file events for surrounding output or staging artifacts. $investigate_4
 81  - Implication: escalate when execution is fileless or sourced from temp, downloads, mounted shares, or user-writable paths; also escalate when the script writes reusable share results, prioritizes ADMIN$ or accessible shares, or builds target lists for collection or ransomware staging. Lower concern only when a stable admin repository path, transient output, script content, and user/host anchors all match one bounded recurring workflow. Path alone does not clear the behavior.
 82
 83- Do the user and host anchors fit the expected administrative scope?
 84  - Focus: user identity, host identity, reconstructed target scope, and recovered launch context.
 85  - Implication: escalate when a non-admin user, unusual service account, workstation, or unexpected host performs broad share discovery; lower concern when the same user and host anchors match the bounded management cohort, script path, and target set shown by local evidence.
 86
 87- If local findings stay suspicious or unresolved, does the same share-discovery pattern change scope?
 88  - Focus: related alerts for `user.id` carrying the same ShareFinder/API-wrapper, access-check, or target-list pattern, plus same-host/user network events for SMB or file-server activity when script content suggests access testing or follow-on collection. $investigate_2 $investigate_5
 89  - Hint: if user scope is inconclusive, check related alerts for the same `host.id` before widening beyond this host. $investigate_3
 90  - Hint: network events need destination or share corroboration before they prove access or collection; missing network telemetry is unresolved, not benign.
 91  - Implication: broaden when the same script pattern, operator account, or host appears in unrelated share-discovery alerts; keep the case local when it stays confined to one `host.id`, one `user.id`, one script/source pattern, and one bounded target set.
 92
 93- Escalate when reconstructed content, discovery breadth, access-check markers, source/output pattern, recovered launcher context, or user/host scope show unauthorized share discovery; close only when those categories bind to one recognized workflow with no contradictory evidence; preserve and escalate when evidence is mixed or incomplete.
 94
 95### False positive analysis
 96
 97- PowerView's Invoke-ShareFinder and raw P/Invoke NetShareEnum wrappers with shi1_netname/shi1_remark are offensive tooling patterns with near-zero legitimate administrative use. Legitimate share inventory uses built-in cmdlets (Get-SmbShare, net share) or management platforms, not these APIs. Close as benign true positive only for confirmed authorized red-team, penetration testing, or security validation where reconstructed script content, `user.id`, `host.id`, test-engagement scope, and recovered launch context all align. Do not close on an IT-administration claim when the script uses these specific offensive patterns.
 98
 99### Response and remediation
100
101- If confirmed benign, reverse any temporary containment and record the script owner, source path or recurring fileless content, expected `user.id`, expected `host.id`, target scope, and recovered launch context when available. Create a narrow exception only after the local evidence is confirmed and prior alerts, when present, show the same stable workflow.
102- If suspicious but unconfirmed, preserve the reconstructed `powershell.file.script_block_text`, all fragments linked by `powershell.file.script_block_id`, alert process PID, recovered process record when available, source path, output or target/share list, `user.id`, and `host.id` before containment. Apply reversible containment first: heightened monitoring, temporary SMB restrictions from the affected host to named servers/shares, or temporary restrictions for the implicated account when access testing or credential misuse is indicated. Escalate to host isolation or stronger credential actions only if access testing, staging, or credential misuse is confirmed and host criticality permits it.
103- If confirmed malicious, isolate the host or restrict the account only after preserving the reconstructed script, recovered launch context, source/output artifacts, and target/share list. Review the named servers, shares, accounts, and related alerts for the same indicators before deleting scripts, killing processes, or resetting credentials; remove malicious scripts, scheduled tasks, or credential material only after scope is complete.
104- Post-incident hardening: keep PowerShell script block logging enabled, restrict unsigned or user-writable PowerShell execution on management hosts where feasible, retain endpoint and file-server telemetry needed to confirm share access, and record the confirmed workflow or malicious server/share list for future triage.
105"""
106
107setup = """## Setup
108
109PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
110Setup instructions: https://ela.st/powershell-logging-setup
111"""
112
113[rule.investigation_fields]
114field_names = [
115    "@timestamp",
116    "user.name",
117    "user.id",
118    "user.domain",
119    "powershell.file.script_block_text",
120    "powershell.file.script_block_id",
121    "powershell.sequence",
122    "powershell.total",
123    "file.path",
124    "file.directory",
125    "file.name",
126    "process.pid",
127    "host.name",
128    "host.id",
129    "powershell.file.script_block_length"
130]
131
132[transform]
133
134[[transform.investigate]]
135label = "Script block fragments for the same script"
136description = ""
137providers = [
138  [
139    { excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" },
140    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
141  ]
142]
143relativeFrom = "now-1h"
144relativeTo = "now"
145
146[[transform.investigate]]
147label = "Process events for the PowerShell instance"
148description = ""
149providers = [
150  [
151    { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
152    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
153    { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" },
154    { excluded = false, field = "event.type", queryType = "phrase", value = "start", valueType = "string" }
155  ]
156]
157relativeFrom = "now-1h"
158relativeTo = "now"
159
160[[transform.investigate]]
161label = "Alerts associated with the user"
162description = ""
163providers = [
164  [
165    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
166    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
167  ]
168]
169relativeFrom = "now-48h/h"
170relativeTo = "now"
171
172[[transform.investigate]]
173label = "Alerts associated with the host"
174description = ""
175providers = [
176  [
177    { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
178    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
179  ]
180]
181relativeFrom = "now-48h/h"
182relativeTo = "now"
183
184[[transform.investigate]]
185label = "Same host and user file events"
186description = ""
187providers = [
188  [
189    { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
190    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
191    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
192  ]
193]
194relativeFrom = "now-1h"
195relativeTo = "now"
196
197[[transform.investigate]]
198label = "Same host and user network events"
199description = ""
200providers = [
201  [
202    { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
203    { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
204    { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
205  ]
206]
207relativeFrom = "now-1h"
208relativeTo = "now"
209
210[[rule.threat]]
211framework = "MITRE ATT&CK"
212[[rule.threat.technique]]
213id = "T1135"
214name = "Network Share Discovery"
215reference = "https://attack.mitre.org/techniques/T1135/"
216
217[rule.threat.tactic]
218id = "TA0007"
219name = "Discovery"
220reference = "https://attack.mitre.org/tactics/TA0007/"
221[[rule.threat]]
222framework = "MITRE ATT&CK"
223[[rule.threat.technique]]
224id = "T1059"
225name = "Command and Scripting Interpreter"
226reference = "https://attack.mitre.org/techniques/T1059/"
227[[rule.threat.technique.subtechnique]]
228id = "T1059.001"
229name = "PowerShell"
230reference = "https://attack.mitre.org/techniques/T1059/001/"
231
232[[rule.threat.technique]]
233id = "T1106"
234name = "Native API"
235reference = "https://attack.mitre.org/techniques/T1106/"
236
237[rule.threat.tactic]
238id = "TA0002"
239name = "Execution"
240reference = "https://attack.mitre.org/tactics/TA0002/"
241[[rule.threat]]
242framework = "MITRE ATT&CK"
243[[rule.threat.technique]]
244id = "T1039"
245name = "Data from Network Shared Drive"
246reference = "https://attack.mitre.org/techniques/T1039/"
247
248[rule.threat.tactic]
249id = "TA0009"
250name = "Collection"
251reference = "https://attack.mitre.org/tactics/TA0009/"

Triage and analysis

Investigating PowerShell Share Enumeration Script

Possible investigation steps

  • Does the reconstructed script block show active share enumeration or only helper code loading?

    • Why: PowerView-style modules can define functions before invocation, so a function name alone is weaker than target selection, loops, output handling, or access checks.
    • Focus: reconstruct the script with powershell.file.script_block_id + powershell.sequence + powershell.total on the same host.id, then inspect powershell.file.script_block_text for ShareFinder calls, NetShareEnum wrappers, and share result fields such as "shi1_netname" or "shi1_remark". $investigate_0
    • Implication: escalate when reconstruction shows active enumeration, target lists, loops, share output, or access testing; lower concern when it only defines helper code and no later invocation appears. Missing fragments keep intent unresolved, not benign.
  • Can the PowerShell launch context be recovered?

    • Why: script block events preserve code; command line and parentage require a matching process event.
    • Focus: when endpoint process telemetry exists, recover the matching process via host.id + process.pid before using process.* or process.parent.*; review process.command_line, process.parent.executable, and session type. $investigate_1
    • Hint: anchor returned process starts to @timestamp; empty, multiple, or distant PID matches keep launch context unresolved.
    • Implication: escalate when the launcher is a document, script host, remote session, scheduled task, or user-writable path; lower concern when launcher, arguments, and session type match the same script path, target scope, and user/host anchors for a recurring inventory or storage-audit job. If endpoint process telemetry is missing, continue with script content, source path, user/host anchors, and related-alert scope instead of closing.
  • Does the script widen discovery with broad targets, threading, or access checks?

    • Focus: reconstructed powershell.file.script_block_text for threading, host/domain lists, access-check options, ADMIN$ testing, ping suppression, delay/jitter, credential objects, or loops over many hosts or shares.
    • Implication: escalate when the script uses threading, access checks, alternate credentials, broad domain or host-list discovery, or ADMIN$ testing; lower concern when the target set is tightly bounded to one recognized inventory, access-review, or storage-audit task.
  • Are source or output artifacts risky?

    • Focus: source path when present, fileless execution, output redirection/export, target/share arrays or excluded-share logic, and same-host/user file events for surrounding output or staging artifacts. $investigate_4
    • Implication: escalate when execution is fileless or sourced from temp, downloads, mounted shares, or user-writable paths; also escalate when the script writes reusable share results, prioritizes ADMIN$ or accessible shares, or builds target lists for collection or ransomware staging. Lower concern only when a stable admin repository path, transient output, script content, and user/host anchors all match one bounded recurring workflow. Path alone does not clear the behavior.
  • Do the user and host anchors fit the expected administrative scope?

    • Focus: user identity, host identity, reconstructed target scope, and recovered launch context.
    • Implication: escalate when a non-admin user, unusual service account, workstation, or unexpected host performs broad share discovery; lower concern when the same user and host anchors match the bounded management cohort, script path, and target set shown by local evidence.
  • If local findings stay suspicious or unresolved, does the same share-discovery pattern change scope?

    • Focus: related alerts for user.id carrying the same ShareFinder/API-wrapper, access-check, or target-list pattern, plus same-host/user network events for SMB or file-server activity when script content suggests access testing or follow-on collection. $investigate_2 $investigate_5
    • Hint: if user scope is inconclusive, check related alerts for the same host.id before widening beyond this host. $investigate_3
    • Hint: network events need destination or share corroboration before they prove access or collection; missing network telemetry is unresolved, not benign.
    • Implication: broaden when the same script pattern, operator account, or host appears in unrelated share-discovery alerts; keep the case local when it stays confined to one host.id, one user.id, one script/source pattern, and one bounded target set.
  • Escalate when reconstructed content, discovery breadth, access-check markers, source/output pattern, recovered launcher context, or user/host scope show unauthorized share discovery; close only when those categories bind to one recognized workflow with no contradictory evidence; preserve and escalate when evidence is mixed or incomplete.

False positive analysis

  • PowerView's Invoke-ShareFinder and raw P/Invoke NetShareEnum wrappers with shi1_netname/shi1_remark are offensive tooling patterns with near-zero legitimate administrative use. Legitimate share inventory uses built-in cmdlets (Get-SmbShare, net share) or management platforms, not these APIs. Close as benign true positive only for confirmed authorized red-team, penetration testing, or security validation where reconstructed script content, user.id, host.id, test-engagement scope, and recovered launch context all align. Do not close on an IT-administration claim when the script uses these specific offensive patterns.

Response and remediation

  • If confirmed benign, reverse any temporary containment and record the script owner, source path or recurring fileless content, expected user.id, expected host.id, target scope, and recovered launch context when available. Create a narrow exception only after the local evidence is confirmed and prior alerts, when present, show the same stable workflow.
  • If suspicious but unconfirmed, preserve the reconstructed powershell.file.script_block_text, all fragments linked by powershell.file.script_block_id, alert process PID, recovered process record when available, source path, output or target/share list, user.id, and host.id before containment. Apply reversible containment first: heightened monitoring, temporary SMB restrictions from the affected host to named servers/shares, or temporary restrictions for the implicated account when access testing or credential misuse is indicated. Escalate to host isolation or stronger credential actions only if access testing, staging, or credential misuse is confirmed and host criticality permits it.
  • If confirmed malicious, isolate the host or restrict the account only after preserving the reconstructed script, recovered launch context, source/output artifacts, and target/share list. Review the named servers, shares, accounts, and related alerts for the same indicators before deleting scripts, killing processes, or resetting credentials; remove malicious scripts, scheduled tasks, or credential material only after scope is complete.
  • Post-incident hardening: keep PowerShell script block logging enabled, restrict unsigned or user-writable PowerShell execution on management hosts where feasible, retain endpoint and file-server telemetry needed to confirm share access, and record the confirmed workflow or malicious server/share list for future triage.

References

Related rules

to-top