«الاستمرارية» (persistence) هو المصطلح الأمني لمشكلة محددة واحدة: كيف يرتب كود عمل مرة واحدة أن يعمل مجددًا، تلقائيًا، بعد إعادة تشغيل أو تسجيل دخول، دون أن يعيد أحد تشغيله يدويًا؟ يمنح macOS البرمجيات المشروعة طرقًا معتمدة كثيرة للقيام بذلك بالضبط — أداة فحص تحديثات، عميل مزامنة في شريط القوائم، مساعد لتعريف طابعة — وكل واحدة من تلك الآليات متاحة بالقدر نفسه لشيء تفضّل ألا يعمل على الإطلاق. هذه جولة على الأماكن الفعلية التي يجب النظر فيها، بالأوامر الحقيقية، وسرد صادق لأين تنتمي أداة تركّز على الشبكة مثل FireAI في هذه الصورة وأين لا تنتمي.
LaunchAgents وLaunchDaemons: الاثنان الكبيران
يشغّل macOS تقريبًا كل شيء عبر launchd، مدفوعًا بملفات قوائم خصائص (.plist) في عدد قليل من الأدلة المعروفة. تصف تقنية T1543.001 من MITRE ATT&CK الآلية بوضوح: عند تسجيل الدخول، تحمّل عملية launchd خاصة بكل مستخدم قوائم plist من أدلة LaunchAgents الخاصة بالمستخدم والنظام، وتُشغَّل قائمة plist مضبوطة على RunAtLoad بقيمة true تلقائيًا لحظة تحميلها — دون الحاجة إلى أي إجراء إضافي ممن وضعها هناك. تسرد التقنية المواقع الثلاثة المهمة: /System/Library/LaunchAgents، و/Library/LaunchAgents، و~/Library/LaunchAgents. وتشير MITRE إلى أمر يستحق التذكر أثناء تصفحك قائمة من هذه الملفات: غالبًا ما «تُموَّه» العملاء (agents) المثبَّتة للاستمرارية «باستخدام أسماء تشبه مكوّنات نظام تشغيل أو برامج شرعية» — فالملف الذي يبدو مثل com.apple.something.plist يستحق نظرة ثانية بالضبط لأنه يحاول ألا يحصل عليها.
أما LaunchDaemons، التي تغطيها التقنية ذات الصلة T1543.004، فهي النسخة على مستوى النظام بأكمله ولا تتطلب تسجيل دخول: تعمل بصلاحيات root، وتبدأ عند الإقلاع، من /System/Library/LaunchDaemons/ أو /Library/LaunchDaemons/. ولأن تثبيت واحدة هناك يتطلب صلاحيات إدارية أصلًا، تصف MITRE مسار الخدمة (daemon) بأنه طريقة لتحويل موطئ قدم مميَّز أولي إلى شيء يصمد أمام إعادة التشغيل، ويعمل بوصول على مستوى root منذ تلك اللحظة — وهذا أيضًا سبب كون ظهور ملف جديد غير مألوف في /Library/LaunchDaemons إشارة أثقل من ظهوره في مجلد LaunchAgents الخاص بمستخدم ما.
ls -la ~/Library/LaunchAgents /Library/LaunchAgents /Library/LaunchDaemons
# compare this list against what you remember installing; anything you don't
# recognise is worth reading with: plutil -p /path/to/the.plistوجود ملف على القرص وتحميل مهمة فعليًا سؤالان مختلفان، ويجيب launchctl print عن الثاني. يصف دليل استخدامه الأمر بأنه يطبع «معلومات عن الخدمة أو النطاق المحدد» — وموجَّهًا إلى نطاق مثل system/ أو gui/501/ (حيث 501 هو معرّف مستخدم UID)، يسرد كل خدمة ونقطة نهاية محمَّلة حاليًا في ذلك السياق، مع حالة كل واحدة:
launchctl print gui/$(id -u)
# example output, trimmed — a real run lists every loaded agent for your session
"com.apple.someAgent" => {
active count = 1
path = /Library/LaunchAgents/com.apple.someAgent.plist
state = running
}عناصر تسجيل الدخول وإدارة المهام الخلفية
الواجهة الظاهرة للمستخدم في كثير من هذا هي لوحة عناصر تسجيل الدخول (Login Items) في إعدادات النظام، ويستحق الأمر التحقق منها بعينيك، لا سطر الأوامر فقط. يصف دليل الدعم من Apple ذلك مباشرة: يمكنك «اختيار عناصر تسجيل دخول تُفتح تلقائيًا عند تسجيل الدخول»، وإضافتها أو إزالتها هناك، وبشكل منفصل السماح للتطبيقات أو منعها من «أداء مهام حين لا يكون التطبيق مفتوحًا، مثل التحقق من تحديثات البرامج أو مزامنة البيانات» — وتلك الفئة الثانية تغطي المساعدات الخلفية التي ليست عناصر تسجيل دخول كاملة لكنها لا تزال تعمل دون مراقبة.
منذ macOS Ventura، يُطلق على النظام الذي يقف خلف لوحة الإعدادات تلك عادة اسم إدارة المهام الخلفية (Background Task Management أو BTM) في مجتمع الأمن: خدمة تتتبع كل عميل إطلاق، وخدمة إطلاق، وعنصر تسجيل دخول بمجرد أن يسجّل نفسه، وهذا ما يتيح لإعدادات النظام عرض قائمة حية ومركزية بدلًا من اضطرارك للبحث يدويًا عبر ثلاثة أدلة plist. توجد أداة سطر أوامر غير موثَّقة، sfltool، يستخدمها بعض الباحثين للاستعلام عن تلك القاعدة مباشرة أكثر عبر sfltool dumpbtm — لا تشحن Apple دليل استخدام لها، وتنسيق مخرجاتها غير مضمون أن يبقى ثابتًا، فعاملها كفضول بحثي تجربه على جهازك الخاص لا شيئًا تبني عليه سير عمل. الطريقة المدعومة والثابتة لرؤية المعلومات نفسها لا تزال لوحة عناصر تسجيل الدخول في إعدادات النظام، أو launchctl print للحالة الحية لمهمة محددة.
cron: أقدم، أهدأ، ولا يزال موجودًا
ظل launchd المجدوِل المفضَّل لدى Apple لفترة طويلة، لكن خدمة Unix الأقدم cron لا تزال تُشحَن وتشغّل أي شيء مجدوَل فيها. يصف دليل استخدام crontab تنسيق الملف مباشرة: يحتوي كل سطر على خمسة حقول وقت/تاريخ — الدقيقة، والساعة، ويوم الشهر، والشهر، ويوم الأسبوع — يتبعها الأمر المطلوب تشغيله، مع توفر اختصارات مثل @reboot بدلًا من الحقول الخمسة على بعض الأنظمة. يقوم crontab -l، وفق دليل استخدام crontab(1)، بـ«عرض جدول crontab الحالي على المخرج القياسي» للمستخدم الحالي:
crontab -l
sudo crontab -l -u rootنتيجة فارغة لكليهما أمر طبيعي على معظم أجهزة Mac اليوم — وهذا بالضبط سبب استحقاق أي شيء موجود هناك للانتباه. cron غير لافت ونادرًا ما يُفحص، وهذا بالضبط سبب استمرار ظهوره كموقع استمرارية احتياطي في تقارير الحوادث.
ملفات تعريف الإعداد: استمرارية بسجل ورقي
يمكن لملف تعريف إعداد تثبيت خدمة LaunchDaemon، أو منح أذونات خصوصية، أو دفع إعدادات عبر أسطول من أجهزة Mac — وهذا، بشكل مشروع، هو كيفية عمل إدارة الأجهزة المحمولة (MDM). أما بشكل غير مشروع، فملف التعريف طريقة موثَّقة لجعل تغييرات تصمد دون لمس ملف plist مباشرة. تسرد أداة سطر الأوامر profiles ما هو مثبَّت: يعرض profiles list ملفات التعريف المثبَّتة، وكما يشير دليل استخدامها، فإن تشغيلها بصلاحيات root مع -all «يسرد كل ملفات تعريف الإعداد على النظام» لا ملفات المستخدم الحالي فقط.
sudo profiles list -all
sudo profiles show -allينبغي عمومًا ألا يحتوي جهاز Mac شخصي غير مسجَّل في MDM على أي ملف تعريف، أو فقط ملفات ثبّتّها أنت عمدًا (إعداد VPN، ملف تعريف عمل). ملف تعريف لا تتذكر تثبيته يستحق التحقيق قبل إزالته، إذ تدعم profiles أيضًا الإزالة بحماية كلمة مرور لهذه الخطوة بالضبط.
إضافات التفويض والذيل الطويل
إلى جانب الأربعة الكبار أعلاه، هناك ذيل طويل من آليات أصغر وأقدم: إضافات خدمة الدليل والتفويض، ومستوردات Spotlight، ومولّدات QuickLook، وإضافات أيقونات Dock، وملفات بدء تشغيل الصدفة (shell) التي تعمل في كل مرة تُفتح فيها جلسة طرفية جديدة. وهنا تثبت أداة مصمَّمة خصيصًا لهذا الغرض جدارتها على الفحص اليدوي. فأداة KnockKnock من Objective-See، على سبيل المثال، تعدّد أكثر من عشرين فئة من مواقع الاستمرارية في مرور واحد — بما في ذلك عملاء وخدمات الإطلاق، وعناصر تسجيل الدخول، وإضافات المتصفح، ومهام cron، وإضافات النواة والنظام، وإضافات التفويض وخدمة الدليل — وتعرض حالة توقيع الكود لما تجده في كل واحدة منها. ورفيقتها، BlockBlock، تأخذ القائمة نفسها من المواقع وتراقبها باستمرار، منبِّهة لحظة تسجيل شيء جديد نفسه؛ ووفق وصفها الخاص، فهي «تراقب مواقع الاستمرارية الشائعة وتنبّه كلما أُضيف مكوّن مستمر جديد»، معروضةً العملية المسؤولة وحالة توقيعها، وتتيح لك السماح أو الحظر فورًا.
ملفات بدء تشغيل الصدفة: الشبكة الصامتة الجامعة
موقع آخر يستحق نظرة مباشرة، لأنه لا يحتاج إلى plist ولا إلى تثبيت مميَّز على الإطلاق: ملفات إعداد الصدفة (shell). تعمل ~/.zshrc و~/.zprofile و~/.bash_profile في كل مرة تُفتح فيها جلسة طرفية جديدة مطابقة، وسطر واحد مُضاف — يمرّر إلى سكربت، أو يصدّر متغير PATH مُخترَقًا، أو يشغّل عملية خلفية — كافٍ لإعادة ترسيخ موطئ قدم في كل مرة تفتح فيها Terminal، دون شيء يُحمَّل في launchd ودون شيء يعرضه launchctl print. تتضمن أداة KnockKnock من Objective-See هذه الفئة بالضبط في فحصها، مدرَجة إلى جانب عملاء الإطلاق وعناصر تسجيل الدخول باسم ملفات إعداد الصدفة، للسبب نفسه الذي يجعلها تستحق مكانها في هذا المقال: فهي شائعة بما يكفي، وغير لافتة بما يكفي، لتستحق الفحص بدلًا من الافتراض.
cat -A ~/.zshrc ~/.zprofile ~/.bash_profile 2>/dev/null | less
# -A shows non-printing characters, which surfaces anything hidden with
# trailing whitespace or a carriage return trying to push it off-screenأين يندمج FireAI، وأين لا يندمج عمدًا
لنكن مباشرين بشأن هذا: لا يفحص FireAI مجلد /Library/LaunchDaemons، ولا يقرأ ملفات plist، ولا يحاول اكتشاف عنصر تسجيل دخول جديد أو ملف تعريف إعداد. هذا تخصص مختلف عمّا يفعله FireAI، وأدوات مصمَّمة خصيصًا لذلك — من بينها KnockKnock وBlockBlock — تؤدي تلك المهمة جيدًا بالفعل. ما يراقبه FireAI هو الخطوة التي تأتي بعد الاستمرارية، والتي تحتاجها في النهاية كل واحدة من هذه الآليات إن أرادت أن تكون مفيدة لمن ثبّتها: اتصال شبكي. عميل إطلاق يعمل بهدوء في كل تسجيل دخول لكنه لا يتحدث مع الشبكة أبدًا هو، من منظور جدار حماية للشبكة، غير مرئي — وأيضًا، عمليًا، أقل فائدة بكثير لمهاجم. لحظة أن يفتح مقبسًا فعليًا، تنطبق عليه قواعد FireAI الخاصة بكل تطبيق مثل أي عملية أخرى: ملف تنفيذي موقّع أو غير موقّع غير مألوف يجري اتصاله الأول يُطلق مطالبة، مع عرض تفكير النموذج العامل على الجهاز بلغة بسيطة، وكل قرار مرئي وقابل للتراجع ويمكن تصديره كقاعدة نصية لاحقًا.
الطريقة الصادقة للجمع بين التخصصين: تحقق من المواقع في هذا المقال بجدول يناسب تحملك للمخاطر — شهريًا معقول لمعظم الناس، وأسبوعيًا إن كنت تثبّت كثيرًا من برامج الطرف الثالث — واترك أداة شبكية تتحمل العبء بينهما، على افتراض أن أي شيء استمر بهدوء سيضطر في النهاية إلى التحدث للوصول إلى من يرد إليه.
دور FireAI وHisnLabs
FireAI does not scan for persistence — that is a different job, and tools like KnockKnock and BlockBlock already do it well; what FireAI watches is what that persisted code does the moment it opens a socket, which is the step every one of these mechanisms eventually has to take to be useful to whoever installed it.
FireAI هو منتج HisnLabs نفسها: جدار حماية بذكاء اصطناعي يعمل على جهاز Mac مباشرة. يعرض بلغة واضحة كل اتصال تجريه تطبيقاتك، ويترك لك القرار فيما يخرج من جهازك — ذكاؤه الاصطناعي يعمل محليًا، فلا يُرسَل ترافيكك إلينا ولا إلى أي جهة أخرى أبدًا. فريق أبحاث الأمن في HisnLabs هو من يحافظ على دقة هذه القرارات: يصنّف النطاقات بين قياس عن بُعد عادي وخدمة حقيقية، ويتتبّع بلد وشبكة كل اتصال، ويدرّب النموذج المحلي (ميزة Autopilot) على حركة اتصال حقيقية، دون أن يغادر أي شيء جهاز Mac.
يمكنك الاطلاع على القرارات التقنية وراء ذلك، أو تجربة FireAI لمدة 17 يومًا، على FireAI من HisnLabs.
