CVE-2019-13288

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.