
تمرين كشف مختبري لـ DirtyFrag (CVE-2026-43284) - تصعيد صلاحيات نواة لينكس عبر فساد ذاكرة التخزين المؤقت للصفحات xfrm-ESP. شرح كامل يغطي تنفيذ الاستغلال، ثغرات الكشف، وقواعد EQL المصححة باستخدام Elastic Stack
التصنيف: مختبر داخلي - CyberLAB
التاريخ: 24 مايو 2026
المنصة: Elastic Stack v9.4.1
الحالة: تم تأكيد الكشف
تمرين استغلال موجه يحاكي خصماً لديه وصول أولي يستخدم DirtyFrag (CVE-2026-43284)، وهي ثغرة تصعيد صلاحيات في نواة Linux. سيناريو المهاجم المحاكي: مستخدم ذو صلاحيات منخفضة (saskia، uid=1001) تم الحصول عليه عبر بيانات اعتماد مُخترقة يحاول التصعيد إلى root على مضيف Linux داخلي. استخدم المختبر جهاز Ubuntu معرض للخطر عمداً (ubuntu-vuln، نواة 6.0.0-22-generic) معزولاً عن شبكات الإنتاج.
حقق المهاجم وصولاً كاملاً كـ root (uid=0) داخل بيئة المختبر. أنشأ حزمة Elastic Security للكشف 3 تنبيهات عالية الخطورة (درجة المخاطرة 73) حددت بشكل صحيح سلسلة الاستغلال. ومع ذلك، تطلب الكشف ضبطاً يدوياً - التكوين الافتراضي كان به ثغرات كانت ستؤدي إلى فقدان التنبيهات.
الخلاصة: مضيفات Linux غير المُصححة التي تعمل بنواة <= 6.x معرضة للخطر. إذا كان المهاجم لديه بالفعل موطئ قدم بصلاحيات منخفضة، فإن هذا الاستغلال يمنحه صلاحيات root كاملة بصمت وسرعة، دون أي أثر على القرص يمكن لأدوات سلامة الملفات رؤيته.
auditd الافتراضية لا تنتج أي دليل. بدون قواعد استدعاء نظام صريحة لـ socket و splice و unshare، يعمل الاستغلال بصمت - لا سجلات، لا تنبيهات. النشر الافتراضي لـ Elastic Agent لا يضيف هذه القواعد تلقائياً.process.parent.pid كمفتاح ارتباط. عملياً، يقوم DirtyFrag بإنشاء عمليات وسيطة، مما يكسر هذا الارتباط. تم تحديد الإصلاح - الارتباط بواسطة auditd.session - وتطبيقه خلال هذا التمرين./etc/shadow، ووصل إلى مفاتيح SSH المصرح بها، وكتب علامة استمرارية (/root/pwned.txt)، وبدأ استطلاع الشبكة عبر nc. حدث كل ذلك خلال 30 دقيقة من الوصول الأولي.الهدف: التحقق من تغطية الكشف لاستغلال DirtyFrag في مختبر SOC المنزلي، وتحديد ثغرات الكشف، وإنتاج قاعدة كشف مصححة تستند إلى سلوك المهاجم المرصود.
نموذج التهديد: خصم محاكى لديه وصول أولي بعد الاختراق باستخدام بيانات اعتماد مُخترقة لحساب مستخدم بصلاحيات منخفضة (saskia، uid=1001). الهدف: تصعيد الصلاحيات إلى root عبر DirtyFrag باستخدام مسار استقبال xfrm-ESP. تم تنفيذ التمرين عبر وحدة تحكم Proxmox - وهو مكافئ وظيفياً للوصول عبر SSH بعد الاختراق.
تم النظر في مستويين من قدرات المهاجم:
غطى هذا التمرين المستوى العادي.
DirtyFrag هو الثالث في عائلة من أخطاء نواة Linux ذات الصلة التي تسيء استخدام نفس السبب الجذري:
السبب الجذري: لم تقم مسارات إلحاق مخططات بيانات IPv4/IPv6 بتعيين SKBFL_SHARED_FRAG بعد أن زرعت skb_splice_from_iter() صفحة من ذاكرة التخزين المؤقت للملفات في مخزن مؤقت للمقبس (sk_buff). ثم قام مسار إدخال ESP بتنفيذ تشفير في المكان على صفحات ذاكرة تخزين مؤقت يتحكم فيها المهاجم، معاملًا إياها كـ skbs غير خطية عادية غير مستنسخة.
بدائية الاستغلال: كتابة موجهة بـ 4 أو 8 بايت في ذاكرة التخزين المؤقت للملفات. حتمي - لا يتطلب شرط سباق.
سلسلة الاستغلال:
/usr/bin/su) إلى ذاكرة التخزين المؤقت للملفاتsplice() بحيث تكون صفحة الملف في frag[0] من struct sk_buffxfrm-ESPexecve() في النواة - تُرجع بايتات تالفةخاصية التهرب الحرجة: لا يتم تعديل الملف على القرص أبداً. أدوات مراقبة سلامة الملفات (AIDE، Tripwire، التحقق من التجزئة) جميعها تبلغ عن أن الملف المستهدف نظيف.
التوزيعات المؤكدة القابلة للاختراق: Ubuntu 24.04.4، RHEL 10.1، AlmaLinux 10، openSUSE Tumbleweed، CentOS Stream 10، Fedora 44.
التيليمتري النشط وقت التمرين:
تم عزل شبكة المختبر قبل التمرين. تم تأكيد تعطيل اسم القاعدة Cyber_escape_door - مما يمنع الوصول الجانبي إلى شبكات VLAN الأخرى أو الإنترنت.

تم تأكيد النواة القابلة للاختراق وحساب الصلاحيات المنخفضة على ubuntu-vuln:```
saskia@ubuntu-vuln:$ uname -r
6.0.0-22-generic
saskia@ubuntu-vuln:$ whoami
saskia
saskia@ubuntu-vuln:~$ id
uid=1001(saskia) gid=1001(saskia) groups=1001(saskia),27(sudo),100(users)

#### 4.3 فحص صحة المكدس
**Suricata: قيد التشغيل والالتقاط (حالة systemctl)**

**Kibana/Elasticsearch: أخضر/سليم (فحص API)**

**لقطات VM المأخوذة قبل أي تغييرات**



#### 4.4 التقاط الشبكة
بدأ tcpdump على مضيف Suricata (`emp6s19`، طول اللقطة 262144 بايت) لالتقاط كامل حزم حركة المرور لـ `172.66.66.27`.


---
### 5. المرحلة 2 - تنفيذ الاستغلال
#### 5.1 التجهيز
تم تجهيز مصدر الاستغلال (`exp.c`) من V4bel/dirtyfrag PoC على المضيف الضحية.```bash
ubuntu-vuln@ubuntu-vuln:~/dirtyfrag$ ls
exp exp.c README.md
ubuntu-vuln@ubuntu-vuln:~/dirtyfrag$ cp exp.c /tmp/exp/

تم التجميع كجذر عبر sudo gcc (المستخدم saskia في قائمة sudoers):```
saskia@ubuntu-vuln:$ sudo gcc -o /tmp/exp/clean_frag /tmp/exp/exp.c
saskia@ubuntu-vuln:$ ls -la /tmp/exp/
-rwxr-xr-x 1 root root 62320 May 24 12:18 clean_frag
-rw-rw-r-- 1 ubuntu-vuln ubuntu-vuln 67803 May 24 12:13 exp.c
saskia@ubuntu-vuln:~$ id
uid=1001(saskia) gid=1001(saskia) groups=1001(saskia),27(sudo),100(users)
ثنائي: ELF 64-bit LSB قابل للتنفيذ، x86-64، مرتبط ديناميكياً.

#### 5.3 التنفيذ - الحصول على صلاحية الجذر
تم تنفيذ الاستغلال بواسطة المستخدم `saskia` (uid=1001). العملية (`clean_frag`, pid=4326) فتحت مآخذ `AF_RXRPC` و `AF_ALG`، ثم استدعت `splice()` لزرع صفحة ذاكرة التخزين المؤقت في المخزن المؤقت للشبكة. التشفير في المكان على مسار ESP قام بكتابة بايتات يتحكم بها المهاجم إلى ذاكرة التخزين المؤقت. عملية فرعية (pid=4327) استدعت `unshare` مع `a0=50000000` (CLONE_NEWUSER | CLONE_NEWNET) للحصول على صلاحيات ضمن نطاق مساحة الأسماء.```
saskia@ubuntu-vuln:~$ /tmp/exp/clean_frag
...
root@ubuntu-vuln:~# id
uid=0(root) gid=0(root) groups=0(root)
root@ubuntu-vuln:~# ls
تم الحصول على شيل الجذر الكامل في 12:22 CEST (10:22 UTC), 24 مايو 2026.
تسلسل استدعاءات النظام لـ auditd المُلتقط (UTC):
جميع الأحداث تشترك في auditd.session=2.

جميع الإجراءات نُفذت كمستخدم root على ubuntu-vuln من ~12:22 CEST فصاعدًا.
root@ubuntu-vuln:# echo "Dirty Frag PoC executed at $(date)" > /root/pwned.txt
root@ubuntu-vuln:# cat /root/pwned.txt
Dirty Frag PoC executed at Sun May 24 12:28:05 PM CEST 2026

#### 6.2 الوصول إلى بيانات الاعتماد```bash
root@ubuntu-vuln:~# cat /etc/shadow | head -2
root:*:19823:0:99999:7:::
daemon:*:19823:0:99999:7:::
root@ubuntu-vuln:~# cat /home/ubuntu-vuln/.ssh/authorized_keys
ssh-ed25519 AAAA[...]
تم الوصول إلى ملف shadow ومفاتيح SSH authorized keys. في اختراق حقيقي، يمكّن ذلك من كسر كلمات المرور دون اتصال والوصول الخلفي الدائم عبر SSH.

root@ubuntu-vuln:~# nc -vz 172.66.66.1 100-8000
مسح المنافذ لبوابة المختبر (`172.66.66.1`, المنافذ 100-8000) تم تنفيذه من سياق الجذر في الساعة 12:51 CEST. يوضح هذا القدرة على الحركة الجانبية ورسم خريطة الشبكة من جلسة موسعة الصلاحيات.

#### 6.4 رؤية شبكة Suricata
سجلت Suricata **105 حدثًا** مرتبطة بـ `172.66.66.27` عبر نافذة التمرين (88 mdns, 17 flow). في وقت التقاط لقطة الشاشة (أثناء فحص nc في الساعة ~12:53 CEST)، كان 29 حدثًا ظاهرًا في لوحة التحكم.
استغلال DirtyFrag نفسه داخلي للنواة ولا ينتج توقيعًا شبكيًا - بدائية التصعيد لا تولد حركة مرور غير طبيعية على الشبكة. تم استخدام Suricata لجمع ملفات pcap لحركة المرور بعد الاستغلال ومحاولات التعداد بدلاً من اكتشاف الاستغلال نفسه.
| نوع الحدث | العدد |
| ---------- | ----- |
| mdns | 88 |
| flow | 17 |
| **المجموع** | **105** |
تتجمع أحداث flow حول نافذة فحص المنافذ nc (10:50-11:10 UTC / 12:50-13:10 CEST).

---
### 7. المرحلة 4 - هندسة الكشف
#### 7.1 قواعد الكشف المنشورة
تم إنشاء قاعدتي تسلسل EQL في محرك كشف Kibana استنادًا إلى مقال Elastic Security Labs.
**القاعدة 1 - مقبس AF_RXRPC أو AF_ALG مع Splice متبوعًا بالتنفيذ** (لم تعمل - انظر الفجوة أدناه)```eql
sequence with maxspan=60s
[any where host.os.type == "linux" and
(
(event.category == "process" and auditd.data.syscall == "socket"
and auditd.data.a0 in ("26", "21")) or
(event.category == "process" and auditd.data.syscall == "splice") or
(event.category == "network" and event.action == "bound-socket"
and data_stream.dataset == "auditd_manager.auditd"
and auditd.data.socket.family == "38")
)
and user.id != "0"] by process.pid, host.id, user.id with runs=10
[process where host.os.type == "linux" and event.action == "executed" and
(
(user.effective.id == "0" and user.id != "0") or
(process.name in ("bash", "sh", "zsh", "dash", "fish", "ksh", "busybox")
and process.args in ("-c", "--command", "-ic", "-ci", "-cl", "-lc",
"-bash", "-sh", "-zsh", "-dash", "-fish", "-ksh"))
)] by process.parent.pid, host.id, user.id
القاعدة 2 - التلاعب بمساحة الاسم متبوعًا بتصعيد الامتيازات (تم تفعيله بعد الإصلاح)```eql sequence by host.id, auditd.session with maxspan=30s [process where host.os.type == "linux" and auditd.data.syscall == "unshare" and auditd.data.a0 in ("10000000", "50000000", "70000000", "10020000", "50020000", "70020000") and user.id != "0" and user.id != null] [process where host.os.type == "linux" and user.id == "0" and user.id != null and (process.name in ("bash", "sh", "zsh", "dash", "fish", "ksh", "su", "sudo", "pkexec", "busybox", "mksh") or process.name like ("python*", "perl*", "ruby*", "php*", "lua*"))]
#### 7.2 فجوة الكشف الأولية - تغطية استدعاءات النظام المفقودة
القاعدة 1 أعادت صفر نتائج. تهيئة auditd الافتراضية على `ubuntu-vuln` التقطت: `write`, `bpf`, `openat`, `unshare` فقط.
المفقودة: `socket`, `splice`, `bind` - أساسيات الاستغلال الأساسية.
**المعالجة:** تمت الإضافة إلى `/etc/audit/rules.d/dirtyfrag.rules`:```
-a always,exit -F arch=b64 -S socket -k socket_syscall
-a always,exit -F arch=b32 -S socketcall -k socket_syscall
-a always,exit -F arch=b64 -S splice -k splice-syscall
-a always,exit -F arch=b32 -S splice -k splice-syscall
-a always,exit -F arch=b64 -S unshare -k unshare-syscall
-a always,exit -F arch=b32 -S unshare -k unshare-syscall
272 حدثًا جديدًا من auditd تم تسجيله في Elasticsearch بعد ثوانٍ من تشغيل الاستغلال.
على الرغم من تسجيل الأحداث، أعادت القاعدة 2 صفر نتائج مطابقة.
السبب الجذري - شجرة العمليات الفعلية (من Elasticsearch):
القاعدة الأصلية كانت تربط بواسطة process.parent.pid. حدث unshare كان له ppid=4326، لكن واجهة الأوامر الجذرية كان لها أب مختلف - DirtyFrag يقوم بتفرع عمليات وسيطة، مما يكسر الارتباط.
الإصلاح: الربط بواسطة auditd.session. جميع الأحداث في سلسلة الاستغلال تشترك في session=2، مما يربط التسلسل بشكل صحيح بغض النظر عن عمق التفرع.
3 تنبيهات عالية الخطورة، درجة المخاطرة 73، في تنبيهات Kibana الأمنية في 2026-05-24T10:25:57Z UTC (12:25:57 CEST).
| التنبيه | الطابع الزمني (UTC) | الإشارة |
|---|---|---|
| تطابق التسلسل - حدث unshare | 10:25:57.869 | العملية=clean_frag، المستخدم=saskia (uid=1001) |
| تطابق التسلسل - واجهة أوامر الجذر | 10:25:57.881 | العملية=bash، المستخدم=الجذر (uid=0) |
DirtyFrag - التلاعب بمساحات الأسماء متبوع بتصعيد الامتيازاتubuntu-vuln

جميع أحداث auditd المتعلقة بـ dirtyfrag:```kql data_stream.dataset: "auditd_manager.auditd" and auditd.summary.how: dirtyfrag
**التلاعب بالمساحات الاسمية من قبل غير الجذر:**```kql
data_stream.dataset: "auditd_manager.auditd" and auditd.data.syscall: "unshare" and auditd.data.a0: "50000000"
نشاط الجذر بعد التصعيد في نفس الجلسة:```kql data_stream.dataset: "auditd_manager.auditd" and user.id: "0" and auditd.session: "2"
**جميع أحداث auditd خلال نافذة الاستغلال:**```kql
data_stream.dataset: "auditd_manager.auditd" and @timestamp >= "2026-05-24T10:20:00Z" and @timestamp <= "2026-05-24T10:30:00Z"
استدعاءات النظام Socket و splice من عملية الاستغلال:```kql data_stream.dataset: "auditd_manager.auditd" and auditd.summary.how: "/tmp/exp/clean_frag"
---
### ٩. ملخص النتائج الرئيسية
| # | النتيجة | الخطورة | تمت المعالجة |
| - | ------- | -------- | ---------- |
| 1 | قواعد auditd الافتراضية تفتقد `socket`، `splice`، `unshare` - لا دليل بدون قواعد صريحة | حرجة | نعم - تم نشر قواعد مخصصة في `/etc/audit/rules.d/dirtyfrag.rules` |
| 2 | ارتباط EQL بواسطة `process.parent.pid` يفشل في سلاسل الاستغلال المتفرعة | عالية | نعم - تم التغيير إلى `auditd.session` |
| 3 | مراقبة سلامة الملفات عمياء تجاه DirtyFrag - الملفات على القرص لم تتغير طوال الوقت | عالية | لا يوجد علاج داخل النطاق - إصلاح النواة هو الحل |
| 4 | بعد الاستغلال: ملف الظل، مفاتيح SSH، واستطلاع الشبكة كلها نُفذت كجذر قبل أي استجابة قائمة على التنبيهات | عالية | تم الكشف عبر سجلات auditd؛ لم يتم إطلاق قاعدة مخصصة للوصول إلى بيانات الاعتماد أو مرحلة الاستطلاع |
---
### ١٠. المراجع
- Elastic Security Labs: [Copy Fail and DirtyFrag: Linux Page Bugs in the Wild](https://www.elastic.co/security-labs/copy-fail-dirtyfrag-linux-page-bugs-in-the-wild)
- إثبات المفهوم العام: [V4bel/dirtyfrag على GitHub](https://github.com/V4bel/dirtyfrag)
- MITRE ATT&CK: [T1068 - الاستغلال لتصعيد الامتيازات](https://attack.mitre.org/techniques/T1068/)
- MITRE ATT&CK: [TA0004 - تصعيد الامتيازات](https://attack.mitre.org/tactics/TA0004/)
- MITRE ATT&CK: [T1003.008 - /etc/passwd و /etc/shadow](https://attack.mitre.org/techniques/T1003/008/)
| العنصر | التفصيل |
|---|
| الثغرة | DirtyFrag - CVE-2026-43284 (مسار xfrm-ESP)، CVE-2026-43500 (مسار RxRPC) |
| تأثير CVSS | تصعيد صلاحيات محلي كامل إلى root |
| النوى المتأثرة | نواة Linux >= يناير 2017 (عمر 9 سنوات) |
| التوزيعات المتأثرة | Ubuntu 24.04.4، RHEL 10.1، AlmaLinux 10، openSUSE، CentOS Stream 10، Fedora 44 |
| تجاوز سلامة الملفات | الملفات على القرص لم تتغير - AIDE، Tripwire، مراقبة التجزئة جميعها تبلغ عن نظافة الملفات |
| PoC عام | متوفر (V4bel/dirtyfrag على GitHub) |
| الوقت إلى root | < 10 دقائق من موطئ القدم بصلاحيات منخفضة |
| الأولوية | الإجراء |
|---|
| فورية | تصحيح نواة Linux إلى إصدار مُصلح على جميع المضيفات. تطبيق النصائح الأمنية من البائعين لـ Ubuntu و RHEL و AlmaLinux و openSUSE و CentOS و Fedora. |
| قصيرة المدى | نشر قواعد استدعاء نظام auditd صريحة لـ socket و splice و unshare على جميع مضيفات Linux المراقبة بواسطة Elastic Agent. |
| قصيرة المدى | تحديث قواعد الكشف EQL للارتباط بواسطة auditd.session بدلاً من process.parent.pid لتسلسلات معالجة مساحة الاسم. |
| مستمرة | التعامل مع تنبيهات تصعيد الصلاحيات ذات درجة المخاطرة >= 73 كأولوية عالية في الفرز. القاعدة الحالية تُطلق في غضون ثوانٍ من التصعيد. |
| CVE | الاسم المستعار | المقدَم | المسار |
|---|
| CVE-2022-0847 | Dirty Pipe | - | pipe |
| CVE-2026-31431 | Copy Fail | - | splice |
| CVE-2026-43284 | DirtyFrag | يناير 2017 (الالتزام cac2661c53f3) | xfrm-ESP |
| CVE-2026-43500 | DirtyFrag | يونيو 2023 (الالتزام 2dc334f1a63a) | RxRPC |
| المكون | التفاصيل |
|---|
| خادم Fleet / مضيف ELK | ubuntu-tm / elk-docker - 172.66.66.30 (داخلي للمختبر) |
| حزمة Elastic | v9.4.1 (Elasticsearch، Kibana، Logstash - Docker) |
| المضيف المستهدف (الضحية) | ubuntu-vuln - 172.66.66.27 |
| نواة الضحية | 6.0.0-22-generic (قابلة للاختراق) |
| مستخدم الضحية | saskia - uid=1001، مجموعات=1001(saskia)،27(sudo)،100(users) |
| Elastic Agent | v9.4.1 مع auditbeat |
| نظام كشف الشبكات (NIDS) | Suricata 8.0.5 على مستشعر مخصص |
| Kibana | http://172.66.66.30:5601 (داخلي للمختبر) |
| مجموعة البيانات | النسبة |
|---|
suricata.eve | 75.2% |
elastic_agent.fleet_server | 10.8% |
elastic_agent | 9.1% |
elastic_agent.filebeat | 1.9% |
elastic_agent.auditbeat | 1.4% |
auditd_manager.auditd | 0.5% |
system.auth | 0.2% |
system.syslog | 0.1% |
| الطابع الزمني (UTC) | استدعاء النظام | الوسيطة | العملية (pid) | المستخدم |
|---|
| 10:21:11.054 | unshare | a0=50000000 | clean_frag (4327) | saskia (1001) |
| 10:21:11.055 | socket | a0=21 (AF_RXRPC) | clean_frag (4326) | saskia (1001) |
| 10:21:17.403 | socket | a0=26 (AF_ALG) | clean_frag (4326) | saskia (1001) |
| 10:21:17.419 | splice | a0=4 | clean_frag (4326) | saskia (1001) |
| 10:21:17.419 | splice | a0=7 | clean_frag (4326) | saskia (1001) |
| العملية | PID | PPID | UID | جلسة auditd |
|---|
| shell (saskia) | 4182 | - | 1001 | 2 |
clean_frag (الرئيسي) | 4326 | 4182 | 1001 | 2 |
clean_frag (طفل unshare) | 4327 | 4326 | 1001 | 2 |
bash (الجذر) | - | 4451 | 0 | 2 |
| تنبيه التسلسل المركب | 10:25:57.893 | المضيف=ubuntu-vuln |
| التكتيك | التقنية | المعرف |
|---|
| تصعيد الامتيازات | الاستغلال لتصعيد الامتيازات | T1068 |
| تصعيد الامتيازات | الهروب إلى المضيف | T1611 |
| الوصول إلى بيانات الاعتماد | تفريغ بيانات اعتماد نظام التشغيل: /etc/passwd و /etc/shadow | T1003.008 |
| الاكتشاف | اكتشاف خدمة الشبكة | T1046 |
| استدعاء النظام | الوسيطة | المعنى |
|---|
unshare | a0=50000000 | CLONE_NEWUSER | CLONE_NEWNET |
socket | a0=26 | AF_ALG (النظام الفرعي للتشفير في النواة) |
socket | a0=21 | AF_RXRPC (مسار RxRPC) |
bind | socket.family=38 | ربط AF_ALG |
splice | - | حقن الصفحات في مخازن الشبكة المؤقتة |