Potential PowerShell HackTool Script by Author
Identifies PowerShell script block content containing known offensive-tool author handles or attribution strings (for example, public tool author names). Attackers often run public PowerShell tooling with minimal changes, leaving author artifacts in comments or headers.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2024/05/08"
3integration = ["windows"]
4maturity = "production"
5updated_date = "2026/05/01"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies PowerShell script block content containing known offensive-tool author handles or attribution strings (for
11example, public tool author names). Attackers often run public PowerShell tooling with minimal changes, leaving author
12artifacts in comments or headers.
13"""
14from = "now-9m"
15index = ["logs-windows.powershell*", "winlogbeat-*"]
16language = "kuery"
17license = "Elastic License v2"
18name = "Potential PowerShell HackTool Script by Author"
19references = [
20 "https://github.com/atc-project/atc-data/blob/master/docs/Logging_Policies/LP_0109_windows_powershell_script_block_log.md",
21]
22risk_score = 73
23rule_id = "2553a9af-52a4-4a05-bb03-85b2a479a0a0"
24severity = "high"
25tags = [
26 "Domain: Endpoint",
27 "OS: Windows",
28 "Use Case: Threat Detection",
29 "Tactic: Execution",
30 "Data Source: PowerShell Logs",
31 "Resources: Investigation Guide",
32]
33timestamp_override = "event.ingested"
34type = "query"
35
36query = '''
37host.os.type:windows and event.category:process and
38 powershell.file.script_block_text : (
39 "mattifestation" or "JosephBialek" or
40 "harmj0y" or "ukstufus" or
41 "SecureThisShit" or "Matthew Graeber" or
42 "secabstraction" or "mgeeky" or
43 "oddvarmoe" or "am0nsec" or
44 "obscuresec" or "sixdub" or
45 "darkoperator" or "funoverip" or
46 "rvrsh3ll" or "kevin_robertson" or
47 "dafthack" or "r4wd3r" or
48 "danielhbohannon" or "OneLogicalMyth" or
49 "cobbr_io" or "xorrior" or
50 "PetrMedonos" or "citronneur" or
51 "eladshamir" or "RastaMouse" or
52 "enigma0x3" or "FuzzySec" or
53 "424f424f" or "jaredhaight" or
54 "fullmetalcache" or "Hubbl3" or
55 "curi0usJack" or "Cx01N" or
56 "itm4n" or "nurfed1" or
57 "cfalta" or "Scott Sutherland" or
58 "_nullbind" or "_tmenochet" or
59 "jaredcatkinson" or "ChrisTruncer" or
60 "monoxgas" or "TheRealWover" or
61 "splinter_code" or "samratashok" or
62 "leechristensen" or "nikhil_mitt"
63 ) and
64 not powershell.file.script_block_text : ("Get-UEFIDatabaseSigner" or "Posh-SSH")
65'''
66
67note = """## Triage and analysis
68
69### Investigating Potential PowerShell HackTool Script by Author
70
71#### Possible investigation steps
72
73- What did the alert-local author match show?
74 - Focus: `powershell.file.script_block_text`, `powershell.file.script_block_length`, `file.path`, and `user.id` on `host.id`.
75 - Implication: escalate when the handle appears beside executable functions, encoded strings, download, credential, discovery, remote-execution, or persistence logic; lower suspicion when it is only an inert header or comment in a recognized lab, test, or community-module path with harmless surrounding code.
76
77- Can you reconstruct the complete script block before judging intent?
78 - Focus: collect and order fragments on `host.id` with `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, and `powershell.file.script_block_text`. $investigate_0
79 - Implication: escalate when reconstruction reveals hidden stages, helper functions, obfuscation, decoding, or payload logic; keep unresolved if fragments are missing because they can hide decisive code.
80
81- Was the script file-backed or fileless, and what does that say about delivery?
82 - Focus: `file.path`, `file.directory`, and `file.name` when present; absent `file.path` suggests inline, generated, or interactive execution.
83 - Implication: escalate when fileless execution, user-writable paths, shares, temp or staging folders, or suspicious names pair with hacktool code; lower suspicion when a stable repository, lab path, or community-module path matches benign content.
84
85- Can you recover the PowerShell process and explain launch?
86 - Focus: With endpoint process telemetry, recover the matching process via `host.id + process.pid` before interpreting `process.*` or `process.parent.*`. Capture `process.entity_id`, `process.command_line`, `process.parent.executable`, and `process.parent.command_line`. $investigate_1
87 - Hint: confirm timestamps to reduce PID-reuse ambiguity; if no process start event appears, expand time before falling back to `host.id`, `user.id`, and alert time.
88 - Implication: escalate when a document, browser, chat client, remote-management tool, scheduled task, service, or unexpected script host launched the code without matching lab, assessment, support, or deployment evidence; lower suspicion when lineage matches the exact workflow proven by script content.
89
90- What capability or observables move this beyond attribution text?
91 - Focus: reconstructed script for credential access, discovery, remote execution, payload delivery, persistence, AMSI or logging tampering, reflection, or decode-and-execute logic; extract domains, IPs, URLs, paths, accounts, registry targets, and reusable function or module names.
92 - Implication: escalate when the body implements offensive capability or yields high-signal observables; lower suspicion only when it remains benign utility logic tied to a recognized workflow.
93
94- Did script-extracted file or registry targets appear on the host?
95 - Focus: With file or registry telemetry, search same-PID events around `@timestamp` for extracted `file.path`, `registry.path`, `registry.value`, or `registry.data.strings`. $investigate_4
96 - Implication: escalate when extracted payload paths are created or executed, or registry targets indicate persistence or security changes; missing artifact or configuration telemetry is unresolved, not benign.
97
98- Did extracted network or identity observables confirm active offensive use?
99 - Focus: With network telemetry, search same-PID DNS and connection events for extracted domains in `dns.question.name` or `dns.resolved_ip` and IPs in `destination.ip`. $investigate_5 Review Windows 4624 or 4648 with `winlog.event_data.TargetUserName` and `winlog.event_data.SubjectUserName` for extracted accounts.
100 - Implication: escalate when the host contacts extracted infrastructure, downloads content, or shows remote, credential, or lateral-use evidence. Missing network or authentication telemetry is unresolved, not benign.
101
102- If the script content or launch chain remains suspicious or unresolved, does recurrence change scope?
103 - Focus: related alerts for `user.id` in the last 48 hours, comparing author string, reconstructed script body, file source, launch pattern, and extracted observables. $investigate_2
104 - Hint: if the user view is quiet or ambiguous, compare related alerts for `host.id` in the last 48 hours. $investigate_3
105 - Implication: broaden when the same script body or extracted observables reach unrelated users or hosts; keep local when recurrence stays within the same lab, assessment, support, or deployment host/user cohort. Do not close on recurrence alone if script content or recovery remains unresolved.
106
107- Escalate on reconstructed capability, unauthorized launch, follow-on evidence, or missing/conflicting required telemetry; close only when the author match, reconstructed script, source path, launch context, observables, and `user.id` or `host.id` scope bind one exact benign workflow, with outside confirmation when telemetry cannot verify it.
108
109### False positive analysis
110
111- Authorized testing, red-team, malware-analysis, validation, community-module, or admin scripts can retain author strings. Confirm the reconstructed body, exact `user.id` and `host.id` scope, `file.path` or launch context, recognized test or lab records when telemetry cannot prove legitimacy, and no contradictory observables or follow-on activity.
112- Before creating an exception, validate recurrence of the same benign workflow with the same `powershell.file.script_block_text` fragment, `file.path` or launch source, and `user.id` or `host.id` scope. Avoid author-string-only exceptions because unrelated offensive scripts can reuse the same handle.
113
114### Response and remediation
115
116- If confirmed benign:
117 - Reverse temporary containment and document the reconstructed script, source path, launch context, `user.id`, and `host.id` evidence confirming the legitimate workflow. Build an exception only for that exact workflow and scope.
118- If suspicious but unconfirmed:
119 - Preserve or export alert details, reconstructed script with fragment metadata, process PID, source path, extracted indicators, and recovered launch details before containment or cleanup.
120 - Apply reversible containment tied to the evidence, such as temporary restrictions for extracted destinations or heightened monitoring on affected `host.id` and `user.id`.
121 - Escalate to host isolation or stronger account action only if the script is still executing, staging payloads, reaching suspicious destinations, or showing credential or lateral-use evidence, and the host role tolerates isolation.
122- If confirmed malicious:
123 - Preserve the reconstructed script, recovered process entity ID and launch details, extracted indicators, staged artifacts, and timeline before isolation, process termination, or cleanup.
124 - Isolate the host when script capability, launch context, follow-on artifacts, or destination evidence confirms unauthorized activity and the host role tolerates isolation.
125 - Block confirmed malicious destinations, URLs, file hashes, and script paths found during triage.
126 - Eradicate only dropped files, registry changes, scheduled tasks, services, and follow-on payloads tied to this script, then remediate the path that delivered or launched it.
127 - Review related hosts and users for the same author string, reconstructed script body, or extracted indicators before destructive cleanup so scoping is complete.
128- Post-incident hardening:
129 - Verify PowerShell 4104 logging coverage and retention are sufficient to reconstruct multi-part scripts and preserve process recovery context.
130 - Restrict authorized testing of public offensive PowerShell tooling to controlled hosts and identities.
131 - Document matched author strings, extracted observables, and author-stripped or rebranded variants surfaced during triage for future analyst reference.
132"""
133
134setup = """## Setup
135
136PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
137Setup instructions: https://ela.st/powershell-logging-setup
138"""
139
140[rule.investigation_fields]
141field_names = [
142 "@timestamp",
143 "user.name",
144 "user.id",
145 "user.domain",
146 "powershell.file.script_block_text",
147 "powershell.file.script_block_id",
148 "powershell.sequence",
149 "powershell.total",
150 "file.path",
151 "file.directory",
152 "file.name",
153 "process.pid",
154 "host.name",
155 "host.id",
156 "powershell.file.script_block_length"
157]
158
159[transform]
160
161[[transform.investigate]]
162label = "Script block fragments for the same script"
163description = ""
164providers = [
165 [
166 { excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" },
167 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
168 ]
169]
170relativeFrom = "now-1h"
171relativeTo = "now"
172
173[[transform.investigate]]
174label = "Process events for the PowerShell instance"
175description = ""
176providers = [
177 [
178 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
179 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
180 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
181 ]
182]
183relativeFrom = "now-1h"
184relativeTo = "now"
185
186[[transform.investigate]]
187label = "Alerts associated with the user"
188description = ""
189providers = [
190 [
191 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
192 { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
193 ]
194]
195relativeFrom = "now-48h/h"
196relativeTo = "now"
197
198[[transform.investigate]]
199label = "Alerts associated with the host"
200description = ""
201providers = [
202 [
203 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
204 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
205 ]
206]
207relativeFrom = "now-48h/h"
208relativeTo = "now"
209
210[[transform.investigate]]
211label = "File and registry events for the PowerShell PID"
212description = ""
213providers = [
214 [
215 { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" },
216 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
217 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
218 ],
219 [
220 { excluded = false, field = "event.category", queryType = "phrase", value = "registry", valueType = "string" },
221 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
222 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
223 ]
224]
225relativeFrom = "now-1h"
226relativeTo = "now"
227
228[[transform.investigate]]
229label = "Network and DNS events for the PowerShell PID"
230description = ""
231providers = [
232 [
233 { excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" },
234 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
235 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
236 ],
237 [
238 { excluded = false, field = "event.category", queryType = "phrase", value = "dns", valueType = "string" },
239 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
240 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" }
241 ]
242]
243relativeFrom = "now-1h"
244relativeTo = "now"
245
246[[rule.threat]]
247framework = "MITRE ATT&CK"
248[[rule.threat.technique]]
249id = "T1059"
250name = "Command and Scripting Interpreter"
251reference = "https://attack.mitre.org/techniques/T1059/"
252[[rule.threat.technique.subtechnique]]
253id = "T1059.001"
254name = "PowerShell"
255reference = "https://attack.mitre.org/techniques/T1059/001/"
256
257[rule.threat.tactic]
258id = "TA0002"
259name = "Execution"
260reference = "https://attack.mitre.org/tactics/TA0002/"
Triage and analysis
Investigating Potential PowerShell HackTool Script by Author
Possible investigation steps
-
What did the alert-local author match show?
- Focus:
powershell.file.script_block_text,powershell.file.script_block_length,file.path, anduser.idonhost.id. - Implication: escalate when the handle appears beside executable functions, encoded strings, download, credential, discovery, remote-execution, or persistence logic; lower suspicion when it is only an inert header or comment in a recognized lab, test, or community-module path with harmless surrounding code.
- Focus:
-
Can you reconstruct the complete script block before judging intent?
- Focus: collect and order fragments on
host.idwithpowershell.file.script_block_id,powershell.sequence,powershell.total, andpowershell.file.script_block_text. $investigate_0 - Implication: escalate when reconstruction reveals hidden stages, helper functions, obfuscation, decoding, or payload logic; keep unresolved if fragments are missing because they can hide decisive code.
- Focus: collect and order fragments on
-
Was the script file-backed or fileless, and what does that say about delivery?
- Focus:
file.path,file.directory, andfile.namewhen present; absentfile.pathsuggests inline, generated, or interactive execution. - Implication: escalate when fileless execution, user-writable paths, shares, temp or staging folders, or suspicious names pair with hacktool code; lower suspicion when a stable repository, lab path, or community-module path matches benign content.
- Focus:
-
Can you recover the PowerShell process and explain launch?
- Focus: With endpoint process telemetry, recover the matching process via
host.id + process.pidbefore interpretingprocess.*orprocess.parent.*. Captureprocess.entity_id,process.command_line,process.parent.executable, andprocess.parent.command_line. $investigate_1 - Hint: confirm timestamps to reduce PID-reuse ambiguity; if no process start event appears, expand time before falling back to
host.id,user.id, and alert time. - Implication: escalate when a document, browser, chat client, remote-management tool, scheduled task, service, or unexpected script host launched the code without matching lab, assessment, support, or deployment evidence; lower suspicion when lineage matches the exact workflow proven by script content.
- Focus: With endpoint process telemetry, recover the matching process via
-
What capability or observables move this beyond attribution text?
- Focus: reconstructed script for credential access, discovery, remote execution, payload delivery, persistence, AMSI or logging tampering, reflection, or decode-and-execute logic; extract domains, IPs, URLs, paths, accounts, registry targets, and reusable function or module names.
- Implication: escalate when the body implements offensive capability or yields high-signal observables; lower suspicion only when it remains benign utility logic tied to a recognized workflow.
-
Did script-extracted file or registry targets appear on the host?
- Focus: With file or registry telemetry, search same-PID events around
@timestampfor extractedfile.path,registry.path,registry.value, orregistry.data.strings. $investigate_4 - Implication: escalate when extracted payload paths are created or executed, or registry targets indicate persistence or security changes; missing artifact or configuration telemetry is unresolved, not benign.
- Focus: With file or registry telemetry, search same-PID events around
-
Did extracted network or identity observables confirm active offensive use?
- Focus: With network telemetry, search same-PID DNS and connection events for extracted domains in
dns.question.nameordns.resolved_ipand IPs indestination.ip. $investigate_5 Review Windows 4624 or 4648 withwinlog.event_data.TargetUserNameandwinlog.event_data.SubjectUserNamefor extracted accounts. - Implication: escalate when the host contacts extracted infrastructure, downloads content, or shows remote, credential, or lateral-use evidence. Missing network or authentication telemetry is unresolved, not benign.
- Focus: With network telemetry, search same-PID DNS and connection events for extracted domains in
-
If the script content or launch chain remains suspicious or unresolved, does recurrence change scope?
- Focus: related alerts for
user.idin the last 48 hours, comparing author string, reconstructed script body, file source, launch pattern, and extracted observables. $investigate_2 - Hint: if the user view is quiet or ambiguous, compare related alerts for
host.idin the last 48 hours. $investigate_3 - Implication: broaden when the same script body or extracted observables reach unrelated users or hosts; keep local when recurrence stays within the same lab, assessment, support, or deployment host/user cohort. Do not close on recurrence alone if script content or recovery remains unresolved.
- Focus: related alerts for
-
Escalate on reconstructed capability, unauthorized launch, follow-on evidence, or missing/conflicting required telemetry; close only when the author match, reconstructed script, source path, launch context, observables, and
user.idorhost.idscope bind one exact benign workflow, with outside confirmation when telemetry cannot verify it.
False positive analysis
- Authorized testing, red-team, malware-analysis, validation, community-module, or admin scripts can retain author strings. Confirm the reconstructed body, exact
user.idandhost.idscope,file.pathor launch context, recognized test or lab records when telemetry cannot prove legitimacy, and no contradictory observables or follow-on activity. - Before creating an exception, validate recurrence of the same benign workflow with the same
powershell.file.script_block_textfragment,file.pathor launch source, anduser.idorhost.idscope. Avoid author-string-only exceptions because unrelated offensive scripts can reuse the same handle.
Response and remediation
- If confirmed benign:
- Reverse temporary containment and document the reconstructed script, source path, launch context,
user.id, andhost.idevidence confirming the legitimate workflow. Build an exception only for that exact workflow and scope.
- Reverse temporary containment and document the reconstructed script, source path, launch context,
- If suspicious but unconfirmed:
- Preserve or export alert details, reconstructed script with fragment metadata, process PID, source path, extracted indicators, and recovered launch details before containment or cleanup.
- Apply reversible containment tied to the evidence, such as temporary restrictions for extracted destinations or heightened monitoring on affected
host.idanduser.id. - Escalate to host isolation or stronger account action only if the script is still executing, staging payloads, reaching suspicious destinations, or showing credential or lateral-use evidence, and the host role tolerates isolation.
- If confirmed malicious:
- Preserve the reconstructed script, recovered process entity ID and launch details, extracted indicators, staged artifacts, and timeline before isolation, process termination, or cleanup.
- Isolate the host when script capability, launch context, follow-on artifacts, or destination evidence confirms unauthorized activity and the host role tolerates isolation.
- Block confirmed malicious destinations, URLs, file hashes, and script paths found during triage.
- Eradicate only dropped files, registry changes, scheduled tasks, services, and follow-on payloads tied to this script, then remediate the path that delivered or launched it.
- Review related hosts and users for the same author string, reconstructed script body, or extracted indicators before destructive cleanup so scoping is complete.
- Post-incident hardening:
- Verify PowerShell 4104 logging coverage and retention are sufficient to reconstruct multi-part scripts and preserve process recovery context.
- Restrict authorized testing of public offensive PowerShell tooling to controlled hosts and identities.
- Document matched author strings, extracted observables, and author-stripped or rebranded variants surfaced during triage for future analyst reference.
References
Related rules
- PowerShell PSReflect Script
- Potential Process Injection via PowerShell
- Potential PowerShell HackTool Script by Function Names
- PowerShell Suspicious Discovery Related Windows API Functions
- Suspicious .NET Reflection via PowerShell