Contagious Interview: Tracking the VS Code Tasks Infection Vector
Detection stack
- AIDR
- Alert
- ETL
- Query
Summary
The report details a North Korea–attributed campaign that weaponizes Visual Studio Code task definitions (tasks.json) to gain initial code execution on developer endpoints. Malicious task entries run commands that fetch additional payloads from hosting platforms such as Vercel, Render, and similar services, or they pull in malicious NPM dependencies. This execution chain ultimately enables deployment of backdoors including BeaverTail and InvisibleFerret.
Investigation
Researchers leveraged GitHub code search to identify repositories containing tasks.json files with embedded curl or wget execution. They analyzed payload-hosting domains, documented obfuscation methods that hide scripts inside image and font files, and uncovered a malicious NPM package named jsonwebauth. The study also correlated commit-author email addresses and expanded infrastructure mapping beyond Vercel-based delivery.
Mitigation
Disable automatic task execution in VS Code, and review tasks.json contents before trusting or opening a workspace. Use the in-browser github.dev environment to inspect repositories without running local tasks. Monitor for suspicious VS Code child processes, unexpected network requests to known payload domains, and Node.js execution paths that attempt to run non-JavaScript files.
Response
If identified, isolate the endpoint, terminate suspicious VS Code–spawned processes, and block outbound traffic to the associated malicious domains. Collect and analyze downloaded payloads, and perform forensic validation for persistence and backdoor activity linked to BeaverTail and InvisibleFerret.
Attack Flow
Simulation Execution
Prerequisite: The Telemetry & Baseline Pre‑flight Check must have passed.
Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic. Abstract or unrelated examples will lead to misdiagnosis.
-
Attack Narrative & Commands:
An attacker who has already compromised the user’s workstation leverages VS Code’s tasks.json feature to run a malicious Windows executable (payload.exe) via Node.js. The attacker crafts a task that invokescmd.exe /c node payload.exe, thereby satisfying the rule’s three‑keyword requirement (tasks.json,node,cmd). After saving the malicious task definition under the user’s.vscodefolder, the attacker executes the task through VS Code’s command palette, causingcmd.exeandnode.exeprocesses to appear in the Windows security log with a command line that contains the three required strings. -
Regression Test Script: (PowerShell – self‑contained)
# --------------------------------------------------------- # Malicious VS Code Task Simulation – Triggers Sigma Rule # --------------------------------------------------------- # 1. Prepare a dummy malicious payload (non‑JS executable) $payloadPath = "$env:USERPROFILEDesktoppayload.exe" # Create a tiny executable using PowerShell’s Add-Type (for demo) Add-Type -TypeDefinition @" using System; public class Dummy { public static void Main() { System.Console.WriteLine("Payload executed"); } } "@ -Language CSharp [Dummy]::Main() | Out-File -FilePath $payloadPath -Encoding ascii # 2. Build the VS Code tasks.json with malicious command $vscodeDir = "$env:USERPROFILE.vscode" if (-not (Test-Path $vscodeDir)) { New-Item -ItemType Directory -Path $vscodeDir | Out-Null } $tasksJson = @{ version = "2.0.0" tasks = @( @{ label = "Run Malicious Payload" type = "shell" command = "cmd.exe" args = @("/c", "node", "`"$payloadPath`"") } ) } | ConvertTo-Json -Depth 5 $tasksFile = Join-Path $vscodeDir "tasks.json" $tasksJson | Set-Content -Path $tasksFile -Encoding UTF8 # 3. Trigger the task via VS Code CLI # (Assumes `code` is in PATH) Write-Host "Executing malicious VS Code task..." code --folder-uri "$env:USERPROFILE" --command "workbench.action.tasks.runTask" --args "Run Malicious Payload" # 4. Wait a few seconds for the processes to appear in the log Start-Sleep -Seconds 5 # 5. OPTIONAL: Query local event log to verify (for demonstration) Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4688; Data='node.exe'; } | Where-Object {$_.Message -match 'tasks.json'} | ft TimeCreated, Message -AutoSize -
Cleanup Commands: (PowerShell)
# Remove malicious payload and VS Code task definition Remove-Item -Path "$env:USERPROFILEDesktoppayload.exe" -Force -ErrorAction SilentlyContinue Remove-Item -Path "$env:USERPROFILE.vscodetasks.json" -Force -ErrorAction SilentlyContinue # Optional: restart VS Code to clear any cached tasks Get-Process -Name "Code" -ErrorAction SilentlyContinue | Stop-Process -Force