들어가며
1-day 익스플로잇 실습을 진행한다. CVE-2019-13288 취약점이며 Xpdf라는 pdf 뷰어에서 발생한 Dos 취약점이다. 자세한 취약점 정보는 https://www.cvedetails.com/cve/CVE-2019-13288/에서 볼 수 있으며, 관련된 취약점 설명은 https://cwe.mitre.org/data/definitions/674.html 에서 확인할 수 있다.
정리하면, 프로그램에서 호출된 각 함수가 스택에 스택 프레임을 할당하기 때문에, 함수를 너무 많이 재귀적으로 호출하면 스택 메모리 부족과 충돌로 이어질 수 있는 취약점이다.
준비
1-day 실습이므로 취약점이 발생했던 같은 환경을 준비한다. 또는 다음의 내용을 학습할 수 있다.
- Ubuntu 20.04(https://releases.ubuntu.com/20.04/)
- afl-fuzz(Fuzzer)
- GDB(크래시 분석 디버깅 도구)
Download and Build
1. 대상 프로그램 다운로드
cd $HOME
mkdir fuzzing_xpdf && cd fuzzing_xpdf/
2. 빌드 위한 make와 gcc 다운로드
sudo apt install build-essential
3. Xpdf 3.02 다운로드
wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz
tar -xvzf xpdf-3.02.tar.gz
4. 빌드
cd xpdf-3.02
sudo apt update && sudo apt install -y build-essential gcc
./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install
5. 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
6. pdfinfo 바이너리를 통한 테스트
$HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta
$HOME/fuzzing_xpdf/pdf_examples/helloworld.pdf
AFL++ 설치
1. 의존성패키지 설치
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
2. AFL++ 빌드 checkout
cd $HOME
git clone https://github.com/AFLplusplus/AFLplusplus && cd AFLplusplus
export LLVM_CONFIG="llvm-config-11"
make distrib
sudo make install
3. afl-fuzz
Fuzzing 101
AFL은 커버리지 가이드 퍼저로, 새로운 실행 경로와 잠재적인 버그를 발견하기 위해 변형된 각 입력에 대한 커버리지 정보를 수집한다는 것을 의미한다. 소스 코드를 사용할 수 있을 때 AFL은 계측(instrumentation)을 사용할 수 있으며, 각 기본 블록(함수, 루프 등)의 시작 부분에 함수 호출을 삽입할 수 있다.
대상 응용 프로그램에 대한 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
make install
이제 다음 명령어를 이용해서 fuzzer를 실행시킬 수 있다.
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 : 퍼저가 변환한 파일을 저장할 경로
- -s : 정적 랜덤 시드(빠른 재현을 위해 -123 사용)
- @@ : AFL이 각 입력 파일 이름으로 대체할 자리 표시자
이렇게 실행하게 되면 fuzzer는 각각의 다른 입력 파일을 생성해서 다음의 명령을 실행하는 것이다.
$HOME/fuzzing\_xpdf/install/bin/pdftotext <input-file-name> $HOME/fuzzing\_xpdf/output
"Hmm, your system is configured to send core dump notifications to an external utility..." 에러 발생 시 다음과 같이 실행한다.
sudo su
echo core >/proc/sys/kernel/core_pattern
exit
퍼징을 진행하다보면 크래시가 발생하고 크래시가 발생한 파일은 $HOME/fuzzing_xpdf/out/ 경로에 저장된다. Ctrl+C를 이용하여 퍼저를 중지할 수 있고 경로에 들어가서 파일을 분석해볼 수 있다.
out 경로에는 크래시가 발생한 파일들의 목록을 확인할 수 있다.
~/fuzzing\_xpdf/install/bin/pdftotext ‘~/fuzzing\_xpdf/out/default/crashes/<결과파일명>’ ~/fuzzing\_xpdf/output
명령어로 실행했을 때 Segmentation fault와 함께 프로그램이 종료되는 것을 확인할 수 있다.
Triage
gdb를 이용하여 크래시를 분석해 본다.
먼저, 디버그 정보 및 심볼릭 링크 정보를 얻기 위해 Xpdf를 다시 빌드해야 한다.
rm -r $HOME/fuzzing_xpdf/install
cd $HOME/fuzzing_xpdf/xpdf-3.02/
make clean
CFLAGS="-g -O0" CXXFLAGS="-g -O0" ./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install
gdb --args $HOME/fuzzing\_xpdf/install/bin/pdftotext $HOME/fuzzing\_xpdf/out/default/crashes/<your\_filename> $HOME/fuzzing\_xpdf/output
gdb 실행 후 분석한다.
$run과 $bt (back trace) 명령어를 보면 많은 재귀적인 Parser::getObj 호출을 볼 수 있다. CVE-2019-13288 의 설명과 같이 GDB 분석결과가 일치하는 것을 확인할 수 있다.
'Reversing' 카테고리의 다른 글
[리버싱] DynamoRIO, Lighthouse로 코드커버리지 분석하기 (0) | 2022.07.19 |
---|---|
[GDB] 사용법 (0) | 2022.07.15 |
[Cheat Engine] 상용프로그램 후킹하기1 (1) | 2022.05.31 |
[Frida] Windows Socket Program hooking (0) | 2022.05.26 |
[Cheat Engine] Socket Program 분석 (0) | 2022.05.21 |