Reddit

nine npm packages shipping worm that spread by itself over SSH

SSH로 퍼지는 웜을 숨긴 npm 패키지 9개

Express와 React를 사칭한 npm 패키지 9개가 Linux 웜을 설치하고, SSH 키와 npm 토큰을 이용해 원격 호스트·AUR·npm 패키지로 확산합니다. 웜은 Tor를 거치는 원격 제어 백도어도 설치하므로, 감염된 시스템의 자격 증명까지 침해된 것으로 취급해야 합니다.

AI 요약

npm 계정 dirtyblanket은 2026년 9월 29일 33분 사이 패키지 9개를 공개했습니다. 8개는 Express를, 하나는 React를 사칭합니다. 패키지를 Linux에서 설치하면 npm의 preinstall 훅이 실행되고, 이 훅은 Internet Archive의 Wayback Machine을 경유해 Codeberg에서 JavaScript 로더를 받아 실행합니다. 로더는 다시 Linux 셸 스크립트를 내려받습니다.

설치부터 백도어 실행까지

preinstall 명령에는 내려받는 파일의 버전 고정이나 무결성 검사가 없습니다. 공격자는 Codeberg의 파일을 바꾸면 이후 설치되는 패키지의 동작도 바꿀 수 있습니다. 첫 단계 로더는 Wayback Machine 주소를 사용하지만, 두 번째 단계는 Codeberg에서 직접 받습니다. Linux에서만 동작하며, 실행 결과와 오류를 출력하지 않아 npm 설치 과정에서는 감염 여부를 알아채기 어렵습니다. 셸 스크립트도 백그라운드에서 실행돼 설치가 끝난 뒤 작업을 이어갑니다.

스크립트는 root 권한으로 실행되면 Tor, OpenSSH, Git, npm과 빌드 도구를 설치합니다. 이어 CHAOS 원격 관리 도구의 Linux 클라이언트를 systemd 백도어로 배치합니다. root 환경에서는 실행 파일과 서비스 이름을 systemd 구성요소처럼 꾸미고, 실행 파일·서비스 파일·서비스 링크에 immutable 속성을 설정해 삭제나 변경을 어렵게 합니다. 일반 사용자 권한에서는 Tor Expert Bundle과 사용자 systemd 서비스를 설치합니다. 백도어 통신은 로컬 Tor 프록시를 거쳐 onion 주소의 서버에 연결됩니다.

SSH·AUR·npm으로 이어지는 확산

웜은 각 사용자의 .ssh/known_hosts와 시스템 SSH 호스트 목록을 모으고, 읽을 수 있는 OpenSSH 개인 키를 찾아 기록된 호스트에 접속합니다. 키를 이용한 로그인에 성공하고 대상이 Linux로 확인되면, 원격 호스트에서 웜을 다시 실행합니다. 다만 known_hosts에서 호스트 이름을 해시하는 설정을 썼다면 첫 필드가 해시라서 해당 호스트에 접속하지 못합니다.

같은 SSH 키로 AUR 계정의 저장소 목록도 조회합니다. 관리 중인 패키지를 복제해 PKGBUILD의 pkgrel을 올리고, .install 파일에 웜 실행 명령을 추가한 뒤 유지관리자의 이름과 이메일로 커밋해 푸시합니다. 패키지 사용자가 업데이트하면 웜이 실행됩니다.

로컬 파일 시스템에서는 node_modules를 제외한 package.json 경로를 찾아 npm 패키지에도 손을 댑니다. 기존 preinstall 훅 뒤에 로더 실행 명령을 추가하고 patch 버전을 올린 다음, 발견한 .npmrc마다 npm publish를 시도합니다. 유효한 토큰이 있는 계정으로 감염된 버전을 배포하고 나면 로컬 package.json은 원본으로 복구합니다. 따라서 개발자가 로컬 파일만 확인해선 배포된 변경을 발견하지 못할 수 있습니다.

백도어의 기능과 대응 범위

분석 대상 바이너리는 7.6MB Go 프로그램이며, 빌드 정보와 함수 구성이 오픈소스 CHAOS 클라이언트와 일치합니다. 백도어는 호스트 정보와 사용자 정보, 운영체제, 아키텍처, MAC 주소, 로컬 IP를 서버에 보내고 30초 간격으로 상태를 확인합니다. 원격 명령으로 셸 실행, 화면 캡처, 파일 목록 확인과 전송, 파일 삭제, URL 열기, 재부팅과 종료를 수행합니다. 셸은 서비스 권한으로 실행되므로 root로 설치됐다면 공격자에게 root 권한이 주어집니다.

본문은 감염된 Linux 시스템뿐 아니라 그 안의 SSH 키와 npm 토큰도 침해된 것으로 간주하라고 권고합니다. 확인 지표로는 패키지명과 게시 계정, Codeberg·Wayback URL, systemd 서비스·파일 경로, 바이너리 SHA-256, Tor onion 주소 등이 제시됩니다.

Reddit 반응

  • @u/tanksc — 나중에 돌아보면, 우리가 이런 공급망 공격 경로를 대체 무슨 생각으로 받아들였는지 의아해할 것 같습니다.
  • @u/Nice_Mix_1021 — Express.js인 척했다는 점이 정말 놀랍습니다.
  • @u/rcklmbr — 흥미로운 주제인데 AI 슬롭(AI Slop) 같아서 읽지 못했습니다.
    • @u/Nice_Mix_1021 — 😂 기술 블로그이지 소설은 아니잖아요.

원문: SafeDep / 번역·요약: Trawling