Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2017-9608 PoC — FFmpeg dnxhd decoder 安全漏洞

Source
Associated Vulnerability
Title:FFmpeg dnxhd decoder 安全漏洞 (CVE-2017-9608)
Description:FFmpeg是FFmpeg团队的一套可录制、转换以及流化音视频的完整解决方案。dnxhd decoder是其中的一个dnxhd解码器。 FFmpeg 3.2.6之前的版本和3.3.3之前的3.3.x版本中的dnxhd decoder存在安全漏洞。远程攻击者可借助特制的mov文件利用该漏洞造成拒绝服务(空指针逆向引用)。
Description
CVE-2017-9608 analysis
Readme
# Проект

Для запуска: `./script.sh`

Репозиторий на гитхаб - https://github.com/LaCinquette/practice-22-23

# Ход выполнения

1. Для поиска уязвимости я выбрал проект FFmpeg. Нашел в нем [коммит](https://github.com/FFmpeg/FFmpeg/commit/611b35627488a8d0763e75c25ee0875c5b7987dd), который соответствовал требованиям, а именно:
   - Соответствовал типу **CWE-476** - разыменование нулевого указателя

2. Создал докерфайл, в котором:
   1. Выбрал в качестве базового образа Ubuntu 22.04
   2. Уствновил `DEBIAN_FRONTEND=nointeractive` для исключения взаимодействия с командной строкой во время установки пакетов и других команд
   3. Установил необходимые зависимости указанные в официальной [вики](https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu)
   4. Подготавливаю рабочее место (папка *workdir*)
   5. Скачиваю, распаковываю и перемещаю коммит с еще не исправленной уязвимостью в рабочее место
   6. Запускаю билд программы с помощью утилиты make
   7. Создаю скрипт *copy_out.sh*, который занимается поиском необходимого объектного файла с ошибкой и копированием его в директорию *workspace/out*
   8. Оставляю инструкцию на выполнение скрипта *copy_out.sh*, которая должна выполниться при запуске контейнера

3. Для автоматизации создаю скрипт *script.sh*, который собирает образ и запускает контейнер из которого затем забирает файл и перемещает его в текущую директорию:
   1. Удаляю текущую папку *out* (если она есть)
   2. Собираю образ с именем *ffmpeg_image*
   3. Запускаю контейнер на основе собранного образа, в котором передаю следующие параметры:
      - `--rm` для автоматического удаления контейнера по завершению
      - `-v $PWD/out:/workspace/out` для монтирования временной директории, через которую обЪектный файл передается на хост
   4. Копирую нужный файл из папки *out*
   5. Удаляю папку *out*

# Анализ уязвимости

## Источники:
- [Коммит](https://github.com/FFmpeg/FFmpeg/commit/611b35627488a8d0763e75c25ee0875c5b7987dd) с исправленной ошибкой
- [Страница](https://github.com/advisories/GHSA-gj8f-pc7g-p9w6) на Github об уязвимости
- [Письмо](https://www.openwall.com/lists/oss-security/2017/08/14/1) исследователя безопасности об уязвимости

## Анализ:

### Проблема:

1. С помощью команды `ffmpeg -c:v dnxhd -i poc.mov -y output.ts` на вход программе подается специально созданный .mov файл
2. Для парсинга формата DNxHD вызывается функция dnxhd_parse в файле dnxhd_parser
3. Она в свою очередь вызывает функцию dnxhd_find_frame_end (в том же файле), которая при определенных условиях не находит конец и выдает отрицательное число, не являющееся кодом ошибки
4. Это число вместе с другими параметрами затем передается в функцию ff_combine_frame (находящуюся в файле parser) для соединения фреймов
5. Так как это число не является кодом ошибки, то ff_combine_frame распознает это как сдвиг и пытается заново прочитать эти байты в буфере, а так как буфер в этот момент пустой, происходит разыменование нулевого указателя, что приводит к Segmentation fault

### В ассемблере:

0x08000d4e - начало секции 

1. movsxd rcx, dword [rbx + 0xc]
   
   В регистре rcx получаем ссылку на pc->buffer
2. add rcx, rdi
   
   Добавляем next к pc->buffer
3. add rcx, qword [rbx]
   
   Добавляем pc->last_index к next и pc->buffer
4. movzx edi, byte [rcx]
   
   Вычисляем байт по адресу rcx, но так как pc->buffer изначально null - ловим Segmentation fault

### Решение:

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

[4.0K] /data/pocs/9c47e7dee3aeb9057218e66791b9dd65886a0f21 ├── [ 79K] dnxhd_parser.o ├── [1.1K] Dockerfile ├── [ 96K] parser.o ├── [5.5K] README.md └── [ 182] script.sh 0 directories, 5 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.