- 북한 Sapphire Sleet가 2026-06-17 Mastra npm 메인테이너 계정을 탈취해 약 88분간 140개+ 패키지를 오염
- 가짜 의존성 `easy-day-js` 한 줄 + postinstall 훅으로 166개 암호화폐 지갑 익스텐션을 노린 다단계 스틸러 실행
- 패키지를 직접 쓰지 않는 빌드 서버도 `npm install`만으로 감염 — 의존성 트리에 이름만 있어도 트리거돼 탐지가 어렵다

북한 위협 행위자 Sapphire Sleet가 AI 프레임워크 Mastra npm 저장소를 침투해 140개 패키지에 악성코드를 심고 166개 암호화폐 지갑 익스텐션을 표적으로 삼은 2026년 6월 공급망 공격 분석.

북한 Sapphire Sleet, Mastra npm 패키지 140개 오염해 개발자 암호화폐 탈취
2026년 6월 17일 새벽 1시 20분(UTC), AI 에이전트 프레임워크 Mastra의 npm 저장소에 조용한 변화가 일어났다. 정규 버전 업데이트처럼 보이는 1.13.1 릴리스가 배포됐고, 그 안에는 개발자 컴퓨터의 암호화폐 지갑 166개를 동시에 노리는 다단계 악성코드가 숨어 있었다. 장악된 관리자 계정 하나, 의존성 한 줄 추가, 그리고 단 19분. 그것으로 @mastra 스코프 전체 140개 패키지가 무기화됐다.
Sapphire Sleet는 2020년부터 추적되는 북한 국가 연계 위협 행위자다. 미국·아시아·중동의 금융·암호화폐·블록체인 기업을 주요 표적으로 삼아 국가 자금 조달을 위한 암호화폐 탈취에 집중한다. 보안 업계에서는 BlueNoroff, UNC1069, STARDUST CHOLLIMA 등의 이름으로도 추적된다.
이 그룹이 소프트웨어 공급망 채널을 택한 것은 이번이 처음이 아니다. 2026년 4월, Sapphire Sleet는 주간 1억 건 이상 다운로드되는 JavaScript HTTP 클라이언트 Axios의 npm 패키지를 오염시킨 전례가 있다. Axios 공격 이후에도 이 채널이 반복 사용됐다는 사실 자체가, 성공 여부와 무관하게 npm 공급망이 이 그룹에게 운영 패턴으로 정착했음을 보여준다.
공격 설계는 정밀했다. 공격자는 npm 생태계의 신뢰 구조, 즉 관리자 계정 권한과 시맨틱 버전 자동 업데이트 규칙을 동시에 역이용했다.
6월 16일 오전 7시 5분, 공격자 계정(sergey2016@tutamail.com)은 easy-day-js@1.11.21을 npm에 등록했다. 주간 5,700만 건 다운로드를 기록하는 정규 라이브러리 dayjs와 이름이 유사한 이 패키지는 처음에는 완전히 무해한 미끼였다. 탐지를 피하기 위한 평판 세탁이었다.
다음 날 새벽 1시 1분, 같은 계정에서 easy-day-js@1.11.22가 등록됐다. 이번에는 달랐다. 4,572바이트의 난독화된 드로퍼가 내장돼 있었다. 그리고 19분 후인 1시 20분, 공격자는 이미 장악해 둔 Mastra 메인테이너 계정 ehindero를 이용해 패키지 업데이트를 시작했다. 이때부터 약 88분 동안 mastra@1.13.1을 포함한 140개 이상의 @mastra 패키지가 잇따라 오염된 버전으로 교체됐고, 모두 latest 태그를 받았다. ehindero는 권한이 회수되지 않은 채 남아 있던 옛 기여자 계정이었으며, 어떤 방법으로 탈취됐는지는 아직 공개되지 않았다. 변경 내용은 단 하나, "easy-day-js": "^1.11.21" 의존성 한 줄 추가였다.
npm의 시맨틱 버전 레인지 규칙상 ^1.11.21은 최신 패치 버전인 1.11.22를 자동으로 가리키게 돼 있었다. 이후 어느 개발자든 npm install을 실행하는 순간, 악성 드로퍼가 node setup.cjs --no-warnings postinstall 훅을 통해 자동 실행됐다. postinstall 훅은 패키지 설치 완료 직후 npm이 자동으로 호출하는 스크립트로, 별도 코드 실행 없이 설치 행위만으로 트리거된다.
드로퍼는 세 단계로 확장됐다. 첫 단계에서 TLS 인증서 검증을 비활성화한 채 C2 서버에 연결하고 약 41KB 규모의 크로스플랫폼 Node.js 태스킹 클라이언트를 내려받았다. 두 번째 단계에서는 운영체제별로 영속성을 확보했다. Windows는 레지스트리 Run 키(NvmProtocal)에, macOS는 LaunchAgent 설정 파일에, Linux는 systemd 유닛에 임플란트를 심었다. 세 번째 단계에서는 Windows 환경에 한해 별도 C2 인프라에서 PowerShell 백도어를 내려받아 메모리에서 실행하고, PSReadLine 명령 기록을 삭제해 흔적을 지웠다.
페이로드의 최종 표적은 암호화폐였다. MetaMask, Phantom, Coinbase, Binance를 포함해 166개의 브라우저 암호화폐 지갑 익스텐션 ID가 하드코딩돼 있었다. 여기에 더해 Chrome·Edge·Brave의 히스토리 SQLite 데이터베이스, 실행 중인 프로세스 목록, API 키, 환경 변수도 C2로 전송됐다.
피해 범위는 단순히 개발자 개인에 그치지 않는다. postinstall 훅은 코드에서 패키지를 import했을 때가 아니라 설치되는 순간 실행된다. 따라서 CI/CD 파이프라인에서 npm install이 실행되는 빌드 서버라면, @mastra 패키지를 실제로 사용하지 않아도 의존성 트리 어딘가에 이름이 있는 것만으로 드로퍼가 동작했다. 빌드 서버에는 개발자 개인 PC보다 더 많은 API 키와 환경 변수가 집중돼 있는 경우가 많다.
Microsoft는 사고를 탐지하고 분석 결과를 공개하며 Defender 시그니처 4종(Trojan:JS/NpmStealz.Z!MTB 외)을 배포했고, 6월 19일 후속 분석에서 이 캠페인을 높은 신뢰도(high confidence)로 Sapphire Sleet에 귀속했다. 피해 개발자의 정확한 규모는 아직 공개되지 않았다.
이번 공격에서 Sapphire Sleet가 택한 핵심 전략은 "의존성 사슬 무기화"였다. 코드를 직접 수정하지 않고 신뢰받는 패키지 생태계에 가짜 라이브러리 한 줄을 심는 것만으로 140개 패키지를 동시에 오염시켰다. 관리자 계정 하나가 전체 스코프의 공격 표면이 된다는 것을 다시 보여준 사례다.
19분이라는 속도는 탐지 창이 사실상 없었다는 의미이기도 하다. npm 레지스트리가 패키지 이상 징후를 감지하고 대응하기 전에, 세계 어딘가의 빌드 서버에서 이미 npm install이 완료됐을 수 있다.
한국은 전 세계에서 암호화폐 거래 활동이 가장 활발한 시장 중 하나다. Sapphire Sleet의 표적 기준인 금융·크립토·DeFi 개발 환경과 국내 블록체인 스타트업 생태계가 교차하는 지점은 좁지 않다. npm 기반 프로젝트를 운용하는 개발팀이라면, 이번 사건의 공격 경로인 메인테이너 계정 보안과 postinstall 훅 실행 정책이 어떻게 설정돼 있는지 짚어볼 이유가 생겼다.
AI 활용 안내 이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 인용된 통계와 사례는 참고 자료에 명시된 출처에 근거하며, 설명을 위한 일부 표현은 각색되었습니다.
면책 조항 본 글은 보안 인식 제고를 위한 교육 목적으로 작성되었습니다. 언급된 공격 기법을 실제로 시도하는 행위는 「정보통신망법」, 「형법」 등에 따라 처벌받을 수 있으며, 본 블로그는 이에 대한 법적 책임을 지지 않습니다.