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
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.