Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
SPiCa — كاشف روتكيت لينكس يعتمد على eBPF باستخدام تحليل متعدد القنوات عبر الرؤى (sched_switch, NMI, /proc) لكشف DKOM والتلاعب بنقاط التتبع وإخفاء العمليات مع التحقق من التكامل على مستوى العتاد. | Kitploit
أدوات/GitHubGitHub/0xkirisame/spica
أدوات دفاعيةإدارة مؤشرات الاختراق (IOC)التحقيق الجنائي الرقميتحليل البرمجيات الخبيثةتحليل الملفات الثنائيةكشف التسللالأوراق والأبحاثالتعلم والتعليمالاستجابة للحوادثكشف الشذوذ
GitHub0xkirisame/spica

SPiCa

1046منذ شهر واحدتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

كاشف روتكيت لينكس يعتمد على eBPF باستخدام تحليل متعدد القنوات عبر الرؤى (sched_switch, NMI, /proc) لكشف DKOM والتلاعب بنقاط التتبع وإخفاء العمليات مع التحقق من التكامل على مستوى العتاد.

عرض المستودع

SPiCa

تحليل سلامة العمليات النظامية ورؤية متقاطعة

SPiCa

"سأغني، لذا أشرق بشدة، SPiCa..."

SPiCa هو كاشف روتكيت لنظام لينكس يعتمد على eBPF ومكتوب بلغة رست. الاسم مستوحى من أغنية Hatsune Miku SPiCa والنجم الذي تشير إليه — سبيكا (ألفا العذراء)، ألمع نقطة في برج العذراء. ما يبدو كنجم واحد بالعين المجردة هو في الواقع ثنائي طيفي: نجمان في مدار متبادل، لا يمكن تمييزهما كجسمين منفصلين دون قياس أطيافهما. يطبق SPiCa نفس المبدأ على مراقبة النواة: عدة قنوات مستقلة تقيس نفس حالة النواة من آليات متميزة فيزيائيًا، والروتكيت الذي يكتم إحداها يفضح بواسطة الأخرى.

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


جدول المحتويات

  1. نموذج التهديد
  2. نظرة عامة على البنية
  3. قناة مراقبة sched_switch
  4. قناة سلامة NMI
  5. منطق الكشف
  6. سرية العناوين المحدودة بالمدقق
  7. بوابة الوصول إلى الخرائط LSM
  8. إدارة المفاتيح والتعتيم
  9. ختم TPM المقيد بـ PCR (تصميم)
  10. الدفاع في العمق
  11. حادثة خطأ BTF
  12. القيود المعروفة وسطح الهجوم
  13. البناء والتشغيل
  14. خريطة الطريق
  15. المسرد

1. نموذج التهديد

الخصم المقيد: روتكيت eBPF

صُمم SPiCa لهزيمة الخصم المقيد بـ eBPF — مهاجم يتمتع بصلاحيات مرتفعة (CAP_BPF أو CAP_SYS_ADMIN) ويقوم بتحميل برنامج eBPF ذو صلاحيات في النواة. هذا الخصم أضعف جوهريًا من روتكيت LKM لأن مدقق BPF يفرض قيودًا صارمة:

مع حظر LKMs بواسطة بوابة LSM بعد الإقلاع، يبقى هذا الخصم المقيد هو التهديد الواقعي المتبقي. آليات SPiCa المضادة للتهرب معايرة لهذا التهديد — كل دفاع صريح بشأن ما يغطيه وما لا يغطيه.

أهداف غير مدرجة

  • ثغرات النواة على مستوى الدولة — إفساد الذاكرة يؤدي إلى كتابة عشوائية للنواة دون init_module. SPiCa يرفع المستوى الأدنى بحجب ناقل LKM الأسهل ولكنه لا يحد من الخصم عند المستوى الأعلى.
  • LKMs معادية تم تحميلها قبل بدء SPiCa — الدفاع في العمق (الإقلاع الآمن، توقيع الوحدات، IMA) مطلوب لنافذة الإقلاع.
  • ثغرات المدقق — إذا كان مدقق BPF غير سليم (ثغرات تاريخية: CVE-2020-27194, CVE-2022-23222, CVE-2023-2163)، فإن الخصم يهرب من النموذج المقيد إلى تنفيذ شيفرة نواة عشوائية. هذه فئة تهديد منفصلة. دفاعات SPiCa صالحة في ظل مدقق صحيح.

SPiCa هو طبقة الملاذ الأخير في مجموعة دفاع في العمق، وليس بديلاً عن الطبقات التي تعلوه.


2. نظرة عامة على البنية

يشغل SPiCa أربعة برامج eBPF مرتبطة بخطافات النواة، بالإضافة إلى محرك كشف في مساحة المستخدم يربط ناتجها عرضيًا مع رؤية النظام لنفسه (/proc).

ثلاث قنوات مراقبة، كل منها يمكن كتمه فقط بآلية ذات تكلفة متصاعدة

الخاصية البنيوية الرئيسية: لا يمكن للروتكيت كتم جميع القنوات الثلاث في وقت واحد دون أن يصبح الكتم نفسه قابلاً للكشف أو مزعزعًا للاستقرار. كتم NMI يتطلب تعديل IDT (جدول واصف المقاطعات)، مما يسبب ذعرًا في معظم النوى. هذه هي "القنبلة الحية" — الطريق الوحيد للعمى الكامل للمهاجم هو طريق من المحتمل أن ينهار النظام.

نموذج الكشف — ثلاث جمل```

sched sees it, /proc doesn't → DKOM NMI finds sched's heartbeat stopped → TAMPER sched goes globally silent, /proc != empty → SILENT

root@kitploit:~
كل فئة كشف هي حكم تفاضلي: تباين بين قناتين أو أكثر. محرك الكشف هو دالة خالصة فوق سجل النظام + لقطة /proc + طوابع زمنية للقنوات — لا إدخال/إخراج، لا آثار جانبية، قابلة للاختبار بالكامل بالوحدات.

### إعادة تصميم NMI: من المراقبة إلى التكامل

في التصميم الأصلي، كانت NMI قناة مراقبة عمليات ثانية تقوم بأخذ عينات من وحدة المعالجة المركزية والإبلاغ عن المهمة الجاري تشغيلها. كان هذا زائدًا عن الحاجة: `sched_switch` تراقب بالفعل جدولة العمليات، وكانت NMI تأخذ نفس البيانات عبر آلية مختلفة. كلف هذا التكرار ما يقرب من 1000+ حدث/ثانية/CPU في الحلقة العازلة من بيانات العملية والتي تؤكد في 99.999% من الوقت "نعم، المجدول يفعل ما يفعله المجدول."

في البنية المعاد تصميمها، **تم إعادة استخدام NMI من مراقبة العمليات إلى التحقق من سلامة نقاط التتبع (tracepoint).** لم تعد تُبلغ عن العملية التي تعمل على وحدة المعالجة المركزية. بدلاً من ذلك، تتحقق من أن `sched_switch` تعمل بالفعل عن طريق قراءة إشارة نبض مشتركة في قسم `.bss`. هذا:

1. يلغي حوالي 99% من حركة مرور الحلقة العازلة الخاصة بـ NMI (أحداث شبه صفرية في الحالة المستقرة)
2. يكتشف بشكل مباشر انفصال نقاط التتبع، وقمعها، وفشل إرفاق BTF (خلل BTF الأصلي — انظر [§11](#11-the-btf-bug-incident))
3. يعمل من مقاطعة أجهزة، خارج مسار إرسال نقاط التتبع — محصن ضد `bpf_override_return`، واعتراض kprobe، والتلاعب بمصفوفة الدوال
4. يقرأ المتغيرات العامة في `.bss` عبر الوصول المباشر للذاكرة، وليس مساعدات BPF — محصن ضد `fmod_ret` على الدوال المساعدة

---

## 3. قناة مراقبة sched\_switch

برنامج eBPF ملحق بنقطة التتبع `sched_switch` يتم تشغيله في كل مرة يقوم فيها النواة بجدولة عملية على وحدة معالجة مركزية. يقرأ معرف العملية (PID) واسم الأمر (comm) الخاصين بالمهمة الواردة مباشرة من وسيطات نقطة التتبع باستخدام قراءات تقليدية (غير BTF) ذات إزاحة ثابتة:```
ctx.read_at::<u32>(56)    → next_pid
ctx.read_at::<[u8;16]>(40) → next_comm

متعمد عدم استخدام BTF/CO-RE. تخطيط وسيطات نقاط التتبع ثابت عبر إصدارات النواة (فهي جزء من واجهة ABI لنقاط التتبع). استخدام الإزاحات المبرمجة يجنب هشاشة إصدارات النواة التي قد تسببها تنقل بنى struct عبر BTF. هذا اختيار تصميمي متعمد موثق في §11.

في كل استدعاء، يقوم البرنامج بما يلي:

  1. قراءة next_pid و next_comm من سياق نقطة التتبع
  2. تصفية مهمة الخمول (PID 0)
  3. إخفاء بنية ProcessInfo باستخدام XOR مع BASE_KEY
  4. إرسالها إلى الحلقة المخزنة sc_sched
  5. كتابة bpf_ktime_get_ns() إلى المتغير العام .bss SCHED_HEARTBEAT — النبضة التي يراقبها مدقق سلامة NMI

يتجنب البرنامج عمداً استخدام bpf_get_current_pid_tgid() في هذا السياق. في وقت sched_switch، تكون "المهمة الحالية" هي المهمة الخارجة، وليست الواردة. توفر وسيطات نقطة التتبع هوية العملية الصحيحة (الواردة).

انضباط القاعدة الزمنية

يستخدم محرك الكشف قاعدة زمنية أحادية رتيبة: نانوثانية منذ بدء تشغيل عملية SPiCa (Instant::now() منذ دخول run_detection()). عندما يصل حدث جدولة، يخزن معالج الحدث now المقدم من المتصل (نانوثانية محلية للعملية)، وليس قيمة bpf_ktime_get_ns() من eBPF المضمنة في الحدث. هذا يتجنب عدم تطابق القاعدة الزمنية الذي قد يحدث إذا اختلط زمن إقلاع النواة بالزمن المحلي للعملية — وهو خطأ كان موجوداً في الإصدارات السابقة وتسبب في فشل جميع مسندات البقاء بصمت.


4. قناة سلامة NMI

التصميم: نبضة .bss، بدون BTF، بدون التنقل في بنى النواة

برنامج NMI ملحق بعداد أداء عتادي (HW_CPU_CYCLES) ينطلق عند مستوى مقاطعة العتاد. لا يمكن تعطيل NMIs باستخدام cli — قمعها يتطلب إعادة برمجة PMU أو ربط IDT، وكلاهما صاخب وزعزعة للاستقرار.

آلية فحص السلامة بسيطة للغاية:``` .bss (shared within SPiCa's ELF object — all programs see the same memory): SCHED_HEARTBEAT ← written by sched_switch on every invocation NMI_LAST_HB ← NMI's record of the last heartbeat it observed NMI_FIRST_TICK ← first NMI invocation timestamp (grace period reference) NMI_LAST_EMIT ← throttle: last event emission timestamp

sched_switch runs → SCHED_HEARTBEAT = bpf_ktime_get_ns()

NMI fires (once per second, throttled): if SCHED_HEARTBEAT == NMI_LAST_HB: if past grace period (5 seconds since first NMI tick): → sched_switch stopped running → emit event_type=1 (TAMPER) else: → sched_switch is alive → emit event_type=0 (heartbeat OK) NMI_LAST_HB = SCHED_HEARTBEAT

root@kitploit:~
### لماذا يكتشف هذا كل هجوم في النطاق

| الهجوم | ما يحدث | ما يراه NMI |
|---|---|---|
| تم فصل نقطة التتبع عن مصفوفة الدوال | يتوقف sched\_switch عن التنفيذ | يتجمد `SCHED_HEARTBEAT` → TAMPER |
| خلل BTF / فشل الإرفاق (صامت) | لا يتم تنفيذ sched\_switch أبدًا | يبقى `SCHED_HEARTBEAT` صفرًا → TAMPER (بعد فترة السماح) |
| `bpf_override_return` على دالة جدولة | إذا منع نقطة التتبع من الإطلاق | يتجمد `SCHED_HEARTBEAT` → TAMPER |
| تصحيح البايت كود في مكانه | يتطلب كتابة عشوائية في النواة (على مستوى LKM) | خارج نموذج تهديد eBPF |
| معالجة مؤشر المستهلك للمخزن المؤقت الحلقي | أحداث sched لا تصل إلى مساحة المستخدم | لا يزال `SCHED_HEARTBEAT` يتقدم (البرنامج يعمل) → لا TAMPER خاطئ؛ تكتشف مساحة المستخدم عبر `max(sched_last)` stale → SILENT |

### لماذا `.bss` تحديدًا

متغيرات `.bss` العامة تُخزن في قسم البيانات الداخلي لبرنامج BPF، الذي يديره المُحمل بواسطة مصفوفة خريطة داخلية. وهي:

- **غير قابلة للتثبيت بشكل منفصل** — لا تظهر كخرائط مسماة في `/sys/fs/bpf/`
- **غير قابلة للاعتراض عبر خطافات `bpf_map_update_elem`** — كتابات `.bss` هي تخزين مباشر في الذاكرة، وليست استدعاءات نظام لتحديث الخريطة. لم تعد آلية `sc_canary` القديمة (مقارنة نسخة `.bss` مع نسخة خريطة مسماة للكشف عن اعتراض `bpf_map_update_elem`) ضرورية.
- **مشتركة بين البرامج في نفس كائن ELF** — يتواصل sched\_switch و NMI عبر `.bss` بدون أي واجهة خارجية

### المناعة ضد الاعتراض القائم على BPF

مُدقق سلامة NMI محصن هيكليًا ضد هجمات تجاوز BPF بسبب خاصية أساسية: `bpf_override_return` يعترض استدعاءات **الدوال**، لكن مدقق NMI لا *يستدعي* الأشياء التي يتحقق منها — بل *يقرأ ذاكرة `.bss` مباشرة*. لا يمكنك تجاوز قيمة الإرجاع لقراءة ذاكرة لأن قراءة الذاكرة ليست استدعاء دالة.

بالإضافة إلى ذلك:
- `bpf_probe_read_kernel` (المستخدم لقراءة هياكل النواة في التصاميم البديلة) هو مساعد آمن ضد الأخطاء يقبل أي عنوان — لكن تصميم SPiCa للنبضات عبر `.bss` لا يحتاجه حتى. يقرأ المدقق متغيرات `.bss` العامة عبر تعليمات تحميل مباشرة.
- برنامج NMI يعمل في سياق NMI، حيث تكون kprobes غير موثوقة هيكليًا (تؤجلها النواة أو تمنعها). هجوم قائم على kprobe ضد تنفيذ المدقق يصطدم بالعتاد.

### دلالات أحداث NMI

المخزن المؤقت الحلقي NMI (`sc_nmi`) يحمل أحداثًا خفيفة الوزن:

| `event_type` | المعنى | إجراء مساحة المستخدم |
|---|---|---|
| 0 | نبضات — NMI حي، sched\_switch حي | تحديث طابع زمني `last_nmi_heartbeat` |
| 1 | TAMPER — NMI حي، نبضات sched\_switch مجمدة | طباعة `[TAMPER]` فورًا |

تصدر الأحداث مرة واحدة على الأكثر في الثانية (مقيدة بـ `NMI_LAST_EMIT`). إذا أصبح المخزن المؤقت الحلقي NMI صامتًا لأكثر من 5 ثوانٍ، تطلق مساحة المستخدم `[SILENT]` — قناة NMI نفسها ميتة.

---

## 5. منطق الكشف```mermaid
graph TD
    subgraph RING0["Kernel Space: Four eBPF Programs"]
        direction TB
        SCHED_P["TracePoint, sched_switch<br/>read next_pid, next_comm<br/>write SCHED_HEARTBEAT (.bss)<br/>XOR obfuscate → sc_sched"]
        NMI_P["PerfEvent hardware NMI<br/>read SCHED_HEARTBEAT (.bss)<br/>compare to NMI_LAST_HB<br/>frozen → event_type=1 (TAMPER)<br/>alive → event_type=0 (heartbeat)<br/>→ sc_nmi"]
        LSM_P["BPF LSM, kernel_read_file<br/>READING_MODULE<br/>gate=0: allow + log<br/>gate=1: EPERM + log → sc_lsm"]
        WATCH_P["TracePoint, sched_process_exit<br/>current == SPICA_PID (.bss)? → sc_wd flag"]
    end

    subgraph RING3["User Space: Differential Engine"]
        ENGINE["SPiCa (Tokio async)"] -->|XOR deobfuscate| RB_S[(sc_sched RingBuf)]
        ENGINE -->|event_type=0: heartbeat<br/>event_type=1: TAMPER| RB_N[(sc_nmi RingBuf)]
        ENGINE -->|raw read| RB_L[(sc_lsm RingBuf)]
        ENGINE -->|read_dir| PROC[" /proc"]
        RB_S --> FSM{Detection FSM}
        PROC --> FSM
        FSM -->|scheduled, absent /proc, >2s| D1["[DKOM]"]
        FSM -->|in /proc, never seen by sched, >5s| D2["[GHOST]"]
        RB_N -->|event_type = 1| D3["[TAMPER]"]
        FSM -->|sched channel silent, /proc ≠∅| D4["[SILENT]"]
        FSM -->|raw getdents64 ≠ libc readdir| D9["[HOOK]"]
        RB_S -->|same TGID, different start_time_ns| D5["[DUPE]"]
        RB_L -->|allowed = 1| D7["[LKM-ALLOW]"]
        RB_L -->|allowed = 0| D8["[LKM-DENY]"]
        WATCH_P -.->|pin exists at startup| D6["[WATCHDOG]"]
    end

    classDef kernbox  fill:#fdf2f8,stroke:#9333ea,stroke-width:2px,color:#581c87;
    classDef userbox  fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a;
    classDef alertbox fill:#fff7ed,stroke:#ea580c,stroke-width:1px,color:#7c2d12;
    classDef storage  fill:#f8fafc,stroke:#64748b,stroke-width:1px;
    class RING0 kernbox;
    class RING3 userbox;
    class D1,D2,D3,D4,D5,D6,D7,D8,D9 alertbox;
    class RB_S,RB_N,RB_L,PROC storage;

اكتشاف SILENT على مستوى القناة

SILENT هو حكم على مستوى القناة، وليس لكل عملية. يتم تفعيله عندما:

  1. قناة sched ميتة: max(sched_last) عبر جميع سجلات السجل قديم بعد CHANNEL_DEAD_NANOS بينما /proc غير فارغ. الحارس غير الفارغ /proc هو ضمان النشاط: على أي نظام لينكس قيد التشغيل، يكون /proc غير فارغ (init، خيوط النواة، عمال kwork)، والمجدول ليس خاملاً أبداً (أجهزة ضبط الوقت، منتظرو الإدخال/الإخراج، ردود RCU). يشير max(sched_last) القديم على نظام غير فارغ إلى أن القناة ماتت — وليس أن النظام خامل.

  2. قناة NMI ميتة: لم يصل حدث نبضة القلب (event_type=0) من الحلقة العازلة لـ NMI لأكثر من 5 ثوانٍ. هذا يعني أن حدث أداء NMI توقف عن العمل — إما أنه تم فصل حدث الأداء أو إعادة برمجة PMU.

كلا الفحصين له فترة تهدئة لمدة 30 ثانية لمنع إغراق التنبيهات.

اكتشاف روت كيت LD_PRELOAD ([HOOK])

يقرأ SPiCa /proc عبر آليتين مستقلتين في كل نبضة:

  1. استدعاء getdents64 الخام (read_tgids()) — يستخدم Rust std::fs::read_dir هذا مباشرة عبر libc::syscall(SYS_getdents64, ...) متجاوزاً جميع ربطات دالات libc. لا تستطيع روت كيت LD_PRELOAD اعتراض هذا المسار.

  2. readdir من libc (read_tgids_libc()) — يستدعي libc::opendir / libc::readdir عبر FFI، والذي يمر عبر الرابط الديناميكي ويمكن اعتراضه بالكامل بواسطة ربطات /etc/ld.so.preload.

إذا رأى getdents64 PIDs لا تراها readdir من libc، فإن روت كيت في مساحة المستخدم يقوم بربط readdir لإخفاء العمليات. يقوم SPiCa بتفعيل [HOOK]:``` [HOOK] 3 PID(s) hidden from libc readdir — LD_PRELOAD rootkit suspected

root@kitploit:~
تحوّل هذه التقنية امتياز SPiCa على مستوى النواة إلى كشف نشط لجذور مساحة المستخدم. مسار استدعاء النظام الخام هو الحقيقة الأساسية — لا يمكن لأي خطاف في مساحة المستخدم إخفاؤه. مسار مكتبة libc هو المنظر "المتصوّر" الذي ستراه أداة عادية (مثل `ps`، `ls`). التناقض هو دليل لا لبس فيه على اعتراض المكتبة.

**الجذور التي تم اكتشافها بواسطة `[HOOK]`:**

| الجذر | آلية الإخفاء | مكتشف |
|---------|-----------------|----------|
| Symbiote | طفيلي LD_PRELOAD، يخطف `readdir` | نعم (عند الإخفاء النشط) |
| JynxKit | LD_PRELOAD، إخفاء `MAGIC_GID` عبر `readdir` | نعم |
| Azazel | LD_PRELOAD، خطافات `readdir` + `stat` | نعم |
| Medusa/OrBit | LD_PRELOAD، خطف `readdir` + سرقة بيانات الاعتماد | نعم |

**تم اختباره ضد Symbiote حقيقي:** تم نشر عينة Symbiote حية (SHA256 `f55af21f...`، MalwareBazaar) عبر `/etc/ld.so.preload` على جهاز ظاهري يعمل بنظام Ubuntu 24.04. العينة تخطف `readdir`, `readdir64`, `stat`, `fstatat`, `pam_authenticate`, `pcap_loop`, `recvmsg`, `fopen`, `read`, `execve`. عندما يخفي خطاف LD_PRELOAD بشكل نشط رقم عملية من `readdir`، يُطلق SPiCa `[HOOK]` خلال دورة علامة واحدة (<1 ثانية). عندما يتم تحميل Symbiote ولكنه سلبي (لا يخفي بنشاط)، يُنتج SPiCa صفر من النتائج الإيجابية الكاذبة.

### نافذة السماحية

نافذة سماحية مقدارها 50 مللي ثانية تمنع النتائج الإيجابية الكاذبة في العمليات المستحدثة حديثًا. عمليات التحقق من القناة على مستوى SILENT لديها فترة سماح قدرها 5 ثوانٍ (مرجع `NMI_FIRST_TICK` لبرنامج NMI) بحيث لا يؤدي زمن بدء التشغيل إلى إنشاء تنبيهات TAMPER كاذبة.

---

## 6. سرية العنوان المحدودة بواسطة المدقق

### تعريف

**سرية العنوان المحدودة بواسطة المدقق** هي خاصية أمنية حسابية تصمد تحت نموذج الخصم المقيد بـ eBPF. تنص على:

> بالنظر إلى خصم يمكنه تحميل برامج eBPF (CAP\_BPF) ولكنه مقيد بمدقق BPF (حلقات محدودة، مساعدات مقيدة، لا كتابة عشوائية في النواة)، فإن عنوان النواة لقسم بيانات `.bss` لبرنامج BPF يكون من غير الممكن حسابيًا اكتشافه.

### الآليات الأربع

الخاصية هي تركيب من أربعة حواجز مستقلة:

1. **kASLR** — عشوائية تخطيط مساحة عنوان النواة تقوم بعشوائية منطقة كومة النواة حيث يتم تخصيص ذاكرة خريطة BPF (بما في ذلك خرائط الإسناد الخلفي `.bss`). يتغير العنوان الدقيق في كل إقلاع.

2. **حد تعليمات المدقق** — يحد مدقق BPF إجمالي التعليمات لكل برنامج إلى ~1 مليون ويطلب حلقات تنتهي بشكل مؤكد. يمكن لبرنامج المسح الخاص بالخصم استجواب N ≈ 10^6 عنوان على الأكثر لكل تحميل عبر `bpf_probe_read_kernel`. بالنظر إلى مساحة بحث عشوائية بواسطة kASLR، فإن احتمال النجاح لكل برنامج لا يُذكر.

3. **بوابة الوصول إلى الخريطة عبر LSM** (راجع [§7](#7-lsm-map-access-gate)) — بدون البوابة، يمكن للخصم تعداد خرائط BPF حسب المعرف (`BPF_MAP_GET_NEXT_ID` → `BPF_MAP_GET_FD_BY_ID` → `BPF_MAP_LOOKUP_ELEM`) وقراءة محتويات `.bss` مباشرة. تزيل البوابة هذا المسار السهل، مما يُجبر الخصم على مسار فحص الذاكرة المحدود بواسطة المدقق.

4. **موضع `.bss`** — لا تظهر المتغيرات العامة `.bss` في واجهات تعداد الخرائط المسماة بأسماء مقروءة إنسانياً. خريطة الإسناد الخلفي الداخلية `.bss` تُسمى `.bss` بواسطة libbpf/aya، ولكن محتوياتها (المتغيرات العامة الفعلية) لا يمكن الوصول إليها إلا إذا كان لديك واصف ملف الخريطة (map fd). يتطلب واصف ملف الخريطة إما جدول واصفات عملية التحميل أو معرف الخريطة (المحظور بواسطة البوابة).

### هيكل الحجة الرسمي```
Adversary's goal:    locate SPiCa's .bss in kernel virtual memory
Search space:        kernel heap region, kASLR-randomized (~2^30 entropy)

Path A — map enumeration (blocked):
  BPF_MAP_GET_NEXT_ID → BPF_MAP_GET_FD_BY_ID → BPF_MAP_LOOKUP_ELEM
  → blocked by LSM gate (§7) for non-SPiCa processes

Path B — memory scan (bounded):
  bpf_probe_read_kernel(addr, buf, len) — fault-safe, accepts any addr
  Per-program capacity: N ≈ 10^6 probes (instruction limit)
  Success probability per load: N / |search space| ≈ 10^6 / 2^30 ≈ 10^-24
  Can reload programs, but: each load is a syscall (observable), and
  the target address doesn't change between loads (same boot session)

Path C — timing side channel (theoretical):
  bpf_probe_read_kernel timing varies on fault vs success
  Binary search over the heap could reduce scan complexity to O(log |A|)
  → O(30) probes, well within instruction budget
  LIMITATION: must be acknowledged. Mitigated by rate-limiting BPF_PROG_LOAD
  via the LSM gate (future work).

ما الجديد في هذا

معظم أبحاث أمان BPF تتعامل مع المدقق (verifier) كـ سطح هجوم (أخطاء المدقق، عدم الاتساق، رش JIT). هذا العمل يعكس الإطار: قيود المدقق هي أداة دفاعية تحدد نطاق بحث الخصم. السرية هنا ليست تشفيرية (ليست AES)؛ إنها حسابية — يحدها ما يسمح به المدقق للخصم من حسابات.

القيود (يجب ذكرها بصراحة)

  • استغلالات المدقق — إذا كان المدقق غير متسق، فإن حدود التعليمات تنهار ويستطيع الخصم إجراء حسابات عشوائية. هذا خارج نموذج تهديد eBPF.
  • القنوات الجانبية الزمنية — bpf_probe_read_kernel يمكن ملاحظة توقيته (الخطأ مقابل النجاح يستغرق دورات مختلفة). البحث الثنائي الزمني عبر الكومة (heap) أكثر كفاءة نظريًا من المسح الخطي. حد التعليمات يقيد عمليات الفحص لكل برنامج، لكن البحث الثنائي قد يقلل عدد عمليات الفحص إلى O(log |A|) ≈ 30. هذا قيد حقيقي. التخفيف: تحديد معدل BPF_PROG_LOAD عبر بوابة LSM.
  • صلاحية الجذر في فضاء المستخدم — عملية جذر في فضاء المستخدم (غير مقيدة بالمدقق) يمكنها تعداد الخرائط حسب المعرف. بوابة LSM تمنع هذا، ولكن فقط للعمليات غير SPiCa. العملية التي تخترق معرف SPiCa الخاص بها تحصل على وصول كامل.

7. بوابة وصول خرائط LSM

المشكلة

المتغيرات العامة .bss مدعومة بخريطة BPF داخلية. أي عملية لديها CAP_BPF يمكنها تعداد جميع الخرائط على النظام:``` bpf(BPF_MAP_GET_NEXT_ID, …) → iterate all map IDs bpf(BPF_MAP_GET_FD_BY_ID, id) → get fd to any map bpf(BPF_MAP_LOOKUP_ELEM, fd, key, value) → read map contents

root@kitploit:~
ضد خصم eBPF (الذي لا يمكنه استدعاء syscalls)، يتم إخفاء `.bss`. ضد جذر userspace، إنها خريطة قياسية — قابلة للقراءة بالكامل. بوابة LSM تسد هذه الفجوة.

### الدفاع

خطاف BPF LSM على استدعاء النظام `bpf` يفحص أوامر الوصول إلى الخريطة:```
hook = "bpf"
  read cmd (arg 0)
  if cmd == BPF_MAP_GET_FD_BY_ID:
    read map_id from userspace bpf_attr (bpf_probe_read_user)
    if map_id matches any of SPiCa's stored IDs (.bss):
      if caller_tgid != SPICA_PID:
        return -EPERM

تُكتب معرفات الخريطة إلى .bss بواسطة أداة تحميل مساحة المستخدم مباشرة بعد تحميل البرنامج، وقبل تفعيل ربط LSM (نفس نمط التوقيت الموجود في sc_gate الحالي لحجب LKM). لا حاجة لـ BTF — cmd و map_id يأتيان من وسائط استدعاء النظام، وليس من بنى kernel النواة.

جراحي: يحجب فقط الوصول إلى معرفات الخريطة المحددة لـ SPiCa. أدوات BPF الأخرى للعمليات الأخرى (tcpdump، bpftrace، bcc) تصل إلى خرائطها الخاصة ولا تتأثر.

ما لا يغطيه

  • ptrace / /proc/pid/mem — يمكن لعملية جذر أخرى قراءة ذاكرة عملية SPiCa مباشرة عبر ptrace، متجاوزة استدعاء نظام BPF بالكامل. هذا قيد أساسي: لا يمكنك الحماية من عملية بنفس مستوى الصلاحية تقرأ ذاكرتك عبر /proc/pid/mem. الدفاع: إرسال السجلات إلى مضيف خارجي (إذا كان المهاجم يستطيع قراءة الذاكرة المحلية، يمكنه أيضًا كبت التنبيهات المحلية — فقط التسجيل عن بُعد يساعد).
  • اختراق PID الخاص بـ SPiCa نفسها — إذا سيطر المهاجم على عملية SPiCa، فإن لديه وصولًا شرعيًا إلى الخرائط.

8. إدارة المفاتيح والإبهام

مفتاح مصدره TPM

على المضيفات المزودة بـ TPM، يتم الحصول على مفتاح الإبهام XOR ذي الـ 64 بت من TPM2_GetRandom عبر crate tss-esapi (استدعاء مكتبة مباشر لـ libtss2-esys). لا يمر المفتاح عبر أي أنبوب (pipe)، ولا عبر أي وسيط سطر أوامر لعملية فرعية، ولا عبر قرص. إنه موجود فقط في عتاد TPM وفي ذاكرة kernel المتطايرة (خريطة .bss) طوال مدة عملية SPiCa.

على المضيفات التي لا تحتوي على TPM (VM بدون vTPM، حاويات، أجهزة بدون شريحة TPM)، يتراجع SPiCa إلى مفتاح وقت البناء لكل نسخة يتم إنشاؤه من /dev/urandom بواسطة سكريبت البناء. يكون التراجع صاخبًا بشكل مرئي عند بدء التشغيل مع لافتة تحذير.

وضع .bss

القيم التالية موجودة في قسم .bss الخاص ببرنامج eBPF، وتُكتب بواسطة مساحة المستخدم عبر set_global() قبل تحميل أي برنامج:

خرائط BPF المسماة يمكن تعدادها عبر واجهة تكرار الخريطة لاستدعاء النظام bpf() (محجوبة بواسطة بوابة LSM — انظر §7)؛ يتم الوصول إلى المتغيرات العامة لـ .bss عبر نفس الخريطة الداخلية ولكنها ليست مسماة بشكل منفصل ولا قابلة للتثبيت.

إبهام XOR — دفاع ضد تسرب القراءة، ليس تشفيرًا

يتم إجراء عملية XOR لجميع حقول ProcessInfo باستخدام BASE_KEY ذي 64 بت قبل كتابتها إلى المخازن الحلقية. يُترك حقل event_type بدون إبهام عمدًا حتى تتمكن مساحة المستخدم من قراءته كحارس قبل فك إبهام الباقي.

هذا إبهام ضد تسرب القراءة، وليس تشفيرًا ضد خصم قادر. XOR بمفتاح متكرر من 8 بايتات معرض هيكليًا للنص المعروف: قيم comm المتوقعة ("bash"، "systemd"، "kthreadd") يتم XOR لها ضد النص المشفر تستعيد بايتات المفتاح مباشرة. الدفاع مناسب لخصم eBPF (الذي لا يستطيع قراءة المخزن الحلقي بسهولة — يتطلب نفس فجوة القدرة التي تحمي .bss)، وليس لخصم لديه وصول ثنائي + اعتراض للمخزن الحلقي.


9. ختم TPM المرتبط بـ PCR (تصميم)

الحالة: مرحلة التصميم. لم يُنفذ بعد. يوثق هذا القسم البنية المستهدفة للورقة البحثية.

نظرة عامة

ينقل ختم TPM المرتبط بـ PCR حدود توزيع المفاتيح من طبقة البرمجيات إلى السيليكون. يُختم المفتاح في وقت التثبيت مقابل قيم PCR المتوقعة لسجلات تكوين المنصة، ولا يمكن فك ختمه إلا إذا تطابقت حالة إقلاع النظام مع القياسات المتوقعة.

سلسلة قياس الإقلاع

أثناء الإقلاع، يقيس البرنامج الثابت، ومحمل الإقلاع، وkernel النواة المكونات الحرجة في PCRs:

ملاحظة: تخصيص PCR يعتمد على سلسلة الإقلاع. يقيس GRUB kernel إلى PCR 4؛ يقيس systemd-stub إلى PCR 4 وسطر الأوامر إلى PCR 8. يجب أن تتطابق سياسة الختم مع سلسلة الإقلاع المستهدفة.

تدفق الختم → فك الختم → الحقن → الإخفاق الآمن

  1. الختم (وقت التثبيت): يُختم المفتاح ذو 64 بت مقابل قيم PCR المتوقعة باستخدام TPM2_Create مع جلسة TPM2_PolicyPCR. يُخزن الكائن المختم على القرص. إنه مشفر بمفتاح TPM الداخلي ولا يمكن فك تشفيره إلا عندما تتطابق PCRs المحددة.

  2. فك الختم (إقلاع مبكر، مرحلة initramfs): قبل تنفيذ أي كود غير موثوق في مساحة المستخدم، يطلب خطاف initramfs الخاص بـ SPiCa تنفيذ TPM2_Unseal. إذا تطابقت قيم PCR الحالية مع سياسة الختم، يُصدر TPM المفتاح.

  3. الحقن: يُكتب المفتاح إلى .bss عبر set_global() قبل تحميل البرامج.

  4. المصيدة: إذا كان المهاجم قد عدّل kernel (عدم تطابق PCR 4)، أو استبدل initramfs (عدم تطابق PCR 9)، أو غيّر سياسة Secure Boot (عدم تطابق PCR 7)، فإن تجزئات PCR تتباعد. يرفض TPM فك الختم، و يفشل SPiCa بشكل آمن — يرفض البدء بدلاً من العمل بشكل أعمى بمفتاح مخترق.

خيارات سياسة PCR

للوثيقة البحثية، اعرض السياسة القوية وناقش المفاضلة المتعلقة بإعادة الختم في القيود.

العلاقة مع سرية العناوين المحددة بواسطة المدقق (verifier-bounded address secrecy)

الآليتان متكاملتان:

  • ختم PCR يحمي المفتاح عند الإقلاع — يضمن أن المفتاح متاح فقط في حالة نظام موثوقة.
  • سرية العناوين المحددة بواسطة المدقق + بوابة LSM تحمي المفتاح في زمن التشغيل — تضمن أن خصم eBPF لا يستطيع تحديد موقع أو قراءة .bss حيث يوجد المفتاح.

لا تكفي أي منهما بمفردها. ختم PCR لا يساعد إذا تم اختراق المفتاح في زمن التشغيل (تعداد الخريطة). سرية العناوين لا تساعد إذا تم اختراق النظام قبل بدء SPiCa (initramfs معادٍ).

ما لا يلتقطه ختم PCR

  • فصل برامج LSM في زمن التشغيل — يتم تحميل برامج BPF LSM (spica_lsm_modblock، بوابة الوصول للخريطة) في زمن التشغيل ولا تُقاس في أي PCR. الجذور الخفية (rootkit) التي تفصلها بعد الإقلاع لا يلتقطها ختم PCR. ما يلتقط ذلك هو نبضة NMI القلبية (اكتشاف أن نظام الكشف نفسه توقف عن العمل).
  • استغلال kernel بعد الإقلاع — إذا تم استغلال kernel بعد الإقلاع (فساد الذاكرة → كتابة عشوائية)، تبقى PCRs دون تغيير. هذا هو الهدف غير المرغوب فيه "على مستوى الدولة القومية".

10. الدفاع في العمق

SPiCa هي طبقة الإنفاذ الأخيرة. إنها تكمل نظامًا مهيأً بشكل صحيح، ولا تحل محل الطبقات أعلاه.```mermaid flowchart TD SB["UEFI Secure Boot
─────────────────────────────
Verifies bootloader signature against
the UEFI db certificate store
Measured to PCR 7"] MS["Kernel Module Signing
─────────────────────────────
CONFIG_MODULE_SIG_FORCE=y
Kernel rejects unsigned .ko at load time"] IMA["IMA, Integrity Measurement Architecture
─────────────────────────────
Measures file hashes to TPM PCR10
Appraise policy blocks non-matching signatures"] SPICA["SPiCa
─────────────────────────────
LSM gate: blocks LKM loads + map enumeration
sched_switch + NMI integrity channels
Differential detection: DKOM · GHOST · TAMPER · SILENT · DUPE
PCR-bound key sealing (design phase)"]

root@kitploit:~
SB  -->|"boot chain verified"| MS
MS  -->|"signed modules only"| IMA
IMA -->|"measured + appraised"| SPICA

classDef firmware fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#78350f
classDef kernel   fill:#fdf2f8,stroke:#9333ea,stroke-width:2px,color:#581c87
classDef spica    fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a
class SB firmware
class MS,IMA kernel
class SPICA spica
root@kitploit:~
SPiCa checks all four layers at startup and prints their status.

---

## 11. حادثة خطأ BTF

### ما حدث

أثناء الاختبار على Ubuntu (أحدث نواة)، تسبب عدم توافق BTF في إرفاق برنامج نقطة التتبع `sched_switch` بنجاح ولكن **لم يطلق أي حدث واحد.** أعاد استدعاء النظام `attach()` قيمة `Ok(())`، لذا استمر SPiCa بشكل طبيعي — لكن المخزن الدائري للجدولة بقي فارغًا. لم يتم إطلاق أي تنبيهات اكتشاف لأن محرك الكشف لم يحتوي على بيانات جدولة. **عمل SPiCa أعمى دون أي إشارة إلى الفشل.**

هذا هو أسوأ نمط فشل لأداة أمنية: العمى الصامت.

### لماذا لم يتم اكتشافه

كان محرك الكشف الأصلي يعمل **لكل عملية**: كل سجل عملية كان يحتوي على الطوابع الزمنية `sched_last` و `nmi_last`، وكان يتم حساب النشاط لكل سجل. عندما ماتت sched_switch عالميًا:

1. `sched_live` أصبح خطأ لكل سجل (لا توجد أحداث جدولة جديدة → جميع قيم `sched_last` تنتهي صلاحيتها)
2. الشرط `TAMPER` لكل عملية (`in_proc && nmi_live && !sched_live`) يمكن أن يشتعل، لكنه تطلب استمرار `nmi_live` *باستمرار* لمدة ثانيتين. NMI يأخذ عينات متفرقة (فترة دورة 10M)، لذلك استمر `suspect_since` في إعادة الضبط بسبب تذبذب العينات ولم ينضج أبدًا.
3. الشرط `SILENT` لكل عملية تطلب `sched_live`، والذي أصبح الآن خطأ لكل شيء — انعكس الشرط تحت الظروف التي كان من المفترض أن يكشفها بالضبط.
4. لم يكن هناك **فحص نشاط على مستوى القناة** — لا آلية "هل اشتعلت sched من قبل؟" أو "هل max(sched_last) قديم؟".

بالإضافة إلى ذلك، تم اكتشاف عدم تطابق في الأساس الزمني: قام `sched_last` بتخزين `bpf_ktime_get_ns()` (نانو ثانية بدء تشغيل النواة) بينما تقارن `evaluate()` مع `nanos_since_startup()` (نانو ثانية محلية للعملية). أنتج `wrapping_sub` لهذه الأسس الزمنية المختلفة قيمًا ضخمة، مما جعل جميع تأكيدات النشاط خاطئة ببساطة. لم يعمل منطق الكشف بشكل صحيح أبدًا في الإنتاج — خطأ BTF قام فقط بإخفائه عن طريق منع وصول الأحداث بالكامل.

### كيف يعيد التصميم إصلاحه

| المشكلة | الإصلاح |
|---|---|
| لا يوجد فحص نشاط على مستوى القناة | يقوم `evaluate()` الآن بحساب `max(sched_last)` ويطلق `[SILENT]` إذا كان قديمًا بينما `/proc` غير فارغ |
| TAMPER لكل عملية لم ينضج أبدًا (إعادة ضبط التذبذب) | أصبح TAMPER الآن إشارة مباشرة من برنامج NMI (مقارنة نبضات `.bss`)، وليس آلية FSM لكل عملية مع عتبات |
| SILENT لكل عملية انعكس عندما ماتت sched | أصبح SILENT الآن على مستوى القناة، محسوبًا من الإجماليات، وليس من تأكيدات لكل سجل |
| عدم تطابق الأساس الزمني | يقوم `sched_last` الآن بتخزين الوقت المحلي للعملية (معامل `now`)، وليس `bpf_ktime_get_ns()` |
| NMI كان ملاحظة زائدة | أصبح NMI الآن مدقق سلامة — يكتشف موت sched مباشرة عبر نبضة `.bss` |

---

## 12. القيود المعروفة وسطح الهجوم

### ضمن نموذج التهديد eBPF

| الهجوم | الحالة | ملاحظات |
|---|---|---|
| التلاعب بمؤشر المستهلك للمخزن الدائري | مكتشف (SILENT) | يصبح `max(sched_last)` قديمًا → SILENT. `SCHED_HEARTBEAT` لا يزال يتقدم (البرنامج يعمل) → لا TAMPER خاطئ. |
| تدمير struct حدث الأداء (صفر حقل `state`) | مكتشف (SILENT) | يتوقف NMI عن الإطلاق → لا أحداث نبضات → SILENT على قناة NMI |
| انتحال حقل `task_struct` (الكتابة فوق pid/tgid) | جزئي (DUPE) | إذا تطابق TGID المنتحل مع سجل موجود يحتوي على `start_time_ns` مختلف، يشتعل DUPE. إذا تم انتحال `start_time_ns` أيضًا، فإن هذا يمر دون اكتشاف. |
| فصل برنامج eBPF (إزالة من مصفوفة funcs) | مكتشف (TAMPER) | تجمد نبضة NMI → TAMPER |
| تصحيح البايت كود في مكانه | غير مكتشف | يتطلب كتابة عشوائية للنواة (مستوى LKM) — خارج نموذج تهديد eBPF |
| قناة جانبية زمنية على `bpf_probe_read_kernel` | مخاطرة نظرية | البحث الثنائي على الكومة يمكن أن يجد `.bss` في حوالي 30 استكشافًا. انظر قيود [§6](#6-verifier-bounded-address-secrecy). |

### خارج نموذج التهديد eBPF (معترف به، لم يتم حله)

| الهجوم | الحالة | ملاحظات |
|---|---|---|
| خطاف معالج IDT/NMI | القنبلة الحية | تجاوز كامل هندسيًا. ذعر نواة شبه مؤكد. |
| قمع ثنائي القناة | القنبلة الحية | قم بكبت كل من sched + NMI في وقت واحد. يرث عدم استقرار خطاف NMI. |
| استغلال المدقق | غير هدف | يهرب إلى تنفيذ كود نواة عشوائي. فئة تهديد منفصلة. |
| ptrace / `/proc/pid/mem` | قيود أساسية | قراءة الذاكرة بنفس الامتياز. فقط شحن السجلات خارج المضيف يساعد. |
| تصحيح مؤشر المستهلك + نبضة القلب | مستوى LKM | إذا كان لدى المهاجم كتابة عشوائية للنواة، يمكنه تقديم مؤشر المستهلك وكتابة نبضات مزيفة. لكن الكتابة العشوائية للنواة = مستوى LKM = خارج نموذج التهديد. |

---

## 13. البناء والتشغيل

### المتطلبات الأساسية

- نواة لينكس >= 5.15 مع `CONFIG_DEBUG_INFO_BTF=y` (لخطاف LSM فقط)
- لحظر الوحدة: `CONFIG_BPF_LSM=y` و `lsm=bpf` في سطر أوامر النواة
- رقاقة TPM 2.0 + مكتبة `tpm2-tss` (اختياري؛ يتراجع مع تحذير مرئي)
- سلسلة أدوات Rust الليلية

> **ملاحظة:** لم يعد خطوة `generate-vmlinux` **مطلوبة**. تستخدم برامج eBPF إزاحات نقاط التتبع التقليدية والعامة `.bss` — لا حاجة لتصفح بنية CO-RE/BTF. تم الاحتفاظ بأمر xtask `generate-vmlinux` لاستخدام مستقبلي ولكنه ليس جزءًا من خط البناء.

تحقق من أن BPF LSM نشط: يجب أن يحتوي `cat /sys/kernel/security/lsm` على `bpf`.

### الإعداد```shell
make install-deps     # system packages + nightly Rust (pacman/apt/dnf auto-detected)
make install-tools    # bpf-linker
make build            # compiles eBPF + userspace (no vmlinux generation needed)

تشغيل```shell

make run # sudo ./target/release/spica

root@kitploit:~
### التثبيت في initramfs (حماية الإقلاع المبكر)```shell
sudo make install     # spica install — auto-detects Debian (initramfs-tools) or Fedora (dracut)

تحقق من أنه يعمل```shell

sudo insmod some_module.ko # should fail with EPERM (gate locked) cat /sys/kernel/security/lsm # should contain 'bpf' ls /sys/fs/bpf/spica_watchdog # exists if previous run was killed ungracefully

root@kitploit:~
### التطوير (ماك أو لينكس)

لا يمكن تشغيل برامج eBPF على macOS. تعمل `cargo check` واختبارات الوحدة لمنطق الكشف؛ أما التحقق الكامل في وقت التشغيل فيتطلب لينكس.```shell
make check      # cargo check for workspace
make check-ebpf # cargo check for the eBPF crate (bpfel-unknown-none)
make test       # unit tests for detection FSM, key derivation, obfuscation

١٤. خارطة الطريق

  • ختم المفاتيح المقيدة بـ PCR — إثبات حقيقي للأجهزة. عند التثبيت، يتم ختم المفتاح بقيم PCR المتوقعة (PCR 4/7/9/10). عند التشغيل، يفشل فتح الختم إذا تغيرت PCRs. يحل محل استخدام GetRandom الحالي لـ TPM باستخدام جذر أجهزة كامل للثقة. انظر §9.
  • بوابة الوصول إلى خرائط LSM — ربط خطاف LSM من نوع BPF باستدعاء النظام bpf لمنع تعداد الحالة الداخلية لـ SPiCa من العمليات غير التابعة لـ SPiCa. انظر §7.
  • تحديد معدل BPF_PROG_LOAD — توسيع بوابة LSM للحد من معدل تحميل برامج BPF من العمليات غير التابعة لـ SPiCa، للتخفيف من مخاطر القناة الجانبية الزمنية على اكتشاف .bss. انظر §6 القيود.
  • ترقية إخفاء PRF باستخدام SipHash — إذا توسع نموذج التهديد ليشمل خصومًا لديهم إمكانية قراءة الحلقة العازلة، استبدال XOR بتيار مفاتيح SipHash-1-3 (الاعتماد على siphasher موجود بالفعل في الشجرة للرمز التكاملي).
  • واجهة خلفية للسجلات المؤسسية — إرسال اختياري إلى Elasticsearch/Elastic SIEM لبيئات SOC. يتم إرسال جميع التنبيهات وأحداث الإنهاء وشذوذ عداد إعادة التشغيل خارج المضيف في الوقت الفعلي.
  • دعم توزيعات إضافية — Arch (mkinitcpio)، openSUSE.
  • خط أنابيب CI — اختبارات تدخين على Linux تمارس تحميل + إرفاق + تدفق الحلقة العازلة لـ eBPF.

١٥. مسرد المصطلحات


الترخيص

ترخيص محرك SPiCa: MIT OR Apache-2.0 (مساحة العمل). يصدر برنامج eBPF ترخيص GPL عبر الثابت _license — وهذا مطلب نواة لبرامج eBPF التي تستخدم مساعدات مرخصة بموجب GPL، وينطبق فقط على الرمز البايتي المحمل لـ eBPF، وليس على الثنائي في مساحة المستخدم.

نسب الشخصية: "Hatsune Miku" والأعمال الفنية المرتبطة بها هي ملكية محفوظة لحقوق الطبع لشركة Crypton Future Media, INC. (www.piapro.net). هذا المشروع هو أداة بحثية مستقلة غير تجارية، وليست تابعة لـ Crypton Future Media. تُستخدم الشخصية بموجب ترخيص شخصية Piapro (PCL).

اسم مشروع SPiCa مستوحى من الأغنية الأصلية لـ Toku-P.

تنزيل الأداة
القيدالتأثير على الخصم
الحلقات المحدودة (~1 مليون تعليمة لكل برنامج)لا يمكنه مسح كل ذاكرة النواة
سلامة المؤشرات (الإشارة المباشرة تتطلب هدفًا صحيحًا ومحدودًا)لا يمكنه متابعة مؤشرات عشوائية
الوظائف المساعدة المقيدة (قائمة مسموح بها حسب نوع البرنامج)لا يمكنه استدعاء kmalloc أو vmalloc أو أي وظيفة تخصيص نواة
لا كتابة عشوائية للنواة (bpf_probe_write_kernel مقيد بشدة)لا يمكنه تعديل task_struct أو مصفوفات وظائف نقاط التتبع أو شيفرة برنامج BPF
الوصول إلى الخرائط مقيد بالمراجع المحملةلا يمكنه الوصول إلى خرائط تنتمي لبرامج أخرى (إلا إذا تم تعدادها بواسطة ID — انظر §7)
القناةالآليةما يكتمهاتكلفة الكتم
/procتعداد دليل procfsDKOM (فصل العملية عن قائمة المهام)منخفضة — تقنية روتكيت معروفة جيدًا
sched\_switchنقطة تتبع eBPF على المجدولفصل البرنامج عن مصفوفة الوظائف؛ تصفية السياقمتوسطة — تتطلب كتابة نواة على مصفوفة الوظائف
NMIمقاطعة عداد الأداء العتادي → حدث أداء eBPFربط معالج IDT/NMIشبه مؤكد يسبب ذعر النواة — مقاطعة عتادية غير قابلة للإخفاء
التنبيهالشرطما يكتشفه
[DKOM]TGID المجدول من قبل النواة غائب عن /proc لأكثر من 2 ثانيةالتلاعب المباشر بكائنات النواة — عملية مخفية عن التعداد في مساحة المستخدم
[GHOST]TGID موجود في /proc لكن لم يتم رؤيته بواسطة sched_switch لأكثر من 5 ثوانٍتزوير /proc — إدخال وهمي لاجتياز فحوصات DKOM
[TAMPER]يكتشف NMI تجمد نبضة قلب sched_switch (event_type=1)فصل نقطة التتبع، أو قمعها، أو فشل BTF/attach
[SILENT]max(sched_last) قديم عبر السجل بأكمله بينما /proc غير فارغ؛ أو غياب نبضة قلب NMI لأكثر من 5 ثوانٍفقدان الرصد على مستوى القناة — قناة sched أو NMI ميتة
[DUPE]نفس TGID مع start_time_ns مختلفة عبر الأحداثتزوير حقل task_struct — يقوم الروت كيت بتصحيح tgid لانتحال هوية عملية شرعية
[HOOK]PIDs مرئية عبر getdents64 الخام ولكنها غائبة عن readdir الخاص بالمكتبة libcروت كيت LD_PRELOAD — اعتراض مكتبات مساحة المستخدم يخفي العمليات عن ps، ls، والأدوات الأخرى (Symbiote، JynxKit، Azazel، Medusa/OrBit)
[WATCHDOG]وجود pin /sys/fs/bpf/spica_watchdog عند بدء التشغيلتم إنهاء المثيل السابق بشكل غير نظيف (SIGKILL، OOM، تعطل)
[LKM-ALLOW]اعتراض READING_MODULE أثناء فتح البوابة (نافذة الإقلاع)سجل التدقيق: تم تحميل الوحدة قبل قفل البوابة
[LKM-DENY]اعتراض READING_MODULE أثناء قفل البوابةمنع insmod/modprobe بعد التهيئة
المتغير العامالغرضيُكتب بواسطة
BASE_KEYمفتاح إبهام XORمساحة المستخدم عند التحميل
SPICA_PIDTGID الخاص بـ SPiCa (مراقب)مساحة المستخدم عند التحميل
SCHED_HEARTBEATطابع زمني لحيوية sched_switchبرنامج sched_switch عند كل استدعاء
NMI_LAST_HBسجل NMI لآخر نبضة حيوية لـ schedبرنامج NMI عند كل فحص
NMI_FIRST_TICKأول ktime لاستدعاء NMI (فترة سماح)برنامج NMI عند أول استدعاء
NMI_LAST_EMITخنق: آخر ktime لإصدار حدثبرنامج NMI عند كل إصدار
PCRما يقيسهالاستقرار
PCR 4كود محمل الإقلاع + صورة kernel (يقيس GRUB كليهما)يتغير عند تحديث kernel
PCR 5جدول أقسام GPT/MBR، تكوين الإقلاعمستقر عبر التحديثات
PCR 7سياسة Secure Boot (SI policy، MOK، db/dbx)مستقر عبر تحديثات kernel
PCR 8سطر أوامر kernel (قياسات systemd-stub)مستقر ما لم يتغير سطر الأوامر
PCR 9Initramfs (GRUB يقيس initrd هنا)يتغير عند تحديث initramfs
PCR 10قائمة قياس IMA (Integrity Measurement Architecture)يتغير مع قياس الملفات القابلة للتنفيذ
السياسةمختم مقابلالقوةالتكلفة التشغيلية
قويةPCR 4 + 7 + 9 + 10يلتقط تغييرات kernel و initramfs و Secure Boot و IMAإعادة الختم بعد كل تحديث kernel/initramfs
متوازنةPCR 7 + 10يلتقط تغييرات Secure Boot وتقييم IMA؛ مستقر عبر تحديثات kernelإعادة الختم فقط عند تغيير سياسة Secure Boot أو سياسة IMA
دنياPCR 7 فقطيلتقط تغييرات حالة Secure Boot فقطمستقر جدًا؛ أضعف ربط
المصطلحالتعريف
BPFمرشح حزم بيركلي — محرك تنفيذ داخل النواة للبرامج المعزولة. يمتد BPF الحديث (eBPF) إلى ما بعد الحزم ليشمل التتبع والأمان والشبكات.
BTFتنسيق نوع BPF — معلومات تصحيح النواة التي تسمح للبرامج من نوع CO-RE (تجميع مرة، تشغيل في كل مكان) بالتنقل عبر بنى النواة بشكل محمول.
CO-REتجميع مرة، تشغيل في كل مكان — تقنية BPF تستخدم BTF لكتابة برامج محمولة تتكيف مع إصدارات النواة المختلفة.
DKOMمعالجة مباشرة لكائنات النواة — تقنية الجذر الخفي لإزالة عملية من القائمة المرتبطة للنواة لإخفائها عن /proc.
fmod_retنوع برنامج BPF يعدل قيمة الإرجاع لدالة نواة عبر دعامة BPF.
freplaceامتداد برنامج BPF — يلتصق بدالة (فرعية) محددة لبرنامج BPF آخر، معترضًا تنفيذها.
مصفوفة الدوالمصفوفة مؤشرات الدوال في بنية نقطة تتبع النواة التي تحمل دوال الاستدعاء (بما في ذلك برامج BPF) لاستدعائها عند إطلاق نقطة التتبع.
IDTجدول واصف المقاطعة — بنية وحدة المعالجة المركزية التي تربط متجهات المقاطعة بدوال المعالجة. يتطلب ربط مدخل NMI تعديل IDT.
kASLRتوزيع عشوائي لمساحة عنوان النواة — يعشو عناوين رمز/بيانات النواة عند كل إقلاع لإعاقة الاستغلال.
NMIمقاطعة غير قابلة للإخفاء — مقاطعة أجهزة لا يمكن تعطيلها بواسطة البرنامج (cli). تستخدم بواسطة عدادات الأداء للمراقبة على مستوى الأجهزة.
PCRسجل تكوين المنصة — سجل TPM يجمع قياسات (تجزئات) لمكونات الإقلاع. لا يمكن إعادة تعيينه (باستثناء إعادة التشغيل)، فقط يتم توسيعه.
PMUوحدة مراقبة الأداء — عدادات أجهزة في وحدة المعالجة المركزية تحسب الأحداث (دورات، أخطاء ذاكرة مؤقتة، إلخ) ويمكنها تشغيل المقاطعات (NMIs) عند عتبات معينة.
TPMوحدة المنصة الموثوقة — معالج تشفير يوفر تخزين مفاتيح موثوق بالأجهزة، وتوليد أرقام عشوائية، وإثبات القياسات.
المُدققمُدقق BPF — مكون النواة الذي يحلل برامج BPF بشكل ثابت قبل التحميل لضمان إنهائها وعدم وصولها إلى ذاكرة غير آمنة.