Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2025-62821 — Расширение HEIF от Microsoft (msheif_store.dll) OOB-read | Kitploit
Инструменты/GitHubGitHub/hyunjungg/cve-2025-62821
Криминалистика памятиАнализ уязвимостейЭксплуатацияОбратная инженерияФаззингАнализ Бинарных Файлов
GitHubhyunjungg/cve-2025-62821

CVE-2025-62821

Расширение HEIF от Microsoft (msheif_store.dll) OOB-read

Репозиторий
10 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Microsoft HEIF Image Extensions (msheif_store.dll): Недостаточное выделение буфера-источника в пути CopyPixels приводит к чтению за пределами буфера и нарушению доступа (DoS)

При декодировании специально созданного HEIF-изображения через WIC кодек msheif выделяет исходный буфер размером 1 байт, но затем пытается скопировать из этого буфера очень большой объём пиксельных данных во время CopyPixels. Копирование выполняется с помощью memmove с размером, вычисленным как stride × высота ROI, без проверки фактической длины исходного буфера. Это вызывает чтение за пределами буфера и немедленное нарушение доступа (аварийное завершение). На практике открытие или предварительный просмотр вредоносного HEIF вызывает отказ в обслуживании в любом компоненте WIC, который использует расширения HEIF.

Примечание к именованию: имена переменных, такие как 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. Анализ первопричины

    a. Подробное описание уязвимости

    • Конвейер декодирования вычисляет большую длину копирования для memmove на основе геометрии изображения (например, copy_size = stride * abs(roi_height)).
    • Исходный буфер, который должен содержать декодированные данные кадра/элемента, выделяется размером 1 байт, поскольку:
      • CHEIFStreamReader_ReadItemData вызывает CHEIFItemInfoEntry_GetDataSize для вычисления длины данных элемента.
      • При определённой ветви ошибки CHEIFItemInfoEntry_GetDataSize возвращает успех, но оставляет вычисленный размер равным 0.
      • Затем CHEIFStreamReader_ReadItemData вызывает MFCreateMemoryBuffer(0, &ppBuffer). Согласно поведению MF, это создаёт буфер с минимальным выделением в 1 байт.
    • В дальнейшем CopyPixels проверяет размер буфера назначения, но не проверяет длину исходного буфера относительно запрошенного размера копирования перед вызовом memmove.
    • Результат: memmove(dst, src, large_size) читает далеко за пределами 1-байтового src, вызывая ошибку при векторизованной загрузке.

    Эта ошибка независимо усугубляется, если ширина изображения/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

b. Поток кода от входных данных

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 00007fff`31857e52     windowscodecs!CFormatConverterResolver::CopyPixels+0xc2
08 0000005d`6a9af480 00007ff6`15fb0f5d     heif_decoder!HEIF_LoadBitmapFromMemory+0x34d [C:\\\\Users\\\\test\\\\source\\\\repos\\\\heif_decoder\\\\heif_decoder\\\\heif_decoder.cpp @ 256]
09 0000005d`6a9af670 00007ff6`15fb04ab     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  // выполняет memmove
       → memmove         // AV (vmovdqu загрузка из src)

c. Размер буфера

  • Созданный HEIF, который заставляет CHEIFItemInfoEntry_GetDataSize пройти по пути раннего «успеха с размером 0» (например, когда sub_7FFD8408B898 терпит неудачу и функция возвращает успех с sizeBuffer = 0).

  • Исходный буфер: выделяется через MFCreateMemoryBuffer(0) ⇒ 1 байт.

  • Размер копирования: вычисляется как copy_size = stride * abs(roi_height). При неправильно разобранной ширине (например, 0x01000100) и типичном BPP 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) {
          // Нет проверки, что 'src' содержит как минимум (stride * abs_roi_height) байт
          memmove(dst, src, (size_t)abs_roi_height * stride); // AV здесь
        }
      }
    }
    
  • Почему источник равен 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 может быть 0, если GetDataSize вернула успех раньше
        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) )
            {
            // возвращает успех (0/S_OK) без обновления sizeBuffer
    	      // вызывающий код считает длину = 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;
    }
    

d. Предлагаемые исправления

В пути CopyPixels проверяйте, что исходный буфер содержит как минимум stride * abs(roi_height) байт (и что src_stride/src_height соответствуют или превышают запрошенную область). Если нет, возвращайте ошибку WINCODEC_ERR_INSUFFICIENTBUFFER (или эквивалентную).

e. Методология анализа (восстановление символов)

Чтобы сделать поток вызовов обозримым, мы восстановили имена внутренних функций в IDA на основе строк журналирования самого кодека.

  • Цель. Определить читаемые имена функций для ключевых процедур (…CopyPixels_Base, …CopyPixels_Transform, CHEIFStreamReader::ReadItemData и т.д.), чтобы согласовать стек аварийного завершения с декомпилированным кодом.

  • Процедура:

    1. Найдите вспомогательную функцию журналирования: в декомпиляторе среди вызывающих функций рядом с местом аварии найдите небольшую вспомогательную функцию, которая вызывается с

      константной строкой

      , напоминающей имя функции (например, "CWICHeifBitmapSourceBase::CopyPixels_Base").

      • В IDA: откройте функцию в месте аварии, поднимитесь на один фрейм вверх и проверьте вызовы при входе в функцию на наличие вспомогательной функции, принимающей строковый литерал.
    2. Соберите вызывающие функции: используйте перекрёстные ссылки (xrefs) на эту вспомогательную функцию, чтобы получить список всех вызывающих функций.

    3. Извлеките имена: для каждой вызывающей функции откройте декомпилированный вид и прочитайте второй аргумент вспомогательной функции (строковый литерал). Эта строка последовательно содержит предполагаемое имя функции.

    4. Переименуйте вызывающие функции: в каждой вызывающей функции нажмите N (Edit → Rename) и задайте имя функции в виде восстановленной строки (например, CWICHeifBitmapSourceBase::CopyPixels_Base).

    5. Повторите для соседних фреймов, пока вся цепочка аварийного завершения не будет иметь осмысленные имена.

Проверка. После переименования снова пройдитесь по точкам вызова и убедитесь, что типы аргументов и поведение соответствуют меткам (например, …CopyPixels_Base — это место, где выполняются вычисления stride/ROI и производится вызов memmove).

  1. Proof-of-Concept

  • Предварительные требования: расширения HEIF Image Extensions из Microsoft Store должны быть установлены/включены (необходимы для декодирования HEIC/HEIF).

  • Шаги для воспроизведения

    1. Загрузите и сохраните прикреплённый PoC-файл (../access_violation_0000xxxxxxxxx461_00000xxxxxxxx6B0_1.heif) в локальную папку.

    2. Убедитесь, что расширения HEIF Image Extensions установлены (откройте Microsoft Store → выполните поиск «HEIF Image Extensions» → Установить).

    3. Откройте PoC-файл с помощью Microsoft Photos (дважды щёлкните файл, если Photos является программой по умолчанию, или Правой кнопкой мыши → Открыть с помощью → Фотографии).

  • Ссылка для загрузки программного обеспечения

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

Скачать инструмент