
PoC وسلسلة استغلال لـ CVE-2026-89633، وهو كتابة خارج الحدود في الكومة (heap out-of-bounds write) في مسار دمج SMB1 TRANS2 في وحدة cifs.ko في Linux، مع تصعيد الصلاحيات إلى uid 0 عبر الكتابة فوق بيانات الاعتماد (cred overwrite) وإعادة تسمية PTE (PTE aliasing).
coalesce_t2 لعميل cifs SMB1English | 简体中文
إثبات مفهوم/استغلال بحثي (PoC/EXP) لكتابة خارج الحدود في كومة الذاكرة في عميل SMB1 الخاص بـ cifs.ko في Linux. يتحكم خادم SMB1 خبيث في DataOffset داخل استجابة TRANS2 الثانوية، وتقوم coalesce_t2() بنسخ الحمولة الثانوية ذات 8 بايت إلى &primary->Protocol + DataOffset + accumulated دون أي فحص لحدود الهدف. تكون وجهة النسخ حيثما وجّهها الخادم، نسبةً إلى مخزن الاستجابة (server->bigbuf).
يحتفظ هذا المستودع بعرضين توضيحيين بأدوار متمايزة؛ وليسا بديلين أحدهما عن الآخر:
DataOffset أثناء التشغيل.uid/gid/suid/sgid/euid/egid/fsuid/fsgid. وهو الدليل الأكثر مباشرة على أن الكتابة خارج الحدود قابلة للتحكم ويمكنها تعديل cred، مع أقل عدد من الاعتماديات.selinux_state، ويصبح الـ clone بالـ uid 0 مع كامل الصلاحيات (caps) دون ملاحظة من جهة الجذر. وهو امتداد لـ EXP 1، وليس بديلًا عنه.تحميل وحدات النواة (kernel modules) خارج نطاق هذا المستودع عمدًا: تتوقف السلسلة عند uid 0 (واختياريًا selinux_state في وضع permissive) ولا تثبّت أي وحدة. وحتى دون وحدة محمّلة، فإن uid 0 + permissive هو عرض LPE الكامل الذي يدّعيه هذا المستودع.
تبقى تكاليف EXP 2 صريحة: يانصيب لكل نافذة (25–33%، و97–99% على مدى 12 محاولة)، وPTE عارية تبقى حيّة حتى إعادة التشغيل، واعتماد على tracefs قابل للكتابة من الصدفة، وافتراضات خاصة بالبناء حول direct-map/موقع الاستدعاء/SEL_PFN. يبقى EXP 1 أبسط دليل على البدائية والخيار الاحتياطي عند عدم توفر tracefs قابل للكتابة من الصدفة.
| العنصر | القيمة |
|---|---|
| CVE | CVE-2026-89633 |
| الفئة | كتابة خارج الحدود في كومة الذاكرة (CWE-787) |
| المكوّن | cifs.ko، دمج TRANS2 الثانوي في SMB1 |
| الإصلاح في المنبع | 36d01415d881 ("smb: client: fix ... coalesce_t2", 6.12.113) |
| POC | تم التحقق من الإطلاق والكتابة خارج الحدود (بعد التركيب وأثناء التركيب) |
| EXP 1 (بدائية بسيطة) | كتابة cred خارج الحدود ذات 4 إطارات تحت ملاحظة من جهة الجذر؛ تم التحقق من uid 0 (بعد التركيب والاستجابة المحتجزة وقت التركيب) |
| EXP 2 (بدائية متقدمة) | سلسلة PTE المعتمدة على الصدفة فقط؛ تم التحقق من uid 2000 → uid 0 + كامل الصلاحيات + Permissive (SEL_PFN/SEL_OFF)؛ تتوقف عند PTE عارية، دون تحميل وحدة |
| المتطلبات | تركيب SMB1 إلى خادم يتحكم به المهاجم (بوابة مميزة)؛ تستخدم البوابة المرجعية su، ويحتاج التموضع المعتمد على الصدفة فقط إلى tracefs قابل للكتابة من الصدفة |
بيئة الاختبار: بناء مورّد (vendor build) لـ Android 16 على arm64، نواة 6.12.38 مع cifs.ko مبني من خط أساس KMI 6.12.23، وSELinux في وضع enforcing.
statfs، ودون الوصول إلى نقطة التركيب)، والتموضع المعتمد على الصدفة فقط في EXP 2 (tracefs فقط، دون ملاحظة من جهة الجذر)، والقبول الكامل لـ EXP 2 (uid 0 + جميع بتات الصلاحيات + Permissive مع SEL_PFN/SEL_OFF)، وبوابة التركيب المُدارة بـ su (التركيب فقط يعمل كـ root؛ والتموضع يعمل كـ uid 2000) — تم اختبارها هناك تحت SELinux في وضع enforcing.بالنسبة لاستجابة SMB1 TRANS2 الأكبر من MAX_CIFS_SMALL_BUFFER_SIZE - 4
(444 بايت)، يحتفظ العميل بالاستجابة الأساسية في server->bigbuf ويخزّنها في
mid->resp_buf. تمرّ استجابات SMB_COM_TRANSACTION2_SECONDARY التالية
عبر cifs_check_trans2() -> check2ndT2() -> coalesce_t2():
data_area_of_tgt = &primary->Protocol + primary->DataOffset + total_in_tgt;
memcpy(data_area_of_tgt, data_area_of_src, secondary->DataCount);
يُؤخذ DataOffset حرفيًا من استجابة الخادم. توجد فحوصات العدّاد (تجاوز total_in_tgt/byte_count، وحدود المخزن المؤقت المصدر)، لكن لا يوجد فحص يضمن بقاء data_area_of_tgt داخل مخزن الاستجابة المؤقت. تهبط كل إطار ثانوي على مسافة 8 بايت إضافية (بمجموع DataCount المتراكم)، لذا تمنح استجابة متعددة الإطارات كتابة بمقدار 8*N بايت عند إزاحة يختارها المهاجم (16 بت) من قاعدة المخزن المؤقت.
شروط التشغيل:
vers=1.0) من خادم يتحكم به المهاجم؛statfs)؛TotalDataCount > DataCount ويكون كبيرًا بما يكفي لمسار bigbuf، ثم إطار ثانوي واحد أو أكثر يحمل TotalDataCount > DataCount.Makefile
src/poc/poc_smb1_trans2.py malicious SMB1 server (QFS hook, runtime ctl)
src/poc/smb1_proxy.py TCP proxy: patches DataOffset, repeats secondaries
src/exp/pipesearch.c pipe placement/write driver (modes 3, 8, 9)
src/exp/shcred.c shell-side drain + clone helper (uid 2000)
src/exp/shp4a2.c trace-based drainer/observer/clone (modes 8/9)
src/exp/pte_fault.c 2 MiB fault + PTE alias writes
src/exp/bscan.c bigbuf discovery by call site (no kprobes)
src/exp/kslide.c KASLR slide from a raw call site
src/exp/smbd.c device-side SMB1 server (held TRANS2)
src/exp/smbd_templates.h SMB1 response templates for smbd
src/exp/pfn.c linear-map VA to pfn
src/exp/kflags.c /proc/kpageflags reader
scripts/setup_device.sh trace instance + kprobes (root on device)
scripts/start_servers.sh host: SMB1 server + proxy + mount helper
scripts/probe_round.sh one probe round: bigbuf base + free target page
scripts/place.sh placement: pipesearch mode 3 + shcred
scripts/write_cred.sh 4-frame coalesce write + /proc verification
scripts/mount_su.sh generic su mount gate (target/decoy/abort/unmount)
scripts/chain_shell.sh shell-only placement for an already-held TRANS2
scripts/gen_smb_templates.py regenerates smbd_templates.h from a capture
docs/analysis.md vulnerability and chain analysis
docs/exp-protocol.md shared-page and smbd ctl protocols
make deps # checks impacket
make helpers # NDK cross-build of all C helpers
make push # adb push to /data/local/tmp
NDK وAPI وARCH وADB وDEVICE_DIR قابلة للتجاوز.
لا يحتاج المُشغِّل نفسه سوى إلى تركيب SMB1 والخادم/الوكيل قيد التشغيل.
إنّ kprobes وkflags هي أدوات مساعدة للمراقبة، وليست جزءًا من المُشغِّل —
ثبّتها عندما تريد أدلة dst/src/len (وهي مطلوبة في
سلسلة EXP أدناه، التي تحتاج إلى قاعدة bigbuf، ومراقبة الموضع،
وعنوان cred الهدف).
الجهاز (root، اختياري — للمراقبة فقط): ثبّت المجسّات.
adb push scripts/setup_device.sh /data/local/tmp/
adb shell su -c 'sh /data/local/tmp/setup_device.sh'
adb push build/kflags /data/local/tmp/kflags
المضيف: ابدأ خادم SMB1 والوكيل (يقوم السكربت أيضًا بإنشاء دليل المشاركة وطباعة أمر التركيب):
scripts/start_servers.sh /tmp/cifs01-ctl
يشغّل src/poc/poc_smb1_trans2.py على 1470 وsrc/poc/smb1_proxy.py
(1460 -> 1470) مع دليل التحكم /tmp/cifs01-ctl.
طوبولوجيا الاختبار المحلية: اربط منفذ الوكيل بالجهاز وقم بتركيب المشاركة كجذر على الجهاز.