
«Snapshotting our way to CVE-2026-9539» 블로그 게시물에 대한 PoC
sudo apt install meson ninja-build valgrind clang-20 binutils libglib-2.0-dev cmake python3-venv
Rust 툴체인을 설치합니다.
fuzzer 디렉터리 옆에 libafl을 클론하고 올바른 커밋을 체크아웃합니다
git clone https://github.com/AFLplusplus/LibAFL.git libafl/
cd libafl
git checkout 6e7ea0da898b63c5098f84c0908a8c427a5c73ff
git apply ../patches/libafl/module_snapshot.patch
git apply ../patches/libafl/snapshot.patch
git apply ../patches/libafl/libafl_bolts_wide.patch
git apply ../patches/libafl/libafl_targets_simd.patch
cd ..
git clone https://gitlab.freedesktop.org/slirp/libslirp.git
cd libslirp
git checkout 4ddbcd5cc4f7a14473ebfc1dcdd1afb4edf96908
git apply ../patches/libslirp/meson_fuzzing.patch
git apply ../patches/libslirp/meson_options.patch
git apply ../patches/libslirp/meson.patch
git apply ../patches/libslirp/qemu_target.patch
git apply ../patches/libslirp/tcp_input.patch
git apply ../patches/libslirp/tcp_outpt.patch
CC=clang-20 CXX=clang++-20 meson build
ninja -C build
바이너리를 IDA/Binja/ghidra에서 열어 cksum 함수의 ret 명령어 오프셋을 찾거나
nm -n build/fuzzing/qemu-target | grep cksum
objdump -d --disassemble=cksum build/fuzzing/qemu-target | grep -E '\bret[qwl]?\b'
처음 찾은 오프셋에서 두 번째 오프셋을 빼고 그 값을 fuzzer/src/libslirp/hooks.rs:200에서 교체합니다
cd ../fuzzer
cargo +nightly build --release
참고: llvm 설치 환경에 따라 LLVM_CONFIG_PATH 환경 변수를 지정해야 할 수 있습니다.
cp ../libslirp/build/fuzzing/qemu-target ./target/release/
cd target/release
mkdir corpus
RUST_LOG=warn ./slirp-snapshots-stateful-fuzzer
경고: 이는 VM 또는 네트워크 마운트와 공유된 폴더에서는 작동하지 않습니다.
단계 6을 수행하여 offline_reproducer/runner/src/libslirp/hooks.rs:17의 오프셋을 변경합니다. 그런 다음 runner와 driver를 컴파일합니다
cd runner
cargo +nightly-2026-06-11 build --release
cp target/release/offline_runner ../../fuzzer/target/release
cp target/release/x86_64-unknown-linux-gnu/release/libafl_qemu_asan_host.so ../../fuzzer/target/release
cd ../driver
cargo +nightly build --release
cp target/release/offline_driver ../../fuzzer/target/release
cd ../../fuzzer/target/release
mkdir corpus coverage repro_files
한 터미널에서 driver를 실행한 다음, 다른 터미널에서 fuzzer를 실행합니다.
RUST_LOG=warn ./offline_driver
RUST_LOG=warn ./slirp-snapshots-stateful-fuzzer
커버리지 파일은 coverage 폴더에 저장되며, bncov (binja)/lighthouse (ida/binja)/lightkeeper (ghidra)로 열 수 있습니다. 필요한 경우 drcov-merge로 병합할 수 있습니다.