e_yejun
Jun_ : Pwn
e_yejun
전체 방문자
오늘
어제
  • 분류 전체보기 (240)
    • Profile (1)
    • Pwnable (54)
    • Reversing (14)
    • Network (7)
    • Forensic (10)
    • Embedded (4)
    • Android (2)
    • Web (18)
    • 알고리즘 (42)
    • 프로그래밍 (24)
    • 프로젝트 (6)
    • 1-day (7)
    • CTF (15)
    • 기타 (33)
    • 일기장 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • how2heap
  • 1-day
  • Heap
  • rev-basic
  • dvwa
  • X86
  • wargame
  • dreamhack.io
  • x64
  • BOF

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
e_yejun

Jun_ : Pwn

1-day

[Fuzzing 101] Exercise 1 - Xpdf(CVE-2019-13288) 실습

2024. 1. 8. 21:33
 

GitHub - antonio-morales/Fuzzing101: An step by step fuzzing tutorial. A GitHub Security Lab initiative

An step by step fuzzing tutorial. A GitHub Security Lab initiative - GitHub - antonio-morales/Fuzzing101: An step by step fuzzing tutorial. A GitHub Security Lab initiative

github.com

fuzzing 101이라는 실습을 따라 진행하면서 퍼징에 대해 공부해볼 것이다.

첫 번째 실습은 Xpdf에서 발생한 DoS 취약점을 퍼저를 돌려 크래시를 발생시키고, 이를 분석하는 실습니다. AFL++ 퍼저를 빌드하고 실행하는 방법까지 상세하게 설명되어 있다.

 

Exercise 1 - Xpdf

📌 The goal is to find a crash/PoC for CVE-2019-13288 in XPDF 3.02.

 

 

CVE-2019-13288

Xpdf 4.01.01에서 Parser.cc의 Parser::getObj() 함수는 제작된 파일을 통해 무한 재귀를 일으킬 수 있습니다. 원격 공격자는 이를 DoS 공격에 활용할 수 있습니다.

OS : Ubuntu 20.04.2 LTS (download)

fuzzing 101에서 실습 환경 VM을 제공해주기 때문에, 위 다운로드 링크를 통해 다운받아 사용했다.

VM 다운로드 후, 다운 순서대로 진행하면 AFL++ 퍼징을 돌릴 수 있게 된다.

퍼징을 돌리기 위해서는 gcc, pip와 같은 기본적인 패키지를 먼저 다운로드 해준다.

sudo apt update -y && sudo apt upgrade -y
sudo apt install build-essential gcc -y
sudo apt-get install python3-pip

 

 

Xpdf 설치 및 테스트 실행

Xpdf 설치 및 빌드

wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz
tar -xvzf xpdf-3.02.tar.gz
./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install

실습의 타겟 프로그램인 Xpdf를 다운로드하고 빌드한다.

 

Sample 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 http://www.africau.edu/images/default/sample.pdf
wget https://www.melbpc.org.au/wp-content/uploads/2017/10/small-example-pdf-file.pdf

pdf의 샘플 파일을 다운로드 해준다.

 

pdfinfo 바이너리 테스트 실행

$HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta $HOME/fuzzing_xpdf/pdf_examples/helloworld.pdf

빌드 된 Xpdf 바이너리 중에사 pdfinfo를 통해 샘플 pdf의 정보를 확인해보면, 잘 작동하는 것을 확인할 수 있다.

 

 

AFL++ 설치

AFL++ 설치 시 필요한 종속 패키지들을 먼저 설치한다.

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

 

AFL++ 설치

cd $HOME
git clone https://github.com/AFLplusplus/AFLplusplus && cd AFLplusplus
export LLVM_CONFIG="llvm-config-11"
make distrib
sudo make install

 

빌드 시 unicornafl error

unicornafl 관련 에러가 발생했다. 무시하고 진행해도 문제 없었다.

 

AFL++ 설치 완료

afl-fuzz++ 설치 완료

 

 

AFL 컴파일러로 Xpdf 재빌드 및 실행

rm -r $HOME/fuzzing_xpdf/install
cd $HOME/fuzzing_xpdf/xpdf-3.02/
make clean

이전에 테스트 실행을 위해 빌드했던 Xpdf를 삭제한다. AFL 컴파일러로 다시 빌드하기 위해서이다.

 

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
make install

 

AFL++로 pdftotext 바이너리 퍼저 실행

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 : 입력 파일(Seed)이 있는 디렉터리 경로
  • o : AFL++ 퍼저가 실행되면서 발생하는 정보를 저장하는 디렉터리 경로
  • s : 사용할 정적 무작위 시드
  • @@ : AFL이 생성하는 파일을 @@이 입력된 부분에 input으로 대체

 

퍼저 실행 시 오류

AFL이 외부 유틸리티로 코어 덤프 알림을 보내도록 설정되어 있다고 한다.

/proc/sys/kernel/core_pattern 파일을 다음과 같이 수정하면 에러가 발생하지 않는다.

sudo su
echo core >/proc/sys/kernel/core_pattern
exit

 

퍼저 실행 화면

퍼저가 잘 실행되면, 위와 같은 화면을 볼 수 있다. 퍼저를 실행한지 1시간 39분이 지났고 9개의 크래시가 발생한 것을 확인할 수 있다.

퍼저의 크래시는 output 디렉터리 설정 경로 아래 /defalut/crashes 에 저장된다.

 

 

Crash reproduction

$ /home/fuzz/fuzzing_xpdf/install/bin/pdftotext id:000003,sig:11,src:001344,time:1451803,execs:399942,op:havoc,rep:7

발생한 크래시 파일을 pdftotext 바이너리의 인자로 직접 넣어본다.

해당 파일로 바이너리를 실행했을 때 크래시가 난다.

 

 

GDB 분석

gdb -q --args ./install/bin/pdftotext ./out/default/crashes/id:000000,sig:11,src:
pwngdb> r

gdb로 실행시켜보면 Segmentation fault가 뜬다.

 

backtrace를 보면 특정 부분이 반복된다. 따라서, 특정 부분이 재귀 호출되면서 스택 프레임을 계속 쌓아올리면서 크래시가 발생한 것이라고 볼 수 있다.

backtrace를 확인하면서 반복되는 코드 부분인 #13부터 #19까지 분석해볼 것이다.

 

#19

Parser::getObj - parser.cc:94

위 코드 부분에서 makeStream 함수를 호출한다. VScode의 ‘Ctrl + 왼쪽 클릭’으로 해당 함수를 찾아갈 수 있다.

 

#18

Parser::makeStream - parser.cc:156

makeStream 함수 안에서 dictLookup 함수가 호출된다. 이 역시 따라간다.

 

#17

Object::dictLookup - object.h:253

lookup 함수를 호출한다.

 

#16

Dict::lookup - Dict.cc:76

삼항 연산자를 통해 값을 리턴하고 있다. fetch 함수를 따라간다.

 

#15

Object::fetch - Object.cc:106

fetch 함수를 따라간다.

 

#14

XRef::fetch - XRef.cc:823

getObj 함수를 따라간다.

 

#13

Parser::getObj - parser.cc:94

#19 번째부터 backtrace로 따라오면서 #13까지 왔는데 #19와 동일한 코드로 도달했다.

코드가 실행될 때는 13번째부터 18번째까지 차례대로 호출되었을 것이며, 이 루틴이 재귀 호출되면서 크래시가 발생하는 것이다.

 

취약점 상세정보 비교

Parser.cc의 Parser::getObj() 함수가 무한 재귀를 일으킬 수 있다고 한다. 위 분석에서도 Parser::getObj() 부터 무한 재귀가 시작된다.

 

 

 

    '1-day' 카테고리의 다른 글
    • [1-day] dact-0.8.42 취약점 분석
    • [1-day] Path Traversal (CVE-2021-41773/42013)
    • [1-day] CVE-2020-13160(AnyDesk) 분석
    • [1-day] CVE-2019-17147(TP-Link) 분석 - (1)
    e_yejun
    e_yejun
    정리노트 •_•

    티스토리툴바