COMMENTS (0)
댓글은 익명으로 작성되며, 삭제 비밀번호를 설정하면 본인만 삭제할 수 있습니다. 비밀번호를 설정하지 않은 댓글은 누구나 삭제할 수 있습니다.
TeamPCP가 공개한 Shai-Hulud 악성코드 소스가 유출 5일 만에 npm 4개 패키지에 삽입됐다. 개발자 환경의 클라우드 자격 증명과 GitHub 토큰을 탈취하는 공급망 공격의 전개를 분석한다.
댓글은 익명으로 작성되며, 삭제 비밀번호를 설정하면 본인만 삭제할 수 있습니다. 비밀번호를 설정하지 않은 댓글은 누구나 삭제할 수 있습니다.
2026년 5월 18일, npm 레지스트리를 통해 배포된 4개 패키지가 사흘 만에 2,678회 설치됐다. 설치한 개발자 대부분은 chalk나 axios의 오기(typo)를 알아채지 못했고, 그 시간 동안 자신의 클라우드 자격 증명과 SSH 개인 키가 외부로 빠져나갔다. 이 패키지들의 공통점은 하나다. 6일 전 GitHub에 무료로 공개된 악성코드 Shai-Hulud를 검수 없이 그대로 복사했다는 것.
2026년 5월 12일, 위협 행위자 그룹 TeamPCP는 자신들이 제작한 악성코드 Shai-Hulud의 전체 소스코드를 GitHub에 공개했다. 공개 제목은 "A Gift From TeamPCP"였고, 코드에는 배포 지침과 함께 탐지 우회 기술이 내장돼 있었다. 닷새 후, 별도의 공격자가 이 코드를 검수 없이 그대로 복사해 4개의 악성 npm 패키지를 게시했고, 사흘 동안 2,678회의 설치가 이뤄졌다.
Shai-Hulud는 TypeScript와 Bun 런타임 기반으로 제작된 모듈형 자격 증명 탈취 도구다. 개발자 환경에서 수집하는 데이터의 범위는 다음과 같다:
자격 증명 탐지 도구 TruffleHog가 파일시스템 전체를 스캔하며 위 항목을 수집한다. 수집된 데이터는 실시간 전송용 C2 서버와, 탈취한 GitHub 토큰으로 자동 생성한 공개 레포지터리 두 채널로 외부에 노출된다. 레포지터리는 저장소 역할 외에 피해자의 토큰을 이용해 새로운 악성 패키지를 게시하는 권한으로도 전용된다.
TeamPCP는 이번이 첫 등장이 아니다. 이미 Trivy 보안 스캐너 76개 태그를 무기화한 5일짜리 공급망 침해 사건의 행위자로 기록된 그룹이다. 코드를 유출하기 하루 전인 5월 11일에도 대규모 공급망 공격을 감행했다. 당시 84개의 악성 버전을 6분 이내에 npm에 게시했으며, 주간 수백만 건이 다운로드되는 @tanstack/react-router를 포함해 400개 이상의 패키지가 오염됐다. 5월 11일 직접 공격의 흔적은 이후 GitHub에서 발견된 1,000개 이상의 레포지터리에 남았다. 각 레포지터리에는 "A Mini Shai-Hulud has Appeared"라는 서명이 공통으로 기록돼 있었다.
소스코드가 GitHub에 공개된 순간, 공격 진입 장벽이 사라졌다. TypeScript 개발 환경만 있으면 별도 악성코드 작성 없이 즉시 재배포가 가능한 상태였다. 닷새는 새로운 공격자가 코드를 발견하고 npm 계정을 만들어 패키지 4개를 게시하기에 충분한 시간이었다.
5월 18일, npm 사용자 "deadcode09284814"는 TeamPCP의 코드를 재사용해 4개의 악성 패키지를 배포했다. 패키지명은 모두 인기 라이브러리를 오기(typosquatting)한 형태였다.
| 패키지명 | 다운로드 수 | 주요 페이로드 |
|---|---|---|
| chalk-tempalte | 825 | Shai-Hulud 인포스틸러 |
| @deadcode09284814/axios-util | 284 | SSH 키·클라우드 자격 증명 탈취 |
| axois-utils | 963 | 인포스틸러 + Phantom Bot DDoS |
| color-style-utils | 934 | 암호화폐 지갑·시스템 정보 탈취 |
설치가 시작되는 순간, npm install이 완료되기 전에 preinstall 스크립트가 자동 실행된다. 설치 자체가 실패하더라도 스크립트는 이미 실행을 마친 상태가 된다.
chalk-tempalte에서 GitHub 토큰이 탈취된 시스템에서는 "A Mini Shai-Hulud has Appeared"라는 설명이 달린 공개 레포지터리가 자동 생성됐다. 탈취된 토큰은 수집된 자격 증명의 저장소이자 동시에 추가 악성 패키지를 게시할 권한으로도 활용됐다.
axois-utils는 인포스틸러 외에 Golang으로 작성된 Phantom Bot DDoS 봇넷을 함께 탑재했다. Windows 시작 폴더와 예약 작업에 자신을 등록해 npm 패키지를 삭제한 뒤에도 시스템에서 계속 실행되며, 감염 시스템을 HTTP·TCP·UDP 플러딩 공격 인프라에 편입시킨다.
공개된 소스코드에는 탐지 우회를 위한 흔적도 포함됐다. 모든 커밋 날짜가 2099년 1월 1일로 위조돼 있어 일반적인 타임스탬프 기반 탐지를 무력화하도록 설계됐다.
copycat 4개 패키지만으로 총 2,678회의 설치가 발생했다. 각 감염 시스템에서 클라우드 자격 증명, SSH 개인 키, 환경 변수 파일이 유출됐으며, GitHub 토큰이 탈취된 경우 새로운 악성 패키지 게시로 이어지는 연쇄 감염이 뒤따랐다.
copycat의 규모(2,678회·4 패키지)는 5월 11일 직접 공격(400개+ 패키지 오염)과 비교하면 작다. 그러나 차단 비용이 다르다. 5월 11일은 TeamPCP 인프라 한 곳을 막으면 됐다. 5월 18일 이후는 GitHub에서 소스를 본 누구라도 새 npm 계정 하나로 같은 공격을 재시작할 수 있다. 한국 환경에서도 npm은 전 세계 공통 의존성 채널이므로 동일한 typosquatting이 통한다.
Shai-Hulud 캠페인은 공급망 공격의 패턴 변화를 두 측면에서 보여준다.
첫째, 악성코드의 오픈소스화다. 코드가 공개되는 순간, 별도의 개발 역량 없이도 누구든 새로운 캠페인을 즉시 시작할 수 있다. 유출 후 5일 만에 copycat이 등장한 이번 사례는 그 전환 속도를 실증했다. MITRE ATT&CK의 T1195.001(공급망 의존성 침해) 기법은 이제 전문 공격 그룹의 전유물이 아니게 됐다.
둘째, 공급망이 공격 수단인 동시에 결과물이 되는 구조다. chalk-tempalte 하나가 GitHub 토큰을 빼가고, 그 토큰이 다시 새로운 악성 패키지를 게시하는 권한이 됐다. 2,678회라는 설치 수치 뒤에 이 자기 증폭 사이클이 작동하고 있었다. 보안 연구자들이 레포지터리 서명 하나로 1,000개 이상의 감염 흔적을 추적할 수 있었다는 점은, 코드 오픈소스화가 추적 가능성까지 높인 결과이기도 하다. 공격자가 같은 서명을 남긴 덕에 감염 범위가 드러났다.
AI 활용 안내 이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 인용된 통계와 사례는 참고 자료에 명시된 출처에 근거하며, 설명을 위한 일부 표현은 각색되었습니다.
면책 조항 본 글은 보안 인식 제고를 위한 교육 목적으로 작성되었습니다. 언급된 공격 기법을 실제로 시도하는 행위는 「정보통신망법」, 「형법」 등에 따라 처벌받을 수 있으며, 본 블로그는 이에 대한 법적 책임을 지지 않습니다.