
هجوم Trusting-Trust على توزيعة لينكس كاملة: باحثون يحولون GNU strip إلى سلاح ضد NixOS
هجوم Trusting-Trust على توزيعة لينكس كاملة: باحثون يحولون GNU strip إلى سلاح ضد NixOS
قاعدة أساسية في أمن البرمجيات مفتوحة المصدر تقول: راجع الشيفرة المصدرية وستكتشف أي باب خلفي. ورقة بحثية جديدة تُظهر أن هذه القاعدة لا تحمي من شيء محدد، وأن أداة بناء عادية يمكن أن تفعل ما يُعتقد منذ أربعين عاماً أن المترجمات وحدها قادرة عليه.
فريق من Télécom Paris ومعهد KTH الملكي للتقنية في ستوكهولم (Julien Malka و Aman Sharma و Martin Monperrus و Stefano Zacchiroli و Théo Zimmermann) نشر على arXiv أول تنفيذ موثق من طرف إلى طرف لهجوم Ken Thompson الشهير “trusting trust” عبر أداة GNU strip بدل المترجم، داخل بناء توزيعة NixOS الحقيقية. النتيجة: صورة تثبيت رسومية كاملة تخرج من البناء بنجاح، بينما شبه كل ملفاتها التنفيذية ملغومة.
ما حدث
الورقة، المنشورة على arXiv برقم 2607.24888 بتاريخ 27 يوليو 2026، تصف هجوماً نظرياً وعملياً في آن واحد. الباحثون لم يكتشفوا ثغرة في NixOS ولا في GNU strip، بل بنوا هجوماً كاملاً لإثبات أن نطاق هجوم Thompson أوسع مما يُعتقد. أطلقوا كود “You’ve been pwned!” بدل حمولة حقيقية، وأفرجوا عن التنفيذ الكامل كحزمة تكرار قابلة للفحص.
الفكرة الأصلية: لماذا لا تكفي مراجعة الشيفرة
في محاضرته الشهيرة بجائزة تورنغ عام 1984 بعنوان “Reflections on Trusting Trust”، بيّن كين تومسون أن مترجماً ملغوماً يستطيع حقن باب خلفي في البرامج التي يبنيها، وفي نفس الوقت حقن منطق التلغيم نفسه في النسخ الجديدة من المترجم نفسه. الشيفرة المصدرية تبقى نظيفة تماماً، وأي إعادة بناء من المصدر تنتج ثنائيات ملغومة من جديد.
بقي هذا الهجوم لعقود فكرة نظرية تُناقش في أوساط أمنية، مع تنبيهات قديمة مثل تقرير Karger و Schell عن أمن Multics عام 1974، دون تنفيذ موثق كامل على توزيعة إنتاج حقيقية. الورقة الجديدة تسد هذه الفجوة، وتغيّر الفهم: المشكلة ليست في المترجمات بل في أي أداة تبني تعيش في بذرة الإقلاع (bootstrap seed) وتكتب في مخرجات البناء.
لماذا GNU strip تحديداً
GNU strip أداة من حزمة binutils تنظف الملفات التنفيذية من الجداول الرمزية ومعلومات التصحيح بعد البناء. لا تقرأ شيفرة مصدرية ولا تنتجها. لكن موقعها في خط البناء يمنحها خاصيتين ذهبيتين لأي هجوم من هذا النوع:
- تلمس كل شيء: كل حزمة في التوزيعة تمر بمرحلة fixup التي تستدعي strip على مخرجاتها، بغض النظر عن لغة البرمجة. المترجم مثل gcc يصيب فقط ما يترجمه؛ strip يصل إلى كل الثنائيات.
- تعيش في بذرة الإقلاع: بناء أي توزيعة يبدأ من حزمة صغيرة من الثنائيات الجاهزة (حوالي عشرين أداة في حالة NixOS: مترجم C و binutils والمكتبة القياسية و bash و coreutils وغيرها). هذه البذرة تُقبل ثقةً مسبقاً، لأنك تحتاج أدوات جاهزة لتبني الأدوات.
من يملك القدرة على استبدال ملف واحد في هذه البذرة يملك التوزيعة كاملة. الورقة تفترض هذا نموذج تهديد بوضوح: المهاجم يستطيع تعديل ثنائي واحد في البذرة، ولا يستطيع تعديل أي وصفة بناء أو شيفرة مصدرية.
كيف يعمل الهجوم: ثلاث مراحل
المرحلة الأولى هي تلغيم البذرة. الباحثون حقنوا الحمولة في ملف strip التنفيذي عبر ثلاث تحويلات على صيغة ELF لا تعدّل بايت واحد من كود البرنامج الأصلي: إلحاق (Append) للحمولة في نهاية الملف، إعادة توظيف (Repurpose) لرأس PT_NOTE احتياطي، وهو رأس يحمله كل ثنائي حديث كسجل build-id، وتحويله إلى مقطع تنفيذي، ثم إعادة توجيه (Redirect) لحقل نقطة الدخول في رأس ELF ليقفز المعالج إلى الحمولة أولاً. كما بنوا جدول مقاطع جديداً في نهاية الملف يتضمن مقطعاً باسم .payload حتى تبقى الأداة متسقة من وجهة نظر أدوات المعالجة اللاحقة في nixpkgs.
المرحلة الثانية هي الانتشار عبر أجيال strip. هنا تتحقق قاعدة Thompson الحقيقية. عند إعادة بناء strip من مصدر نظيف، تشتغل مرحلة fixup وتستدعي strip الأقدم (الملغوم) على الثنائيات الجديدة، ومنها strip الجديد نفسه. الأداة الملغومة تتعرف على نفسها عبر اسم العملية، تلغم الخليفة قبل تنظيفه، وتبقى الشيفرة المصدرية نظيفة. تتكرر العملية عبر مراحل البناء في nixpkgs حتى يصل التلغيم إلى strip البيئة القياسية النهائية، بعد أن تخرج البذرة الأصلية من دائرة الاعتماديات.
المرحلة الثالثة هي الاختراق. الحمولة مكتوبة كبرنامج freestanding مستقل: لا مكتبات، لا libc، استدعاءات مباشرة للنواة، لأن البايتات نفسها تُزرع في ثنائيات تبعياتها مختلفة تماماً. عند تشغيل أي ثنائي ملغوم تنفذ الحمولة أولاً، تتحقق من متغير NIX_BUILD_TOP لتبقى صامتة داخل بيئات بناء Nix فلا تفشل أي اختبار وظيفي أثناء البناء، وتنتحل صفة strip فقط عندما يكون اسم العملية strip، ثم تعيد الحالة وتقفز إلى نقطة الدخول الأصلية فيستمر البرنامج بشكل طبيعي.
النتائج بالأرقام
قيم الباحثون الهجوم على إصدار حقيقي من nixpkgs (الإصدار fef9403a3e4d بـ binutils 2.44 على x86_64-linux):
- بناء صورة التثبيت الرسومية اكتمل دون أي فشل عبر حوالي 2000 حزمة.
- حزمة المخرجات النهائية: 1,199 مخرج حزم، و 3,799 ملفاً تنفيذياً قابلاً للاستدعاء من المستخدم، بحجم إجمالي 6.16 جيجابايت.
- من بين 3,791 ثنائياً قابلاً للاستدعاء المباشر، 3,790 أظهرت علامة الإصابة عند تشغيلها.
- الثنائي الوحيد السليم: firefox 147.0.3، والسبب موثق تماماً: وصفة بنائه تمرر خيارَي —disable-strip و —disable-install-strip فتتخطى مرحلة strip بالكامل. هذا الاستثناء يؤكد القاعدة: الهجوم يصيب كل ما تلمسه strip.
- إصابة عبر مختلف الأنظمة البيئية: bash و git و sudo و curl و python3.13 وغيرها: لغة البرمجة لا تعني شيئاً لأن الهجوم يشتغل على الثنائيات مباشرة.
- اختبارات NixOS الوظيفية لصورة الرسوميات نجحت بالكامل، أي أن السلوك الخبيث لا يفسد شيئاً أثناء البناء.
هذا الرقم الأخير هو الأكثر إثارة للقلق: التوزيعة الملغومة تجتاز اختباراتها الوظيفية كلها. البناء “ينجح” والاختبارات “تنجح” والثنائيات كلها خبيثة.
هل NixOS عرضة أكثر من غيرها؟
لا. البذرة الملغومة تمثل سيناريو هجوم لا خصوصية له في NixOS؛ نفس البنية موجودة في كل التوزيعات، فقط اسمها يختلف. لكن NixOS (و GNU Guix) يملكان شيئاً يقلل فعلياً من جدوى الهجوم: بناء قابلاً لإعادة الإنتاج (Reproducible Builds) وثقافة إعادة بناء شبه كاملة من المصدر.
عندما يمكن إعادة بناء كل ثنائي من المصدر ومقارنة النتيجة بايت ببايت، فإن أي اختلاف غير مبرر بين بناءين مستقلين هو إنذار. ورقة Malka نفسها (منشورة في أكتوبر 2025) تشرح كيف كان بإمكان البناء القابل لإعادة الإنتاج كشف هجوم xz في 2024. المناهج الأعم مثل Diverse Double-Compiling من David Wheeler و مشروع Bootstrappable Builds و GNU Mes التي تعيد بناء سلسلة المترجمات كاملة من مصدر أصغر، تعالج جذر المشكلة نفسه.
الفارق العملي: التوزيعات التي تشحن ثنائيات مباشرة من بنية خوادم مركزية أكثر عرضة لفكرة “بذرة ملغومة واحدة تكفي”، والتوزيعات التي تعيد البناء والتحقق تكتشف هذا النوع من التلاعب. لا توزيعة محصنة بالكامل، لكن التحقق المستقل يقلص نافذة الهجوم.
ماذا يفعل المطورون الآن
- مطوّر التوزيعات والبنى التحتية: انظر إلى بذرة الإقلاع لديك كم سطح هجوم من الدرجة الأولى. أي ثنائي فيها يكفي. قيّم أدوات إعادة البناء من المصدر (bootstrappable builds) وازن تكلفة إضافتها مقابل سطح الهجوم الذي تقطعه.
- فريق الأمن في مؤسسة تبني من مصادر مفتوحة: لا تعتبر الثنائيات الموقعة ضماناً كافياً. التوقيع يثبت سلسلة النقل، لا نظافة البناء الأصلي. فعّل Reproducible Builds حيثما أمكن وتحقق من بناءات مستقلة.
- مستخدم NixOS أو Guix: استخدم ذاكرة (cache) ثنائية موثوقة، وفعّل التحقق من التواقيع، وتابع عمل Reproducible Builds داخل المشروعين؛ الورقة فعلياً حجة إضافية لصالح البناء من المصدر الذي تشتهر به هذه الأنظمة.
- كل المطورين: هذا تذكير بأن سطح هجوم سلسلة التوريد لا يتوقف عند المترجم. أي أداة تُقبل ثقةً مسبقاً وتكتب في مخرجات البناء مرشح نظرياً.
حدود الهجوم
الورقة صريحة بشأن حدودها. نموذج التهديد يفترض مهاجماً يستطيع تعديل بذرة الإقلاع نفسها، وهذا ليس اختراقاً عن بعد بل يتطلب الوصول لنظام بناء البذرة أو إقحام تحديث موقّع أو هندسة اجتماعية لعملية مراجعة البذرة. الحمولة في النموذج العملي مجرد رسالة “You’ve been pwned!” وليست برمجية خبيثة حقيقية. إعادة تشغيل البناء بخلاف البذرة الملغومة نظيف. والهجوم كما نُفذ يستهدف x86_64-linux و binutils 2.44 وتحديداً NixOS. تعميمه على بيئات أخرى ممكن نظرياً لكنه غير مثبت في الورقة.
نقطة أخيرة: وجود تنفيذ كامل منشور يعني أن عتبة تنفيذ هذا الهجوم انخفضت للجميع. حتى لو لم تُستغل اليوم، فالورقة موضع اهتمام حقيقي لأي يعمل على بناء البرمجيات.