Fuzzing FFMpeg with AFL on ubuntu

https://ffmpeg.org/ is a software to record,convert and stream audio and video. this has been used by many people. in this post i will discuss how to fuzz it with afl on ubuntu.

Downloading the code:

you need to clone git repo, run this command:

git clone https://github.com/FFmpeg/FFmpeg.git

Compiling:

after you have clone the git repo, run the following configure command to make the build:

./configure --prefix="$HOME/ffmpeg_build" --pkg-config-flags="--static" --extra-cflags="-I$HOME/ffmpeg_build/include" --extra-ldflags="-L$HOME/ffmpeg_build/lib" --extra-libs="-lpthread -lm" --bindir="$HOME/bin" --enable-gpl --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libx264 --enable-libx265 --enable-nonfree --cc=afl-clang --cxx=afl-clang++ --extra-cflags="-I$HOME/ffmpeg_build/include -O1 -fno-omit-frame-pointer -g" --extra-cxxflags="-O1 -fno-omit-frame-pointer -g" --extra-ldflags="-L$HOME/ffmpeg_build/include -fsanitize=address -fsanitize=undefined -lubsan" --enable-debug

at first configure will complain about missing libs.

also:

1.this will use afl-clang and afl-clang++ compilers.

2. this will use address sanitizer and undefined behavior sanitizer.

3. this will enable debug mode.

4. this will enable static libs.

as you can see it also enables following modules:

–enable-libass

–enable-libfreetype

–enable-libmp3lame

–enable-libopus

–enable-libvorbis

–enable-libx264

–enable-libx265

if you dont have all the above libs installed, then you need to install them. i will leave up to readers on figuring our how to install all the above libs. it may take some googling and searching but worth learning.

after you have installed all the dependencies, you can run the configure command again:

./configure --prefix="$HOME/ffmpeg_build" --pkg-config-flags="--static" --extra-cflags="-I$HOME/ffmpeg_build/include" --extra-ldflags="-L$HOME/ffmpeg_build/lib" --extra-libs="-lpthread -lm" --bindir="$HOME/bin" --enable-gpl --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libx264 --enable-libx265 --enable-nonfree --cc=afl-clang --cxx=afl-clang++ --extra-cflags="-I$HOME/ffmpeg_build/include -O1 -fno-omit-frame-pointer -g" --extra-cxxflags="-O1 -fno-omit-frame-pointer -g" --extra-ldflags="-L$HOME/ffmpeg_build/include -fsanitize=address -fsanitize=undefined -lubsan" --enable-debug

this time ./configure should complete successfully.

Running Make:

after that lets compile using make, run following command:

AFL_HARDEN=1 make -j8

AFL_HARDEN=1 means it add some more code hardening options like -D_FORTIFY_SOURCE=2 and -fstack-protector-all this will cause very minor performance issue but can find crashes which otherwise will not be detected.

you need to wait for sometime till build gets finished. it will generate executable. we will fuzz “ffmpeg” executable.

Checking for ASAN/UBSAN build:

lets make sure its compiled with asan or not. for that we can use “checksec” utility from pwntools.

it will give output like this:

[*] '/home/FFmpeg/ffmpeg'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
FORTIFY: Enabled
ASAN: Enabled
UBSAN: Enabled

as you can see, both ASAN and UBSAN is enabled for our compiled binary. thats good.

Corpus collection:

now next step is to gather some samples. so you can google for different media filetypes and collect some corpus.

hint: there are lot of media samples already available. search them 🙂

Minimizing the corpus:

once you have collected some corpus, you need to minimize it. for that run following command:

afl-cmin -i input -o mininput -- ./ffmpeg -i @@ test

after that the minimized sample will be saved in mininput dir.

Fuzzing:

depending on number of cores you have, you can run this command to start afl-fuzz:

afl-fuzz -M master -i mininput -o fuzz -m none — ./ffmpeg -i @@ test

afl-fuzz -S slave1 -i mininput -o fuzz -m none — ./ffmpeg -i @@ test

this will run 1 master and 1 slave. you can run multiple slaves.

results:

this is a software which is heavily fuzzed. but that doesnt means you will not find any issues. i ran it for couple of days on 8 core(1 Mater and 7 Slaves) and found 1 assert failure and 1 heap-use-after free issue.

unfortunately both the issues were fixed few days back. one of the issue seems to be found by oss-fuzz.

conclusion:

if a software is already fuzzed by lot of people, you will need good corpus but you can still find crash. so keep fuzzing and do not loose hope.