Project
To run: ./script.sh
GitHub repository - https://github.com/LaCinquette/practice-22-23
Progress
-
For vulnerability research I chose the FFmpeg project. I found a commit that met the requirements, namely:
- Matched the type CWE-476 - null pointer dereference
-
Created a Dockerfile in which:
- Chose Ubuntu 22.04 as the base image
- Set
DEBIAN_FRONTEND=nointeractive to avoid command-line interaction during package installation and other commands
- Installed the necessary dependencies listed in the official wiki
- Prepare the working directory (folder workdir)
- Download, extract and move the commit with the still unfixed vulnerability to the working directory
- Run the build of the program using the make utility
- Create the script copy_out.sh, which finds the required object file with the error and copies it to the workspace/out directory
- Leave an instruction to execute the copy_out.sh script, which should run when the container starts
-
For automation, create the script script.sh, which builds the image and runs the container, then retrieves the file and moves it to the current directory:
- Remove the current out folder (if it exists)
- Build an image named ffmpeg_image
- Run a container based on the built image, passing the following parameters:
--rm for automatic container removal upon completion
-v $PWD/out:/workspace/out to mount a temporary directory through which the object file is transferred to the host
- Copy the required file from the out folder
- Remove the out folder
Vulnerability Analysis
Sources:
- Commit with the fixed bug
- Page on GitHub about the vulnerability
- Letter from a security researcher about the vulnerability
Analysis:
Problem:
- Using the command
ffmpeg -c:v dnxhd -i poc.mov -y output.ts, a specially crafted .mov file is fed to the program
- To parse the DNxHD format, the function dnxhd_parse in the file dnxhd_parser is called
- It in turn calls the function dnxhd_find_frame_end (in the same file), which under certain conditions does not find the end and returns a negative number that is not an error code
- This number, along with other parameters, is then passed to the function ff_combine_frame (located in the file parser) for frame combining
- Since this number is not an error code, ff_combine_frame interprets it as an offset and tries to re-read those bytes in the buffer. Since the buffer is empty at that moment, a null pointer dereference occurs, leading to a segmentation fault
In assembly:
0x08000d4e - start of section
-
movsxd rcx, dword [rbx + 0xc]
Register rcx gets a reference to pc->buffer
-
add rcx, rdi
Add next to pc->buffer
-
add rcx, qword [rbx]
Add pc->last_index to next and pc->buffer
-
movzx edi, byte [rcx]
Compute the byte at address rcx, but since pc->buffer is initially null, we get a segmentation fault
Solution:
Prevent access to an unallocated memory region by correctly handling the exceptional case. When a negative number of remaining bytes is detected, continue processing the file by skipping the loop.