Fuzzing101에서 Exercise1을 할 것이다.
Xpdf가 타겟이라 되어있다.

- All the exercises have been tested on Ubuntu 20.04.2 LTS. You can download it from here
Thank you for downloading Ubuntu Desktop | Ubuntu
Ubuntu is an open source software operating system that runs from the desktop, to the cloud, to all your internet connected things.
ubuntu.com
이렇게 Ubuntu 20.04.2 LTS를 다운하라고 한다.
다운하고 패키지를 다운한다.
sudo apt update -y && sudo apt upgrade -y
sudo apt install build-essential gcc -y
sudo apt-get install python3-pip
다음으로 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
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
실행해보면
$HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta $HOME/fuzzing_xpdf/pdf_examples/helloworld.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

설치 한 후 alf-fuzz를 입력하면 다음과 같이 나온다.
이전의 컴파일된 개체 파일을 정리한다.
cd xpdf-3.02
make clean
다음을 입력하여 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 계측 빌드에 문제가 있는 것 같아서 셋팅해보니
cd ~/fuzzing_xpdf/xpdf-3.02
make distclean || true # 이전 빌드 잔여물 제거
export PATH="/usr/local/bin:$PATH"
export CC=afl-cc
export CXX=afl-c++
export CFLAGS='-O2 -g'
export CXXFLAGS='-O2 -g'
./configure --prefix="$HOME/fuzzing_xpdf/install" --disable-shared
make -j"$(nproc)"
make install
이 후 계측 확인을 한다.
afl-showmap -o /tmp/map -- \
~/fuzzing_xpdf/install/bin/pdftotext \
~/fuzzing_xpdf/seeds/helloworld.pdf /dev/null
wc -c /tmp/map # 0보다 크면 OK (커버리지 맵 생성 확인)
afl-fuzz \
-i ~/fuzzing_xpdf/seeds \
-o ~/fuzzing_xpdf/out \
-s 123 -- \
~/fuzzing_xpdf/install/bin/pdftotext @@ ~/fuzzing_xpdf/output
퍼징을 실행한다.

10분 정도 돌렸더니 3개의 크래시가 나왔다.

이렇게 3개의 pdf가 있다.
이걸
setarch $(uname -m) -R gdb --args \
> "$HOME/fuzzing_xpdf/install/bin/pdftotext" \
> "$HOME/fuzzing_xpdf/out/default/crashes/id:000000,sig:11,src:000001,time:186147,execs:120878,op:havoc,rep:6" \
> /dev/null
하여 실행해보면
gdb가 실행되고 실행한다음 run을 하고
멈추면 bt를 입력하면

다음과 같이 나온다.
이걸 보면
getObj가 많이 나오는데 이는 무한 재귀를 나타낸다.
#254 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff805a00) at XRef.cc:823
#255 0x00005555555f8b8e in Object::fetch (this=0x555556669fe8, xref=0x5555556ca230, obj=0x7fffff805a00) at Object.cc:106
#256 0x000055555559c4f6 in Dict::lookup (this=0x555556669f90, key=0x55555564aa54 "Length", obj=0x7fffff805a00) at Dict.cc:76
#257 0x00005555555f9843 in Object::dictLookup (this=0x7fffff805c80, key=0x55555564aa54 "Length", obj=0x7fffff805a00) at Object.h:253
#258 0x00005555555fde39 in Parser::makeStream (this=0x555556669ee0, dict=0x7fffff805c80, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#259 0x00005555555fda69 in Parser::getObj (this=0x555556669ee0, obj=0x7fffff805c80, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#260 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff805c80) at XRef.cc:823
#261 0x00005555555f8b8e in Object::fetch (this=0x555556669b08, xref=0x5555556ca230, obj=0x7fffff805c80) at Object.cc:106
#262 0x000055555559c4f6 in Dict::lookup (this=0x555556669ab0, key=0x55555564aa54 "Length", obj=0x7fffff805c80) at Dict.cc:76
#263 0x00005555555f9843 in Object::dictLookup (this=0x7fffff805f00, key=0x55555564aa54 "Length", obj=0x7fffff805c80) at Object.h:253
#264 0x00005555555fde39 in Parser::makeStream (this=0x555556669a00, dict=0x7fffff805f00, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#265 0x00005555555fda69 in Parser::getObj (this=0x555556669a00, obj=0x7fffff805f00, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#266 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff805f00) at XRef.cc:823
#267 0x00005555555f8b8e in Object::fetch (this=0x555556669628, xref=0x5555556ca230, obj=0x7fffff805f00) at Object.cc:106
#268 0x000055555559c4f6 in Dict::lookup (this=0x5555566695d0, key=0x55555564aa54 "Length", obj=0x7fffff805f00) at Dict.cc:76
#269 0x00005555555f9843 in Object::dictLookup (this=0x7fffff806180, key=0x55555564aa54 "Length", obj=0x7fffff805f00) at Object.h:253
#270 0x00005555555fde39 in Parser::makeStream (this=0x555556669520, dict=0x7fffff806180, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#271 0x00005555555fda69 in Parser::getObj (this=0x555556669520, obj=0x7fffff806180, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#272 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff806180) at XRef.cc:823
#273 0x00005555555f8b8e in Object::fetch (this=0x555556669148, xref=0x5555556ca230, obj=0x7fffff806180) at Object.cc:106
#274 0x000055555559c4f6 in Dict::lookup (this=0x5555566690f0, key=0x55555564aa54 "Length", obj=0x7fffff806180) at Dict.cc:76
#275 0x00005555555f9843 in Object::dictLookup (this=0x7fffff806400, key=0x55555564aa54 "Length", obj=0x7fffff806180) at Object.h:253
#276 0x00005555555fde39 in Parser::makeStream (this=0x555556669040, dict=0x7fffff806400, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#277 0x00005555555fda69 in Parser::getObj (this=0x555556669040, obj=0x7fffff806400, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#278 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff806400) at XRef.cc:823
#279 0x00005555555f8b8e in Object::fetch (this=0x555556668c68, xref=0x5555556ca230, obj=0x7fffff806400) at Object.cc:106
#280 0x000055555559c4f6 in Dict::lookup (this=0x555556668c10, key=0x55555564aa54 "Length", obj=0x7fffff806400) at Dict.cc:76
#281 0x00005555555f9843 in Object::dictLookup (this=0x7fffff806680, key=0x55555564aa54 "Length", obj=0x7fffff806400) at Object.h:253
#282 0x00005555555fde39 in Parser::makeStream (this=0x555556668b60, dict=0x7fffff806680, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#283 0x00005555555fda69 in Parser::getObj (this=0x555556668b60, obj=0x7fffff806680, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#284 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff806680) at XRef.cc:823
#285 0x00005555555f8b8e in Object::fetch (this=0x555556668788, xref=0x5555556ca230, obj=0x7fffff806680) at Object.cc:106
#286 0x000055555559c4f6 in Dict::lookup (this=0x555556668730, key=0x55555564aa54 "Length", obj=0x7fffff806680) at Dict.cc:76
#287 0x00005555555f9843 in Object::dictLookup (this=0x7fffff806900, key=0x55555564aa54 "Length", obj=0x7fffff806680) at Object.h:253
#288 0x00005555555fde39 in Parser::makeStream (this=0x555556668680, dict=0x7fffff806900, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#289 0x00005555555fda69 in Parser::getObj (this=0x555556668680, obj=0x7fffff806900, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#290 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff806900) at XRef.cc:823
#291 0x00005555555f8b8e in Object::fetch (this=0x5555566682a8, xref=0x5555556ca230, obj=0x7fffff806900) at Object.cc:106
#292 0x000055555559c4f6 in Dict::lookup (this=0x555556668250, key=0x55555564aa54 "Length", obj=0x7fffff806900) at Dict.cc:76
#293 0x00005555555f9843 in Object::dictLookup (this=0x7fffff806b80, key=0x55555564aa54 "Length", obj=0x7fffff806900) at Object.h:253
#294 0x00005555555fde39 in Parser::makeStream (this=0x5555566681a0, dict=0x7fffff806b80, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#295 0x00005555555fda69 in Parser::getObj (this=0x5555566681a0, obj=0x7fffff806b80, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#296 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff806b80) at XRef.cc:823
#297 0x00005555555f8b8e in Object::fetch (this=0x555556667dc8, xref=0x5555556ca230, obj=0x7fffff806b80) at Object.cc:106
#298 0x000055555559c4f6 in Dict::lookup (this=0x555556667d70, key=0x55555564aa54 "Length", obj=0x7fffff806b80) at Dict.cc:76
#299 0x00005555555f9843 in Object::dictLookup (this=0x7fffff806e00, key=0x55555564aa54 "Length", obj=0x7fffff806b80) at Object.h:253
#300 0x00005555555fde39 in Parser::makeStream (this=0x555556667cc0, dict=0x7fffff806e00, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#301 0x00005555555fda69 in Parser::getObj (this=0x555556667cc0, obj=0x7fffff806e00, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#302 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff806e00) at XRef.cc:823
#303 0x00005555555f8b8e in Object::fetch (this=0x5555566678e8, xref=0x5555556ca230, obj=0x7fffff806e00) at Object.cc:106
#304 0x000055555559c4f6 in Dict::lookup (this=0x555556667890, key=0x55555564aa54 "Length", obj=0x7fffff806e00) at Dict.cc:76
#305 0x00005555555f9843 in Object::dictLookup (this=0x7fffff807080, key=0x55555564aa54 "Length", obj=0x7fffff806e00) at Object.h:253
#306 0x00005555555fde39 in Parser::makeStream (this=0x5555566677e0, dict=0x7fffff807080, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
#307 0x00005555555fda69 in Parser::getObj (this=0x5555566677e0, obj=0x7fffff807080, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:94
#308 0x00005555556217dc in XRef::fetch (this=0x5555556ca230, num=7, gen=0, obj=0x7fffff807080) at XRef.cc:823
#309 0x00005555555f8b8e in Object::fetch (this=0x555556667408, xref=0x5555556ca230, obj=0x7fffff807080) at Object.cc:106
#310 0x000055555559c4f6 in Dict::lookup (this=0x5555566673b0, key=0x55555564aa54 "Length", obj=0x7fffff807080) at Dict.cc:76
#311 0x00005555555f9843 in Object::dictLookup (this=0x7fffff807300, key=0x55555564aa54 "Length", obj=0x7fffff807080) at Object.h:253
#312 0x00005555555fde39 in Parser::makeStream (this=0x555556667300, dict=0x7fffff807300, fileKey=0x0, encAlgorithm=cryptRC4, keyLength=0, objNum=7,
objGen=0) at Parser.cc:156
이걸 보면 특정 부분이 계속 반복되는걸 알 수 있다.
이를 통해 무한 재귀로 인한 크래시가 발생하는 것을 알 수 있다.
Fuzzing101에서는 고치라 하는데 소스코드를 어디서 얻어야 하는지 모르겠어서 안할것이다.
'pwanble' 카테고리의 다른 글
| [How2Heap] - house_of_spirit.c (0) | 2025.10.28 |
|---|---|
| [Fuzzing101] Exercise 2 (0) | 2025.09.20 |
| 06. [How2Heap] - unsafe_unlink.c (0) | 2025.09.09 |
| 05. [How2Heap] fastbin_dup_consolidate.c (0) | 2025.09.05 |
| Heap (0) | 2025.05.29 |