Fuzzing 101 - Exercise 2
목표
- 외부 어플리케이션을 이용해 라이브러리 퍼징해보기
- afl-clang-lto을 사용해서 afl-clang-fast보다 더 빠르게, 더 좋은 결과를 얻기
- GDB 대신 Eclipse IDE 사용해보기
Target
- libexif 0.6.14
- 어떤 프로그램인가?
exif 정보들을 편하게 파싱할 수 있도록 도와주는 라이브러리 - 어떤 취약점인가?
- CVE-2009-3895
libexif 0.6.18의 libexif/exif-entry.c에 있는 exif_entry_fix 함수(일명 태그 수정 루틴)에서 발생하는 Heap Buffer overflow는 잘못된 EXIF 이미지를 통해 공격자가 서비스 거부를 일으키거나 가능하다면 RCE가 발생합니다. - CVE-2012-2836
0.6.21 버전 이전의 EXIF 태그 파싱 라이브러리(일명 libexif)의 exif-data.c에 있는 exif_data_load_data 함수는 이미지 내의 잘못된 EXIF 태그를 통해 원격 공격자가 서비스 거부(범위를 벗어난 읽기)를 일으키거나 가능하면 프로세스 메모리에서 민감한 정보를 얻을 수 있게 합니다.
- CVE-2009-3895
- 전략
libexif
는 이름에서도 알 수 있듯이 라이브러리인데, 이걸 Fuzzing 하려면 라이브러리 내의 함수를 호출해야 가능하다. 그래서 외부 어플리케이션을 사용하는 것!
찾다보니exif
를 설치해서 사용하면 되는듯 하다. 친절하게 README에 있다.
- 어떤 프로그램인가?
가이드
- Find an interface application that makes use of the libexif library
- Create a seed corpus of exif samples
- Compile libexif and the chosen application to be fuzzed using afl-clang-lto
- Fuzz libexif until you have a few unique crashes
- Triage the crashes to find a PoC for each vulnerability
- Fix the issues
Build & Test
1. libexif Build
```
// 많은 삽질 끝에 패키지가 설치하다는 걸 하나씩 설치했는데, 솔루션에 다 나와있었다
sudo apt-get install autopoint libtool gettext libpopt-dev
autoreconf -i
CC=afl-clang-lto ./configure --enable-shared=no
make
sudo make install
```
마지막에 에러가 뜨긴 했으나 상관 없을 것 같다.
2. exif Build
```
wget https://github.com/libexif/exif/releases/download/exif-0_6_22-release/exif-0.6.22.tar.gz
tar -xvf exif-0.6.22.tar.gz
autoreconf -i
CC=afl-clang-lto ./configure --enable-shared=no
make
sudo make install
```
최신 버전은 에러가 뜨면서 빌드가 안된다.
버전을 내려보자!
```
wget https://github.com/libexif/exif/archive/refs/tags/exif-0_6_15-release.tar.gz
tar -xvf exif-0_6_15-release.tar.gz
autoreconf -i
CC=afl-clang-lto ./configure
make
sudo make install
```
에러도 없고 깔끔하다!
3. Test
테스트를 위해서는 exif 태그가 있는 사진들을 들고와야 한다.
```
wget https://github.com/ianare/exif-samples/archive/refs/heads/master.zip
unzip master.zip
```
Fuzzing
```
afl-fuzz -i ~/fuzzing_libexif/exif-samples-master/jpg/ -o ~/fuzzing_libexif/out/ -s 123 -- exif @@
```
결과
Fuzzing Result
분석
GDB 대신 Eclipse 써보기
- 설치 및 설정
이클립스는 무겁다는 생각이 많이 들어서 사용하기 싫긴 하지만 해보자
공식 홈페이지에서 다운로드하고 설치하면 된다.exif
를 이용해서 디버깅을 해야하니 [New] -> [Makefile Project with Existing Code]를 선택 후 exif 소스코드가 있는 폴더를 선택한다.
그 후엔 [Run] -> [Debug Configurations]에서 Argument를 설정해주자
이 화면이 나오면 C/C++을 택 해주자- 디버깅
첫 진입점에 break point가 자동으로 설정되어있으며 Resume으로 진행시키면 Crash가 발생하는 곳에서 멈춘다.exif_get_short
를 호출하는 곳인데 여기에 브레이크 포인트를 찍고 확인해보자exif_data_load_data_content (data, EXIF_IFD_0, d + 6, ds - 6, offset, 0);
에서 break point를 찍고 ds 값을 확인했다.
해당 함수 내부에서ds
가 1336이므로,exif_data_load_data
에서 사용되는ds
의 값은 1342(0x53E)이다.d
는 73(0x49)였으므로exif_data_load_data
에서 사용되는d
의 값은 67(0x43)이다.offset
을 적당히 수정하니 조건문에서 통과가 안되고 프로그램이 끝나는데,[31m'/home/paka/fuzzing_libexif/out3/default/crashes/crash2' does not contain EXIF data!
라고 뜬다. - Unsigned Integer Overflow를 감지해서 적절하게 조치해주면 될 것 같다.
exif_get_short
에 들어가는 모든 값을 찾았다!
해당 시점에서offset
의 값은 4294967295 = 0xffffffff이다.
상식적으로 위의 조건문에서 넘어오면 안될 값으로 보이는데 ds 값을 확인해보자.- 대부분의 crash가 Little Endian, Big Endian으로 변환하는 과정에서 발생한다.
- 패치
offset
값을 검사하는 조건이 하나 더 추가 되었다.
+--------------------------------+
| clang/clang++ 11+ is available | --> use LTO mode (afl-clang-lto/afl-clang-lto++)
+--------------------------------+ see [instrumentation/README.lto.md](instrumentation/README.lto.md)
|
| if not, or if the target fails with LTO afl-clang-lto/++
|
v
+---------------------------------+
| clang/clang++ 6.0+ is available | --> use LLVM mode (afl-clang-fast/afl-clang-fast++)
+---------------------------------+ see [instrumentation/README.llvm.md](instrumentation/README.llvm.md)
|
| if not, or if the target fails with LLVM afl-clang-fast/++
|
v
+--------------------------------+
| gcc 5+ is available | -> use GCC_PLUGIN mode (afl-gcc-fast/afl-g++-fast)
+--------------------------------+ see [instrumentation/README.gcc_plugin.md](instrumentation/README.gcc_plugin.md) and
[instrumentation/README.instrument_list.md](instrumentation/README.instrument_list.md)
|
| if not, or if you do not have a gcc with plugin support
|
v
use GCC mode (afl-gcc/afl-g++) (or afl-clang/afl-clang++ for clang)
분석 다하고 놓친게 있나 찾아봤는데, 설치된 버전에 따라서 Fuzzing에서 사용되는 도구를 다르게 가져갈 수 있다.
'공부 > Pwnable' 카테고리의 다른 글
[Fuzzing 101] Exercise 1 (1) | 2024.03.25 |
---|---|
[Fuzzing 101] 사전 준비 (0) | 2024.03.15 |
pwntools 사용법 #1 (0) | 2022.01.15 |