Axios npm 하이재킹: 북한이 주간 1억 다운로드 라이브러리에 RAT를 심은 3시간
Axios npm 공급망 공격 분석. 북한 UNC1069가 메인테이너를 사회공학으로 속여 주간 1억 다운로드 라이브러리에 RAT를 심은 3시간의 기록. 가짜 Teams 미팅부터 WAVESHAPER.V2 RAT까지.
Axios npm 공급망 공격 분석. 북한 UNC1069가 메인테이너를 사회공학으로 속여 주간 1억 다운로드 라이브러리에 RAT를 심은 3시간의 기록. 가짜 Teams 미팅부터 WAVESHAPER.V2 RAT까지.
2026년 3월 31일 00시 21분(UTC), npm 레지스트리에 axios@1.14.1이 올라왔다. 주간 다운로드 1억 건, 의존 패키지 17만 4,000개인 JavaScript 라이브러리다. 22분 뒤 axios@0.30.4도 올라왔다.
두 버전 모두 latest 태그가 붙었다. 이 시점부터 npm install axios를 실행한 모든 개발자의 머신에 북한 RAT가 설치되기 시작했다.
3시간 뒤 npm이 두 버전을 삭제했다. 하지만 Google Threat Intelligence Group(GTIG)은 "수십만 개의 도난된 비밀(시크릿)이 유통되고 있을 수 있다"고 경고했다. 역사상 가장 큰 blast radius를 가진 npm 공급망 공격이었다.
공격자는 코드를 해킹하지 않았다. 사람을 해킹했다.
UNC1069(북한 연계 위협 행위자)는 Axios의 주요 메인테이너 Jason Saayman을 표적으로 삼았다. 공격은 수 주 전부터 준비됐다.
1단계는 가짜 Slack 워크스페이스였다. 실제 회사의 브랜딩과 창업자 신원을 복제했다. 워크스페이스 안에는 채널별 대화, 다른 오픈소스 메인테이너를 가장한 프로필, LinkedIn 포스트 공유까지 준비되어 있었다. Saayman은 이를 "super convincing"이라고 표현했다.
2단계는 가짜 Teams 미팅이었다. 다자 통화처럼 보이는 화면에서 "시스템 컴포넌트가 오래됐다"는 가짜 에러 메시지가 떴다. Saayman에게 "Teams 업데이트"를 설치하라고 유도했다. 이 업데이트가 WAVESHAPER 악성코드(RAT)였다.
3단계는 크리덴셜 탈취였다. RAT로 원격 접근 권한을 확보한 뒤, Saayman의 npm 클래식 액세스 토큰을 추출했다. MFA가 설정되어 있었지만, 이미 인증된 세션에서 토큰을 가져갔으므로 우회됐다. 공격자는 npm 계정의 등록 이메일을 ifstap@proton.me로 변경했다.
공격자는 plain-crypto-js@4.2.1이라는 패키지를 미리 만들었다. 56개의 정상 파일은 실제 crypto-js@4.2.0과 바이트 단위로 동일했다. 다른 것은 3개 파일뿐이었다.
package.json — postinstall 훅 추가setup.js — 4.2KB 난독화된 드로퍼package.md — 안티포렌식 위장용axios@1.14.1과 axios@0.30.4의 package.json에 "plain-crypto-js": "^4.2.1" 의존성을 추가했다. npm install axios를 실행하면 plain-crypto-js가 함께 설치되고, postinstall 스크립트가 자동 실행됐다.
setup.js는 XOR 키 "OrDeR_7077"과 Base64 디코딩(문자 역전)의 2중 난독화를 사용했다. 복호화된 C2 URL은 http://sfrclak.com:8000/6202033이었다.
운영체제별로 다른 경로에 페이로드를 다운로드했다.
| OS | 드롭 경로 | 실행 방식 |
|---|---|---|
| macOS | /Library/Caches/com.apple.act.mond | AppleScript + /bin/zsh |
| Windows | %PROGRAMDATA%\wt.exe | VBScript → PowerShell (숨겨진 창) |
| Linux | /tmp/ld.py | nohup python3 |
Windows에서 PowerShell을 wt.exe로 복사한 것은 Windows Terminal로 위장하기 위한 것이다. %PROGRAMDATA% 경로는 재설치 후에도 유지된다.
드로퍼는 실행 후 3단계 정리를 수행했다. 먼저 setup.js 자체를 삭제했다. 다음으로 악성 package.json(postinstall 훅 포함)을 삭제했다.
마지막으로 package.md를 package.json으로 이름을 바꿨다. 이 파일은 버전 4.2.0으로 보고하며 스크립트가 없다. npm list를 실행해도 정상 버전으로 표시된다.
드로퍼가 다운로드한 RAT의 기능은 다음과 같다.
| 시각 (UTC) | 사건 |
|---|---|
| 3/30 05:57 | plain-crypto-js@4.2.0 발행 (정상 미끼) |
| 3/30 23:59 | plain-crypto-js@4.2.1 발행 (악성) |
| 3/31 00:21 | axios@1.14.1 발행 (악성) |
| 3/31 00:43 | axios@0.30.4 발행 (악성) |
| 3/31 ~03:15 | npm이 두 버전 삭제 |
| 3/31 04:26 | plain-crypto-js 보안 스텁으로 교체 |
| 4/1 | Google GTIG, UNC1069 공식 귀속 발표 |
악성코드가 latest 태그로 약 2시간 54분간 노출됐다. StepSecurity의 Harden-Runner는 npm install 후 2초 만에 C2 접속을 감지했다.
GTIG가 UNC1069(북한 연계)로 귀속한 근거는 4가지다.
sfrclak.com(IP: 142.11.206.73)이 이전 UNC1069 작전에 사용된 AstrillVPN 노드와 연결된다.Axios 하이재킹은 빙산의 일각이다. Socket은 4월 7일, 단일 위협 행위자 클러스터가 5개 생태계에 동시에 악성 패키지를 배포하고 있다고 공개했다.
| 생태계 | 악성 패키지 예시 |
|---|---|
| npm | dev-log-core, logger-base, logkitx |
| PyPI | logutilkit, apachelicense, fluxhttp |
| Go | github.com/golangorg/formstash |
| Rust | logtrace |
| PHP | golangorg/logkit |
Contagious Interview 캠페인은 원래 가짜 채용 면접으로 개발자를 속이는 방식이었다. 이제 피해자와 직접 대화할 필요 없이 레지스트리에 독을 뿌리는 방식으로 진화했다. npm을 "재생 가능한 초기 접근 채널"로 취급하고 있다.
| 사건 (연도) | 노출 시간 | 주간 다운로드 |
|---|---|---|
| event-stream (2018) | 수 개월 | ~200만 |
| ua-parser-js (2021) | 수 시간 | ~700만 |
| Axios/UNC1069 (2026) | ~3시간 | 1억+ |
| 패키지 | 해시 |
|---|---|
axios@1.14.1 | 2553649f2322049666871cea80a5d0d6adc700ca |
axios@0.30.4 | d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71 |
plain-crypto-js@4.2.1 | 07d889e2dadce6f3910dcbc253317d28ca61c766 |
| 타입 | 값 | 맥락 |
|---|---|---|
| Domain | sfrclak.com | C2 서버 |
| IP | 142.11.206.73 | C2 IP |
| Port | 8000 | C2 포트 |
| URL | http://sfrclak.com:8000/6202033 | 드로퍼 페이로드 URL |
| OS | 경로 |
|---|---|
| macOS | /Library/Caches/com.apple.act.mond |
| Windows | %PROGRAMDATA%\wt.exe |
| Linux | /tmp/ld.py |
감염 확인:
axios@1.14.1 또는 axios@0.30.4가 package-lock.json에 있는지 확인한다. 있다면 해당 머신은 완전 침해된 것으로 간주해야 한다.
즉시 조치:
axios@1.7.7(1.x) 또는 axios@0.28.0(0.x)으로 다운그레이드한다package-lock.json과 node_modules를 삭제하고 재설치한다예방:
--ignore-scripts 플래그로 postinstall 훅을 차단한다AI 활용 안내 이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 인용된 통계와 사례는 참고 자료에 명시된 출처에 근거하며, 설명을 위한 일부 표현은 각색되었습니다.
면책 조항 본 글은 보안 인식 제고를 위한 교육 목적으로 작성되었습니다. 언급된 공격 기법을 실제로 시도하는 행위는 「정보통신망법」, 「형법」 등에 따라 처벌받을 수 있으며, 본 블로그는 이에 대한 법적 책임을 지지 않습니다.
KW_PROTECT_0