Remote Command Execution in Visual Studio Code Remote Development Extension

Visual Studio Code Remote Development Extension 1.50 failed to sanitize the host field before using it as an argument of the ssh command, allowing to inject a ProxyCommand option which could be used to run arbitray commands.

Product description (from vendor)

Visual Studio Code Remote Development allows you to use a container, remote machine, or the Windows Subsystem for Linux (WSL) as a full-featured development environment.
You can:

  • Develop on the same operating system you deploy to or use larger or more specialized hardware.
  • Separate your development environment to avoid impacting your local machine configuration.
  • Make it easy for new contributors to get started and keep everyone on a consistent environment.
  • Use tools or runtimes not available on your local OS or manage multiple versions of them.
  • Develop your Linux-deployed applications using the Windows Subsystem for Linux.
  • Access an existing development environment from multiple machines or locations.
  • Debug an application running somewhere else such as a customer site or in the cloud.

No source code needs to be on your local machine to get these benefits. Each extension in the Remote Development extension pack can run commands and other extensions directly inside a container, in WSL, or on a remote machine so that everything feels like it does when you run locally.

CVE

Root cause analysis

An argument injection is present in the “Remote - SSH” extension, which is used and installed by the “Remote Development” one.

This extension uses the SSH binary of the host to setup the connection with the remote host.

One of the ways to trigger the SSH connection is to use the vscode:// URI scheme. Specifically, the format is the following: vscode://vscode-remote/ssh-remote+$REMOTE_HOST+$PATH_OF_PROJECT_ON_THE_REMOTE_HOST

Once a user browses an URI as the previous one, VSCode is opened and the extension tries to connect to the $REMOTE_HOST.

While connecting the following command is executed: ssh -T -D $RANDOM_PORT "$REMOTE_HOST" bash

As no sanitization is performed on the $REMOTE_HOST user-supplied input it is possible to inject arbitrary arguments to the SSH binary.

SSH has an option called ProxyCommand, which specifies a command which is executed before performing the actual SSH connection.

Combining all together it is possible to execute arbitrary system commands on the host of a victim by forcing them into opening a malicious link.

Proof of concept

  1. Install Visual Studio Code
  2. Install the “Remote Development” extension (https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)
  3. Open a browser
  4. Visit the following URL: vscode://vscode-remote/ssh-remote+-oProxyCommand=C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -c msg %username% command_injection" "a@127.0.0.1+/a
  5. Confirm to open VSCode
  6. Select a random OS (Linux / Windows / MacOS)
  7. Notice the pop-up executed by Powershell with the message “command_injection”

The same attack can be reproduced on Linux and MacOS by editing the ProxyCommand.

Impact

An attacker able to force a victim into visiting a malicious link could execute arbitrary commands on their system.

Remediation

Upgrade the Visual Studio Code Remote Development Extension to version 1.51 or higher.

Disclosure timeline

  • 17/08/2020: The vulnerability was found and reported to Microsoft
  • 20/08/2020: Microsoft acknowledged the vulnerability
  • 02/11/2020: Microsoft released the fix
  • 24/09/2021: Shielder’s advisory is made public

Credits

Abdel Adim `smaury` Oisfi of Shielder

This advisory was first published on https://www.shielder.it/it/advisories/remote-command-execution-in-visual-studio-code-remote-development-extension/

Data

24 settembre 2021