Axios가 NPM에서 침해되어 원격 접근 트로이목마가 배포됨

1 day ago 4
  • 널리 사용되는 axios HTTP 클라이언트의 두 악성 버전이 npm에 게시되어, 설치 시 원격 접근 트로이목마(RAT) 를 배포함
  • 공격자는 유지관리자 계정 자격 증명 탈취를 통해 GitHub Actions를 우회하고 수동으로 악성 패키지를 업로드함
  • 악성 버전은 가짜 의존성 plain-crypto-js@4.2.1 을 포함해, postinstall 스크립트로 RAT를 설치하고 흔적을 삭제함
  • RAT는 macOS, Windows, Linux를 모두 감염시키며, C2 서버(sfrclak.com:8000)와 통신해 추가 페이로드를 다운로드함
  • npm과 GitHub이 신속히 악성 버전을 제거했으나, 공급망 보안 강화와 자격 증명 보호의 중요성이 다시 부각됨

axios npm 공급망 공격 개요

  • 2026년 3월 31일, 널리 사용되는 axios HTTP 클라이언트 라이브러리의 두 악성 버전(axios@1.14.1, axios@0.30.4)이 npm에 게시됨
  • 공격자는 axios 주요 유지관리자의 npm 자격 증명을 탈취해 GitHub Actions CI/CD 파이프라인을 우회하고 수동으로 악성 패키지를 게시함
  • 두 버전 모두 plain-crypto-js@4.2.1 이라는 가짜 의존성을 삽입, 이 패키지는 postinstall 스크립트를 통해 원격 접근 트로이목마(RAT) 를 설치함
  • RAT는 macOS, Windows, Linux를 모두 대상으로 하며, C2(Command and Control) 서버(sfrclak.com:8000)와 통신해 2단계 페이로드를 내려받음
  • 설치 후 악성 코드와 흔적을 삭제하고 깨끗한 package.json으로 교체해 포렌식 탐지를 회피

공격 타임라인

  • 3월 30일 05:57 UTC: plain-crypto-js@4.2.0(정상 버전) 게시
  • 3월 30일 23:59 UTC: plain-crypto-js@4.2.1(악성 버전) 게시, postinstall 훅 추가
  • 3월 31일 00:21 UTC: axios@1.14.1 게시, 악성 의존성 삽입
  • 3월 31일 01:00 UTC: axios@0.30.4 게시, 동일한 악성 의존성 삽입
  • 3월 31일 03:15 UTC: npm이 두 악성 버전 삭제
  • 3월 31일 04:26 UTC: npm이 plain-crypto-js를 보안 홀더 스텁(0.0.1-security.0)으로 대체

axios 개요

  • axios는 JavaScript 생태계에서 가장 널리 사용되는 HTTP 클라이언트로, Node.js와 브라우저 모두에서 사용됨
  • 주간 다운로드 3억 회 이상으로, 단 한 번의 악성 릴리스도 광범위한 피해 가능성을 가짐
  • 일반 개발자는 npm install 시 악성 코드 설치를 인지하기 어려움

공격 단계

  • 1단계 — 유지관리자 계정 탈취

    • 공격자는 jasonsaayman npm 계정을 탈취하고 이메일을 ifstap@proton.me로 변경
    • 이후 1.x와 0.x 릴리스 브랜치 모두에 악성 빌드를 게시
    • 정상 릴리스는 GitHub Actions의 OIDC Trusted Publisher를 통해 게시되지만, axios@1.14.1은 수동 게시로 gitHead와 OIDC 서명이 없음
    • 공격자는 장기 유효한 npm 액세스 토큰을 이용한 것으로 추정됨
  • 2단계 — 악성 의존성 사전 배포

    • plain-crypto-js@4.2.1은 nrwise@proton.me 계정에서 게시됨
    • crypto-js를 위장하며 동일한 설명과 저장소 URL 사용
    • "postinstall": "node setup.js" 훅을 포함해 설치 시 자동 실행
    • 공격 후 package.md를 package.json으로 교체해 증거 삭제 준비
  • 3단계 — axios에 의존성 삽입

    • plain-crypto-js@^4.2.1을 런타임 의존성으로 추가
    • 코드 내에서는 한 번도 import되지 않음 → 유령 의존성(phantom dependency)
    • npm install 시 자동 설치되어 postinstall 스크립트 실행

RAT 드로퍼(setup.js) 분석

  • 난독화 기법

    • 문자열을 배열 stq[]에 암호화 저장하고 _trans_1(XOR)과 _trans_2(Base64+역순)로 복호화
    • C2 URL은 http://sfrclak.com:8000/6202033
    • 복호화된 문자열에는 OS 식별자(win32, darwin), 파일 경로, 쉘 명령 등이 포함
  • 플랫폼별 페이로드

    • macOS

      • AppleScript를 /tmp에 작성 후 osascript로 실행
      • C2에서 RAT 바이너리를 받아 /Library/Caches/com.apple.act.mond에 저장 및 실행
      • 파일명은 Apple 시스템 데몬처럼 위장
    • Windows

      • PowerShell 경로 탐색 후 %PROGRAMDATA%\wt.exe로 복사
      • VBScript를 통해 C2에서 PowerShell RAT 다운로드 및 실행
      • 임시 파일(.vbs, .ps1)은 실행 후 삭제
    • Linux

      • curl로 /tmp/ld.py 다운로드 후 nohup python3으로 실행
      • /tmp/ld.py 파일이 남음
      • 세 플랫폼 모두 packages.npm.org/product0~2 POST 바디를 사용해 정상 npm 트래픽처럼 위장
  • 자기 삭제 및 은폐

    • setup.js와 package.json 삭제
    • package.md를 package.json으로 교체해 정상 패키지로 위장
    • 이후 npm audit이나 수동 검토로는 탐지 불가
    • 단, node_modules/plain-crypto-js/ 존재 자체가 감염 증거

StepSecurity Harden-Runner를 통한 실행 검증

  • Harden-Runner는 GitHub Actions에서 네트워크·프로세스·파일 이벤트를 실시간 기록
  • axios@1.14.1 설치 시 두 번의 C2 연결(curl, nohup)이 감지됨
    • 첫 번째 연결은 npm install 시작 2초 후 발생
    • 두 번째 연결은 36초 후, 백그라운드 프로세스로 지속 실행
  • 프로세스 트리 분석 결과, nohup 프로세스가 PID 1(init) 에 고아 프로세스로 남아 지속 실행 확인
  • 파일 이벤트 로그에서 package.json이 두 번 덮어써짐
    • 첫 번째: 설치 중 악성 버전 작성
    • 두 번째: 36초 후 깨끗한 스텁으로 교체

침해 지표(IOC)

  • 악성 npm 패키지

    • axios@1.14.1 · shasum: 2553649f232204966871cea80a5d0d6adc700ca
    • axios@0.30.4 · shasum: d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71
    • plain-crypto-js@4.2.1 · shasum: 07d889e2dadce6f3910dcbc253317d28ca61c766
  • 네트워크

  • 파일 경로

    • macOS: /Library/Caches/com.apple.act.mond
    • Windows: %PROGRAMDATA%\wt.exe
    • Linux: /tmp/ld.py
  • 공격자 계정

    • jasonsaayman (탈취된 유지관리자)
    • nrwise (공격자 생성 계정)
  • 안전 버전

    • axios@1.14.0 (정상)

영향 확인 및 대응 절차

  • npm list axios 또는 package-lock.json에서 1.14.1 / 0.30.4 확인
  • node_modules/plain-crypto-js 존재 여부 확인
  • OS별 RAT 파일 존재 시 시스템 완전 감염으로 간주
  • CI/CD 로그에서 해당 버전 설치 이력 확인 후 모든 비밀키·토큰 교체 필요

복구 단계

  1. axios를 안전 버전(1.14.0 또는 0.30.3) 으로 고정
  2. plain-crypto-js 폴더 삭제 후 npm install --ignore-scripts 재설치
  3. RAT 흔적 발견 시 시스템 재구축
  4. 모든 자격 증명(AWS, SSH, CI/CD 등) 회전
  5. CI/CD 파이프라인 점검 및 비밀키 교체
  6. 자동 빌드 시 --ignore-scripts 옵션 사용
  7. C2 도메인/IP를 방화벽 또는 /etc/hosts로 차단

StepSecurity Enterprise 기능

  • Harden-Runner

    • GitHub Actions에서 네트워크 송신 화이트리스트 적용
    • 비정상 트래픽 차단 및 로그 기록
    • sfrclak.com:8000 연결을 사전 차단 가능
  • Dev Machine Guard

    • 개발자 PC에서 설치된 npm 패키지 실시간 모니터링
    • axios@1.14.1, 0.30.4 설치된 장비 즉시 탐지
  • npm Package Cooldown Check

    • 새로 게시된 패키지에 일시적 설치 차단 기간 적용
    • plain-crypto-js@4.2.1과 같은 신속한 악성 게시 탐지 가능
  • Compromised Updates Check

    • 실시간 악성 패키지 DB 기반으로 PR 병합 차단
    • axios@1.14.1, plain-crypto-js@4.2.1 즉시 등록
  • Package Search

    • 조직 전체 PR 및 저장소에서 특정 패키지 도입 위치 검색
    • 영향 범위(레포지토리, 팀, PR) 즉시 파악
  • AI Package Analyst

    • npm 레지스트리 실시간 모니터링 및 행동 기반 악성 탐지
    • 두 악성 버전 모두 게시 후 수분 내 탐지
  • Threat Center Alert

    • 공격 요약, IOC, 대응 절차 포함한 위협 인텔 알림 제공
    • SIEM 연동을 통한 실시간 가시성 확보

감사

  • axios 유지관리자 및 커뮤니티가 GitHub issue #10604를 통해 신속히 대응
  • GitHub은 탈취된 계정을 정지하고 npm은 악성 버전 삭제 및 보안 홀더 적용
  • 유지관리자·GitHub·npm 간 협력 대응으로 전 세계 개발자 피해 최소화
Read Entire Article