CVSS 6.8 CVE-2019-6110
CVSS 6.8 CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
In OpenSSH 7.9, due to accepting and displaying arbitrary stderr output from the server, a malicious server (or Man-in-The-Middle attacker) can manipulate the client output, for example to use ANSI control codes to hide additional files being transferred.
SSH Channel Multiplexing and stderr
When SCP runs over SSH, both scp processes (client and server side) communicate
over a single SSH channel. The SSH protocol multiplexes this channel into two data
streams:
stdout (
SSH_MSG_CHANNEL_DATA): used for the SCP file-transfer protocol messages and file contentstderr (
SSH_MSG_CHANNEL_EXTENDED_DATAwithdata_type_code = 1,SSH_EXTENDED_DATA_STDERR): error and diagnostic messages from the remotescpprocess
The client-side OpenSSH code handles incoming SSH_EXTENDED_DATA_STDERR packets by
writing their payload directly to the local terminal (stderr) with no filtering:
/* scp.c (simplified, affected versions) */
case SSH_EXTENDED_DATA_STDERR:
atomicio(vwrite, STDERR_FILENO, data, data_len);
break;
Since the terminal processes whatever bytes arrive on stderr, the server can inject any ANSI escape sequences at any time by sending them as SSH extended data. No sanitization of control characters takes place.
Difference to CVE-2019-6109
Both CVE-2019-6109 and CVE-2019-6110 allow a malicious server to inject ANSI control codes into the user’s terminal during an SCP session, but via different mechanisms:
CVE-2019-6109 |
CVE-2019-6110 |
|
|---|---|---|
Injection vector |
Filename in the SCP C-message ( |
Arbitrary payload in |
Timing |
Triggered when the client renders the progress meter for a specific file |
Can be sent at any point during the session, independent of file transfers |
Byte restrictions |
Cannot contain |
No restrictions — any byte sequence is valid |
Control |
One injection per file transfer |
Continuous, can overwrite terminal output at any time |
Because the two mechanisms are independent, they are typically combined: CVE-2019-6109 hides the injected file via the crafted filename, and CVE-2019-6110 provides a fallback erasure via the stderr channel to cover any residual terminal output.
Attack Chain
The full attack combines this vulnerability with CVE-2019-6111 (file injection) and CVE-2019-6109 (progress meter manipulation):
Step 1 — Client initiates download
scp user@server:document.txt .
The server spawns scp -f document.txt. The SCP protocol exchange begins over the
SSH channel’s stdout stream.
Step 2 — Server sends injected file (CVE-2019-6111)
The server sends an additional C-message for a file the client did not request
(e.g., ~/.ssh/authorized_keys). The client accepts it due to insufficient
validation (CVE-2019-6111).
As the injected transfer starts, the progress meter briefly shows something. To
prevent the user noticing, the server immediately sends the following bytes as an
SSH_MSG_CHANNEL_EXTENDED_DATA / stderr packet:
\x1b[1A\x1b[2K
These two sequences have the following terminal effects, executed in order:
\x1b[1A— move cursor up one line (to where the injected file’s progress appeared, if CVE-2019-6109 did not already erase it)\x1b[2K— erase the entire line the cursor is now on
Step 3 — Terminal state after erasure
Before erasure (terminal shows):
document.txt 100% 14 KB 1.4 MB/s 00:00
\x1b[2K\rauthorized_keys 100% 444 B 444 KB/s 00:00
After \x1b[1A\x1b[2K is processed:
document.txt 100% 14 KB 1.4 MB/s 00:00
[blank line, cursor here]
The next terminal output from the client (e.g., the shell prompt) overwrites the blank line, leaving no visible trace of the injected transfer.
Step 4 — Combined effect
With both CVE-2019-6109 and CVE-2019-6110 active simultaneously:
CVE-2019-6109 suppresses the progress line at render time (filename contains erase codes)
CVE-2019-6110 sends a second erasure via stderr as a backup, immediately after the injected transfer completes
A user watching the terminal in real time sees only document.txt completing, with no
indication a second file was written.
Test with SSH-MITM
A proof of concept exploit is integrated in SSH-MITM. This exploit also uses CVE-2019-6111 to inject additional files.
To inject a file during a download from the server to the client:
$ ssh-mitm server --scp-forwarder inject_file --scp-inject /path/to/additional/file
The injected file transfer is hidden using this vulnerability and CVE-2019-6109.