Critical · Active

PolinRider

DPRK 위협 행위자의 npm · GitHub · VS Code 다중 벡터 공급망 공격

OpenSourceMalware 가 추적 중인 활성 캠페인. Lazarus 산하 PolinRider 가 npm 패키지 · 가짜 면접 take-home 프로젝트 · 악성 VS Code 설정을 통해 개발자 PC 에 obfuscated JavaScript 페이로드를 주입하고, 블록체인 dead-drop C2 로 2 차 페이로드(Beavertail)를 호출한다.

최초 공개 2026-03-07 최종 갱신 2026-04-11 변종 2 개 활성 클러스터 PolinRider × TasksJacker × Contagious Interview

📊 Impact 통계

5 주만에 2.9 배 확산. 단일 오픈소스 프로젝트(Neutralinojs, 8.4k stars) 침해로 contributor 수백 명에 도미노 감염.

1,951
+1,276 (5주)
감염 repo
1,047
+695 (5주)
고유 owner
~930
개인 user
~117
조직
2
obfuscator 변종
4
주입 벡터
6+
C2 서브도메인
2+
무기화 template
핵심 변화 (4 월 업데이트) — PolinRider 와 TasksJacker 클러스터의 operational merger 가 확인됨. 101 개 temp_auto_push.bat 피해 중 22 개에서 악성 .vscode/tasks.json 동시 발견. 같은 행위자가 두 벡터를 같은 victim pool 에 동시 운영.

🗓 캠페인 타임라인

2026-03-07 · 초기 공개
OSM 1차 리포트
675 repos / 352 owners. 단일 변종 rmcej%otb%, 단일 벡터(config 파일 주입), 단일 C2 서브도메인(260120.vercel.app). Neutralinojs 침해 사례 분석으로 캠페인 가시화.
2026-03-13 · npm 대응
악성 패키지 takedown
npm 이 tailwind-mainanimation0.0.1-security placeholder 로 교체. allavin · blackedward publisher 계정 삭제. 단 victim 의 package.json 에는 ghost 참조 잔존.
2026-03-18 · 데이터 추가
affected_repos.csv 갱신
769 repos / 399 owners.
2026-04-10 · 2일 hunt 1차
신규 변종 + Vercel C2 5 개 발견
Cot%3t=shtP 변종 — 모든 unique fingerprint 가 rotation 됨 (YARA 룰 회피 의도). 5 개 신규 Vercel 서브도메인 식별. Cross-engine enumeration (GitHub Code Search + Sourcegraph) 으로 v3 master 에 1,556 repos 등록.
2026-04-11 · 2일 hunt 2차
PolinRider × TasksJacker 통합 확인
215 신규 repo 추가 → 누적 1,951 repos / 1,047 owners. ShoeVista · StakingGame 가짜 면접 템플릿 식별 (Contagious Interview playbook). 재감염 사례 발견: HassanHabibTahir/testclient 가 v1+v2 마커 동시 보유.

🎯 4 가지 감염 벡터

모두 동일 캠페인 산출물. 동일 victim 에 복수 벡터가 적용되기도 함.

1

Config 파일 주입

postcss.config.mjs (62%), tailwind.config.js, eslint.config.mjs, next.config.mjs, vite.config.*, webpack.config.js 등에 export default 뒤로 obfuscated JS 를 append.

빌드 시 자동 import → 무인 실행. 1,200+ repos 영향.

2

.vscode/tasks.json

runOn: folderOpen 으로 폴더 열자마자 curl | bash 실행. Vercel 호스팅 C2 가 PolinRider JS loader 를 다운로드.

TasksJacker 클러스터 — 27+ 직접 submission.

3

가짜 .woff2 폰트

public/fonts/fa-solid-400.woff2 등 바이너리 asset 으로 위장한 JS 페이로드. Node 가 import 가능한 경로에 배치되어 실행.

관측 사례 AgbaD/odoo. 단일 사례지만 detection bypass 신호.

4

악성 npm dependency

Tailwind/PostCSS 사칭 패키지. postinstall 시 project root config 파일에 페이로드 주입. 가짜 take-home 템플릿이 dependency 로 사전 탑재한 케이스도 있음.

7 패키지 확인 · 모두 publisher 계정 삭제됨.

🧬 2 종 obfuscator 변종 비교

아키텍처(4-layer shuffle cipher + 블록체인 dead-drop C2)는 동일. Apr 10 에 모든 unique fingerprint 가 rotation 됨 — 공개된 YARA 룰 회피 목적이 강력히 의심됨.

Attribute Original v1 New v2 (Apr 2026)
Signature markerrmcej%otb%Cot%3t=shtP
Shuffle seed (L1)28576871111436
Secondary seed (L2)26676863896884
Decoder fn name_$_1e42MDy
Globals injectedglobal['!'], ['r'], ['m']global['_V'], ['r'], ['m']
버전 태그'8-st1'..'8-st59'
블록체인 C2TRON / Aptos / BSC  unchanged
XOR keys동일  unchanged
현재 상태활성활성
재감염 확인HassanHabibTahir/testclient 가 두 변종 마커를 동시 보유. 공격자 도구가 기존 감염자 host 에 재실행됨. 한 번 청소된 repo 가 깨끗하다고 가정하지 말 것.

📡 C2 인프라

Vercel 호스팅 HTTP C2 (TasksJacker 벡터)

URL 패턴: https://<sub>.vercel.app/settings/(mac|linux|win)?flag=<N>

SubdomainHits (Apr 11)First seenNotes
260120.vercel.app56pre-Mar 8원조 (Q11 쿼리)
default-configuration.vercel.app106Apr 2026현 최대 클러스터
vscode-settings-bootstrap.vercel.app16Apr 2026
vscode-settings-config.vercel.app11Apr 2026
vscode-bootstrapper.vercel.app6Apr 2026
vscode-load-config.vercel.app6Apr 2026

블록체인 dead-drop (2 차 페이로드)

T

TRON (Primary)

TMfKQEd7TJJa5xNZJZ2Lep838vrzrs7mAP

TXfxHUet9pJVU1BgVkBAbrES4YUc1nGzcG

api.trongrid.io/v1/accounts

A

Aptos (Fallback)

0xbe037400670fbf1c32364f762975908dc43eeb38759263e7dfcdabc76380811e

0x3f0e5781d0855fb460661ac63257376db1941b2bb522499e4757ecb3ebd5dce3

fullnode.mainnet.aptoslabs.com

B

BSC (보조)

bsc-dataseed.binance.org

bsc-rpc.publicnode.com

eth_getTransactionByHash

K

XOR keys

Primary

2[gWfGj;<:-93Z^C

Secondary

m6:tTh^D)cBz?NM]

왜 블록체인인가 — 트랜잭션은 immutable 이라 takedown 이 사실상 불가능. loader 는 TRON → Aptos → BSC 순으로 fallback 하며 암호화된 2 차 페이로드(Beavertail infostealer 신 버전)를 가져와 eval().

🎭 가짜 면접 take-home 템플릿

Contagious Interview playbook — 가짜 채용 담당자가 후보자에게 보내는 사전감염 코딩 테스트.

SV

ShoeVista  34+ victims

Stack · MERN (React + Express)

Vector · client/package.jsontailwindcss-style-animate ^1.1.6

Naming · ShoeVista, shoevista-rifat, Test-west-shoe, Test-002, product-catalog, mern-app …

2026-02 ~ 03 생성, 0 stars / 0 forks, 1 년 미만 throwaway 계정. 후보자가 repo 이름을 회사명·플랫폼 기반으로 명명.

SG

StakingGame  42+ victims

Theme · 블록체인/staking-game 개발자 평가 — Web3 후보자 타겟

Vector · 무기화된 .vscode/tasks.json + runOn: folderOpen

UUID · e9b53a7c-2342-4b15-b02d-bd8b8f6a03f9 (불변, false positive 0)

예시 victim: Devba/lmng-top-, wyrustaaruz/cal-eco-platform.

핵심 함의 — npm 공급망 공격이 아니라 채용시장 소셜 엔지니어링이다. victim 은 기존 감염자가 아닌 신규 후보자 계정. 헌터는 test-*, *-interview, *-assessment 네이밍 패턴을 추가 heuristic 으로 사용해야 한다.

📦 악성 npm 패키지

전부 Tailwind/PostCSS 사칭. allavin · blackedward 등 publisher 계정 모두 삭제. ghost 참조는 package.json 에 잔존.

Package Version Status Publisher Victims (Apr 11)
tailwindcss-style-animate1.1.6observed(deleted)34
tailwind-mainanimation2.3.3 → 0.0.1-securitytaken downallavin1
tailwind-autoanimation2.3.6removedblackedward2
tailwindcss-typography-style0.8.2observed(deleted)6
tailwindcss-style-modify0.8.3observed(deleted)4
tailwindcss-animate-style1.2.5observed(deleted)0
tailwind-animationbasedobserved(deleted)0

🪟 temp_auto_push.bat — git history 위조 도구

공격자가 감염 머신 101 곳에 leftover 로 남긴 Windows 배치. JS 페이로드가 청소되어도 이 파일 자체가 과거 침해의 직접 증거.

@echo off
:: 1) 마지막 commit 의 metadata 추출
for /f "delims=" %%A in ('git log -1 --format=%%cd') do set LAST_COMMIT_DATE=%%A
...

:: 2) Windows 시스템 시계를 last commit 시점으로 변경
date %LAST_COMMIT_DATE%
time %LAST_COMMIT_TIME%

:: 3) author 위장 후 amend — 시계가 과거이므로 timestamp 보존됨
git config --local user.name %USER_NAME%
git config --local user.email %USER_EMAIL%
git add .
git commit --amend -m "%LAST_COMMIT_TEXT%" --no-verify

:: 4) 시계 복구 후 force push (--no-verify 로 hook 우회)
date %CURRENT_DATE%
git push -uf origin %CURRENT_BRANCH% --no-verify

Windows 시계 변경엔 관리자 권한 필요. force-push 로 remote history 덮어쓰기. 두 --no-verify 로 CI/pre-commit hook 완전 우회. 결과 — author · timestamp · 메시지가 원본과 동일한 위조 commit. 평범한 git log 검사로 탐지 불가.

🔍 YARA 룰 — 두 변종 동시 탐지

rule polinrider_payload {
    meta:
        description = "PolinRider shuffle-cipher — v1 rmcej%otb% + v2 Cot%3t=shtP"
        author      = "OpenSourceMalware.com"
        date        = "2026-04-10"
        severity    = "high"

    strings:
        // v1 fingerprints
        $marker_v1   = "rmcej%otb%"
        $seed1_v1    = "2857687"
        $seed2_v1    = "2667686"
        $varname_v1  = "_$_1e42"
        $global_bang = "global['!']"

        // v2 fingerprints (rotated, Apr 2026)
        $marker_v2   = "Cot%3t=shtP"
        $seed1_v2    = "1111436"
        $seed2_v2    = "3896884"
        $varname_v2  = "MDy"
        $global_V    = "global['_V']"

        // 공통
        $global_r    = "global['r'] = require"
        $global_m    = "global['m'] = module"

    condition:
        any of ($marker_*) or
        ($global_bang and ($seed1_v1 or $varname_v1)) or
        ($global_V    and ($seed1_v2 or $varname_v2)) or
        ($global_r and $global_m and (any of ($seed1_*)))
}

🚨 Incident Response 체크리스트

감염 의심 시 즉시

크리덴셜 로테이션

네트워크 차단

지속 모니터링