{"id":"CMP-202611-t22f34","kind":"campaign","aliases":[],"related":[],"title":"North Korean fake job coding tests: World-bat repo infects developers who open it in VS Code or Cursor, or run npm install (Contagious Interview, BeaverTail)","description":null,"summary":"DPRK-linked Contagious Interview operators send developers a fake Web3/metaverse poker take-home coding test, the Git repo World-bat (codeberg.org/improbable-Hub/World-bat), branded GGLab, Virtual Pangea, deAIOS and 0G Rollplay. Cloning is safe. Two things infect the machine: trusting the folder in VS Code or Cursor runs a hidden folder-open task that pipes a loader from improbable-check1.vercel.app into a shell, and npm install (prepare hook), npm start or node server runs an obfuscated beacon hidden off-screen in routes/api/auth.js. The BeaverTail beacon sends hostname, MAC, OS and the whole environment (process.env, so any API keys and tokens in it) to 51.210.65.37:1224 every 5 seconds and runs whatever code the operator sends back. Public reporting says the next stages are usually the BeaverTail stealer, the InvisibleFerret backdoor or OtterCookie, which go after browser passwords, crypto wallets, the macOS Keychain and SSH keys. Windows, macOS and Linux. Analysed 11 Nov 2026 by researcher Philipp Mieden (Amsterdam Technologies); lure commits run 2025-10 to 2026-10. Number of victims unknown.","severity":"high","cvss":null,"epss":null,"exploited":true,"exploited_at":"2026-11-12T00:07:39+00:00","products":[{"name":"Visual Studio Code","fixed":[]},{"name":"Cursor","fixed":[]},{"name":"npm","fixed":[]},{"name":"Node.js","fixed":[]}],"ecosystems":[],"tags":["campaign","early-warning"],"not_affected_if":[],"how_to_check":"Repo: codeberg.org/improbable-Hub/World-bat (HEAD 53218da0a97adb6afbbda25ac0e4b45d6e40ee1b) or a take-home test with poker/metaverse branding GGLab, Virtual Pangea, deAIOS, 0G Rollplay. In any received test repo: .vscode/tasks.json with runOn: folderOpen and a command pushed far right with whitespace; package.json with prepare 'start /b node server || nohup node server &'; long whitespace runs at line ends of JS files (e.g. routes/api/auth.js line 18). Network: improbable-check1.vercel.app (paths /api/settings/mac, /linux, /windows, /bootstraplinux, /bootstrap); http://51.210.65.37:1224/api/checkStatus, or any :1224/api/checkStatus traffic. Decoy hosts: mbank-poker.netlify.app, 0g-rollplay.netlify.app, gglab-poker.netlify.app, multibank-poker.netlify.app. Host: ~/.vscode/vscode-bootstrap.sh or %USERPROFILE%\\.vscode\\vscode-bootstrap.cmd, a file named celt.js (older variants: env-setup.js), a portable Node download plus npm i axios request in ~/.vscode. Stage-2 sha256: c0ccc784abc4cddf2372806b154f67c0701ffbd86c5c1a21e0fec57b95d48acc (mac), 78a881c7be81ac2459fc1810f350d6012a8ed160973a14f0eedebe7327c8e4cd (linux), 4f6ead231ccdafbc6e3f9b9a056ad441966569916352c6f19fdd843c0312ec37 (windows). Lure commit emails include martinsnaith5050@gmail.com, templejett03@gmail.com, romonterozamendoza@gmail.com, hiringtecjreview@outlook.com.","fix":"Open take-home or interview repos only in a throwaway VM or container, and choose 'No, I don't trust the authors' (Restricted Mode) in VS Code/Cursor; check .vscode/tasks.json and package.json scripts before any npm install. Block improbable-check1.vercel.app and 51.210.65.37. If a machine opened or installed the repo: isolate it, remove ~/.vscode/vscode-bootstrap.* and celt.js, and from a clean device rotate every secret that was in the shell environment, browser-saved passwords and sessions, SSH keys and cloud/API tokens; move crypto wallet funds to a new wallet.","status":"open","published_at":null,"first_seen_at":"2026-11-12T00:07:39+00:00","triaged_at":"2026-11-12T00:07:39+00:00","updated_at":"2026-11-12T00:11:17+00:00","category":"package","confidence":null,"triage":{"cause":{"at":"2026-11-12T00:14:23Z","path":"tampered-install","entry":"tampered-install","reason":"Infection happens when the victim opens the repo in VS Code or Cursor, which runs a hidden folder-open task, or runs npm install, whose prepare hook starts the BeaverTail beacon.","confidence":0.6}},"analyst_status":"done","analyst_note":null,"search":"'-10':208B,211B '-202611':29A '/improbable-hub/world-bat),':66B '0g':73B '11':195B '1224':149B '2025':207B '2026':197B,210B '5':151B '51.210.65.37':148B 'amsterdam':202B 'analys':194B 'api':141B 'back':160B 'backdoor':174B 'bat':9A,63B 'beacon':120B,129B 'beavertail':27A,128B,170B 'brand':67B 'browser':180B 'campaign':37B 'clone':75B 'cmp':28A 'code':5A,18A,33A,56B,88B,156B 'codeberg.org':65B 'codeberg.org/improbable-hub/world-bat),':64B 'commit':205B 'contagi':25A,44B 'crypto':182B 'cursor':20A,34A,90B 'deaio':71B 'develop':12A,48B 'dprk':42B 'dprk-link':41B 'earli':39B 'early-warn':38B 'environ':137B 'everi':150B 'fake':3A,50B 'folder':85B,95B 'folder-open':94B 'gglab':68B 'git':59B 'go':178B 'hidden':93B,121B 'home':55B 'hook':111B 'hostnam':131B 'improbable-check1.vercel.app':103B 'infect':11A,80B 'instal':24A,109B 'interview':26A,45B 'invisibleferret':173B 'job':4A 'key':142B,189B 'keychain':186B 'korean':2A 'link':43B 'linux':193B 'loader':101B 'lure':204B 'mac':132B 'machin':82B 'maco':185B,191B 'mieden':201B 'next':165B 'node':115B 'node.js':36A 'north':1A 'nov':196B 'npm':23A,35A,108B,112B 'number':212B 'obfusc':119B 'off-screen':122B 'open':14A,96B 'oper':46B,158B 'os':133B 'ottercooki':176B 'pangea':70B 'password':181B 'philipp':200B 'pipe':99B 'poker':52B 'prepar':110B 'process.env':138B 'public':161B 'repo':10A,60B 'report':162B 'research':199B 'rollplay':74B 'routes/api/auth.js':126B 'run':22A,91B,117B,154B,206B 'safe':77B 'say':163B 'screen':124B 'second':152B 'send':47B,130B,159B 'server':116B 'shell':106B 'ssh':188B 'stage':166B 'start':113B 'stealer':171B 'studio':32A 't22f34':30A 'take':54B 'take-hom':53B 'task':97B 'technolog':203B 'test':6A,57B 'thing':79B 'token':144B 'trust':83B 'two':78B 'unknown':215B 'usual':168B 'victim':214B 'virtual':69B 'visual':31A 'vs':17A,87B 'wallet':183B 'warn':40B 'web3/metaverse':51B 'whatev':155B 'whole':136B 'window':190B 'world':8A,62B 'world-bat':7A,61B","nicknames":["Contagious Interview","World-bat","BeaverTail","Famous Chollima","DEV#POPPER","UNC5342"],"mitigations":[],"who_affected":null,"tier":"A","verified":{},"analyst_revisit_at":null,"fix_status":null,"audience":null,"plain_action":null,"pkeys":["beavertail","contagiousinterview","cursor","devpopper","famouschollima","nodejs","npm","studiocode","unc5342","visualstudiocode","worldbat"],"ptokens":["code","cursor","nodejs","npm","studio","visual"],"labels":["campaign","earlywarning","high","package"],"campaign_type":"malware","search_a":"'-202611':29A 'bat':9A 'beavertail':27A 'cmp':28A 'code':5A,18A,33A 'contagi':25A 'cursor':20A,34A 'develop':12A 'fake':3A 'infect':11A 'instal':24A 'interview':26A 'job':4A 'korean':2A 'node.js':36A 'north':1A 'npm':23A,35A 'open':14A 'repo':10A 'run':22A 'studio':32A 't22f34':30A 'test':6A 'visual':31A 'vs':17A 'world':8A 'world-bat':7A","search_b":"'-10':208B,211B '/improbable-hub/world-bat),':66B '0g':73B '11':195B '1224':149B '2025':207B '2026':197B,210B '5':151B '51.210.65.37':148B 'amsterdam':202B 'analys':194B 'api':141B 'back':160B 'backdoor':174B 'bat':63B 'beacon':120B,129B 'beavertail':128B,170B 'brand':67B 'browser':180B 'campaign':37B 'clone':75B 'code':56B,88B,156B 'codeberg.org':65B 'codeberg.org/improbable-hub/world-bat),':64B 'commit':205B 'contagi':44B 'crypto':182B 'cursor':90B 'deaio':71B 'develop':48B 'dprk':42B 'dprk-link':41B 'earli':39B 'early-warn':38B 'environ':137B 'everi':150B 'fake':50B 'folder':85B,95B 'folder-open':94B 'gglab':68B 'git':59B 'go':178B 'hidden':93B,121B 'home':55B 'hook':111B 'hostnam':131B 'improbable-check1.vercel.app':103B 'infect':80B 'instal':109B 'interview':45B 'invisibleferret':173B 'key':142B,189B 'keychain':186B 'link':43B 'linux':193B 'loader':101B 'lure':204B 'mac':132B 'machin':82B 'maco':185B,191B 'mieden':201B 'next':165B 'node':115B 'nov':196B 'npm':108B,112B 'number':212B 'obfusc':119B 'off-screen':122B 'open':96B 'oper':46B,158B 'os':133B 'ottercooki':176B 'pangea':70B 'password':181B 'philipp':200B 'pipe':99B 'poker':52B 'prepar':110B 'process.env':138B 'public':161B 'repo':60B 'report':162B 'research':199B 'rollplay':74B 'routes/api/auth.js':126B 'run':91B,117B,154B,206B 'safe':77B 'say':163B 'screen':124B 'second':152B 'send':47B,130B,159B 'server':116B 'shell':106B 'ssh':188B 'stage':166B 'start':113B 'stealer':171B 'take':54B 'take-hom':53B 'task':97B 'technolog':203B 'test':57B 'thing':79B 'token':144B 'trust':83B 'two':78B 'unknown':215B 'usual':168B 'victim':214B 'virtual':69B 'vs':87B 'wallet':183B 'warn':40B 'web3/metaverse':51B 'whatev':155B 'whole':136B 'window':190B 'world':62B 'world-bat':61B","search_c":"","cause_entry":"tampered-install","cause_path":"tampered-install","disclosures_checked_at":null,"first_public_at":"2026-10-30T05:24:18+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"analyst","external_id":"CMP-202611-t22f34","url":"https://amsterdam-technologies.com/blog/a-very-contagious-interview","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-11-12T00:07:39+00:00","fetched_at":"2026-11-12T00:07:39+00:00","note":null,"cites":["https://amsterdam-technologies.com/blog/a-very-contagious-interview"]}],"documents":[{"id":130152,"url":"https://news.ycombinator.com/item?id=50460513","title":"In-depth Analysis of DPRK Contagious Interview campaign","kind":"post","source":"hackernews","publisher":null,"text":"In-depth Analysis of DPRK Contagious Interview campaign\nhttps://amsterdam-technologies.com/blog/a-very-contagious-interview\n\n1 points, 0 comments on Hacker News","published_at":"2026-11-11T23:32:55+00:00","relation":"describes","confidence":null,"note":null},{"id":130342,"url":"https://amsterdam-technologies.com/blog/a-very-contagious-interview","title":"A very contagious interview — Amsterdam Technologies (Philipp Mieden)","kind":"blog","source":"analyst","publisher":null,"text":"Static teardown of World-bat (codeberg.org/improbable-Hub/World-bat, HEAD 53218da0a97adb6afbbda25ac0e4b45d6e40ee1b), a fake Web3 poker take-home coding test (branded GGLab, Virtual Pangea, deAIOS, 0G Rollplay) from DPRK Contagious Interview. Two triggers: .vscode/tasks.json runOn folderOpen task with command hidden ~560 columns off-screen piping https://improbable-check1.vercel.app/api/settings/{mac,linux,windows} into a shell; and obfuscated blob after ~300 spaces on line 18 of routes/api/auth.js, started by npm prepare hook 'start /b node server || nohup node server &'. Loaders write ~/.vscode/vscode-bootstrap.sh / .cmd, fetch portable Node, npm i axios request, run celt.js. BeaverTail beacon every 5s sends hostname, MAC, OS and full process.env to http://51.210.65.37:1224/api/checkStatus and eval()s message when status=error. Follow-on: BeaverTail stealer, InvisibleFerret, OtterCookie. Stage2 sha256: mac c0ccc784abc4cddf2372806b154f67c0701ffbd86c5c1a21e0fec57b95d48acc, linux 78a881c7be81ac2459fc1810f350d6012a8ed160973a14f0eedebe7327c8e4cd, windows 4f6ead231ccdafbc6e3f9b9a056ad441966569916352c6f19fdd843c0312ec37. Decoy hosts mbank-poker.netlify.app, 0g-rollplay.netlify.app, gglab-poker.netlify.app, multibank-poker.netlify.app. Git clone alone is safe; trusting the folder in VS Code/Cursor or npm install/start infects.","published_at":"2026-11-11T00:04:56+00:00","relation":"describes","confidence":null,"note":null},{"id":21447,"url":"https://x.com/MalwareTechBlog/status/2116038465616068863","title":"@MalwareTechBlog: \"compromised DevOps engineer's laptop\" I swear to god if this was Contagious Int","kind":"post","source":"x","publisher":null,"text":"\"compromised DevOps engineer's laptop\" I swear to god if this was Contagious Interview, I'm moving to North Korea and stealing bitcoin for a living.\n\nFor context, Contagious Interview is one of DPRK's techniques where they reach out to developers in the target organization and https://t.co/ylVyboU1Kp\n\nlikes 9 reposts 2","published_at":"2026-10-30T05:24:18+00:00","relation":"discussion","confidence":null,"note":"@MalwareTechBlog"},{"id":21568,"url":"https://x.com/MalwareTechBlog/status/2116040482946203662","title":"@MalwareTechBlog: \"compromised DevOps engineer's laptop\" I swear to god if this was Contagious Int","kind":"post","source":"x","publisher":null,"text":"\"compromised DevOps engineer's laptop\" I swear to god if this was Contagious Interview, I'm moving to North Korea and stealing bitcoin for a living.\n\nFor context, Contagious Interview is one of DPRK's techniques where they reach out to developers in the target organization and https://t.co/hiijxom869\n\nlikes 1133 reposts 140","published_at":"2026-10-30T05:32:19+00:00","relation":"discussion","confidence":null,"note":"@MalwareTechBlog"},{"id":59929,"url":"https://x.com/MalwareTechBlog/status/2117651234018767015","title":"@MalwareTechBlog: Would you look at that. Binance was hacked via phishing (Contagious Interview), ","kind":"post","source":"x","publisher":null,"text":"Would you look at that. Binance was hacked via phishing (Contagious Interview), not zero-day exploits written by abliterated AI models. Exactly as I predicted. \n\nI may shitpost a lot, but I do actually know some things about some stuff. https://t.co/yrBR3yIHz9 https://t.co/W1qxR6v27T\n\nlikes 650 reposts 83","published_at":"2026-11-03T16:12:52+00:00","relation":"discussion","confidence":null,"note":"@MalwareTechBlog"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}