CVE-2019-13288
https://nvd.nist.gov/vuln/detail/CVE-2019-13288
텍스트 추출기, 이미지 변환기, HTML 변환기 등을 포함한 무료 PDF 뷰어 및 툴킷인 XPDF 소프트웨어에서 발생하는 취약점이다.
해당 취약점은 조작된 파일을 통해 무한 재귀를 일으킬 수 있어,
원격 공격자는 이를 이용해 서비스 거부 공격을 일으킬 수 있다.
배우게 되는 것들
- 타겟 애플리케이션을 계측(instrumentation)하여 컴파일하는 방법
- 퍼저(afl-fuzz) 실행 방법
- 디버거(GDB)를 사용한 크래시 분류(Triaging) 방법
작업 환경
Ubuntu 20.04.2 with VMWare Workstation 17.6.2 (
XPDF 환경 구축
1. 빌드 도구 설치
$ cd $HOME $ mkdir fuzzing_xpdf && cd fuzzing_xpdf/
2. 취약한 3.02 버전의 xpdf 소스코드 다운로드 및 압축 해제
$ wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz && tar -xvzf xpdf-3.02.tar.gz
3. Xpdf 빌드 및 설치
$ cd xpdf-3.02 $ sudo apt install -y build-essential gcc $ ./configure --prefix="$HOME/fuzzing_xpdf/install/" $ make -j$(nproc) $ make install
4. 빌드 테스트. 몇 가지 PDF 예제 다운로드하기.
$ cd $HOME/fuzzing_xpdf $ mkdir pdf_examples && cd pdf_examples $ wget https://github.com/mozilla/pdf.js-sample-files/raw/master/helloworld.pdf $ wget https://www.melbpc.org.au/wp-content/uploads/2017/10/small-example-pdf-file.pdf
5. 이제 아래와 같은 명령어로 pdfinfo 바이너리를 테스트할 수 있다.
$ $HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta $HOME/fuzzing_xpdf/pdf_examples/helloworld.pdf
AFL++ 환경 구축
최신 버전의 AFL++ 퍼져를 사용해볼 것이다.
도커로 설치하거나, 직접 로컬로 설치할 수도 있다.
여기서는 로컬로 설치해볼 것이다.
1. 종속성 설치
$ sudo apt-get install -y build-essential python3-dev automake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools python3-pip cmake $ 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
2. AFL++ 빌드
$ cd $HOME $ git clone https://github.com/AFLplusplus/AFLplusplus && cd AFLplusplus $ export LLVM_CONFIG="llvm-config-11" $ make distrib -j$(nproc) $ sudo make install
모든 것이 잘 수행되었다면, afl-fuzz를 실행할 수 있어야 한다.
afl-fuzz 명령어를 입력해보자.
AFL++ 사용해보기
AFL은 커버리지 기반 퍼저(coverage-guided fuzzer)로,
각 변형된 입력에 대한 커버리지 정보를 수집하여 새로운 실행 경로와 잠재적인 버그를 발견할 수 있다.
소스 코드가 있을 경우, AFL은 계측(instrumentation)을 사용하여 각 기본 블록(함수, 루프 등)의 시작 부분에 함수 호출을 삽입할 수 있다.
우리의 타겟 애플리케이션에 대해 계측을 활성화하려면, AFL의 컴파일러를 사용하여 코드를 컴파일해야 한다.
우선, 이전에 컴파일된 모든 객체 파일과 실행 파일을 정리할 것이다.
$ rm -r $HOME/fuzzing_xpdf/install $ cd $HOME/fuzzing_xpdf/xpdf-3.02/ $ make clean
이제 afl-clang-fast 컴파일러를 사용하여 xpdf를 빌드해보자.
$ export LLVM_CONFIG="llvm-config-11" $ CC=$HOME/AFLplusplus/afl-clang-fast CXX=$HOME/AFLplusplus/afl-clang-fast++ ./configure --prefix="$HOME/fuzzing_xpdf/install/" $ make -j$(nproc) $ make install
이제 다음 명령어를 사용하여 퍼저를 실행할 수 있다.
$ afl-fuzz -i $HOME/fuzzing_xpdf/pdf_examples/ -o $HOME/fuzzing_xpdf/out/ -s 123 -- $HOME/fuzzing_xpdf/install/bin/pdftotext @@ $HOME/fuzzing_xpdf/output
명령어의 각 옵션에 대한 간략한 설명은 다음과 같다.
- -i: 입력 케이스(즉, 파일 예시)를 넣을 디렉토리 지정
- -o: AFL++가 변형된 파일을 저장할 디렉토리 지정
- -s: 사용할 정적 랜덤 시드(static random seed) 지정
- @@: AFL이 각 입력 파일 이름으로 대체할 타겟의 명령행 자리 표시자
만약, 퍼져를 돌리려고 하는데,
위와 같이 메시지가 나타나면,
$ sudo su $ echo core >/proc/sys/kernel/core_pattern $ exit
core라는 크래시 코어파일을 덤프할 수 있도록 조치해주면 된다.