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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
shiro-cve-2020-17523 — تحليل تقنيتين لتجاوز المصادقة في Apache Shiro (CVE-2020-17523) مع بيئة استغلال قابلة لإعادة الإنتاج وفحص تفصيلي للسبب الجذري. | Kitploit
أدوات/GitHubGitHub/jweny/shiro-cve-2020-17523
المصادقة والترخيصتحليل الثغرات الأمنيةاستغلال تطبيقات الويباختبار الاختراقالتعلم والتعليممختبرات وتدريب عملي
GitHubjweny/shiro-cve-2020-17523

shiro-cve-2020-17523

تحليل تقنيتين لتجاوز المصادقة في Apache Shiro (CVE-2020-17523) مع بيئة استغلال قابلة لإعادة الإنتاج وفحص تفصيلي للسبب الجذري.

عرض المستودع
118114منذ 5 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

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

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

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

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

Apache Shiro تحليل طريقتين لتجاوز المصادقة (CVE-2020-17523)

0x01 وصف الثغرة

Apache Shiro هو إطار عمل أمني قوي وسهل الاستخدام بلغة Java، يقوم بتنفيذ التحقق من الهوية والتفويض وإدارة كلمات المرور والجلسات. باستخدام واجهة برمجة التطبيقات (API) سهلة الفهم التي يوفرها Shiro، يمكنك بسرعة وسهولة تأمين أي تطبيق، بدءًا من أصغر تطبيقات الهاتف المحمول وصولاً إلى أكبر تطبيقات الويب والمؤسسات.

عند استخدامه مع Spring، وفي ظل قواعد معينة لمطابقة الأذونات، يمكن للمهاجم تجاوز التحقق من الهوية عبر إنشاء حزم طلبات HTTP خاصة.

النطاق المتأثر: Apache Shiro < 1.7.1

0x02 إعداد بيئة الثغرة

shiro 1.7.0

تم تحديث بيئات الثغرة للطريقتين: https://github.com/jweny/shiro-cve-2020-17523

0x03 اختبار poc

الطريقة الأولى:

http://127.0.0.1:8080/admin/%20 أو http://127.0.0.1:8080/admin/%20/

يمكن تجاوز مصادقة Shiro باستخدام الأحرف الفارغة مثل المسافة.

image-20210205120522547

الطريقة الثانية:

بعد التواصل مع الخبير p0desta، تم اكتشاف طريقة استغلال أخرى في سيناريو خاص.

http://127.0.0.1:8080/admin/%2e أو http://127.0.0.1:8080/admin/%2e/

لكن . (وكذلك /) في قواعد مطابقة المسارات في Spring تمثل فواصل المسار، ولا تتم مطابقتها كأحرف عادية. لذلك في الظروف الافتراضية، الوصول إلى /admin/. سيعيد 404.

ولكن في سيناريو تفعيل المسار الكامل setAlwaysUseFullPath(true)، تتم المطابقة بشكل طبيعي.

image-20210205102100797

0x04 تحليل الثغرة

في Shiro، يتم الحصول على عنوان URL ومطابقته في org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain

لنلقِ نظرة سريعة على طريقة getChain هذه:

carbon (2)

image-20210205103341569

تتحقق هذه الطريقة أولاً مما إذا كان requestURI ينتهي بـ/، وإذا كان كذلك، فتحذف آخر /.

ثم في حلقة مطابقة المسارات، تتحقق أولاً مما إذا كان نمط المسار pathPattern ينتهي بـ/، وإذا كان كذلك فسيتم حذفه أيضًا. بعد ذلك تستدعي طريقة pathMatches() لإجراء مطابقة المسار.

لذلك في طريقتي الاستغلال، لا يهم ما إذا كان المسار ينتهي بـ/ أم لا، لأنه سيتم حذفه بمجرد المرور عبر طريقة getChain.

4.1 تحليل تجاوز المسافة

دعنا نركز على طريقة pathMatches():

استدعِ Evaluate، واحسب كلاً من pathMatches("/admin/*","/admin/1") وpathMatches("/admin/*","/admin/ ")، الأول يطابق بشكل طبيعي بينما يفشل الثاني في المطابقة.

image-20210203134044268

image-20210203134119174

ابدأ التصحيح؛ ستمر عملية التصحيح بسلسلة طويلة من ضغطات F7. حتى الوصول إلى doMatch("/admin/*","/admin/ "). نلاحظ أن pathDirs المُعاد من tokenizeToStringArray لم يعد يحتوي على مسار المستوى الثاني. لذلك يؤدي ذلك إلى عدم تطابق /admin/* مع /admin .

image-20210203150854085

عند تتبع طريقة tokenizeToStringArray، نجد أن المعامل trimTokens يكون true عند استدعاء طريقة tokenizeToStringArray.

image-20210203150959413

أما طريقة tokenizeToStringArray، فعندما يكون المعامل trimTokens بقيمة true، فإنها تخضع لمعالجة trim()، مما يؤدي إلى إزالة المسافات. وعند العودة إلى getChain مرة أخرى، يتم حذف آخر /. لذلك فإن pathDirs المُعاد من tokenizeToStringArray لا يحتوي على مسار المستوى الثاني.

image-20210203151053344

الخلاصة: في إصدار Shiro المتأثر بالثغرة، نظرًا لأن المعامل trimTokens يكون true افتراضيًا عند استدعاء طريقة tokenizeToStringArray، فإن المسافات تخضع لمعالجة trim()، مما يؤدي إلى إزالتها. وعند العودة إلى getChain مرة أخرى، يتم حذف آخر /، لذلك يفشل تطابق /admin مع /admin/*، مما يؤدي إلى تجاوز التحقق من الهوية. بينما يستقبل Spring مسار الوصول /admin/%20 ويعيد الاستجابة وفق المنطق الطبيعي، مما يؤدي إلى تجاوز الصلاحيات.

4.2 تحليل تجاوز /./

عند رؤية /. و/./ في الطريقة الثانية، هل تذكرت طريقة مألوفة؟ نعم، إنها normalize().

carbon (3)

وبترجمة مبسطة:

الشرطالمثال
تحويل الخط المائل العكسي إلى خط مائل أمامي\ -> /
تحويل الخطين المائلين الأماميين إلى خط مائل أمامي

لذلك فإن /admin/. بعد معالجته إلى /admin/./ يصبح /admin/.

image-20210205113301788

وبعد معالجته بواسطة org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver#getChain، وبما أن المسار ينتهي بـ/، وإذا كان كذلك يتم حذف آخر /، فيصبح /admin. لا يطابق ``/adminمع/admin/*`، وبالتالي تم تجاوز مصادقة Shiro.

image-20210205113518970

وفي هذا الوقت، يكون الطلب الذي يستقبله Spring هو /admin/.. إذا لم يتم تفعيل مطابقة المسار الكامل، فإن . و/ في Spring تُعتبر فواصل مسار ولا تشارك في مطابقة المسار. لذلك لن يتم العثور على mapping مطابق، ويتم إرجاع 404.

image-20210205114350972

عند تفعيل مطابقة المسار الكامل، سيتم مطابقة عنوان url بالكامل، وبالتالي يعيد Spring 200.

فيما يلي الكود الخاص بتفعيل مطابقة المسار الكامل:

root@kitploit:~
@SpringBootApplication
public class SpringbootShiroApplication extends SpringBootServletInitializer implements BeanPostProcessor {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(SpringbootShiroApplication.class);
    }

    public static void main(String[] args) {

        SpringApplication.run(SpringbootShiroApplication.class, args);
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        if (bean instanceof RequestMappingHandlerMapping) {
            ((RequestMappingHandlerMapping) bean).setAlwaysUseFullPath(true);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        return bean;
    }
}

0x05 خطة الإصلاح الرسمية

بناءً على التحليل أعلاه، هناك سببان لتجاوز صلاحيات Shiro:

  1. دالة tokenizeToStringArray لا تتعامل مع المسافات بشكل صحيح.
  2. منطق معالجة آخر / لا ينبغي أن يكون قبل منطق حلقة مطابقة المسار.

لذلك فإن خطة الإصلاح الرسمية هي:

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

  1. ضبط المعامل trimTokens في tokenizeToStringArray على false.image-20210203154342100
  2. تعديل منطق حذف آخر /. تم التعديل بحيث تتم مطابقة المسار الأصلي أولاً، وعند فشل المطابقة يتم الانتقال إلى منطق حذف آخر /.image-20210205115522098

0x06 حول trim

من حيث المبدأ، تقوم trim() بمسح جميع المسافات البيضاء (whitespace) قبل السلسلة النصية وبعدها، والمسافة (space) هي واحدة منها فقط. لكن في الاختبارات تبيّن أنه بالإضافة إلى المسافة، فإن أي whitespace آخر، مثل %08 و%09 و%0a، سيعيد spring+tomcat 400 عند معالجته.

لذلك، وباستثناء المسافة، لم يتم العثور على حمولات (payload) أخرى مفيدة للطريقة الأولى.

0x07 المراجع

https://github.com/apache/shiro/commit/0842c27fa72d0da5de0c5723a66d402fe20903df

https://www.anquanke.com/post/id/216096

https://www.cnblogs.com/syp172654682/p/9257282.html

تنزيل الأداة
// -> /
إذا انتهى بـ /. أو /..، يتم إضافة / في النهاية/. -> /./ /.. -> /../
تطبيع /.//./ -> /
القفز في المسار/aaa/../bbb -> /bbb