
استغلال نواة CVE-2025-38352 لأجهزة تلفاز LG webOS الذكية (ARM64). يحقق صلاحية الجذر المستمرة على أجهزة استهلاكية حقيقية باستخدام تقنيات استغلال جديدة. تم الإفصاح عنها بشكل مسؤول لشركة LG.
استغلال النواة لـ CVE-2025-38352 (حالة تسابق لمؤقت وحدة المعالجة المركزية POSIX / استخدام بعد التحرير) يحقق صلاحية الجذر الدائمة على تلفزيونات LG webOS الذكية التي تعمل بنواة 5.4.268 على ARM64. تم التحقق على 4 موديلات تلفزيون عبر إصدارات برامج ثابتة متعددة. تم الإبلاغ المسؤول لبرنامج باحثي الأمان في LG (فبراير 2026).
بني على Chronomaly بواسطة farazsth98. تم نقل وتكييف منطق تسابق UAF في المرحلة الأولى والبنية التحتية للتقاطع عبر الذاكرة المخبئية لـ ARM64؛ تم إعادة تصميم المراحل 2–5 بتقنيات استغلال جديدة وحلول لقيود الأجهزة الحقيقية غير الموجودة في البيئات المحاكاة. تم التطوير بمساعدة Claude Opus 4.6.
انظر VULNERABILITY_REPORT.md للتحليل الكامل للثغرة، ودليل سلسلة الاستغلال، والتخفيفات الموصى بها.
prisoner (uid=5038)تم تطوير هذا الاستغلال كجزء من بحث أمني مسؤول وتم الإبلاغ عنه لبرنامج باحثي الأمان في LG في 7 فبراير 2026. يُنشر لأغراض تعليمية فقط. استخدمه بمسؤولية وفقط على الأجهزة التي تملكها. المؤلفون غير مسؤولين عن أي ضرر، أو تلف، أو فقدان بيانات، أو إبطال الضمان الناتج عن استخدام هذا البرنامج. يتم توفير هذا البرنامج كما هو بدون ضمان.
التناقص العشوائي في الاستغلال الأصلي بطيء ومزعج: فهو يرش 1,000 كائن struct cred عبر عمليات متفرعة، ثم يخفض حقل EUID لكائن cred الهدف N مرة. كل تناقص هو عملية منفصلة. هذا مقبول في QEMU حيث يكون التوقيت متسامحًا، لكنه غير موثوق على الأجهزة الحقيقية حيث يمكن لاستعادة الصفحات المدفوعة بالمقاطعات أن تسرق صفحات مخزن الأنبوب بين العمليات.
تم استبدال هذا بكتابة عشوائية واحدة عبر list_del_init(). يقوم الاستغلال بكتابة مؤشرات list_head.next و list_head.prev لـ sigqueue المعرض لـ UAF عبر مخزن الأنبوب. عندما تقوم النواة بإزالة الإشارة المعلقة من الطابور (collect_signal() ← list_del_init())، فإنها تنفذ prev->next = next (تكتب عنوان cred المزيف في task_struct->cred) و next->prev = prev (كتابة جانبية مسيطر عليها). كتابة واحدة تستبدل مؤشر cred للعملية بمؤشر لهيكل cred مزيف يحتوي على حقول uid/gid صفرية. لا رش كائنات cred، ولا عمليات متفرعة، حتمي.
peek_pipe() عبر tee() للقراءات غير التدميريةيستخدم الاستغلال الأصلي استدعاءات read() تدميرية عبر مخازن الأنبوب طوال الاستغلال. في QEMU، يعمل هذا بشكل جيد لأن الصفحات لا تُسرق بين العمليات. على الأجهزة الحقيقية ذات 4 أنوية مادية، تقوم قائمة الصفحات لكل نواة (pcplist) للنواة باستعادة الصفحات المحررة بقوة. القراءة التدميرية تحرر الصفحة الداعمة لمخزن الأنبوب، والتي يمكن أن تُسرق فورًا بواسطة مقاطعة أجهزة قبل أن يتمكن الاستغلال من إعادة تخصيصها.
الحل هو أولية قراءة أنبوب غير تدميرية باستخدام tee(). استدعاء النظام tee() ينسخ بيانات الأنبوب بين أنبوبين دون استهلاكها، مما يحافظ على تثبيت الصفحة الداعمة لمخزن الأنبوب الأصلي. يتيح هذا للاستغلال قراءة بيانات النواة من مخزن الأنبوب عبر الذاكرة المخبئية بشكل متكرر دون خطر فقدان الصفحات. كان هذا ضروريًا للوثوقية على الأجهزة الحقيقية.
يقوم الاستغلال الأصلي برش كائنات cred ويأمل أن تهبط واحدة في موقع يمكن التنبؤ به. هذا الإصدار يبني هيكل cred المزيف في عنوان معروف عن طريق تنفيذ تقاطع ثانٍ عبر الذاكرة المخبئية: تخصيص sigqueue جديد (عبر tkill(SIGRTMIN+1))، تعلم عنوانه من تسرب الكومة لمخزن الأنبوب الأول، ثم تقاطع صفحة شريحة sigqueue تلك إلى مخزن أنبوب ثانٍ. يتم كتابة cred المزيف في مخزن الأنبوب الثاني عند إزاحة الصفحة الدقيقة لعنوان sigqueue المسرب. النتيجة هي cred مزيف في عنوان نواة حتمي دون تخمين.
يقوم الاستغلال الأصلي بإزالة SIGUSR2 من الطابور مبكرًا في المرحلة 2 لتسريب عنوان sigqueue المعرض لـ UAF. هذا يستهلك الإشارة، لذا يحتاج الاستغلال الأصلي لآلية مختلفة للكتابة النهائية. هذا الإصدار لا يحتاج أبدًا إلى عنوان sigqueue المعرض لـ UAF نفسه (تسريب الكومة يأتي من مؤشرات sigqueue المجاورة في مخزن الأنبوب). يبقى SIGUSR2 معلقًا عبر جميع المراحل الخمس ويتم استخدام إزالته من الطابور كمُشغل الكتابة العشوائية النهائية. الإشارة التي أنشأت UAF هي نفس الإشارة التي تستغلها إزالتها من الطابور.
modprobe_path + socket(44)هيكل cred المزيف يحتوي على مؤشرات user_ns و user و group_info فارغة (نظرًا لأن مخزن الأنبوب تم تهيئته بصفر بعد حقول uid/gid). استدعاء setresuid() أو fork() أو exec() سيؤدي إلى إلغاء مرجع هذه المؤشرات الفارغة وتسبب ذعر النواة. يتجنب الاستغلال الأصلي هذا لأن رش cred الخاص به يستخدم كائنات cred حقيقية بمؤشرات صالحة.
الحل: الكتابة فوق /proc/sys/kernel/modprobe للإشارة إلى نص برمجي للحمولة (/tmp/pwn)، ثم تشغيل call_usermodehelper عبر socket(44, SOCK_STREAM, 0) (طلب عائلة بروتوكول غير موجودة). تنفذ النواة مساعد modprobe مع init_cred (صلاحيات جذر النواة الخاصة، صالحة تمامًا)، متجاوزة cred التالف تمامًا. تعمل الحمولة كجذر كامل ويمكنها تنفيذ عمليات عشوائية.
النافذة الحرجة في المرحلة 4 (كتابة مؤشرات ضارة في مخزن الأنبوب، ثم تشغيل إزالة الإشارة من الطابور) معرضة لسرقة مقاطعات الأجهزة لصفحة مخزن الأنبوب من قائمة الصفحات لكل نواة. هذا لا يحدث في QEMU. على الأجهزة الحقيقية، يتم حماية هذه النافذة بأولوية SCHED_FIFO (عند التوفر) و sched_yield() للسماح بإكمال العمل المعلق على وحدة المعالجة المركزية قبل الدخول إلى القسم الحرج، بالإضافة إلى محتويات مخزن الأنبوب المجهزة مسبقًا لتقليل الوقت بين الكتابة والتشغيل. كما يتراجع الاستغلال بسلاسة عندما يكون SCHED_FIFO غير متوفر (كما في webOS حيث يفتقر المستخدم prisoner إلى CAP_SYS_NICE).
task_struct لـ ARM64تستهدف الكتابة العشوائية task_struct->cred، مما يتطلب معرفة إزاحة البايت من task_struct->pending (التي يتم تسريب عنوانها من مخزن الأنبوب) إلى task_struct->cred. هذه الإزاحة تعتمد على تكوين النواة. تم حساب الإزاحة 0x80 (128 بايت) يدويًا من شفرة مصدر نواة LG webOS، مع مراعاة CONFIG_KEYS=y و CONFIG_SYSVIPC=y وتخطيط الهيكل والمحاذاة الخاصة بـ ARM64. إزاحة x86_64 في الاستغلال الأصلي مختلفة بسبب تعبئة هيكل وخيارات تكوين مختلفة.
عند النجاح، يقوم الاستغلال بما يلي:
/proc/sys/kernel/modprobe لتشغيل حمولة تجذير كـ initaarch64-linux-gnu-gcc)# macOS (يتطلب tap جهة خارجية)
brew tap messense/macos-cross-toolchains
brew install aarch64-unknown-linux-gnu
# Ubuntu/Debian
sudo apt-get install gcc-aarch64-linux-gnu
قم بتثبيت تطبيق Homebrew Channel على تلفزيونك عبر Dev Mode قبل تشغيل الاستغلال. بهذه الطريقة، تحتاج حمولة التجذير فقط إلى رفع صلاحيته (سريع، موثوق) بدلاً من تثبيت + رفع (أبطأ، قد يفشل). يمكنك تثبيته جانبياً باستخدام ares-install أو تطبيق Dev Manager:
ares-install org.webosbrew.hbchannel_0.7.3_all.ipk
إذا لم يكن HBC مثبتًا مسبقًا، سيحاول الاستغلال تثبيته من /tmp/hbchannel.ipk (يتم نشره بواسطة deploy-webos.sh)، لكن هذا يضيف خطوات إضافية قد تفشل.