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.

[Notes] Fuzzing on linux

some notes i have taken during my fuzzing work in last 2 years. may be useful for someone.

ram disk create
mkdir /tmp/afl-ramdisk && chmod 777 /tmp/afl-ramdisk
mount -t tmpfs -o size=2048M tmpfs /tmp/afl-ramdisk

creating build with GCC, ASAN etc, 32 bit

CFLAGS=”-m32 -g -fsanitize=address -fno-omit-frame-pointer” LDFLAGS=”-m32 -g -fsanitize=address -fno-omit-frame-pointer” ./configure

options for ASAN

-fsanitize=undefined
-fsanitize=memory
-fsanitize=address

CMAKE build

cmake .. -DCMAKE_CXX_FLAGS=”-fsanitize=address -fsanitize=leak -g” -DCMAKE_C_FLAGS=”-fsanitize=address -fsanitize=leak -g” -DCMAKE_EXE_LINKER_FLAGS=”-fsanitize=address -fsanitize=leak” -DCMAKE_MODULE_LINKER_FLAGS=”-fsanitize=address -fsanitize=leak”

deleteing CMake temp build files

rm -rf CMakeFiles/

CMake change compilers:

cmake .. -DCMAKE_C_COMPILER=path/to/afl-gcc -DCMAKE_CXX_COMPILER=path/to/afl-g++

asan with clang

CFLAGS = “-g -fsanitize=address -I/usr/lib/llvm-6.0/lib/clang/6.0.0/include”
or
../configure –cc=clang –extra-cflags=” -fsanitize=address -g ” –extra-ldflags=” -fsanitize=address -g ” –enable-debug

Configure Disable shared libraries

./configure –disable-shared

Some files related commands, used for corpus managment

find .mdb and move to new folder
find /corpus -name “*.mdb” -exec mv {} /papers \;

find file greater then 1 mb and delete them, this will ask to confirm
find . -size +1M -name “*.mdb” -exec rm -i {} \;screen –

find file greater then 1mb and delte without asking to confirm

find -type f ( -name “mdb” -o -name “accdb” ) -size +1M -delete

To Move all files, but not folders:
find ~/Downloads/ -type f -print0 | xargs -0 mv -t ~/Videos

check if elf is compiled with asan
nm -an | grep asan

alternatively use checksec utility from pwntools package.

use this command for triaging crashes with ASAN

ASAN_OPTIONS=”abort_on_error=1:symbolize=0″

WinAFL useful commands

notes to self and may be useful to someone.

Minimising a crashing test case :

afl-tmin.exe -D C:\DRIO\bin32 -i C:\winafl\crashes\crashfile -o C:\crashes\min_crashfile — -covtype edge -coverage_module coverage.dll -target_method fuzzit -nargs 2 -call_convention thiscall — C:\winafl\fuzzedapp.exe @@

Reducing corpus using winafl-cmin:

..\winafl-cmin.py -i inCorpus -o inMinCorpus -D C:\Fuzzing\DynamoRIO2\bin32 -covtype edge -call_convention thiscall -coverage_module coverage1.dll -coverage_module coverage2.dll -target_module fuzzedapp.exe -target_offset 0x1000 -nargs 2 –skip-dry-run — fuzzedapp.exe @@

Fuzzing afdko with AFL in 32bit Mode

Introduction:

Afdko is a set of tools for building opentype fonts from Postscript and true type fonts. this was previously fuzzed by j00ru of google P0. This library was also used in various adobe products and in windows too. so if you find a issue in it, there are chances that that issue is also present in adobe or windows product as well. although not all the afdko code paths are reachable in windows or adobe. by default this gets compiled in 64 bit. which has its own disadvantages like you can use -m option with AFL which limits the memory for the process. because of this we may miss some unusual crashes with ASAN.

In this post i will cover how to fuzz Afdko using AFL in 32 bit mode.

Downloading the source:

we can simply clone following git repo:

https://github.com/adobe-type-tools/afdko

Compiling:

after you have downloaded the sources, you can go to “afdko/c” directory and run following commands:

CC=afl-gcc ./builalllinux release

this will compile and create various exe files. the file of our interest is “tx” which is present in “afdko/c/tx/exe/linux” folder.

Fuzzing:

after we have instrumented file with afl we can simply run the command:

afl-fuzz -i input -o output -m none — ./tx -cff @@

this will start the fuzzing. you can also run multiple instances with 1 master and n number of slaves if you have multicore available.

but there are some issue with this:

  1. no ASAN/MSAN/UBSAN support
  2. no 32 bit build.

Compiling in 32 bit mode with ASAN/UBSAN

lets compile it with ASAN/MSAN/UBSAN

we need to change couple of files for this and add following to compile it with GCC:

+CFLAGS = $(STD_OPTS) -m32 -g -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer

+LDFLAGS = $(STD_OPTS) -m32 -g -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer

this will make sure that the build is 32 bit and is compiled with ASAN/UBSAN support. as ASAN and MSAN are mutually exclusive, they wont work together. so you can use either one of them depending on your need.

once you compiled the 32 bit build, you can again run afl as below with the corpus you have:

afl-fuzz -i input -o output -m 800 — ./tx -cff @@

note that -m 800 will set 800MB as memory limit, so if program tries to allocate huge memory like 1GB+ you will get crash. i in fact found couple of such cases where program tries to allocate huge memory because of corrupted headers. this may easily lead to DOS condition.

PS: i have created a patch file for compiling it with 32bit and ASAN/UBSAN. please contact me if you need it. it should be simple though to do at your own. but i did spent lot of time in figuring it out as i am not much in to linux. so happy to help if you need it.

Results:

I fuzzed this for few weeks and found lot of crashes. finally i reported around 8 issues to Afdko which where fixed. although i haven’t received any CVEs for them as Afdko issue don’t get any CVEs. but it was a good learning experience for me.

Thanks to Afdko team and Adobe PSIRT for their help in getting the reported issues fixed. they have released a new version 3.5.0 which fixes all the issues i have reported to them.

Exercise for the readers:

i have omitted various details from this post, if you are interested in learning more, you can try following:

  1. figure out which files needs to be modified to compile it in 32 bit with ASAN/MSAN. also check if there is already any build option for this which you can use.
  2. how to get good corpus so that your fuzzing yields in some good crashes?
  3. figure out which adobe and windows product may be using this library?
  4. if you get lot of crashes, how will you triage them?

aws commands

To list all folders:
aws s3 ls s3://bkt –recursive | tr -s ‘ ‘ | cut -d ‘ ‘ -f4- | grep “\/$” | sed ‘s/\/$//’

To list all files:
aws s3 ls s3://bkt –recursive | tr -s ‘ ‘ | cut -d ‘ ‘ -f4- | grep -v /$

To list all .json files:
aws s3 ls s3://bkt –recursive | tr -s ‘ ‘ | cut -d ‘ ‘ -f4- | grep “.json$”

To list all .json and all .yaml files:
aws s3 ls s3://bkt –recursive | tr -s ‘ ‘ | cut -d ‘ ‘ -f4- | grep -E “(.yaml|.json)$”

To list all files except .json files:
aws s3 ls s3://bkt –recursive | tr -s ‘ ‘ | cut -d ‘ ‘ -f4- | grep -v “.json$”