{
	"id": "3c4584c9-2557-40a6-a9ec-d97a0330d057",
	"created_at": "2026-04-06T00:12:14.93333Z",
	"updated_at": "2026-04-10T13:12:05.862869Z",
	"deleted_at": null,
	"sha1_hash": "d9da72ca3fff1c726a2db96956d7eab3b927f15f",
	"title": "Threat Actors Expand Abuse of Microsoft Visual Studio Code",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 882477,
	"plain_text": "Threat Actors Expand Abuse of Microsoft Visual Studio Code\r\nBy Jamf Threat Labs\r\nArchived: 2026-04-05 18:21:19 UTC\r\nJamf Threat Labs identifies additional abuse of Visual Studio Code. See the latest evolution in the Contagious\r\nInterview campaign.\r\nBy Thijs Xhaflaire\r\nIntroduction\r\nAt the end of last year, Jamf Threat Labs published research related to the Contagious Interview campaign, which\r\nhas been attributed to a threat actor operating on behalf of North Korea (DPRK). Around the same time,\r\nresearchers from OpenSourceMalware (OSM) released additional findings that highlighted an evolution in the\r\ntechniques used during earlier stages of the campaign.\r\nSpecifically, these newer observations highlight an additional delivery technique alongside the previously\r\ndocumented ClickFix-based techniques. In these cases, the infection chain abuses Microsoft Visual Studio Code\r\ntask configuration files, allowing malicious payloads to be executed on the victim system.\r\nhttps://www.jamf.com/blog/threat-actors-expand-abuse-of-visual-studio-code/\r\nPage 1 of 4\n\nFollowing the discovery of this technique, both Jamf Threat Labs and OSM continued to closely monitor activity\r\nassociated with the campaign. In December, Jamf Threat Labs identified additional abuse of Visual Studio Code\r\ntasks.json configuration files. This included the introduction of dictionary files containing heavily obfuscated\r\nJavaScript, which is executed when a victim opens a malicious repository in Visual Studio Code.\r\nJamf Threat Labs shared these findings with OSM, who subsequently published a more in-depth technical analysis\r\nof the obfuscated JavaScript and its execution flow.\r\nEarlier this week, Jamf Threat Labs identified another evolution in the campaign, uncovering a previously\r\nundocumented infection method. This activity involved the deployment of a backdoor implant that provides\r\nremote code execution capabilities on the victim system.\r\nAt a high level, the chain of events for the malware look like so:\r\nThroughout this blog post we will shed light on each of these steps.\r\nInitial Infection\r\nIn this campaign, infection begins when a victim clones and opens a malicious Git repository, often under the\r\npretext of a recruitment process or technical assignment. The repositories identified in this activity are hosted on\r\neither GitHub or GitLab and are opened using Visual Studio Code.\r\nWhen the project is opened, Visual Studio Code prompts the user to trust the repository author. If that trust is\r\ngranted, the application automatically processes the repository’s tasks.json configuration file, which can result\r\nin embedded arbitrary commands being executed on the system.\r\nOn macOS systems, this results in the execution of a background shell command that uses nohup bash -c in\r\ncombination with curl -s to retrieve a JavaScript payload remotely and pipe it directly into the Node.js\r\nruntime. This allows execution to continue independently if the Visual Studio Code process is terminated, while\r\nsuppressing all command output.\r\nIn observed cases, the JavaScript payload is hosted on vercel.app , a platform that has been increasingly used in\r\nrecent DPRK-related activity following a move away from other hosting services, as previously documented by\r\nOpenSourceMalware.\r\nJamf Threat Labs reported the identified malicious repository to GitHub, after which the repository was removed.\r\nWhile monitoring the activity prior to takedown, we observed the URL referenced within the repository change on\r\nmultiple occasions. Notably, one of these changes occurred after the previously referenced payload hosting\r\ninfrastructure was taken down by Vercel.\r\nThe JavaScript Payload\r\nOnce execution begins, the JavaScript payload implements the core backdoor logic observed in this activity.\r\nWhile the payload appears lengthy, a significant portion of the code consists of unused functions, redundant logic,\r\nand extraneous text that is never invoked during execution (SHA256:\r\n932a67816b10a34d05a2621836cdf7fbf0628bbfdf66ae605c5f23455de1e0bc) . This additional code increases the size\r\nhttps://www.jamf.com/blog/threat-actors-expand-abuse-of-visual-studio-code/\r\nPage 2 of 4\n\nand complexity of the script without impacting its observed behavior. It is passed to the node executable as one\r\nlarge argument.\r\nFocusing on the functional components, the payload establishes a persistent execution loop that collects basic host\r\ninformation and communicates with a remote command-and-control (C2) server. Hard-coded identifiers are used\r\nto track individual infections and manage tasks from the server.\r\nCore backdoor functionality\r\nWhile the JavaScript payload contains a significant amount of unused code, the backdoor's core functionality is\r\nimplemented through a small number of routines. These routines provide remote code execution, system\r\nfingerprinting, and persistent C2 communication.\r\nRemote code execution capability\r\nThe payload includes a function that enables the execution of arbitrary JavaScript while the backdoor is active. At\r\nits core, this is the main functionality of this backdoor.\r\nThis function allows JavaScript code supplied as a string to be dynamically executed over the course of the\r\nbackdoor lifecycle. By passing the require function into the execution context, attacker-supplied code can\r\nimport additional Node.js modules allowing additional arbitrary node functions to be executed.\r\nSystem fingerprinting and reconnaissance\r\nTo profile the infected system, the backdoor collects a small set of host-level identifiers:\r\nThis routine gathers the system hostname, MAC addresses from available network interfaces, and basic operating\r\nsystem details. These values provide a stable fingerprint that can be used to uniquely identify infected hosts and\r\nassociate them with a specific campaign or operator session.\r\nIn addition to local host identifiers, the backdoor attempts to determine the victim’s public-facing IP address by\r\nquerying the external service ipify.org, a technique that has also been observed in prior DPRK-linked campaigns.\r\nCommand-and-control beaconing and task execution\r\nPersistent communication with the C2 server is implemented through a polling routine that periodically sends host\r\ninformation and processes server responses. The beaconing logic is handled by the following function:\r\nThis function periodically sends system fingerprinting data to a remote server and waits for a response. The\r\nbeacon executes every five seconds, providing frequent interaction opportunities.\r\nThe server response indicates successful connectivity and allows the backdoor to maintain an active session while\r\nawaiting tasking.\r\nIf the server response contains a specific status value, the contents of the response message are passed directly to\r\nthe remote code execution routine, mentioned prior.\r\nFurther Execution and Instructions\r\nhttps://www.jamf.com/blog/threat-actors-expand-abuse-of-visual-studio-code/\r\nPage 3 of 4\n\nWhile monitoring a compromised system, Jamf Threat Labs observed further JavaScript instructions being\r\nexecuted roughly eight minutes after the initial infection. The retrieved JavaScript went on to set up a very similar\r\npayload to the same C2 infrustructure.\r\nReview of this retrieved payload yields a few interesting details...\r\n1. It beacons to the C2 server every 5 seconds, providing its system details and asks for further JavaScript\r\ninstructions.\r\n2. It executes that additional JavaScript within a child process.\r\n3. It's capable of shutting itself and child processes down and cleaning up if asked to do so by the attacker.\r\n4. It has inline comments and phrasing that appear to be consistent with AI-assisted code generation.\r\nConclusion\r\nThis activity highlights the continued evolution of DPRK-linked threat actors, who consistently adapt their tooling\r\nand delivery mechanisms to integrate with legitimate developer workflows. The abuse of Visual Studio Code task\r\nconfiguration files and Node.js execution demonstrates how these techniques continue to evolve alongside\r\ncommonly used development tools.\r\nJamf Threat Labs will continue to track these developments as threat actors refine their tactics and explore new\r\nways to deliver macOS malware. We strongly recommend that customers ensure Threat Prevention and Advanced\r\nThreat Controls are enabled and set to block mode in Jamf for Mac to remain protected against the techniques\r\ndescribed in this research.\r\nDevelopers should remain cautious when interacting with third-party repositories, especially those shared directly\r\nor originating from unfamiliar sources. Before marking a repository as trusted in Visual Studio Code, it’s\r\nimportant to review its contents. Similarly, \"npm install\" should only be run on projects that have been vetted,\r\nwith particular attention paid to package.json files, install scripts, and task configuration files to help avoid\r\nunintentionally executing malicious code.\r\nIndicators or Compromise\r\nDive into more Jamf Threat Labs research on our blog.\r\nSource: https://www.jamf.com/blog/threat-actors-expand-abuse-of-visual-studio-code/\r\nhttps://www.jamf.com/blog/threat-actors-expand-abuse-of-visual-studio-code/\r\nPage 4 of 4",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.jamf.com/blog/threat-actors-expand-abuse-of-visual-studio-code/"
	],
	"report_names": [
		"threat-actors-expand-abuse-of-visual-studio-code"
	],
	"threat_actors": [
		{
			"id": "4fc99d9b-9b66-4516-b0db-520fbef049ed",
			"created_at": "2025-10-29T02:00:51.949631Z",
			"updated_at": "2026-04-10T02:00:05.346203Z",
			"deleted_at": null,
			"main_name": "Contagious Interview",
			"aliases": [
				"Contagious Interview",
				"DeceptiveDevelopment",
				"Gwisin Gang",
				"Tenacious Pungsan",
				"DEV#POPPER",
				"PurpleBravo",
				"TAG-121"
			],
			"source_name": "MITRE:Contagious Interview",
			"tools": [
				"InvisibleFerret",
				"BeaverTail",
				"XORIndex Loader",
				"HexEval Loader"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775434334,
	"ts_updated_at": 1775826725,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/d9da72ca3fff1c726a2db96956d7eab3b927f15f.pdf",
		"text": "https://archive.orkl.eu/d9da72ca3fff1c726a2db96956d7eab3b927f15f.txt",
		"img": "https://archive.orkl.eu/d9da72ca3fff1c726a2db96956d7eab3b927f15f.jpg"
	}
}