Skip to content

Overnight Post-RDP Activity Detection - #74

Open
Nicholas-devsec wants to merge 2 commits into
ByteRay-Labs:mainfrom
Nicholas-devsec:overnight-post-rdp-activity-query
Open

Overnight Post-RDP Activity Detection#74
Nicholas-devsec wants to merge 2 commits into
ByteRay-Labs:mainfrom
Nicholas-devsec:overnight-post-rdp-activity-query

Conversation

@Nicholas-devsec

Copy link
Copy Markdown

Overview

Adds a new detection query for identifying suspicious process executions following overnight remote interactive logons (RDP).

Details

  • Purpose: Correlates overnight LogonType=10 with LOLBins and native recon/enumeration tools within 30 minutes.
  • MITRE ATT&CK: T1021.001, T1033, T1087, T1059, etc.
  • Format: Validated YAML generated via CQL Hub builder.

@Polaceka Polaceka assigned Polaceka and dweissbacher and unassigned Polaceka Aug 17, 2026

@dweissbacher dweissbacher left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Suggested change
field=AuthenticationId,
field=[aid, AuthenticationId],

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants