들어가며
libexif는 exif을 파싱하는 라이브러리이다. libexif 0.6.14 에서 발생하는 CVE-2009-3895, CVE-2012-2836을 분석한다.
CVE-2009-3895는 올바르지 않은 EXIF 이미지에서 발생하는 힙 버퍼 오버플로우 취약점이다. 힙 데이터 영역에서 발생하는 버퍼 오버플로우의 한 종류이며, 동적 메모리 할당(alloc)과 해제(free)와 관련있다.
공격자는 공격 포인트를 이용하여 응용프로그램이 실행될 때 임의 코드를 삽입하여 실행시킬 수 있다.
CVE-2012-2836는 조작된 EXIF 태그가 있는 이미지를 통해 발생할 수 있는 OOB(Out of Bounds Read) 취약점이다. OOB는 프로그램이 의도한 버퍼의 끝을 지나거나 시작 전의 데이터를 읽을 때 발생하는 취약점이다.
공격자는 서비스 거부(DoS)를 발생시키거나, 중요정보를 메모리에서 탈취할 수 있다.
준비
1-day 실습이므로 취약점이 발생했던 같은 환경을 준비한다. 또는 다음의 내용을 학습할 수 있다.
- Ubuntu 20.04(https://releases.ubuntu.com/20.04/)
- afl-fuzz(Fuzzer)
- GDB(크래시 분석 디버깅 도구)
다음의 내용을 학습한다.
- 외부 프로그램 실행을 통한 라이브러리 퍼징 방법
- afl-clang-lto를 사용하여 더 빠른 퍼징
- GDB 대신 Eclipse IDE를 사용한 디버깅
Download and Build
1. 대상 프로그램 다운 및 빌드
cd $HOME
mkdir fuzzing_libexif && cd fuzzing_libexif/
wget https://github.com/libexif/libexif/archive/refs/tags/libexif-0_6_14-release.tar.gz
tar -xzvf libexif-0_6_14-release.tar.gz
cd libexif-libexif-0_6_14-release/
sudo apt-get install autopoint libtool gettext libpopt-dev
autoreconf -fvi ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/"
make
make install
2. libexif는 라이브러리이므로 이 라이브러리를 사용하는 프로그램을 이용하여 퍼징해야 한다. exif command line 이라는 프로그램을 이용하여 퍼징을 진행한다.
cd $HOME/fuzzing_libexif
wget [https://github.com/libexif/exif/archive/refs/tags/exif-0_6_15-release.tar.gz](https://github.com/libexif/exif/archive/refs/tags/exif-0_6_15-release.tar.gz)
tar -xzvf exif-0_6_15-release.tar.gz
cd exif-exif-0_6_15-release/
autoreconf -fvi
./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" PKG_CONFIG_PATH=$HOME/fuzzing_libexif/install/lib/pkgconfig
make
make install
설치가 완료되었다면 다음 명령어로 확인할 수 있다.
$HOME/fuzzing_libexif/install/bin/exif
corpus 생성
corpus는 퍼징을 위한 샘플 데이터셋을 의미한다.
exif 이미지 샘플을 이용하여 퍼징을 진행한다. github의 이미지들을 이용한다.
cd $HOME/fuzzing_libexif wget https://github.com/ianare/exif-samples/archive/refs/heads/master.zip unzip master.zip
압축을 풀었다면 exif 바이너리를 실행시켜서 파일의 정보를 읽을 수 있다.
$HOME/fuzzing_libexif/install/bin/exif $HOME/fuzzing_libexif/exif-samples-master/jpg/Canon_40D_photoshop_import.jpg
Afl-clang-lto instrumentation
afl-clang-lto를 컴파일러로 libexif를 빌드한다.
rm -r $HOME/fuzzing_libexif/install
cd $HOME/fuzzing_libexif/libexif-libexif-0_6_14-release/
make clean
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/"
make
make install
cd $HOME/fuzzing_libexif/exif-exif-0_6_15-release
make clean
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" PKG_CONFIG_PATH=$HOME/fuzzing_libexif/install/lib/pkgconfig
make
make install
afl-clang-fast 대신 afl-clang-lto를 사용했다.
afl-clang-lto는 LTO모드를 사용한다. 이 모드는 AFL 퍼저에서 가장 빠르고 넓은 커버리지를 얻을 수 있다.
https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.lto.md
LTO 모드에서 빌드에 실패한 경우 afl-clang-fast 모드를 사용할 수 있다. LLVM 모드를 사용하며 afl-gcc나 afl-clang 보다 빠른 속도이다.
자세한 내용은 학습이 더 필요하며, AFL 공식 github에 자세한 설명이 되어 있다.
Fuzzing
afl-fuzz -i $HOME/fuzzing_libexif/exif-samples-master/jpg/ -o $HOME/fuzzing_libexif/out/ -s 123 -- $HOME/fuzzing_libexif/install/bin/exif @@
시간이 지나면 몇가지 크래시를 확인할 수 있다.
Triage
크래시를 분석한다. 앞서서는 gdb를 사용했지만 이번에는 eclipse를 이용하여 분석한다.
다운받고 의존성 패키지를 설치한다.
sudo apt install default-jdk
tar -xzvf eclipse-cpp-2021-03-R-linux-gtk-x86_64.tar.gz
설치된 경로에서 실행했다면, 소스코드를 import 해야한다. File > Import > C/C++ > “Existing code as makefile project”
“Linux GCC” 선택 > exif 소스코드 폴더 로드
디버그 파라미터 설정을 위해 Run > Debug Configuration > C/C++ Application 더블클릭 > 아래와 같이 내용 채우기
Parameter 탭, 크래시가 발생한 파일을 인자로 지정
디버깅을 진행하다보면 seg fault가 난 지점에서 프로그램이 종료되는 것을 확인할 수 있다.(01번파일에서 크래시 재현이 안되서 00파일로 변경)
분석해보면 파일의 offset에서 불러오는 ds의 값의 검증을 제대로 하지 않아 발생한 버퍼 오버플로우이다.
Fix Bug
공식 버그 패치는 다음과 같다.
- https://github.com/libexif/libexif/commit/8ce72b7f81e61ef69b7ad5bdfeff1516c90fa361
- https://github.com/libexif/libexif/commit/00986f6fa979fe810b46e376a462c581f9746e06
오류 및 부족한 내용 알려주세요!
'Reversing' 카테고리의 다른 글
[Fuzzing 101] 퍼징으로 1-day 취약점 분석하기(LibTIFF) (0) | 2022.08.01 |
---|---|
[Fuzzing 101] 퍼징으로 1-day 취약점 분석하기(tcpdump) (0) | 2022.07.28 |
[리버싱] DynamoRIO, Lighthouse로 코드커버리지 분석하기 (0) | 2022.07.19 |
[GDB] 사용법 (0) | 2022.07.15 |
[Fuzzing 101] 퍼징으로 1-day 취약점 분석하기 (0) | 2022.07.12 |