퍼징은 2살짜리 아이에게 장난감이나 공구를 주는 것과 같다. 아이는 가능한 모든 방법으로 주어진 도구를 사용하려고 애쓴다. 퍼저는 여러 입력값을 넣어가며 프로그램을 깨부수고(break) 만다.
변이 기반 퍼징(Mutation-based fuzzing)
유전자 알고리즘(Genetic Algorithms, GAs)은 초기 입력을 주고 변형시키며 최적의 결과를 나타내는 값을 찾아내는 방법이다. 입력값이 더 나아질수록 코드 커버리지는 넓어진다. 원칙적으로 GA 구현과 입력값 생성은 AFL에 의해 자동화된다. 어떤 유전자가 살아남을 것인가를 판단하는 적합도 함수(Fitness Function)를 사용하는 대신 다른 함수(Novelty Function)을 사용해 입력값의 가짓수를 최대로 늘려 코드 커버리지를 향상시킨다.
문법 기반 퍼징(Grammer-based fuzzing)
문법 기반 퍼징은 초기 집합으로부터 더 나아간 표현식을 생성할 수 있는 규칙 집합이 필요하다. AFL++는 Nautilus라는 규칙 기반 입력값 생성기를 결합했다. 다음은 Nautilus 문법 규칙의 예시이다.
EXPR -> EXPR + EXPR
EXPR -> NUM
NUM -> 1
위 문법은 표현식은 상수인 표현식을 만들고, 표현식은 다른 표현식과 합쳐져 다른 값을 만든다. 이 문법을 통해 프로그램 입력값 트리를 생성한다.
American Fuzzy Lop / AFL++
AFL은 Michael Zalewsi라는 구글 엔지니어가 개발해 구글에서 사용되던 퍼저였다. AFL은 진화한(evolutive) 알고리즘을 사용했는데, 이 알고리즘은 보상 함수(reward function)에 따라 입력값을 변화(mutate)시킨다.
AFL++는 AFL의 오픈 소스 버전을 포크(fork)해 만들어졌다. 변화적이고(mutational), 확률적이고(probabilistic), 문법에 기반 입력값 생성기와 메타 휴리스틱 생성기를 포함한다. 내장된 수정 GCC를 통해 퍼징하기 알맞게 컴파일할 수 있다.
AFL++로 퍼징하기
먼저 https://github.com/PacktPublishing/Fuzzing-Against-the-Machine/blob/main/Chapter_4/test_fuzzing.c 에서 test_fuzzing.c 파일을 받거나 내용을 복사해 c 파일을 만든다.
다음 아래 명령어를 통해 afl++를 설치한다. 설치와 관련된 자세한 사항은
https://github.com/AFLplusplus/AFLplusplus/blob/stable/docs/INSTALL.md
여기서 확인할 수 있다.
sudo apt-get update
sudo apt-get install -y build-essential python3-dev automake cmake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools cargo libgtk-3-dev
# try to install llvm 14 and install the distro default if that fails
sudo apt-get install -y lld-14 llvm-14 llvm-14-dev clang-14 || 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
sudo apt-get install -y ninja-build # for QEMU mode
git clone https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
make distrib
sudo make install
설치 후 afl-fuzz를 입력해 실행했는데 "파일이나 디렉토리를 찾을 수 없습니다"라고 하면 환경변수에 등록한다.
vi ~/.bashrc
export PATH=$PATH:/home/loca/AFLplusplus
apt-get install로 설치할 수도 있지만, 이러면 QEMU를 활용하기 어려워진다.
afl에 내장된 수정 버전 clang으로 컴파일한다.
afl-clang test_fuzzing.c -o test_fuzzing
작업 디렉토리 내부에 inputs 라는 디렉토리를 생성하고 아래 명령어를 실행하여 5개의 입력값을 만든다. 입력값 중 하나는 충돌을 일으킨다.
echo "B622b6f721088950153f52e4cecc49513AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" > inputs/test1.txt
echo "A622b6f721088950153f52e4cecc49513d2743ff2928f 12e298ce6b1fa4b7d3d1" > inputs/test2.txt
echo "63798763395140dd72572807820ed3b1d6ffaef3d0941ef24971ad510c9e1715" > inputs/test3.txt
echo $RANDOM | md5sum | head -c 20 > inputs/test4.txt
echo "A622b6f721088950153f52e4cecc49513BppppCCCCC" > inputs/test5.txt
퍼징을 시작한다. 명령어에는 입력 테스트 값이 있는 디렉토리와 출력될 디렉토리, 퍼징을 실시할 바이너리 파일을 명시한다.
afl-fuzz -i inputs -o findings_dir -- ./test_fuzzing @@
시간이 지나면 saved crash가 1로 바뀐 것을 볼 수 있다.
finding_dir 폴더에서 오류 목록을 확인할 수 있다.
발생한 오류 파일을 cat으로 실행하면 내용을 볼 수 있다.
아래처럼 입력하면 오류 파일을 프로그램의 매개변수로 넣어 올바른지 확인할 수 있다.
ARM 바이너리 퍼징하기
ARM과 같은 다른 아키텍처의 바이너리 역시 퍼징이 가능하다. 이를 위해서 AFLplusplus 폴더 내 qemu_mode 폴더에서 다음 명령을 입력한다.
CPU_TARGET=arm ./build_qemu_support.sh
다음 GCC, G++ 크로스 컴파일러를 설치한다.
sudo apt update
sudo apt install libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi libncurses5-dev build-essential bison flex libssl-dev bc
test_fuzzing.c 파일이 있는 폴더로 돌아가서 크로스 컴파일러로 컴파일하고, 입력 파일을 주고 실행한다.
arm-linux-gnueabihf-gcc -static -g -o test_fuzzing_arm test_fuzzing.c
qemu-arm ./test_fuzzing_arm inputs/test1.txt
afl-qemu-trace 바이너리 파일의 경로를 명시해 퍼징을 시작한다.
afl-fuzz -i inputs -o ouput_arm -- ../../AFLplusplus/afl-qemu-trace ./test_fuzzing_arm @@
마찬가지로 crash가 하나 발생한다. 다음 명령으로 다시 확인해본다.
ls output_arm/default/crashes/
cat output_arm/default/crashes/id:000000,sig:11,src:000001,time:4597,execs:6048,op:havoc,rep:7
qemu-arm ./test_fuzzing_arm output_arm/defalult/crashes/id:000000,sig:11,src:000001,time:4597,execs:6048,op:havoc,rep:7
참고자료
Antonio Nappa , Eduardo Blázquez - Fuzzing Against the Machine
'보안 > fuzzing' 카테고리의 다른 글
[하드웨어 해킹] QEMU 수정하기 (0) | 2024.01.21 |
---|---|
[하드웨어 해킹] CVE-2011-0531 재현하기(실패) (0) | 2024.01.19 |
[하드웨어 해킹] 퍼징과 분석 기술 - 심볼릭 실행 (0) | 2024.01.11 |
[하드웨어 해킹] QEMU 실행 모드 (1) | 2024.01.11 |
[하드웨어 해킹] QEMU (2) | 2024.01.09 |