
شرح خطوة بخطوة لاستغلال CVE-2023-22515، وهو ثغرة تحكم وصول مكسور حرجة في Atlassian Confluence Server وData Center، مما يتيح إنشاء حساب مسؤول عن بُعد.
المنتج المتأثر: Atlassian Confluence Data Center وConfluence Server.
تاريخ الإعلان: 04/10/2023.
مستوى الخطورة: حرج (CVSS ~ 10.0).
نوع الثغرة: Broken Access Control / تفويض غير صحيح → تسمح للمهاجم بإنشاء حساب مسؤول عن بُعد.
الخلل يكمن في آلية إعداد Confluence (setup mechanism)
التأثير: Confluence Data Center وServer 8.0.0 ← 8.5.1.

يعود السبب إلى أحد الـ interceptor وهي SetupCheckInterceptor من struts.xml
struts.xml هو ملف التكوين المركزي لـ Struts.
يحدد كيفية قيام Confluence بتعيين URL ← Action class ← View template.
كما يصرّح عن الـ interceptor (الطبقات التي تعترض معالجة الطلب قبل/بعد تنفيذ الـ action).

داخل SetupCheckInterceptor يتم استدعاء BootstrapUtils.getBootstrapManager().isSetupComplete()
public String intercept(ActionInvocation actionInvocation) throws Exception {
if (BootstrapUtils.getBootstrapManager().isSetupComplete() && ContainerManager.isContainerSetup())
return "alreadysetup";
return actionInvocation.invoke();
}
الشرح
BootstrapUtils.getBootstrapManager().isSetupComplete()
→ يتحقق مما إذا كان Confluence قد أكمل عملية الإعداد (عبر المعالج، إدخال الترخيص، إنشاء مستخدم المسؤول) أم لا.
ContainerManager.isContainerSetup()
→ يتحقق مما إذا كانت حاوية Spring IoC قد تم تهيئتها بالكامل.
إذا كان الشرطان كلاهما صحيحين:
→ فهذا يعني أن النظام قد اكتمل إعداده بالكامل ← يقوم الـ interceptor بإرجاع "alreadysetup" فورًا.
→ ولا يسمح بمتابعة تنفيذ الـ action (عادةً إجراءات الإعداد مثل SetupDatabaseAction, SetupLicenseAction, ...).
إذا لم يكتمل الإعداد بالكامل:
→ يتم استدعاء actionInvocation.invoke() ← أي متابعة تنفيذ الـ action الذي طلبه المستخدم.
getBootstrapManager() → يُرجع عادةً DefaultAtlassianBootstrapManager
وهو المدير المسؤول عن جميع معلومات التكوين الأساسية أثناء عملية الإعداد
DefaultAtlassianBootstrapManager.isSetupComplete يمكننا رؤية أن طريقة تكوين التطبيق isSetupComplete يتم استدعاؤها للتحقق مما إذا كانت عملية الإعداد قد اكتملت أم لا.
=> إذا جعلنا isSetupComplete = False فإن SetupCheckInterceptor لن يُرجع "alreadysetup" وسيصبح /setup/setupadministrator.action قابلًا للوصول.
بالأسفل لدينا ServerInfoAction
ServerInfoAction = Action عام في Confluence → يسمح لأي مستخدم باستدعائه دون تسجيل دخول، ودون الحاجة إلى رمز CSRF. عند تشغيله، يُرجع فقط "success" ← يتم تعيينه إلى قالب يعرض معلومات الخادم.
ConfluenceActionSupportConfluenceActionSupport نرى أن getBootstrapStatusProvider يُرجع BootstrapStatusProviderImpl وهي الفئة التي نبحث عنها
BootstrapStatusProviderImpl توجد أيضًا getApplicationConfig لإرجاع تكوين التطبيق
ApplicationConfig يمكننا رؤية أنه يوفّر التحقق من setSetupComplete
setSetupComplete = falsegetBootstrapStatusProvider(). getApplicationConfig (). setSetupComplete ( false );
bootstrapStatusProvider.applicationConfig.setupComplete=false
/server-info.action وهو عنوان URL في Confluence تتم معالجته بواسطة ServerInfoAction لأنه نقطة نهاية عامة لا تتطلب تسجيل الدخول./server-info.action?bootstrapStatusProvider.applicationConfig.setupComplete=false

لنفحص وضع التصحيح Debug:
setupComplete (المعامل المُمرَّر إلى الدالة)
← false
أي أن الدالة تُستدعى بالمعامل false.
this.setupComplete (متغير الكائن من صنف ApplicationConfig)
← true (قبل التعيين).
عند اكتمال الأمر ← ستصبح this.setupComplete مساوية false.

/setup/setupadministrator.action وسننجح
