PowerShell Kerberos Ticket Request
Detects PowerShell script content that references KerberosRequestorSecurityToken, which can request Kerberos service tickets. Attackers request service tickets to perform Kerberoasting for offline password cracking of service accounts.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2022/01/24"
3integration = ["windows"]
4maturity = "production"
5updated_date = "2026/04/27"
6
7[rule]
8author = ["Elastic"]
9description = """
10Detects PowerShell script content that references KerberosRequestorSecurityToken, which can request Kerberos service
11tickets. Attackers request service tickets to perform Kerberoasting for offline password cracking of service accounts.
12"""
13from = "now-9m"
14index = ["logs-windows.powershell*", "winlogbeat-*"]
15language = "kuery"
16license = "Elastic License v2"
17name = "PowerShell Kerberos Ticket Request"
18references = [
19 "https://www.cobalt.io/blog/kerberoast-attack-techniques",
20 "https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/Invoke-Kerberoast.ps1",
21]
22risk_score = 73
23rule_id = "eb610e70-f9e6-4949-82b9-f1c5bcd37c39"
24severity = "high"
25tags = [
26 "Domain: Endpoint",
27 "OS: Windows",
28 "Use Case: Threat Detection",
29 "Tactic: Credential Access",
30 "Resources: Investigation Guide",
31 "Data Source: PowerShell Logs",
32]
33timestamp_override = "event.ingested"
34type = "query"
35
36query = '''
37event.category:process and host.os.type:windows and
38 powershell.file.script_block_text : "KerberosRequestorSecurityToken" and
39 not powershell.file.script_block_text : (
40 ("sentinelbreakpoints" and ("Set-PSBreakpoint" or "Set-HookFunctionTabs")) or
41 ("function global" and "\\windows\\sentinel\\4")
42 )
43'''
44
45note = """## Triage and analysis
46
47### Investigating PowerShell Kerberos Ticket Request
48
49#### Possible investigation steps
50
51- What does the reconstructed script actually do with KerberosRequestorSecurityToken?
52 - Focus: Reconstruct full 4104 content on `host.id` with `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total`; interpret `powershell.file.script_block_text`.
53 - Hint: pull fragments with matching `host.id` and `powershell.file.script_block_id`, order by `powershell.sequence`, and note gaps before judging intent. $investigate_2
54 - Implication: escalate when the script requests SPN TGS tickets, loops across "Get-DomainUser -SPN" results, or emits John/Hashcat, "TicketByteHexStream", "$krb5tgs$", or ".kirbi" material; lower suspicion only when reconstruction proves incidental text, comments, or a bounded fixed-SPN test with no output logic.
55
56- Do the user, host, and script source fit a bounded recognized Kerberos test?
57 - Focus: `user.id`, `user.name`, `user.domain`, `host.id`, and `file.path`.
58 - Hint: absent `file.path` means the script block may be interactive, pasted, or generated in memory, so require stronger corroboration before closure.
59 - Implication: escalate when a standard user, shared workstation, production server, user-writable `file.path`, or absent `file.path` pairs with broad SPN targeting; lower suspicion only for a recognized identity test or Kerberos diagnostic on the expected host and user with a fixed SPN set.
60
61- If endpoint process telemetry is available for this host, how did the PowerShell session start?
62 - Focus: `process.command_line`, `process.parent.executable`, `process.parent.command_line`, and `process.Ext.session_info.logon_type`.
63 - Hint: recover the process via `host.id + process.pid` before interpreting `process.*` or `process.parent.*`; if absent after a wider lookup, keep launch context unresolved and scope later pivots with `host.id`, `user.id`, and alert time. $investigate_3
64 - Implication: escalate when launch context shows encoded commands, pasted or remote delivery, Office or browser parents, unexpected service or network logon, or alternate-credential use; lower suspicion when command line and parent chain match the exact recognized test workflow.
65
66- Did the activity create ticket, hash, or target-list artifacts?
67 - Focus: If endpoint file telemetry exists, scope writes to `host.id`, `user.id`, and the alert window; use the recovered process only after process recovery succeeds, and review `file.path` and `file.Ext.header_bytes`. $investigate_4
68 - Implication: escalate when writes show SPN lists, ".kirbi" tickets, "$krb5tgs$" or John/Hashcat text, "TicketByteHexStream", base64 blobs, archives, or temp/share/user-writable staging; no file output does not clear direct hash output or memory-only ticket export, and missing file telemetry is unresolved, not benign.
69
70- Do domain-controller ticket events confirm active Kerberoasting behavior?
71 - Focus: DC-side Windows Security `event.code` 4769 near alert time, starting with `winlog.event_data.TargetUserName` = alert `user.name` for domain requesters; review `winlog.event_data.TargetDomainName`, `source.ip`, `winlog.event_data.ServiceName`, `winlog.event_data.TicketEncryptionType`, and target SPN volume. $investigate_5
72 - Hint: if the alert user is local, SYSTEM, or the transform is quiet, retry DC 4769 with UPN/domain variants from `user.name` + `user.domain`, then pivot by source host/address and candidate requester from reconstruction or launch context.
73 - Implication: escalate when 4769 events show broad SPN enumeration, RC4 or weak encryption, service-account-heavy targeting, or client addresses inconsistent with the expected workflow. Missing authentication telemetry is unresolved, not benign.
74
75- Is this ticket-request activity isolated or part of broader suspicious behavior?
76 - Focus: same-scope events or alerts for `user.id` in the last 48 hours for credential access, execution, discovery, or lateral movement. $investigate_0
77 - Hint: use the host pivot separately when user scope is noisy or service-account-heavy. $investigate_1
78 - Implication: broaden response when either pivot shows adjacent credential access, execution, discovery, or lateral movement; keep the case local only when related alerts stay quiet or match the same bounded recognized workflow.
79
80- Escalate active service-ticket collection without a recognized owner or with suspicious scope, output, launch, artifact, DC 4769, or same-scope evidence; close only when alert-local evidence and supported recovery bind one exact bounded workflow and outside confirmation resolves gaps; preserve evidence and escalate when findings are mixed or incomplete.
81
82### False positive analysis
83
84- Recognized Kerberos diagnostics, identity validation, or red-team tests can trigger this rule when reconstructed `powershell.file.script_block_text` stays limited to a fixed SPN set, creates no ticket or hash output, and the script source fits. If process telemetry was recovered via `host.id + process.pid`, require `process.command_line` and `process.parent.executable` to match. Require test-record alignment when present; otherwise close only when current telemetry proves the same fixed-SPN, no-output, user-host, source, and launch-chain pattern.
85- Build exceptions from the minimum confirmed workflow: `user.id`, `host.id`, exact source pattern, recovered launch chain, and fixed SPN set. If prior alerts exist, verify they do not add expanded targets, crackable output, or a different launch path; for a first verified case, prefer a narrow candidate or time-bounded exception over broad suppression. Avoid exceptions on "KerberosRequestorSecurityToken" alone, `user.name` alone, or host alone.
86
87### Response and remediation
88
89- If confirmed benign, reverse any temporary containment and record the evidence that proved the recognized diagnostics, lab, or identity-test workflow: stable user-host pairing, fixed SPN scope, script source, recovered launch chain when available, and no contradictory artifact or same-scope evidence. Create only a narrow exception from that confirmed evidence; use prior alerts to tighten scope when they exist, not as the primary proof.
90- If suspicious but unconfirmed, preserve the reconstructed `powershell.file.script_block_text`, `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, `process.pid`, any recovered process details, named SPNs, output paths, and available identity records before containment. Apply reversible containment first, such as temporary host isolation or account restriction matched to host criticality, and avoid destructive cleanup until service-account exposure is scoped.
91- If confirmed malicious, contain the host and affected account when script intent, recovered launch context, named SPNs, output artifacts, or same-scope events support unauthorized ticket collection. Record the recovered PowerShell command line, parent chain, named SPNs, output locations, and available identity evidence before terminating processes, deleting files, or purging sessions.
92- If targeted or bulk service-ticket requests are confirmed, prioritize the named service accounts for password rotation, privilege review, and downstream logon analysis, then review affected services for anomalous authentication or access tied to the same period.
93- Eradicate only the unauthorized scripts, SPN lists, ticket or hash output, scheduled tasks, and persistence mechanisms uncovered during the investigation, then remediate the delivery path or administrative-control gap that allowed the script to run.
94- After containment, hunt for the same reconstructed script fragments, SPN patterns, and ticket-request evidence across other hosts, and retain PowerShell Script Block Logging plus supporting endpoint or identity telemetry where gaps limited the investigation.
95"""
96
97setup = """## Setup
98
99PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104).
100Setup instructions: https://ela.st/powershell-logging-setup
101"""
102
103[rule.investigation_fields]
104field_names = [
105 "@timestamp",
106 "user.name",
107 "user.id",
108 "user.domain",
109 "powershell.file.script_block_text",
110 "powershell.file.script_block_id",
111 "powershell.sequence",
112 "powershell.total",
113 "file.path",
114 "file.directory",
115 "file.name",
116 "process.pid",
117 "host.name",
118 "host.id",
119 "powershell.file.script_block_length"
120]
121
122[transform]
123
124[[transform.investigate]]
125label = "Alerts associated with the user"
126description = ""
127providers = [
128 [
129 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
130 { excluded = false, field = "user.id", queryType = "phrase", value = "{{user.id}}", valueType = "string" }
131 ]
132]
133relativeFrom = "now-48h/h"
134relativeTo = "now"
135
136[[transform.investigate]]
137label = "Alerts associated with the host"
138description = ""
139providers = [
140 [
141 { excluded = false, field = "event.kind", queryType = "phrase", value = "signal", valueType = "string" },
142 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" }
143 ]
144]
145relativeFrom = "now-48h/h"
146relativeTo = "now"
147
148[[transform.investigate]]
149label = "All PowerShell 4104 fragments for this script on this host"
150description = ""
151providers = [
152 [
153 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
154 { excluded = false, field = "powershell.file.script_block_id", queryType = "phrase", value = "{{powershell.file.script_block_id}}", valueType = "string" },
155 { excluded = false, field = "event.code", queryType = "phrase", value = "4104", valueType = "string" }
156 ]
157]
158relativeFrom = "now-1h"
159relativeTo = "now"
160
161[[transform.investigate]]
162label = "Process events for the PowerShell instance"
163description = ""
164providers = [
165 [
166 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
167 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
168 { excluded = false, field = "event.category", queryType = "phrase", value = "process", valueType = "string" }
169 ]
170]
171relativeFrom = "now-1h"
172relativeTo = "now"
173
174[[transform.investigate]]
175label = "File events for the PowerShell process"
176description = ""
177providers = [
178 [
179 { excluded = false, field = "process.pid", queryType = "phrase", value = "{{process.pid}}", valueType = "string" },
180 { excluded = false, field = "host.id", queryType = "phrase", value = "{{host.id}}", valueType = "string" },
181 { excluded = false, field = "event.category", queryType = "phrase", value = "file", valueType = "string" }
182 ]
183]
184relativeFrom = "now-1h"
185relativeTo = "now"
186
187[[transform.investigate]]
188label = "Kerberos service ticket events for the alert user name"
189description = ""
190providers = [
191 [
192 { excluded = false, field = "winlog.event_data.TargetUserName", queryType = "phrase", value = "{{user.name}}", valueType = "string" },
193 { excluded = false, field = "event.code", queryType = "phrase", value = "4769", valueType = "string" }
194 ]
195]
196relativeFrom = "now-24h"
197relativeTo = "now"
198
199[[rule.threat]]
200framework = "MITRE ATT&CK"
201[[rule.threat.technique]]
202id = "T1558"
203name = "Steal or Forge Kerberos Tickets"
204reference = "https://attack.mitre.org/techniques/T1558/"
205[[rule.threat.technique.subtechnique]]
206id = "T1558.003"
207name = "Kerberoasting"
208reference = "https://attack.mitre.org/techniques/T1558/003/"
209
210[rule.threat.tactic]
211id = "TA0006"
212name = "Credential Access"
213reference = "https://attack.mitre.org/tactics/TA0006/"
214
215[[rule.threat]]
216framework = "MITRE ATT&CK"
217[[rule.threat.technique]]
218id = "T1059"
219name = "Command and Scripting Interpreter"
220reference = "https://attack.mitre.org/techniques/T1059/"
221[[rule.threat.technique.subtechnique]]
222id = "T1059.001"
223name = "PowerShell"
224reference = "https://attack.mitre.org/techniques/T1059/001/"
225
226[rule.threat.tactic]
227id = "TA0002"
228name = "Execution"
229reference = "https://attack.mitre.org/tactics/TA0002/"
Triage and analysis
Investigating PowerShell Kerberos Ticket Request
Possible investigation steps
-
What does the reconstructed script actually do with KerberosRequestorSecurityToken?
- Focus: Reconstruct full 4104 content on
host.idwithpowershell.file.script_block_id,powershell.sequence, andpowershell.total; interpretpowershell.file.script_block_text. - Hint: pull fragments with matching
host.idandpowershell.file.script_block_id, order bypowershell.sequence, and note gaps before judging intent. $investigate_2 - Implication: escalate when the script requests SPN TGS tickets, loops across "Get-DomainUser -SPN" results, or emits John/Hashcat, "TicketByteHexStream", "$krb5tgs$", or ".kirbi" material; lower suspicion only when reconstruction proves incidental text, comments, or a bounded fixed-SPN test with no output logic.
- Focus: Reconstruct full 4104 content on
-
Do the user, host, and script source fit a bounded recognized Kerberos test?
- Focus:
user.id,user.name,user.domain,host.id, andfile.path. - Hint: absent
file.pathmeans the script block may be interactive, pasted, or generated in memory, so require stronger corroboration before closure. - Implication: escalate when a standard user, shared workstation, production server, user-writable
file.path, or absentfile.pathpairs with broad SPN targeting; lower suspicion only for a recognized identity test or Kerberos diagnostic on the expected host and user with a fixed SPN set.
- Focus:
-
If endpoint process telemetry is available for this host, how did the PowerShell session start?
- Focus:
process.command_line,process.parent.executable,process.parent.command_line, andprocess.Ext.session_info.logon_type. - Hint: recover the process via
host.id + process.pidbefore interpretingprocess.*orprocess.parent.*; if absent after a wider lookup, keep launch context unresolved and scope later pivots withhost.id,user.id, and alert time. $investigate_3 - Implication: escalate when launch context shows encoded commands, pasted or remote delivery, Office or browser parents, unexpected service or network logon, or alternate-credential use; lower suspicion when command line and parent chain match the exact recognized test workflow.
- Focus:
-
Did the activity create ticket, hash, or target-list artifacts?
- Focus: If endpoint file telemetry exists, scope writes to
host.id,user.id, and the alert window; use the recovered process only after process recovery succeeds, and reviewfile.pathandfile.Ext.header_bytes. $investigate_4 - Implication: escalate when writes show SPN lists, ".kirbi" tickets, "$krb5tgs$" or John/Hashcat text, "TicketByteHexStream", base64 blobs, archives, or temp/share/user-writable staging; no file output does not clear direct hash output or memory-only ticket export, and missing file telemetry is unresolved, not benign.
- Focus: If endpoint file telemetry exists, scope writes to
-
Do domain-controller ticket events confirm active Kerberoasting behavior?
- Focus: DC-side Windows Security
event.code4769 near alert time, starting withwinlog.event_data.TargetUserName= alertuser.namefor domain requesters; reviewwinlog.event_data.TargetDomainName,source.ip,winlog.event_data.ServiceName,winlog.event_data.TicketEncryptionType, and target SPN volume. $investigate_5 - Hint: if the alert user is local, SYSTEM, or the transform is quiet, retry DC 4769 with UPN/domain variants from
user.name+user.domain, then pivot by source host/address and candidate requester from reconstruction or launch context. - Implication: escalate when 4769 events show broad SPN enumeration, RC4 or weak encryption, service-account-heavy targeting, or client addresses inconsistent with the expected workflow. Missing authentication telemetry is unresolved, not benign.
- Focus: DC-side Windows Security
-
Is this ticket-request activity isolated or part of broader suspicious behavior?
- Focus: same-scope events or alerts for
user.idin the last 48 hours for credential access, execution, discovery, or lateral movement. $investigate_0 - Hint: use the host pivot separately when user scope is noisy or service-account-heavy. $investigate_1
- Implication: broaden response when either pivot shows adjacent credential access, execution, discovery, or lateral movement; keep the case local only when related alerts stay quiet or match the same bounded recognized workflow.
- Focus: same-scope events or alerts for
-
Escalate active service-ticket collection without a recognized owner or with suspicious scope, output, launch, artifact, DC 4769, or same-scope evidence; close only when alert-local evidence and supported recovery bind one exact bounded workflow and outside confirmation resolves gaps; preserve evidence and escalate when findings are mixed or incomplete.
False positive analysis
- Recognized Kerberos diagnostics, identity validation, or red-team tests can trigger this rule when reconstructed
powershell.file.script_block_textstays limited to a fixed SPN set, creates no ticket or hash output, and the script source fits. If process telemetry was recovered viahost.id + process.pid, requireprocess.command_lineandprocess.parent.executableto match. Require test-record alignment when present; otherwise close only when current telemetry proves the same fixed-SPN, no-output, user-host, source, and launch-chain pattern. - Build exceptions from the minimum confirmed workflow:
user.id,host.id, exact source pattern, recovered launch chain, and fixed SPN set. If prior alerts exist, verify they do not add expanded targets, crackable output, or a different launch path; for a first verified case, prefer a narrow candidate or time-bounded exception over broad suppression. Avoid exceptions on "KerberosRequestorSecurityToken" alone,user.namealone, or host alone.
Response and remediation
- If confirmed benign, reverse any temporary containment and record the evidence that proved the recognized diagnostics, lab, or identity-test workflow: stable user-host pairing, fixed SPN scope, script source, recovered launch chain when available, and no contradictory artifact or same-scope evidence. Create only a narrow exception from that confirmed evidence; use prior alerts to tighten scope when they exist, not as the primary proof.
- If suspicious but unconfirmed, preserve the reconstructed
powershell.file.script_block_text,powershell.file.script_block_id,powershell.sequence,powershell.total,process.pid, any recovered process details, named SPNs, output paths, and available identity records before containment. Apply reversible containment first, such as temporary host isolation or account restriction matched to host criticality, and avoid destructive cleanup until service-account exposure is scoped. - If confirmed malicious, contain the host and affected account when script intent, recovered launch context, named SPNs, output artifacts, or same-scope events support unauthorized ticket collection. Record the recovered PowerShell command line, parent chain, named SPNs, output locations, and available identity evidence before terminating processes, deleting files, or purging sessions.
- If targeted or bulk service-ticket requests are confirmed, prioritize the named service accounts for password rotation, privilege review, and downstream logon analysis, then review affected services for anomalous authentication or access tied to the same period.
- Eradicate only the unauthorized scripts, SPN lists, ticket or hash output, scheduled tasks, and persistence mechanisms uncovered during the investigation, then remediate the delivery path or administrative-control gap that allowed the script to run.
- After containment, hunt for the same reconstructed script fragments, SPN patterns, and ticket-request evidence across other hosts, and retain PowerShell Script Block Logging plus supporting endpoint or identity telemetry where gaps limited the investigation.
References
Related rules
- Potential PowerShell Pass-the-Hash/Relay Script
- PowerShell Invoke-NinjaCopy script
- PowerShell Kerberos Ticket Dump
- PowerShell MiniDump Script
- Potential Invoke-Mimikatz PowerShell Script