PhantomSync: npm 암호화폐 패키지 지갑 탈취 방지

PhantomSync: 8개의 암호화 개발자용 npm 패키지에는 지연되고 자체적으로 유지되는 드롭퍼가 숨겨져 있습니다.

TL; DR

한 명의 npm 게시자가 블록체인 및 지갑 개발에 흔히 사용되는 구성 요소처럼 보이는 이름의 작은 패키지 8개를 출시했습니다. base58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers예산 및 crypto-validate-lib각 모듈에는 실제로 작동하는 유틸리티가 포함되어 있습니다. 하지만 해당 유틸리티 뒤에는 모듈이 임포트되는 순간 실행되는 자체 호출 코드 블록이 추가되어 있습니다.

임포트 후 약 37초해당 블록은 테스트 픽스처로 위장하여 패키지 내부에 포함된 페이로드를 디코딩하고, 사용자의 홈 디렉터리 아래에 있는 숨겨진 파일에 기록하며, 매번 재시작하도록 자체 등록합니다. login Windows, macOS, Linux에서 작동하며 디코딩된 스크립트를 별도의 프로세스로 실행합니다. 이 과정은 npm install 도중에는 전혀 실행되지 않으며, 코드가 임포트되어 실행될 때까지 기다립니다. 따라서 설치 과정보다 훨씬 조용하게 진행됩니다.

페이로드는 불투명하지 않습니다. 일반 base64 형식으로 전송되므로 "테스트 픽스처"를 디코딩하면 두 번째 단계가 완전히 복구됩니다. 암호화폐 지갑 및 비밀 탈취 프로그램 해당 프로그램은 시스템이 유휴 상태가 될 때까지 기다렸다가 개인 키와 시드 구문을 수집하고, 수집된 각 정보를 하드코딩된 RSA-4096 키로 암호화한 다음, 이를 공용 IPFS 저장소에 고정하여 유출하고 12시간마다 신호를 보냅니다.

우리는 클러스터를 다음과 같이 추적합니다. 팬텀싱크분석 당시 8개 패키지 모두 npm 레지스트리에 등록되어 있었고, 단일 계정으로 게시되어 있었습니다.

생태계npm
패키지base58-utils, abi-encode, eth-dev, arb-kit, layer2-sdk, solana-key-utils, eth-wallet-helpers, crypto-validate-lib
대상 플랫폼윈도우, macOS, 리눅스
핵심 행동지연된 가져오기 시간 드롭퍼가 테스트 픽스처로 숨겨져 있으며, 크로스 플랫폼 영구 저장소를 설치합니다.
Payload암호화폐 지갑 및 비밀 키 탈취, RSA-4096 암호화, 공개 IPFS 피닝을 통한 데이터 유출

공격 해부학

처음 봤을 때는 각 패키지가 특별해 보이지 않습니다. base58-유틸리티예를 들어, 는 이름 그대로 의존성이 없는 Base58/Bitcoin-WIF 헬퍼 코드 몇 킬로바이트입니다. 관련 코드는 다음과 같습니다. 시간 내에 모듈의 모듈.exports독자가 파일 맨 위를 훑어볼 가능성이 낮은 곳, 즉 타이머를 사용하여 자체 실행을 예약하는 자기 호출 함수가 있습니다.

패키지 소스 코드에서 재구성한 일련의 작업은 다음과 같습니다.

1. Package is required() by the host project
2. A self-invoking function schedules a callback ~37,000 ms later (setTimeout)
3. On fire, the callback reads test/fixtures/keypairs.dat (a base64 blob)
4. It base64-decodes that blob into a Node.js script
5. It writes the script to ~/.cache-db/.node-sync/syncd.js (mode 0o700)
6. It installs login-persistence for that script (see below)
7. It spawns "node syncd.js" as a detached process

두 가지 디자인 선택이 눈에 띕니다.

탑재체는 테스트 장비로 운송됩니다. 두 번째 단계는 명확한 코드로 작성되어 있지 않습니다. 그것은 내면에 존재합니다. 테스트/픽스처/키페어.dat이 파일은 키 쌍을 처리한다고 주장하는 패키지 이름과 유사한 이름의 base64 파일입니다. 사람이 tarball을 훑어보면 샘플 데이터처럼 보이지만, 첨부된 코드에서는 디코딩하고 실행해야 하는 스크립트입니다. 드로퍼 자체에는 네트워크 주소가 포함되어 있지 않습니다. 네트워크 주소는 두 번째 단계에 있습니다. 하지만 추가적인 난독화는 없습니다. 픽스처는 단일 레이어의 base64로 구성되어 있으므로 디코딩하면 (base64 -d) 전체 값을 복구합니다 syncd.js 그리고 네트워크 동작 방식도 살펴봅니다. 다음 섹션에서는 복구된 단계가 수행하는 작업에 대해 자세히 설명합니다.

폭발은 지연되며 설치가 아닌 가져오기와 연관되어 있습니다. 방아쇠가 다음과 같기 때문입니다. require () 설치 후크 대신 약 37초 타이머를 추가함으로써, 이 동작은 특정 시점만 감시하는 검사를 우회합니다. npm 설치 이 단계에서 발생하는 지연 시간은 여러 단기 샌드박스 및 CI 실행 시간보다 훨씬 깁니다. 결국 어떤 작업이 실행될 때쯤이면 패키지를 설치하는 작업은 이미 오래전에 완료된 상태입니다.

디코딩된 스크립트가 디스크에 저장되면 ~/.cache-db/.node-sync/syncd.js — 일반적인 캐시 디렉터리처럼 읽히도록 선택된 경로 — 이 드롭퍼는 ​​세 가지 주요 플랫폼 모두에서 재부팅 후에도 유지되도록 합니다.

  • Linux : 스크립트를 다시 실행하는 cron 항목입니다. 이 항목은 기존 crontab을 필터링하여 설치됩니다. grep -v syncd이로 인해 동일한 이름을 검색하는 일반 목록에서 새 항목이 제외되는 부작용이 발생합니다.
  • 윈도우 : 예약된 작업 이름 윈노드 동기화12분 간격으로 다시 실행되도록 설정되어 있습니다.
  • 맥 OS : launchd 작업 라벨이 지정됨 com.apple.syncd여러 패키지에 포함된 이 라벨은 정식 애플 시스템 서비스를 모방한 것입니다.

그러면 스크립트는 별도의 프로세스로 즉시 시작되므로 가져오기 프로그램이 종료된 후에도 계속 실행됩니다.

두 번째 단계에서 하는 일은 무엇인가요?

해당 픽스처는 단일 base64 레이어로 구성되어 있으므로 두 번째 단계는 깔끔하게 디코딩되어 전체를 읽을 수 있습니다. 8개의 패키지 모두 동일한 스크립트의 세 가지 변형 중 하나를 포함하고 있으며, 헤더 주석에서 해당 스크립트가 자신을 식별합니다. phantom syncd v3 — 내구성 향상 ("잠자는 두더지"). 이 놈의 임무는 암호화폐 지갑 자료와 개발자 비밀 정보를 훔쳐 시스템 외부로 유출하는 것입니다. 실행 과정은 다음과 같습니다.

  • 1. 기계가 멈춰 있을 때까지 기다리세요. 무엇을 하기 전에, syncd.js 사용자가 얼마나 오랫동안 활동하지 않았는지 확인하고, 일정 시간(약 15분)이 지난 후에만 다음 단계로 진행합니다. xprintidle 리눅스에서는, 아이오렉 macOS에서는 HIDIdleTime을, Windows에서는 PowerShell 유휴 시간 쿼리를 사용합니다. 따라서 데이터 수집은 주로 아무도 키보드를 사용하지 않을 때 발생합니다.
  • 2. 원격 제어 활성화 스위치를 가져옵니다.스크립트는 실행하기 전에 임시 저장소에서 간단한 설정 정보를 가져옵니다. 주요 소스는 GitHub gist의 원시 URL입니다.gist.githubusercontent.com/juang55/…/cfg.txt해당 스크립트는 해당 설정이 다음과 같을 경우에만 활성화됩니다. 활성=1요약 정보를 사용할 수 없는 경우, 공용 게이트웨이를 통해 가져온 세 가지 하드코딩된 IPFS 콘텐츠 식별자를 사용합니다. 게이트웨이.피냐타.클라우드, ipfs.io예산 및 클라우드플레어-ipfs.com이를 통해 운용자는 사후에 무장/무장 해제를 제어할 수 있으며, 파괴에 강한 비상 대책을 마련할 수 있습니다. (가장 작은 변형 모델은 다음 주소로 배송됩니다.) 암호화 검증 라이브러리, 이더리움 지갑 도우미예산 및 솔라나 키 유틸리티(요약 레이어가 제거되었으며 IPFS 식별자에만 의존합니다.)
  • 3. 지갑 속 내용물과 비밀을 수집하세요. 이 스크립트는 사용자의 홈 디렉토리를 탐색합니다. ~/.config/solana, ~/.ethereum/keystore, ~/.파운드리, ~/.hardhat, ~ / .ssh예산 및 데스크탑/서류/다운로드 (스페인어 폴더 이름 포함) ~/.env 그리고 셸 rc 파일과 그에 상응하는 것 의 AppData Windows의 특정 위치를 대상으로 합니다. 이더리움 개인 키, 비트코인 ​​WIF 키, BIP-39 시드 구문, 솔라나 키 쌍, 이더리움 키 저장소 JSON, SSH 키 및 비밀 키를 포함하는 환경 변수를 대상으로 합니다. 더 큰 버전(에서) 아비 인코딩, base58-유틸리티, 이더리움 개발)는 2048개 단어로 구성된 BIP-39 사전 전체를 포함하고 있으며 정규 표현식을 사용합니다. 추출물 읽어들인 모든 텍스트에서 개별 키와 유효성이 검증된 시드 구문을 추출합니다. 두 가지 더 작은 변형은 대신 키워드를 기준으로 파일을 일치시킵니다.씨, 니모닉, 지갑, metamask, 환상, 원장, trezor, …) 전체 파일을 업로드하세요.
  • 4. 공개 피닝 서비스를 통해 암호화하고 유출합니다. 각 발견 사항에는 호스트 지문이 함께 제공됩니다.사용자 이름@호스트 이름(플랫폼, 타임스탬프)를 스크립트에 내장된 하드코딩된 RSA-4096 공개 키로 암호화합니다. 암호화된 레코드는 IPFS에 고정(pinning)하여 업로드됩니다. api.pinata.cloud/pinning/pinJSONToIPFS하드코딩된 Pinata API 자격 증명으로 인증됩니다. 탈취할 수 있는 맞춤형 C2 서버는 없습니다. 탈취된 데이터는 공개 분산 스토리지에 저장되며, 운영자는 생성된 콘텐츠 해시를 사용하여 데이터를 검색할 수 있습니다. 업로드는 몇 초 간격의 무작위 지연으로 이루어지며, 로컬 로그에 기록됩니다. 타임스탬프 | 키 유형 | 반환 해시 보관되어 있습니다 ~/.cache-db/.node-sync/.sl.
  • 5. 12시간 주기로 신호를 지속적으로 보내십시오. 두 번째 단계는 자체적인 지속성을 다시 확립합니다. 리눅스에서는 cron 항목을, com.apple.syncd macOS에서 launchd 작업과 예약된 작업이라는 이름의 작업 WindowsNodeSync Windows에서 12시간마다 다시 실행되도록 설정되어 있습니다. 참고로 이는 다른 드롭퍼가 설치하는 Windows 작업 이름입니다.윈노드 동기화둘 다 찾아볼 만한 가치가 있습니다.

연혁

이 여덟 개의 패키지는 2026년 7월 13일과 14일에 집중적으로 게시되었습니다. 여러 패키지가 여러 버전으로 제공되지만, 드롭퍼 자체는 모든 버전에서 동일하며, 위에 있는 유틸리티 코드의 크기가 변경됨에 따라 줄 간격만 조정됩니다.

날짜이벤트
2026-07-13클러스터의 첫 번째 패키지는 하나의 게시자 아래에 나타납니다(solana-key-utils, eth-wallet-helpers, crypto-validate-lib (그리고 나머지의 초기 버전들)
2026-07-13 → 07-14나머지 이름과 후속 버전이 게시되었습니다. 각 버전에는 동일한 추가 드롭퍼가 포함되어 있습니다.
2026-07-148개 패키지 모두 플래그가 지정되어 분석되었으며, 레지스트리에서 모든 패키지를 여전히 설치할 수 있습니다.

이번 공격 기간 동안 게시자의 레지스트리 평판은 공격 초기에는 거의 중립적이었지만, 탐지 사례가 누적됨에 따라 매우 부정적으로 변했습니다. 이는 패키지가 플래그 처리되면서 나타난 관찰 가능한 부작용이지, 의도적으로 설계된 기능은 아닙니다.

타협의 지표

아래의 모든 지표는 분석 시점에 존재함이 확인되었습니다. ("2단계" 표에 있는 지표들은 디코딩을 통해 확인되었습니다.) 테스트/픽스처/키페어.dat 그리고 복구된 내용을 읽어보세요 syncd.js.

파일 및 경로

지시자직위별
~/.cache-db/.node-sync/syncd.js디코딩된 2단계, 모드 0o700으로 기록됨
~/.cache-db/.node-sync/.sl로컬 데이터 유출 로그(타임스탬프 | 키 유형 | IPFS 해시)
test/fixtures/keypairs.dattarball 내부에 "테스트 픽스처"로 Base64로 인코딩된 페이로드가 포함되어 있습니다.

2단계 네트워크 인프라(syncd.js에서 복구됨)

지시자직위별
gist.githubusercontent.com/juang55/b298754cb72942b1cdcf02ccd45cde2f/raw/cfg.txt활성화 데드 드롭; 스크립트는 구성이 읽힌 경우에만 실행됩니다. active=1
Qmcqz3w8j4qFQXDAXAxnrdc2oSX3nzBT4NqtpTqL8mr1gaIPFS 구성 대체(CID)
QmdTXoqVmTHY1i4ZWLdLkoQ9YChp5TXPh5cWXwnAYZt5iFIPFS 구성 대체(CID)
QmfJkLU5gdCpqbbqEjWYC2anXW9FmuEeSLLeLiHVJKYUjpIPFS 구성 대체(CID)
gateway.pinata.cloud, ipfs.io, cloudflare-ipfs.comIPFS 게이트웨이는 구성 대체 정보를 가져오는 데 사용됩니다.
api.pinata.cloud/pinning/pinJSONToIPFS데이터 유출 엔드포인트, 도난 데이터가 공용 IPFS에 고정됨
피냐타 API 키13c766575b9270a9825d하드코딩된 데이터 유출 자격 증명

2단계 수집 대상(syncd.js에서 복구됨)

지시자직위별
~/.config/solana, ~/.ethereum/keystore, ~/.foundry, ~/.hardhat, ~/.ssh, ~/.env셸 rc 파일키와 비밀 키를 찾기 위해 검색한 디렉터리/파일
AppData\Roaming\Solana, AppData\Local\ethereum\keystoreWindows에서 사용 가능한 유사 항목을 검색했습니다.
수집된 유물 유형이더리움 개인 키, 비트코인 ​​WIF, BIP-39 시드 구문, 솔라나 키 쌍, 이더리움 키 저장소 JSON, SSH 키, 비밀 환경 변수

지속성 아티팩트

플랫폼지시자
Linuxcron 항목 실행 syncd.js; crontab을 통해 설치됨 (필터링됨) grep -v syncd
Windows예정된 작업 WinNodeSync (스포이드) 및 WindowsNodeSync (2단계)
macOS런치드 레이블 com.apple.syncd
전부의2단계는 12시간 주기로 다시 지속됩니다.

행동의

  • 자체 호출 함수가 뒤에 추가되었습니다. 모듈.exports, 일정을 정하다 setTimeout 가져오기에 약 37,000ms가 소요됩니다.
  • 자식 프로세스 spawn(“노드”, ) 분리 옵션이 설정되어 있습니다.
  • 두 번째 단계에서 유휴 게이트 활성화(xprintidle / 아이오렉 HIDIdleTime / PowerShell 유휴 시간; 약 15분 임계값).
  • RSA-4096 암호화를 먼저 적용한 후 HTTPS를 사용합니다. POST 공개 IPFS 피닝 API에 연결합니다.

패키지 및 버전(npm, 게시자 solbuilder_io)

묶음버전
base58-utils1.0.0, 1.0.1, 1.0.3
abi-encode1.0.0, 1.0.1, 1.0.2
eth-dev1.0.0, 1.0.1, 1.0.2
arb-kit1.0.0, 1.0.1
layer2-sdk1.0.0, 1.0.1
solana-key-utils1.0.0
eth-wallet-helpers1.0.0
crypto-validate-lib1.0.0

작성자

  • 솔빌더_io - angel_lopez89[@]proton[.]me이메일이 확인되지 않았고, 소스 제어 계정이 인증되지 않았으며, 저장소가 연결되어 있지 않습니다.

귀인 및 관찰된 행동

이 여덟 개의 패키지는 하나의 게시자 계정과 하나의 페이로드를 공유합니다. 각 패키지는 몇 킬로바이트의 실제 유틸리티 코드에 동일한 드롭퍼가 추가된 간단한 패키지로, 연결된 저장소 없이 검증되지 않은 일회용 이메일 주소로 게시됩니다. 이러한 균일성, 공유된 드롭 경로, 공유된 지속성 레이블, 그리고 공유된 페이로드는 공통적인 특징을 보여줍니다. 키페어.dat 스테이징 파일은 클러스터를 하나로 묶어주는 역할을 합니다.

이 패키지들은 자신들의 행동에 대해 이례적으로 솔직하다. 솔라나 키 유틸리티 추가된 블록을 명확하게 설명하는 인라인 주석이 포함되어 있습니다. 그중 하나는 레이블을 지정합니다. 팬텀: 보이지 않는 지속성또 다른 (스페인어) 글에는 다음과 같이 적혀 있습니다. Ejecutar topo en background"백그라운드에서 두더지를 실행하세요." 이것은 코드가 하는 일을 설명하는 자체 주석입니다. 이 게시물의 캠페인 이름은 첫 번째 레이블과 가짜 노드 "동기화 데몬"을 합쳐서 만들어졌습니다.동기화됨) 지속성 메커니즘이 모방하는 것.

우리는 코드가 실제로 수행하는 작업만 설명합니다. 패키지 이름(모두 암호화폐, 지갑, 블록체인 툴 관련 용어)은 해당 패키지를 사용할 가능성이 가장 높은 개발자층을 나타내는 것이며, 그 자체로 게시자가 누구인지를 알려주는 것은 아닙니다. 두 번째 단계는 base64로 인코딩된 코드를 디코딩하여 완전히 복구할 수 있었으며, 그 동작은 위에서 설명한 바와 같습니다. 지갑 키, 시드 구문, 비밀 키를 수집하여 RSA로 암호화한 후 Pinata를 통해 공개 IPFS 저장소로 유출합니다. 주목할 만한 설계상의 특징은 개인 C2 서버가 없다는 점입니다. 구성 정보는 GitHub gist와 IPFS에서 가져오고, 탈취된 데이터는 콘텐츠 해시를 키로 사용하는 공개 분산 저장소에 저장됩니다. 이는 공격자가 제어하는 ​​단일 호스트보다 탈취하기 훨씬 어렵습니다. 이 클러스터와 일치하는 이전 공개 보고서는 작성 시점까지 발견되지 않았습니다.

영향, 동향 및 수비수를 위한 지침

누가 노출되는가. Node 프로젝트에 이러한 패키지 중 하나를 추가한 후 해당 패키지를 가져오는 코드를 실행한 사람은 누구나 위험에 노출됩니다. 실행은 설치 시점이 아닌 가져오기 시점에 발생하므로 패키지가 존재한다고 해서 충분한 것은 아닙니다. 모듈을 로드하는 일반적인 사용 사례는 모두 페이로드에 도달하게 됩니다. 이러한 미끼 이름은 이더리움, 솔라나, 아비트럼, 레이어 2 기반 플랫폼 및 일반 지갑/인코딩 도구를 개발하는 개발자를 대상으로 합니다. 이들은 2단계에서 노리는 자산을 보유할 가능성이 가장 높은 집단입니다. 지갑 키, 시드 구문, 키 저장소, SSH 키 등을 보유한 컴퓨터에서 이러한 모듈 중 하나를 실행한 사람도 위험에 노출됩니다. .env 비밀 관리자는 해당 자격 증명이 유출된 것으로 간주하고 주기적으로 갱신해야 합니다.

내면화할 가치가 있는 두 가지 패턴. 첫째, 페이로드를 고정 장치로 사용두 번째 단계를 base64 형식으로 적절한 이름의 데이터 파일 안에 담아 전송합니다.테스트/픽스처/키페어.dat) 패키지의 가시적인 소스 코드는 깨끗하게 유지하고 악성 콘텐츠를 검토 도구나 사람이 훑어볼 때 종종 비활성 데이터로 간주하는 파일에 넣습니다. 둘째, 가져오기 시간 지연 실행 및 크로스 플랫폼 지속성설치 후크에서 트리거를 분리하고 타이머를 추가한 다음 cron, 예약된 작업 및 launchd 전반에 걸쳐 유지하는 것은 자동화된 레지스트리 스캔이 가장 면밀히 감시하는 시끄러운 설치 스크립트 기법에서 벗어나기 위한 의도적인 조치입니다.

방어자 및 유지 관리자를 위한 지침:

  • 추가된 코드를 처리하세요 모듈.exports 검토 우선순위로 고려할 때, 드롭퍼 로직은 종종 "실제" 모듈 표면 아래에 숨겨져 있습니다.
  • 데이터 파일이 비활성 상태라고 가정하지 마십시오. base64로 인코딩된 블롭은 다음과 같은 상황에 처할 수 있습니다. 테스트/고정 장치/ 런타임에 읽고 디코딩되는 것은 실행 파일과 유사합니다. 픽스처 파일의 런타임 읽기를 플래그합니다. 함수/평가/쓰기-그다음-알 체인.
  • 낙하 경로를 찾아보세요 ~/.cache-db/.node-sync/ 그리고 지속성 단위의 경우 윈노드 동기화 (예정된 작업) 및 com.apple.syncd (이러한 이름을 가져온) 개발자 컴퓨터에서 실행되었습니다.
  • cron 항목, 예약된 작업 또는 launchd 작업을 생성하는 Node 프로세스에 대한 경고입니다. 정상적인 라이브러리는 가져오기 시 이러한 작업을 거의 수행하지 않습니다.
  • 잠금 파일과 고정 버전을 선호하고, 특히 새로운 작은 "유틸리티" 종속성이 추가될 때마다 차이점을 검토하십시오. 종속성이 없는 패키지가 게시되었습니다. 검증되지 않은 계정이며 연결된 저장소가 없습니다.

레지스트리 보호 담당자에게 중요한 점은 설치 후크 모니터링이 필요하지만 충분하지는 않다는 것입니다. 데이터 파일 내부에 배치된 가져오기 시간 지연 드로퍼는 설치 시간 검사만으로는 통과할 수 있으며, 지속성 유지 단계가 포착하기 가장 어려운 신호인 경우가 많습니다.

sca-tools-software-composition-analysis-tools
소프트웨어 위험을 우선순위화하고, 해결하고, 보호하십시오.
무료 계정을 만드세요.
신용 카드가 필요하지 않습니다.

소프트웨어 개발 및 제공을 안전하게 보호하세요

Xygeni 제품군과 함께