Overnight Post-RDP Activity Detection - #74
Conversation
There was a problem hiding this comment.
Really nice contribution!
Requesting one change before merge: the join key needs to be [aid, AuthenticationId] rather than AuthenticationId alone, see the inline comment for details. Since everything here auto-publishes to cql-hub.com, I'd like that fixed before it lands so nobody copies a version that can correlate a process on one host with a logon on a different one.
Happy to merge as soon as that's in.
| | in(field=remoteHour, values=["21","22","23","00","01","02","03"]) // adjust hours here as well if needed: Example: "02" will detect up to 02:59:99 | ||
| | LogonTimestampMs := LogonTime * 1000 | ||
| }, | ||
| field=AuthenticationId, |
There was a problem hiding this comment.
This join key needs to be scoped to the host. AuthenticationId is a Windows logon-session LUID, which is only unique per machine, per boot, LUIDs are assigned sequentially from similar starting points on every Windows host, so across a fleet the same value will exist on many machines at once.
Because the join matches on this field alone, a process on host A can be stitched to an overnight RDP logon on host B whenever their session LUIDs collide. The resulting row looks like a legitimate hit (plausible TimeFromLogonMinutes, a real UserPrincipal and RemoteAddressIP4, just from the wrong machine), so this fabricates correlations rather than merely adding noise. And since join() keeps only one subquery row per key, a colliding logon from the wrong host can also displace the correct one and hide a genuine hit.
Adding aid to the key makes the match mean what the query intends:
| field=AuthenticationId, | |
| field=[aid, AuthenticationId], |
Overview
Adds a new detection query for identifying suspicious process executions following overnight remote interactive logons (RDP).
Details