
riscv에서 x86으로의 바이너리 변환과 현대적인 퍼징 기법을 활용한 고성능 퍼징
시작 날짜: 2021년 12월
이 도구는 커스텀 Just-In-Time 컴파일러를 사용하여 네이티브에 가까운 성능을 달성하는 커버리지 기반(coverage-guided), 에뮬레이션 기반 그레이박스 퍼저입니다. 실행 중에 RISC-V ELF 바이너리를 중간 표현(IR)으로 리프팅한 다음 JIT 컴파일하여 x86으로 변환하는 방식으로 동작합니다. JIT 컴파일 중에는 커버리지 추적, asan, cmpcov, 스냅샷 기반 퍼징과 같은 퍼징 개선 기능을 활성화하도록 코드가 계측됩니다.

이 프로젝트의 목표는 퍼징에 에뮬레이션 환경을 사용할 때의 이점을 강조하는 것입니다. 이전에도 에뮬레이션 기반 퍼저는 많이 존재했지만, 대부분 기본 에뮬레이션 엔진으로 qemu를 거의 전적으로 사용합니다. qemu 엔진은 상당히 성숙한 JIT 컴파일러를 갖추고 있고 매우 좋은 코드를 생성하지만, 퍼징을 위해 설계된 것은 아닙니다. 퍼징 중에는 동일한 프로세스를 초당 수천 번 실행해야 합니다. 이는 각 프로세스 실행에 동일한 메모리 공간을 재사용하고 더티 비트 메커니즘을 통해 제한된 양의 메모리만 리셋하는 것처럼 qemu가 적극적으로 활용하지 않는 특수한 최적화의 여지를 만들어 줍니다.
여러모로 이 프로젝트는 컴파일러 내부 구조를 배우기 위해 작업하고 싶었던 개념 증명(proof-of-concept)에 가깝고, 다양한 커버리지 메트릭, 시드 스케줄러, 스냅샷 기반 퍼징과 같은 여러 퍼징 기법을 실험할 수 있는 에뮬레이션 기반 플레이그라운드 역할을 합니다. 그러나 더 많은 JIT 최적화와, 가장 중요하게는 mips나 arm과 같은 더 대중적인 아키텍처를 지원하도록 확장된다면, 재컴파일을 통해서는 간단히 계측할 수 없는 클로즈드 소스 코드를 효율적으로 퍼징하는 데 확실히 사용될 수 있습니다.
지금까지 수행한 테스트를 기준으로, sfuzz는 다른 많은 인기 퍼저보다 오버헤드가 훨씬 적어 특히 작은 퍼즈 케이스에서 매우 빠른 성능을 보여줍니다.
이 퍼저에 적용된 기능/설계 선택에 대한 자세한 내용은 함께 제공되는 블로그 게시물(https://seal9055.com/blog/fuzzing/sfuzz)과 아래 나열된 문서 파일에서 확인할 수 있습니다:
이 퍼저는 전체가 rust로 작성되었으므로, 저장소를 클론한 후 cargo build --release를 실행하기만 하면 컴파일됩니다.
이 퍼저는 현재 RISC-V만 지원하므로, 대상은 아래 툴체인(또는 유사한 툴체인)을 사용하여 RISC-V로 컴파일되어야 합니다. 또는 이미 RISC-V 바이너리가 있다면 그것으로도 완벽하게 동작합니다.
이 설정이 완료되면 입력/출력 디렉토리를 만들고 입력 디렉토리에 초기 시드 파일 몇 개를 추가한 다음 퍼저를 시작하면 됩니다.
./sfuzz -i in -o out -- ./test_cases/simple_test @@
스레드 수 지정, 스냅샷 퍼징 활성화, 뮤테이터에 사전(dictionary) 추가 등의 추가 플래그는 명령줄 옵션으로 전달할 수 있습니다. 추가 옵션은 sfuzz를 -h 플래그로 실행하면 확인할 수 있습니다.
다양한 복잡도의 대상으로 퍼저를 테스트하려면 tools/program_generator에 있는 progrem_generator를 사용하여 다양한 복잡도의 프로그램을 자동으로 생성할 수 있습니다. 그런 다음 대상을 컴파일하려면 RISC-V 툴체인이 필요합니다.
이 프로젝트에서 로드/사용할 수 있는 riscv 바이너리를 컴파일하기 위한 툴체인을 설정합니다.
Riscv compiler/tooling:
sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev \
libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev \
libexpat-dev
git clone https://github.com/riscv/riscv-gnu-toolchain && cd riscv-gnu-toolchain
./configure --prefix=/opt/riscv --with-arch=rv64i
sudo make
Debugger:
gdb-multiarch
이 목록은 향후 구현할 계획인 기능들의 집합입니다.