squid is a RISC-V emulator with features that make it a powerful tool for vulnerability research and fuzzing.
It utilizes AOT instead of JIT compilation and allows you to rewrite the binary's code before emulation. During runtime, you get full control over your target by handling all system calls and other events yourself. This makes it easy to create and combine new sanitizers and test programs for all kinds of vulnerabilities, not just memory corruptions.
Features
- Fast snapshots
- Byte-level permissions on memory
- Rewriting binaries before emulation
- Integration into LibAFL
However, it can run only single-threaded Linux user-space applications that are written in C.
The source of the target must be available because squid supports only binaries that have been compiled
with this specific set of flags:
-fPIE -pie -O0 -g -fno-jump-tables -mno-relax -D__thread=
This makes squid unsuitable for blackbox fuzzing. Instead, it was built to augment traditional greybox fuzzing.
It is encouraged to combine squid with native fuzzers to achieve both, high throughput and enhanced bug detection.
Demo
As a quick appetizer let's have a look at how we can overcome common restrictions of LLVM's sanitizers with squid.
One of the biggest restrictions is that multiple sanitizers cannot be combined in a single build. Trying to invoke a compiler like this:
clang -fsanitize=address,memory
results in
clang: error: invalid argument '-fsanitize=address' not allowed with '-fsanitize=memory'
However, since squid allows us to do binary rewriting, we can recreate ASAN and MSAN instrumentation ourselves.
We just have to compile our target with the flags mentioned above and then we can instrument and emulate it like this:
This gives us support for
- ASAN: Because the
AsanPassinserts redzones around global variables and registers interceptors that must be handled inruntime.run() - MSAN: Because we tell the backend to mark newly created stackframes as uninitialized with
enable_uninit_stack(true). New heap memory returned tomalloc()is always marked as uninitialized per default.
And then, we could go even further and combine even more sanitizers to catch a broader range of vulnerabilities, not just memory corruptions.
Getting Started
You can find detailed explanations how to harness squid in our wiki.
For a gentle introduction, see the hello world example.
For an example how to combine native and emulation-based fuzzing for maximum effectiveness, see our readelf fuzzer.
If you find that something is not properly documented / explained or you have any other questions, please do not hesitate to create an issue.