← Back to SOC feed Coverage →

Multiple RDP connections from Single System

kql LOW Azure-Sentinel
T1021
SecurityEventWindowsEvent
microsoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-04-18T16:05:06Z · Confidence: medium

Hunt Hypothesis

Multiple RDP connections from a single system may indicate an adversary attempting to pivot within the network or exfiltrate data. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential lateral movement or unauthorized access attempts that could escalate to a full breach.

KQL Query

let endtime = 1d;
let starttime = 8d;
let threshold = 2.0;
(union isfuzzy=true
(SecurityEvent
| where TimeGenerated >= ago(endtime)
| where EventID == 4624 and LogonType == 10
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ComputerCountToday = dcount(Computer), ComputerSet = makeset(Computer), ProcessSet = makeset(ProcessName)
by Account = tolower(Account), IpAddress, AccountType, Activity, LogonTypeName),
(WindowsEvent
| where TimeGenerated >= ago(endtime)
| where EventID == 4624
| extend LogonType = tostring(EventData.LogonType)
| where  LogonType == 10
| extend ProcessName = tostring(EventData.ProcessName)
| extend Account = strcat(tostring(EventData.TargetDomainName),"\\", tostring(EventData.TargetUserName))
| extend IpAddress = tostring(EventData.IpAddress)
| extend TargetUserSid = tostring(EventData.TargetUserSid)
| extend AccountType=case(Account endswith "$" or TargetUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(TargetUserSid), "", "User")
| extend Activity="4624 - An account was successfully logged on."
| extend LogonTypeName="10 - RemoteInteractive"
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ComputerCountToday = dcount(Computer), ComputerSet = makeset(Computer), ProcessSet = makeset(ProcessName)
by Account = tolower(Account), IpAddress, AccountType, Activity, LogonTypeName)
)
| join kind=inner (
(union isfuzzy=true
(SecurityEvent
| where TimeGenerated >= ago(starttime) and TimeGenerated < ago(endtime)
| where EventID == 4624 and LogonType == 10
| summarize ComputerCountPrev7Days = dcount(Computer) by Account = tolower(Account), IpAddress
),
( WindowsEvent
| where TimeGenerated >= ago(starttime) and TimeGenerated < ago(endtime)
| where EventID == 4624  and EventData has ("10")
| extend LogonType = toint(EventData.LogonType)
| where  LogonType == 10
| extend Account = strcat(tostring(EventData.TargetDomainName),"\\", tostring(EventData.TargetUserName))
| extend IpAddress = tostring(EventData.IpAddress)
| summarize ComputerCountPrev7Days = dcount(Computer) by Account = tolower(Account), IpAddress)
)
) on Account, IpAddress
| extend Ratio = iff(isempty(ComputerCountPrev7Days), toreal(ComputerCountToday), ComputerCountToday / (ComputerCountPrev7Days * 1.0))
// Where the ratio of today to previous 7 days is more than double.
| where Ratio > threshold
| project StartTime, EndTime, Account, IpAddress, ComputerSet, ComputerCountToday, ComputerCountPrev7Days, Ratio, AccountType, Activity, LogonTypeName, ProcessSet
| extend AccountName = tostring(split(Account, @"\")[1]), AccountNTDomain = tostring(split(Account, @"\")[0])

Analytic Rule Definition

id: 78422ef2-62bf-48ca-9bab-72c69818a425
name: Multiple RDP connections from Single System
description: |
  'Identifies when an RDP connection is made to multiple systems and above the normal connection count for the previous 7 days.
  Connections from the same system with the same account within the same day.
  RDP connections are indicated by the EventID 4624 with LogonType = 10'
severity: Low
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: WindowsSecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: WindowsForwardedEvents
    dataTypes:
      - WindowsEvent
queryFrequency: 1d
queryPeriod: 8d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - LateralMovement
relevantTechniques:
  - T1021
query: |
  let endtime = 1d;
  let starttime = 8d;
  let threshold = 2.0;
  (union isfuzzy=true
  (SecurityEvent
  | where TimeGenerated >= ago(endtime)
  | where EventID == 4624 and LogonType == 10
  | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ComputerCountToday = dcount(Computer), ComputerSet = makeset(Computer), ProcessSet = makeset(ProcessName)
  by Account = tolower(Account), IpAddress, AccountType, Activity, LogonTypeName),
  (WindowsEvent
  | where TimeGenerated >= ago(endtime)
  | where EventID == 4624
  | extend LogonType = tostring(EventData.LogonType)
  | where  LogonType == 10
  | extend ProcessName = tostring(EventData.ProcessName)
  | extend Account = strcat(tostring(EventData.TargetDomainName),"\\", tostring(EventData.TargetUserName))
  | extend IpAddress = tostring(EventData.IpAddress)
  | extend TargetUserSid = tostring(EventData.TargetUserSid)
  | extend AccountType=case(Account endswith "$" or TargetUserSid in ("S-1-5-18", "S-1-5-19", "S-1-5-20"), "Machine", isempty(TargetUserSid), "", "User")
  | extend Activity="4624 - An account was successfully logged on."
  | extend LogonTypeName="10 - RemoteInteractive"
  | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), ComputerCountToday = dcount(Computer), ComputerSet = makeset(Computer), ProcessSet = makeset(ProcessName)
  by Account = tolower(Account), IpAddress, AccountType, Activity, LogonTypeName)
  )
  | join kind=inner (
  (union isfuzzy=true
  (SecurityEvent
  | where TimeGenerated >= ago(starttime) and TimeGenerated < ago(endtime)
  | where EventID == 4624 and LogonType == 10
  | summarize ComputerCountPrev7Days = dcount(Computer) by Account = tolower(Account), IpAddress
  ),
  ( WindowsEvent
  | where TimeGenerated >= ago(starttime) and TimeGenerated < ago(endtime)
  | where EventID == 4624  and EventData has ("10")
  | extend LogonType = toint(EventData.LogonType)
  | where  LogonType == 10
  | extend Account = strcat(tostring(EventData.TargetDomainName),"\\", tostring(EventData.TargetUserName))
  | extend IpAddress = tostring(EventData.IpAddress)
  | summarize ComputerCountPrev7Days = dcount(Computer) by Account = tolower(Account), IpAddress)
  )
  ) on Acco

Required Data Sources

Sentinel TableNotes
SecurityEventEnsure this data connector is enabled
WindowsEventEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Detections/SecurityEvent/RDP_MultipleConnectionsFromSingleSystem.yaml