CVE-2019-13288 is a vulnerablity in open-source software-XPDF.
We can use AFL to create the random variant PDF file.
Env Preparation
Download && Install xpdf-3.02
sudo apt install build-essential # download essential tools
wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz # download file
tar -xvzf xpdf-3.02.tar.gz
download the seeds
cd $HOME/fuzzing_xpdf
mkdir pdf_examples && cd pdf_examples
wget https://github.com/mozilla/pdf.js-sample-files/raw/master/helloworld.pdf
wget http://www.africau.edu/images/default/sample.pdf
wget https://www.melbpc.org.au/wp-content/uploads/2017/10/small-example-pdf-file.pdf
Install AFL essential tools
sudo apt-get update
sudo apt-get install -y build-essential python3-dev automake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools
sudo apt-get install -y lld-11 llvm-11 llvm-11-dev clang-11 || sudo apt-get install -y lld llvm llvm-dev clang
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-dev
# Download the AFL in another folder
git clone https://github.com/google/AFL.git
export LLVM_CONFIG="llvm-config-11"
make distrib
sudo make install # must make with root privilege
# in xpdf folder
export LLVM_CONFIG="llvm-config-11"
CC=$HOME/<folder>/afl-clang CXX=$HOME/<folder>/afl-clang++ ./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install
If the program has no instrumentation:
CC=/usr/local/bin/afl-gcc
CXX=/usr/local/bin/afl-g++
afl-fuzz -i $HOME/fuzzing_xpdf/pdf_examples/ -o $HOME/fuzzing_xpdf/out/ -- $HOME/fuzzing_xpdf/install/bin/pdftotext @@ $HOME/fuzzing_xpdf/output
Remove the install folder, compile xpdf again without AFL instrumentation.
And we can debug in GDB, we found that the program will run infinite recursion.
Scroll the call stack and you will see many calls of the “Parser::getObj” method that seems to indicate an infinite recursion. If you go to https://www.cvedetails.com/cve/CVE-2019-13288/ you can see that the description matches with the backtrace we got from GDB.
Compare with the 4.02 version.
Adding the recursionLimit is a good way to avoid the infinite recursion.