السلوك الافتراضي عند تلقي إشارة ... ماذا تعني هذه الكلمات المطمئنة؟ ليس ما كنت تتوقعه ، بالتأكيد. يقول الويكي أن معالجات الإشارات الافتراضية 28 (هناك أخرى!) هي كما يلي: 2 يتم تجاهلها ، 4 تتسبب في توقف العملية ، 1 للمتابعة ، 11 للانتهاء ، 10 للانتهاء بتفريغ الذاكرة. الآن هذا مثير للاهتمام! لذا فالوضع كالتالي: حتى لو لم يذكر برنامجك الإشارات بأي شكل من الأشكال في الكود المصدري ، فهو في الواقع يستخدمها ، وبطريقة درامية للغاية.
من الآن فصاعدًا ، علينا أن نحفر أعمق. من يستطيع إرسال الإشارات ولمن؟ يقول الويكي: "يمكن لعملية (أو مستخدم من قذيفة) ذات UID فعال بخلاف 0 (UID المستخدم المتميز) إرسال إشارات إلى العمليات باستخدام نفس المعرف الفريد فقط." لذلك ، إذا قمت بتشغيل 100 برنامج ، فيمكن لأي منها بسهولة قتل كل هذه البرامج المائة باستخدام واجهة برمجة تطبيقات النظام ، حتى لو لم تذكر جميع البرامج (باستثناء القاتل) الإشارات بأي شكل من الأشكال في شفرة المصدر الخاصة بها. إذا كنت تعمل تحت حساب الجذر ، فلا يهم مطلقًا من أطلق عمليات معينة ، فلا يزال بإمكانك إنهاءها بسهولة. من الممكن ، بالطبع ، معرفة تفاصيل عملية معينة وتنفيذ "القتل المتعاقد عليه" ، ولكن من الأسهل قتل كل شخص يمكن أن يكون مجرد أداة تحكم في القوة الغاشمة.
"انتظر ، انتظر ، لا تقود الخيول. لقد ذكرت أنه يمكن معالجة الإشارات وتجاهلها! " - أسمع صوت القارئ. ماذا سيقول فيكي؟ "من أجل المعالجة البديلة لجميع الإشارات باستثناء SIGKILL و SIGSTOP ، يمكن للعملية تعيين معالجها الخاص أو تجاهل حدوثها عن طريق تعديل قناع الإشارة الخاص بها." ننظر إلى الإجراءات الافتراضية عند تلقي هذه الإشارات ونرى: "إنهاء العملية" ، "إنهاء العملية". اتضح أنه يمكننا القيام بهذين الإجراءين كلما كان إرسال إشارات SIGKILL و SIGSTOP إلى الضحية ممكنًا من حيث المبدأ. "الاستثناء الوحيد هو العملية مع pid 1 (init) ، والتي يُسمح لها بتجاهل أو التعامل مع أي إشارات ، بما في ذلك KILL و STOP."قد لا نكون قادرين حتى على قتل واحدة من أهم عمليات النظام كجذر ، ولكن بطريقة ودية ، هذا يتطلب بحثًا إضافيًا.
حسنًا ، أصبحت الصورة أكثر إيجابية قليلاً ، لكنها لا تزال قاتمة. إذا بدأت عملية ، فمن المؤكد أنها يمكن أن تنتهي وتوقف مجموعة من العمليات الأخرى. عندما يتم استيفاء شرط بسيط للغاية ، "نسي مطورو عملية الاستلام تجاهل إحدى الإشارات العديدة الأخرى أو التعامل معها بطريقة ما" ، فسيكون التطبيق المجنون قادرًا على إنهاء العملية بتفريغ الذاكرة أو مواصلة العملية بعد التوقف. إذا علق مطورو التطبيق المستلم معالجاتهم على بعض الإشارات ، فيمكنك محاولة التدخل في عمل هذا التطبيق عن طريق إرسال إشارات إليه. هذا الأخير موضوع لمناقشة منفصلة ، لأنه بسبب التنفيذ غير المتزامن للمعالجات ، فإن الأجناس والسلوك غير المحدد ممكن ...
سيخبرني القارئ المتطلب: "التفكير المجرد رائع جدًا ، لكن دعنا نقترب أكثر من التفاصيل". حسنا لا مشكلة! أي مستخدم * nix على دراية ببرنامج مثل bash. تم تطوير هذا البرنامج منذ ما يقرب من 30 عامًا ولديه مجموعة كاملة من الاحتمالات. دعونا نملأها من أجل الوضوح ونحصل على بعض لذيذ من ذاكرتها!
أخذت منزلي Ubuntu 16.04.2 من ساق عريضة وقمت بتشغيل نسختين من bash 4.3.46 عليه. في إحداها ، سأنفذ أمرًا افتراضيًا ببيانات سرية: تصدير كلمة المرور = SECRET. دعنا ننسى لفترة من الوقت عن الملف الذي يحتوي على محفوظات الأوامر ، والذي سيتم أيضًا كتابة كلمة المرور فيه. في نفس النافذة ، اكتب الأمر ps لاكتشاف معرف العملية لهذه العملية - لنقل 3580.
بدون إغلاق النافذة الأولى ، دعنا ننتقل إلى الثانية. سيعطي الأمر ps فيه pid آخر لمثال bash هذا - لنقل 5378. فقط من أجل الوضوح ، من هذا bash الثاني سنرسل إشارة إلى الأمر الأول kill -SIGFPE 3580. نعم ، عزيزي القارئ ، هذا عبث كامل: العملية 2 لا تقول شيئًا متعلقًا بـ لعملية 1 ، أنه في هذه العملية بالذات 1 حدثت عملية حسابية خاطئة. تظهر النافذة التالية على الشاشة:
حدث الشذوذ المطلوب مع إنشاء ملف تفريغ للذاكرة ، أي أن bash لا يبدو أنه يعالج هذه الإشارة أو يتجاهلها. بالبحث في Google حيث أبحث عن مكب النفايات ، وجدت إجابة مفصلة ( واحد ، اثنان). في Ubuntu الخاص بي ، يكون الوضع كالتالي: إذا تعطل تطبيق من الحزمة القياسية بسبب إشارة أخرى غير SIGABRT ، فسيتم نقل التفريغ إلى برنامج Apport. هذه فقط حالتنا! يقوم هذا البرنامج بتجميع ملف بمعلومات تشخيصية ويعرض النافذة الموضحة أعلاه. يذكر الموقع الرسمي بفخر ما يلي: "يجمع Apport البيانات التي يحتمل أن تكون حساسة ، مثل عمليات التفريغ الأساسية وتتبعات المكدس وملفات السجل. يمكن أن تحتوي على كلمات مرور وأرقام بطاقات ائتمان وأرقام تسلسلية ومواد خاصة أخرى ". حسنًا ، حسنًا ، أتساءل أين لدينا هذا الملف؟ نعم ، /var/crash/_bin_bash.1000.crash. دعنا نسحب محتوياته إلى مجلد somedir: apport-unpack /var/crash/_bin_bash.1000.crash somedir. بالإضافة إلى العديد من الأشياء الصغيرة غير المهمة ، سيكون هناك تفريغ ذاكرة مرغوب فيه يسمى CoreDump.
ها هي لحظة الحقيقة! دعنا نبحث في هذا الملف عن سلسلة كلمة المرور ونرى ما هو مثير للاهتمام في الرد. أمر Strings CoreDump | ستذكر كلمة مرور grep المتسلل النسيان بأن كلمة المرور سرية. رائع!
فعلت الشيء نفسه مع محرر النصوص المفضل لدي gedit ، وبدأت في الكتابة في المخزن المؤقت ثم قراءتها من التفريغ. ليس هناك أى مشكلة! في هذه المرحلة ، همست فيكي في أذنها محذرة: "في بعض الأحيان (على سبيل المثال ، للبرامج المنفذة نيابة عن المستخدم المتميز) لا يتم إنشاء تفريغ ذاكرة لأسباب أمنية." Soooo ، دعنا نتحقق من ... عند تلقي إشارة من root bash ، تعطلت عملية root bash الثانية بإنشاء ملف تفريغ للذاكرة ، ولكن بسبب الأذونات (-rw-r ----- مع مالك الجذر) لم يعد من السهل قراءتها مثل السابقة مملوكة لحساب المستخدم الخاص بي. حسنًا ، إذا تمكن برنامج القاتل الافتراضي من إرسال إشارة من UID المستخدم المتميز ، فيمكنه لمس مثل هذا التفريغ.
قد يلاحظ القارئ الدقيق ، "كان من السهل جدًا عليك العثور على البيانات التي كنت تبحث عنها في بحر القمامة." هذا صحيح ، لكنني متأكد: إذا كنت تعرف نوع الأسماك التي تريد صيدها وأين تسبح ، فيجب أن يكون العثور عليها في شبكات التفريغ أمرًا واقعيًا دائمًا تقريبًا. على سبيل المثال ، لا أحد يكلف نفسه عناء تنزيل حزمة تحتوي على معلومات تصحيح الأخطاء لبرنامج معطل ومعرفة محتويات المتغيرات التي تهتم بها في GDB عن طريق تصحيح الأخطاء بعد الوفاة.
قد يبدو كل هذا غير ضار تمامًا ، لكنه في الحقيقة ليس كذلك. يمكن بسهولة تنفيذ جميع الإجراءات التي وصفتها بواسطة برنامج أو برنامج نصي يعمل في وضع المستخدم ، ناهيك عن مستوى وصول أكثر امتيازًا. خلاصة القول هي أن الشيء الخبيث القابل للتنفيذ يمكنه بسهولة قطع البرامج إلى اليمين واليسار ، وغالبًا ما يقرأ ذاكرتهم بالكامل بحرية. ها هي الإشارات وتقارير الأخطاء! أنا متأكد من أن الوضع مشابه في الأنظمة الأساسية * nix الأخرى والبرامج المستقبلة الأخرى ، لكنني بالطبع لن أتحقق من ذلك.
قد ينشأ اعتراض: يمكن للبرامج الضارة ببساطة استخدام أدوات تصحيح الأخطاء لسحب البيانات المثيرة للاهتمام من التطبيق. هو حقا. لماذا اذن هذا المنشور؟ وجهة نظري هي أن أول ما يتبادر إلى الذهن عند محاولة إيقاف سرقة البيانات من التطبيقات هو مجرد القيود المفروضة على أدوات تصحيح الأخطاء. من المؤكد أن أدوات مكافحة الفيروسات تلتقط استخدام ptrace () في المقام الأول - وهذا حدث مريب للغاية. الإشارات هي مسألة أخرى تماما. عملية واحدة ترسل إشارة قياسية أخرى - وماذا في ذلك؟ للوهلة الأولى ، هذا حدث طبيعي تمامًا. ولكن ، كما رأينا بالفعل ، يمكن أن يؤدي ذلك إلى إنهاء غير طبيعي للتطبيق ، مما يؤدي إلى إنشاء تفريغ أساسي في مجلد ما ، يمكن محاولة سحبه منه.
عندما حاولت فتح صفحة تسجيل الدخول إلى vk.com وتفريغ Firefox بنفس الإشارة القاتلة ، تعطلت ، لكنها استدعت معالج التفريغ. يتم حفظ عمليات التفريغ بتنسيق minidump الصعب في ~ / .mozilla / Firefox / Crash Reports / {معلق أو تم تقديمه} وتتطلب المزيد من التحقيق. إليك ما ستكتشفه إذا ، في نافذة الإعدادات ، انقر فوق "مزيد من المعلومات" المقابل لعلامة الاختيار (النص أدناه يستخدم للتعليق على www.mozilla.org/ru/privacy/firefox/#crash-reporter ):
« Mozilla Firefox. , Firefox, , URL- , . , , . crash-stats.mozilla.com. . .»نادرًا ما يكون هناك شيء لذيذ حقًا في عناوين URL ، ولكن ما إذا كانت عمليات التفريغ تحتوي على كلمات مرور أو ملفات تعريف الارتباط فهذا سؤال جيد!
في هذه الملاحظة الغامضة والمثيرة للفضول ، سأنتهي. تلقيت إشارة أنني نسيت المعالجة بشكل صريح.
ملاحظة: لقد كتبت برنامجًا بسيطًا باستخدام معالج الإشارة SIGUSR1: اطبع السلسلة "1" على الشاشة ، أدخل حلقة لا نهاية لها. كنت آمل أنه إذا قمت بإرسال إشارة SIGUSR1 عدة مرات إلى هذا البرنامج ، فسيتم استدعاء المعالج عدة مرات ، مما يتسبب في تجاوز سعة المكدس. لسوء حظي ، تم استدعاء المعالج مرة واحدة فقط. حسنًا ، لنكتب معالجًا مشابهًا لإشارة SIGUSR2 ونرسل إشارتين مختلفتين على أمل أن يؤدي ذلك إلى تفريغ الضحية ... للأسف ، لم يساعد أيضًا: تم استدعاء كل معالج مرة واحدة فقط. فاضت ، فاضت ، لكنها لم تفيض!
ملاحظة 2. في عالم Windows ، يوجد نوع من الإشارات - رسائل يمكن إرسالها إلى windows . من المحتمل جدًا أنه يمكن استخدامها للمتعة والربح أيضًا!
تم نشر النص الأصلي على مدونتي في 05/05/17.