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

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2025-62821 — إضافة HEIF من مايكروسوفت (msheif_store.dll) قراءة خارج النطاق (OOB-read) | Kitploit
أدوات/GitHubGitHub/hyunjungg/cve-2025-62821
تحليل الذاكرة الجنائيتحليل الثغرات الأمنيةالاستغلالالهندسة العكسيةالاختبار العشوائيتحليل الملفات الثنائية
GitHubhyunjungg/cve-2025-62821

CVE-2025-62821

إضافة HEIF من مايكروسوفت (msheif_store.dll) قراءة خارج النطاق (OOB-read)

عرض المستودع
منذ 10 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

Microsoft HEIF Image Extensions (msheif_store.dll): تخصيص ناقص للمخزن المؤقت المصدر في مسار CopyPixels يؤدي إلى قراءة خارج الحدود وانتهاك الوصول (رفض الخدمة)

عند فك تشفير صورة HEIF مصممة عبر WIC، يقوم برنامج الترميز msheif بتخصيص مخزن مؤقت مصدر بحجم 1 بايت لكنه يحاول لاحقًا نسخ كمية كبيرة جدًا من بيانات البكسل من ذلك المخزن أثناء CopyPixels. تستخدم النسخة memmove بحجم مشتق من stride × ارتفاع ROI، دون التحقق من الطول الفعلي للمخزن المؤقت المصدر. يتسبب هذا في قراءة خارج الحدود وانتهاك وصول فوري (تعطل). عمليًا، فتح أو معاينة الصورة HEIF الخبيثة تسبب رفض الخدمة في أي مستهلك WIC يمر عبر ملحقات HEIF Image.

ملاحظة حول التسمية: أسماء المتغيرات مثل roi_height تم استنتاجها من التفكيك للقراءة ولا تعكس أسماء رموز البائع.

المنتجMicrosoft HEIF Image Extensions
الوحدةmsheif_store.dll
نظام التشغيلWindows 11
إصدار الامتداد1.2.22.0 (Microsoft.HEIFImageExtension_1.2.22.0_x64__8wekyb3d8bbwe\x64\msheif_store.dll)
  1. تحليل السبب الجذري

    أ. وصف تفصيلي للثغرة

    • يحسب خط أنابيب فك التشفير طول نسخة كبير لـ memmove بناءً على هندسة الصورة (مثل copy_size = stride * abs(roi_height)).
    • المخزن المؤقت المصدر الذي يفترض أن يحتوي على بيانات الإطار/العنصر المفكوك يتم تخصيصه ناقصًا إلى بايت واحد، بسبب:
      • يستدعي CHEIFStreamReader_ReadItemData الدالة CHEIFItemInfoEntry_GetDataSize لحساب طول بيانات العنصر.
      • في فرع فشل محدد، تُرجع CHEIFItemInfoEntry_GetDataSize النجاح لكنها تترك الحجم المحسوب كـ 0.
      • ثم يستدعي CHEIFStreamReader_ReadItemData الدالة MFCreateMemoryBuffer(0, &ppBuffer). وفقًا لسلوك MF، ينتج عن ذلك مخزن مؤقت بحد أدنى من التخصيص قدره 1 بايت.
    • في المراحل اللاحقة، يتحقق CopyPixels من حجم المخزن الوجهة لكنه لا يتحقق من طول المخزن المصدر مقابل حجم النسخة المطلوبة قبل استدعاء memmove.
    • النتيجة: يقرأ memmove(dst, src, large_size) بكثير بعد مصدر 1 بايت، مما يتسبب في خطأ في التحميل المتجه.

    تتفاقم هذه الثغرة بشكل مستقل إذا تم تحليل عرض الصورة/ROI بشكل خاطئ (مثل 0x01000100 = 16,777,472)، مما يضخم stride وحجم النسخة النهائي. ومع ذلك، فإن الثغرة الأساسية هي عدم التحقق من طول المصدر مقابل طول النسخة المحسوبة.

root@kitploit:~
(7de0.78e4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
msheif_store!DllCanUnloadNow+0x228b1d:
00007ffd`841bc45d c5fe6f02        vmovdqu ymm0,ymmword ptr [rdx] ds:000002b0`65be6ff0=c0

0:000> !heap -p -a rdx
    address 000002b065be6ff0 found in
    _DPH_HEAP_ROOT @ 2b05bed1000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                             2b062c2f2d8:      2b065be6ff0                1 -      2b065be6000             2000
    ...
    00007ffe75b90563 MFPlat!operator new+0x0000000000000023
    00007ffe75b83d36 MFPlat!MFCreateMemoryBuffer+0x0000000000000056
    00007ffd840157b1 msheif_store!DllCanUnloadNow+0x0000000000081e71
		...

0:000> r r8
r8=0000000001000100

ب. تدفق الكود من الإدخال

root@kitploit:~
0:000> k
 # Child-SP          RetAddr               Call Site
00 0000005d`6a9aed98 00007ffe`6fdefcc2     msheif_store!DllCanUnloadNow+0x228b21
01 0000005d`6a9aeda0 00007ffe`6fcb3adc     msheif_store!DllCanUnloadNow+0x18c382
02 0000005d`6a9aee00 00007ffe`6fcb4513     msheif_store!DllCanUnloadNow+0x5019c
03 0000005d`6a9aeef0 00007ffe`6fcb96da     msheif_store!DllCanUnloadNow+0x50bd3
04 0000005d`6a9af0a0 00007fff`318551d5     msheif_store!DllCanUnloadNow+0x55d9a
05 0000005d`6a9af1a0 00007fff`318082eb     windowscodecs!CPyramidBase::CopyPixels+0xf5
06 0000005d`6a9af260 00007fff`31857e52     windowscodecs!CFormatConverter::CopyPixels+0x22b
07 0000005d`6a9af3e0 00007ff6`15fb0f5d     windowscodecs!CFormatConverterResolver::CopyPixels+0xc2
08 0000005d`6a9af480 00007ff6`15fb04ab     heif_decoder!HEIF_LoadBitmapFromMemory+0x34d [C:\\\\Users\\\\test\\\\source\\\\repos\\\\heif_decoder\\\\heif_decoder\\\\heif_decoder.cpp @ 256]
09 0000005d`6a9af670 00007ff6`15fb1754     heif_decoder!HEIF_FuzzMemory+0x9b [C:\\\\Users\\\\test\\\\source\\\\repos\\\\heif_decoder\\\\heif_decoder\\\\heif_decoder.cpp @ 357]
0a 0000005d`6a9af830 00007ff6`15fb3039     heif_decoder!wmain+0x394 [C:\\\\Users\\\\test\\\\source\\\\repos\\\\heif_decoder\\\\heif_decoder\\\\heif_decoder.cpp @ 524]
0b 0000005d`6a9afaa0 00007ff6`15fb2ee2     heif_decoder!invoke_main+0x39 [D:\\\\a\\\\_work\\\\1\\\\s\\\\src\\\\vctools\\\\crt\\\\vcstartup\\\\src\\\\startup\\\\exe_common.inl @ 91]
0c 0000005d`6a9afaf0 00007ff6`15fb2d9e     heif_decoder!__scrt_common_main_seh+0x132 [D:\\\\a\\\\_work\\\\1\\\\s\\\\src\\\\vctools\\\\crt\\\\vcstartup\\\\src\\\\startup\\\\exe_common.inl @ 288]
0d 0000005d`6a9afb60 00007ff6`15fb30ce     heif_decoder!__scrt_common_main+0xe [D:\\\\a\\\\_work\\\\1\\\\s\\\\src\\\\vctools\\\\crt\\\\vcstartup\\\\src\\\\startup\\\\exe_common.inl @ 331]
0e 0000005d`6a9afb90 00007fff`3847e8d7     heif_decoder!wmainCRTStartup+0xe [D:\\\\a\\\\_work\\\\1\\\\s\\\\src\\\\vctools\\\\crt\\\\vcstartup\\\\src\\\\startup\\\\exe_wmain.cpp @ 17]
0f 0000005d`6a9afbc0 00007fff`3939c34c     KERNEL32!BaseThreadInitThunk+0x17
10 0000005d`6a9afbf0 00000000`00000000     ntdll!RtlUserThreadStart+0x2c

الاستدعاءات الداخلية المحلولة (أعيدت تسميتها للوضوح):

root@kitploit:~
CWICHeifDecoderFrame::CopyPixels
 → CWICHeifBitmapSourceBase::CopyPixels_Transform
   → CWICHeifBitmapSourceBase::CopyPixels_Base
     → sub_7FFD8411FC40  // issues memmove
       → memmove         // AV (vmovdqu load from src)

ج. حجم المخزن المؤقت

  • صورة HEIF مصممة تتسبب في أن يسلك CHEIFItemInfoEntry_GetDataSize مسار "نجاح بحجم 0" مبكرًا (مثل عندما تفشل sub_7FFD8408B898 وتعيد الدالة النجاح مع sizeBuffer = 0).

  • المخزن المؤقت المصدر: يتم تخصيصه عبر MFCreateMemoryBuffer(0) ⇒ 1 بايت.

  • حجم النسخة: مشتق كـ copy_size = stride * abs(roi_height). مع عرض تم تحليله بشكل خاطئ (مثل 0x01000100) وعدد بتات لكل بكسل نموذجي، يصبح stride هائلاً، مما يؤدي إلى copy_size كبير جدًا.

  • الاستدعاء الضعيف:

    root@kitploit:~
    __int64 sub_7FFD8411FC40(__m128i* dst, __int64 a2, __m128i* src, int a4,
                             unsigned int stride, unsigned int abs_roi_height)
    {
      if (src && dst) {
        if (stride == a2 && stride == a4) {
          // No validation that 'src' contains at least (stride * abs_roi_height) bytes
          memmove(dst, src, (size_t)abs_roi_height * stride); // AV here
        }
      }
    }
    
  • لماذا المصدر هو 1 بايت (مسار التخصيص):

    root@kitploit:~
    __int64 __fastcall CHEIFStreamReader_ReadItemData(__int64 *a1, __int64 *a2, IMFMediaBuffer **a3)
    {
      ppBuffer = 0i64;
      if ( v7(a2) )
      {
        *cbMaxLength = 0i64;
        result = (*(*a2 + 0xA0))(a2, cbMaxLength); // CHEIFItemInfoEntry_GetDataSize
        if ( result < 0 )
        {
          goto LABEL_10;
        }
        if ( *cbMaxLength > 0xC800000ui64 )
        {
          result = 0xC00D36BE;
          goto LABEL_23;
        }
        // cbMaxLength may still be 0 if GetDataSize returned success early
        result = MFCreateMemoryBuffer(cbMaxLength[0], &ppBuffer);
        if ( result < 0 )
        {
          goto LABEL_34;
        }
        ...
    }
    
    root@kitploit:~
    __int64 __fastcall CHEIFItemInfoEntry_GetDataSize(__int64 a1, unsigned __int64 *sizeBuffer)
    {
    
      if ( sizeBuffer )
      {
        *sizeBuffer = 0i64;
        DataLocationInfo = (*(*v5 + 0x78i64))(v5, 0x6D657461i64, &v32);
        if ( DataLocationInfo >= 0 )
        {
          v13 = v32;
          v14 = *(v32 + 0xF0);
          if ( v14 )
          {
            if ( !sub_7FFD8408B898((v14 + 0xC8), (a1 - 0x78), &v33, v31) )
            {
            // returns success (0/S_OK) without updating sizeBuffer
    	      // caller treats this as length=0 → MFCreateMemoryBuffer(0)
    	          DataLocationInfo = 0;
    	          goto LABEL_62;
    	        }
            v17 = v33;
            DataLocationInfo = CHEIFItemInfoEntry_GetDataLocationInfo(v5, v13, *(v33 + 16), &v29, &v30);
            if ( DataLocationInfo >= 0 )
            {
              for ( i = 0; ; ++i )
              {
                if ( i >= *v17 )
                {
                  *sizeBuffer = v6;
                  goto LABEL_62;
                }
                v21 = *(*(v17 + 8) + 24i64 * i + 16);
                }
                if ( v21 + v6 < v6 )
                  break;
                v6 += v21;
                DataLocationInfo = 0;
              }
    
             ...
             ...
    LABEL_62:
      sub_7FFD83F91AEC();
      return DataLocationInfo;
    }
    

د. الإصلاحات المقترحة

في مسار CopyPixels، تحقق من أن المخزن المؤقت المصدر يحتوي على stride * abs(roi_height) بايت على الأقل (وأن src_stride/src_height تفي أو تتجاوز المنطقة المطلوبة). إذا لم يكن كذلك، فشل مع WINCODEC_ERR_INSUFFICIENTBUFFER (أو ما يعادله).

هـ. منهجية التحليل (إعادة بناء الرموز)

لجعل تدفق الاستدعاء قابلاً للمراجعة، أعدنا بناء أسماء الوظائف الداخلية في IDA من سلاسل التسجيل الخاصة ببرنامج الترميز.

  • الهدف. تحديد أسماء وظائف قابلة للقراءة البشرية للروتينات الرئيسية (…CopyPixels_Base, …CopyPixels_Transform, CHEIFStreamReader::ReadItemData, إلخ) لمحاذاة مكدس التعطل مع الكود المفكك.

  • الإجراء:

    1. ابحث عن المساعد للتسجيل: في عرض المفكك للمستدعين حول التعطل، حدد موقع مساعد صغير يتم استدعاؤه مع وسيطة سلسلة ثابتة تشبه اسم دالة (مثل "CWICHeifBitmapSourceBase::CopyPixels_Base").
      • في IDA: افتح الدالة عند التعطل، انتقل إطارًا واحدًا لأعلى، وافحص الاستدعاءات عند دخول الدالة بحثًا عن مساعد يأخذ حرفية سلسلة.
    2. اجمع المستدعين: استخدم المراجع المتقاطعة لذلك المساعد لسرد جميع وظائف المستدعي.
    3. استخراج الأسماء: لكل مستدعي، افتح العرض المفكك واقرأ وسيطة المساعد الثانية (الحرفية السلسلة). تحتوي هذه السلسلة باستمرار على اسم الوظيفة المقصود.
    4. إعادة تسمية المستدعين: في كل مستدعي، اضغط N (تحرير → إعادة تسمية) واضبط اسم الدالة على السلسلة المستردة (مثل CWICHeifBitmapSourceBase::CopyPixels_Base).
    5. كرر للإطارات القريبة حتى تحصل سلسلة التعطل بأكملها على أسماء ذات معنى.

التحقق. بعد إعادة التسمية، أعد التشغيل عبر مواقع الاستدعاء وتأكد من أن أنواع الوسائط/السلوك تتطابق مع التسميات (مثل …CopyPixels_Base هو المكان الذي تحدث فيه عمليات حساب stride/ROI واستدعاء memmove النهائي).

  1. إثبات المفهوم

  • المتطلبات الأساسية: ملحقات HEIF Image من متجر Microsoft مثبتة/ممكّنة (مطلوبة لفك تشفير HEIC/HEIF).

  • خطوات إعادة الإنتاج

    1. قم بتنزيل وحفظ ملف إثبات المفهوم المرفق (../access_violation_0000xxxxxxxxx461_00000xxxxxxxx6B0_1.heif) في مجلد محلي.

    2. تأكد من تثبيت ملحقات HEIF Image (افتح متجر Microsoft → ابحث عن 'HEIF Image Extensions' → تثبيت).

    3. افتح ملف إثبات المفهوم باستخدام Microsoft Photos (انقر نقرًا مزدوجًا على الملف إذا كان Photos هو التطبيق الافتراضي، أو انقر بزر الماوس الأيمن → فتح باستخدام → Photos).

  • رابط تنزيل البرنامج

    HEIF Image Extensions (Microsoft Store) https://apps.microsoft.com/detail/9pmmsr1cgpwg?hl=en-US&gl=US

تنزيل الأداة