샤이훌루드: 광범위한 npm 공급망 공격
Detection stack
- AIDR
- Alert
- ETL
- Query
요약
GitLab은 npm 생태계를 목표로 한 광범위한 공급망 침입을 공개했습니다. 이 캠페인은 악성 사전 설치 스크립트를 통해 업데이트된 Shai-Hulud 멀웨어 변종을 배포합니다. 이 페이로드는 클라우드 및 코드 호스팅 자격 증명을 수집하고, 공격자가 제어하는 GitHub 저장소로 데이터를 전송하며, 트로이 목마화된 패키지를 재게시하여 추가 확산됩니다. 또한 내장된 데드맨 스위치가 공격자의 인프라가 중단되면 사용자 파일을 지우거나 손상시킬 수 있습니다.
조사
GitLab의 취약점 연구 팀은 변조된 package.json에 setup_bun.js 로더를 참조하는 오염된 npm 패키지로 활동을 추적했습니다. 이 로더는 Bun 런타임을 설치하고 자격 증명을 수집하며, 비밀 식별을 위해 Trufflehog를 실행하고 결과를 공용 GitHub 저장소에 업로드하는 번들 bun_environment.js 페이로드를 트리거합니다. 또한, 이 멀웨어는 새로운 GitHub 저장소를 드롭박스로 생성하고 도난된 npm 토큰을 악용하여 손상된 패키지를 재게시합니다. GitHub과 npm 모두에 대한 액세스가 끊어지면 페이로드는 사용자 파일을 삭제하거나 덮어쓰기를 진행합니다.
완화
GitLab은 조직이 예기치 않은 사전 설치 스크립트에 대해 npm 종속성을 검사하고, 게시된 패키지의 무결성을 검증할 것을 권장합니다. 팀은 승인되지 않은 setup_bun.js 로더를 제거하고, 노출된 npm 및 GitHub 토큰을 취소하며, “Sha1-Hulud: The Second Coming” 마커로 표시된 의심스러운 GitHub 저장소를 주시해야 합니다. 엔드포인트 보호는 신뢰할 수 없는 Node 스크립트를 차단하고 보고서에 문서화된 파괴적 명령줄을 탐지하도록 구성해야 합니다.
대응
활동이 감지되면 영향을 받은 시스템을 격리하고, 모든 손상된 자격 증명을 취소하며, 내부 레지스트리에서 악성 npm 패키지를 제거하십시오. 데이터 유출 및 파일 파괴 여부를 확인 또는 배제하기 위해 포렌식 검토를 수행하십시오. 클라우드 플랫폼 및 GitHub에 대한 신규 자격 증명을 발급하고 공격자 마커와 일치하는 새로 생성된 저장소를 지속적으로 모니터링하십시오. 마지막으로, 무단 사전 설치 스크립트를 금지하도록 CI/CD 파이프라인을 강화하십시오.
mermaid graph TB %% Class definitions classDef technique fill:#99ccff classDef file fill:#ffcc99 classDef tool fill:#cccccc classDef malware fill:#ff9999 classDef operator fill:#ff9900 %% Nodes – Attack Techniques tech_supply_chain[“<b>기술</b> – <b>T1195.001 공급망 손상</b>: 악성 npm 패키지가 사전 설치 스크립트를 추가하는 변경된 package.json을 게시”] class tech_supply_chain technique tech_client_exec[“<b>기술</b> – <b>T1203 클라이언트 실행 이용</b>: 패키지 설치 중 npm이 setup_bun.js 악성 스크립트를 실행”] class tech_client_exec technique tech_software_ext[“<b>기술</b> – <b>T1176 소프트웨어 확장</b>: 사전 설치 스크립트가 합법적인 패키지에 악성 확장자로 작동”] class tech_software_ext technique tech_obfuscate[“<b>기술</b> – <b>T1027 난독화된 파일 또는 정보</b>: 난독화된 대용량 페이로드 bun_environment.js를 다운로드”] class tech_obfuscate technique tech_decode[“<b>기술</b> – <b>T1140 파일 또는 정보의 디코딩/해독</b>: 실행 전 페이로드를 디코딩”] class tech_decode technique tech_hidden_files[“<b>기술</b> – <b>T1564.001 숨겨진 파일 및 디렉토리</b>: .truffler-cache/ 및 하위 디렉토리를 생성”] class tech_hidden_files technique tech_path_excl[“<b>기술</b> – <b>T1564.012 파일 경로 제외</b>: 탐지를 피하기 위해 숨겨진 경로에 악성 바이너리 저장”] class tech_path_excl technique tech_cred_in_files[“<b>기술</b> – <b>T1552.001 파일 내 인증 정보</b>: .npmrc, 환경 변수 및 구성 파일에서 클라우드 및 저장소 토큰 검색”] class tech_cred_in_files technique tech_auto_collect[“<b>기술</b> – <b>T1119 자동 수집</b>: Trufflehog 실행하여 파일 시스템에서 비밀 수집”] class tech_auto_collect technique tech_exfil_repo[“<b>기술</b> – <b>T1567.001 코드 저장소로 유출</b>: 도난된 GitHub 토큰을 사용하여 공개 저장소 생성 및 자격 증명 업로드”] class tech_exfil_repo technique tech_destructive[“<b>기술</b> – <b>T1565 데이터 조작</b>: 사용자의 데이터를 삭제 및 덮어쓰기 위해 파괴적인 명령 실행 (del, cipher, shred)”] class tech_destructive technique tech_impair[“<b>기술</b> – <b>T1562 방어 저해</b>: 데드맨 스위치가 데이터 파괴로 복구 불가능한 상태로 만듬”] class tech_impair technique tech_propagate[“<b>기술</b> – <b>T1195.001 공급망 확산</b>: 도난된 npm 토큰을 사용하여 피해자 패키지에 악성 사전 설치 스크립트를 삽입하고 재게시”] class tech_propagate technique %% Nodes – Files and Tools file_package_json[“<b>파일</b>: 사전 설치 스크립트를 포함한 package.json”] class file_package_json file file_setup_bun[“<b>파일</b>: setup_bun.js (사전 설치 스크립트)”] class file_setup_bun file file_bun_env[“<b>파일</b>: bun_environment.js (난독화된 페이로드)”] class file_bun_env file file_trufflehog[“<b>도구</b>: .truffler-cache에 저장된 Trufflehog 바이너리”] class file_trufflehog tool file_hidden_dir[“<b>파일</b>: .truffler-cache/ 숨겨진 디렉토리”] class file_hidden_dir file file_github_repo[“<b>파일</b>: 유출을 위해 생성된 공개 GitHub 저장소”] class file_github_repo file %% Edges – Attack Flow tech_supply_chain u002du002d>|사전 설치 스크립트 추가| file_package_json file_package_json u002du002d>|npm 설치 중 트리거| tech_client_exec tech_client_exec u002du002d>|실행| file_setup_bun file_setup_bun u002du002d>|다운로드| file_bun_env file_bun_env u002du002d>|은| tech_obfuscate tech_obfuscate u002du002d>|요구| tech_decode tech_decode u002du002d>|실행 가능한 페이로드 생성| tech_software_ext tech_software_ext u002du002d>|생성| file_hidden_dir file_hidden_dir u002du002d>|저장| file_trufflehog file_trufflehog u002du002d>|에서 사용| tech_auto_collect tech_auto_collect u002du002d>|자격 증명 수집| tech_cred_in_files tech_cred_in_files u002du002d>|토큰 제공| tech_exfil_repo tech_exfil_repo u002du002d>|데이터 업로드| file_github_repo tech_exfil_repo u002du002d>|토큰 분실 시 트리거| tech_destructive tech_destructive u002du002d>|복구를 통해 비활성화| tech_impair tech_impair u002du002d>|활성화| tech_propagate tech_propagate u002du002d>|새로운 npm 패키지에 악성 사전 설치 스크립트 주입| tech_supply_chain %% Styling class tech_supply_chain,tech_client_exec,tech_software_ext,tech_obfuscate,tech_decode,tech_hidden_files,tech_path_excl,tech_cred_in_files,tech_auto_collect,tech_exfil_repo,tech_destructive,tech_impair,tech_propagate technique class file_package_json,file_setup_bun,file_bun_env,file_hidden_dir,file_github_repo file class file_trufflehog tool
공격 흐름
탐지
악성 Bun 설치 및 파괴적 페이로드 실행 탐지 [Linux 프로세스 생성]
보기
파괴적 PowerShell 및 명령 프롬프트 명령 탐지 [Windows 프로세스 생성]
보기
이름에 점을 접두사로 하는 의심스러운 파일 또는 폴더 (file_event 통해)
보기
일반적이지 않은 TLD를 가진 도메인에서 다운로드된 의심스러운 확장자의 파일 (proxy 통해)
보기
표준 도구를 통한 원격 파일 업로드/다운로드 (cmdline 통해)
보기
시뮬레이션 실행
전제 조건: Telemetry & Baseline Pre-flight Check가 통과해야 합니다.
공격 내러티브 및 명령
적대자는 손상된 Linux 호스트에서 발판을 마련했습니다. JavaScript 기반 페이로드를 추가로 실행할 수 있는 지속적인 런타임을 설정하기 위해 Bun 런타임을 다운로드하고 설치합니다. 이는 설치 프로그램을 직접 스트리밍하는 일회성 명령을 통해 수행됩니다.bash. 런타임이 존재하는지 확인하자마자 공격자는 “데드맨’s 스위치” (여기서는 sleep 타이머로 시뮬레이션)을 트리거합니다.sleep)가 민감한 파일 (shred/var/log/auth.log/var/log/auth.log).
절차는 다음과 같습니다.
- Bun 다운로드 및 설치:
curl -fsSL https://bun.sh/install | bash - 잠시 대기 (스위치 타이밍의 시뮬레이션).
- 파괴적 쉬레드 실행:
shred -uvz -n 1 /var/log/auth.log
두 명령 모두 Sigma 규칙의 정확한 키워드와 일치하는 프로세스 생성 이벤트를 생성합니다.
회귀 테스트 스크립트
#!/bin/bash
# -------------------------------------------------
# Shai-Hulud 'Bun 설치 + 쉬레드' 동작 시뮬레이션
# -------------------------------------------------
# 1️⃣ Bun 설치 (탐지를 위해 정확한 명령 필요)
echo "[*] Bun 런타임 설치 중..."
curl -fsSL https://bun.sh/install | bash
# 현실적인 타이밍을 시뮬레이션하기 위한 짧은 일시 중지
sleep 5
# 2️⃣ 파괴적 파일 삭제 수행 (정확한 명령 필요)
TARGET_FILE="/var/log/auth.log"
if [[ -f "$TARGET_FILE" ]]; then
echo "[*] $TARGET_FILE 를 파괴 중..."
shred -uvz -n 1 "$TARGET_FILE"
else
echo "[!] 타겟 파일을 찾을 수 없음; 데모를 위한 더미 파일 생성 중."
echo "dummy data" > "$TARGET_FILE"
shred -uvz -n 1 "$TARGET_FILE"
fi
echo "[*] 시뮬레이션 완료."
정리 명령
#!/bin/bash
# -------------------------------------------------
# Bun/쉬레드 시뮬레이션 후 정리
# -------------------------------------------------
# 남은 Bun 파일을 제거합니다 (설치된 경우)
if command -v bun >/dev/null 2>&1; then
echo "[*] Bun 런타임 제거 중..."
rm -rf "$HOME/.bun"
rm -f /usr/local/bin/bun
fi
# 시스템 안정성을 위해 파괴된 로그 파일 재생성
TARGET_FILE="/var/log/auth.log"
if [[ ! -f "$TARGET_FILE" ]]; then
echo "재생성된 로그 자리표시자" | sudo tee "$TARGET_FILE" >/dev/null
sudo chmod 600 "$TARGET_FILE"
fi
echo "[*] 정리 완료."