-
Notifications
You must be signed in to change notification settings - Fork 451
Description
Problem
The current detection Windows AD Short Lived Domain Account ServicePrincipalName can generate false positives in environments where modifying an account causes existing SPNs to be temporarily removed and re-added.
During certain account updates, Active Directory rewrites the servicePrincipalName attribute and may produce sequences like:
%%14675 Value Deleted
%%14674 Value Added
%%14675 Value Deleted
%%14674 Value Added
%%14675 Value Deleted
%%14674 Value Added
In this pattern, the first observed operation is Value Deleted (%%14675), which indicates that the SPN already existed before the observed sequence.
However, the current detection logic groups %%14674 and %%14675 events together and evaluates them as a potential short-lived SPN lifecycle. This can trigger alerts even though the SPN was not newly introduced and the activity is benign.
%%14674 Value Added
...
%%14675 Value Deleted
This pattern indicates a new SPN being created and then removed shortly afterward, which may be used for Kerberos abuse (e.g., Kerberoasting preparation).
If the first observed event is a deletion, the sequence likely represents SPN rewrite behavior during account modification rather than the creation of a temporary SPN.
Suggested Enhancement
The detection should only evaluate the SPN lifetime if the first observed operation for a given ObjectDN and AttributeValue is %%14674 (Value Added).
If the first observed operation is %%14675 (Value Deleted), the sequence should be ignored for this use case, as it represents deletion or rewriting of an already existing SPN.
A possible improvement is to enforce an add-first lifecycle check before calculating the SPN lifetime.
Example implementation:
`wineventlog_security` EventCode=5136 AttributeLDAPDisplayName=servicePrincipalName
| where OperationType IN ("%%14674","%%14675")
| sort 0 ObjectDN AttributeValue _time
| streamstats count as seq by ObjectDN AttributeValue
| eventstats first(OperationType) as first_op by ObjectDN AttributeValue
| where first_op="%%14674"
| stats
min(eval(if(OperationType="%%14674", _time, null()))) as add_time
min(eval(if(OperationType="%%14675", _time, null()))) as del_time
values(Computer) as dest
by ObjectDN AttributeValue
| eval duration=del_time-add_time
| eval short_lived=case((duration<300),"TRUE") | search short_lived = TRUE
| rename ObjectDN as user
| rename Computer as dest
| `windows_ad_short_lived_domain_account_serviceprincipalname_filter`