
تحليل تعليمي واستغلال إثبات المفهوم لثغرة CVE-2022-22965، وهي ثغرة تنفيذ تعليمات برمجية عن بُعد في Spring MVC/WebFlux عبر ربط البيانات على JDK 9+ مع نشر Tomcat WAR.
في الآونة الأخيرة، كشفت Spring عن ثغرة CVE من العيار الثقيل. تُظهر معلومات CVE ما يلي: "قد يكون تطبيق Spring MVC أو Spring WebFlux الذي يعمل على JDK 9+ عرضةً لتنفيذ التعليمات البرمجية عن بُعد (RCE) عبر ربط البيانات. يتطلب الاستغلال المحدد تشغيل التطبيق على Tomcat كنشر WAR. إذا تم نشر التطبيق كملف jar تنفيذي من Spring Boot، أي الوضع الافتراضي، فلن يكون عرضةً لهذا الاستغلال. ومع ذلك، فإن طبيعة الثغرة أكثر عمومية، وقد توجد طرق أخرى لاستغلالها. (قد تكون تطبيقات Spring MVC أو Spring WebFlux التي تعمل على JDK 9+ عرضةً لهجوم تنفيذ التعليمات البرمجية عن بُعد (RCE) عبر ربط البيانات. يتطلب الاستغلال المحدد نشر التطبيق كحزمة WAR على Tomcat. إذا تم نشر التطبيق كملف jar تنفيذي من Spring Boot، أي الوضع الافتراضي، فإنه ليس عرضةً للهجوم. لكن طبيعة الثغرة أكثر عمومية، وقد توجد طرق أخرى لاستغلالها.)". يُجري هذا التحليل تكرارًا لهذه الثغرة لتعلّم مبدأ الثغرة.
قبل الاطلاع على مبدأ ربط المعاملات في Spring MVC، دعونا نلقي نظرة أولًا على بعض واجهات برمجة التطبيقات المتعلقة بـ Java Bean.
قم بتعريف فئة java bean كما يلي:```java public class User { private String name;
public User() {
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public int getAge() {
return 18;
}
}
لنلقِ نظرة على المعلومات التي يحصل عليها Introspector.getBeanInfo باستخدام كود الاختبار التالي:```java
@Test
public void testIntrospector() throws IntrospectionException {
BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
for (PropertyDescriptor pdesc:beanInfo.getPropertyDescriptors()){
System.out.println("Property: " + pdesc.getName() + ",Class:" + pdesc.getPropertyType());
}
// for (MethodDescriptor md:beanInfo.getMethodDescriptors()) {
// System.out.println("Method: " + md.getName());
// }
}
المخرجات:```text Property: age,Class:int Property: class,Class:class java.lang.Class Property: name,Class:class java.lang.String
إلى جانب age و"ذلك" المتوقعين، هناك أيضًا خاصية class، واسم الفئة هو Class. وإذا واصلت استدعاء Introspector.getBeanInfo(Class.class)، فيمكنك الحصول على مزيد من المعلومات مثل classLoader وما إلى ذلك:```text jdk11:
Property: annotatedInterfaces
Property: annotatedSuperclass
Property: annotation
Property: annotations
Property: anonymousClass
Property: array
Property: canonicalName
Property: class
Property: classLoader
Property: classes
Property: componentType
Property: constructors
Property: declaredAnnotations
Property: declaredClasses
Property: declaredConstructors
Property: declaredFields
Property: declaredMethods
Property: declaringClass
Property: enclosingClass
Property: enclosingConstructor
Property: enclosingMethod
Property: enum
Property: enumConstants
Property: fields
Property: genericInterfaces
Property: genericSuperclass
Property: interface
Property: interfaces
Property: localClass
Property: memberClass
Property: methods
Property: modifiers
Property: module
Property: name
Property: nestHost
Property: nestMembers
Property: package
Property: packageName
Property: primitive
Property: protectionDomain
Property: signers
Property: simpleName
Property: superclass
Property: synthetic
Property: typeName
Property: typeParameters
بالإضافة إلى ذلك، دعنا نقارن الفرق في المعلومات التي تم الحصول عليها عبر Introspector.getBeanInfo(Class.class) في إصدارات JDK المختلفة؛ ما سبق هو الإخراج تحت jdk-11، وما يلي هو الإخراج تحت JDK8:```text jdk8:
Property: annotatedInterfaces
Property: annotatedSuperclass
Property: annotation
Property: annotations
Property: anonymousClass
Property: array
Property: canonicalName
Property: class
Property: classLoader
Property: classes
Property: componentType
Property: constructors
Property: declaredAnnotations
Property: declaredClasses
Property: declaredConstructors
Property: declaredFields
Property: declaredMethods
Property: declaringClass
Property: enclosingClass
Property: enclosingConstructor
Property: enclosingMethod
Property: enum
Property: enumConstants
Property: fields
Property: genericInterfaces
Property: genericSuperclass
Property: interface
Property: interfaces
Property: localClass
Property: memberClass
Property: methods
Property: modifiers
Property: name
Property: package
Property: primitive
Property: protectionDomain
Property: signers
Property: simpleName
Property: superclass
Property: synthetic
Property: typeName
Property: typeParameters
`\r````text
Property: annotatedInterfaces
Property: annotatedSuperclass
Property: annotation
Property: annotations
Property: anonymousClass
Property: array
Property: canonicalName
Property: class
Property: classLoader
Property: classes
Property: componentType
Property: constructors
Property: declaredAnnotations
Property: declaredClasses
Property: declaredConstructors
Property: declaredFields
Property: declaredMethods
Property: declaringClass
Property: enclosingClass
Property: enclosingConstructor
Property: enclosingMethod
Property: enum
Property: enumConstants
Property: fields
Property: genericInterfaces
Property: genericSuperclass
Property: interface
Property: interfaces
Property: localClass
Property: memberClass
Property: methods
Property: modifiers
Property: module
Property: name
Property: package
Property: packageName
Property: primitive
Property: protectionDomain
Property: signers
Property: simpleName
Property: superclass
Property: synthetic
Property: typeName
Property: typeParameters
بالمقارنة مع JDK8، أضاف JDK9 خاصيتين هما module وpackageName، بينما في JDK11 بالإضافة إلى خاصيتي module وpackageName توجد خاصيتان أخريان هما nestHost وnestMembers.