System Calls Interception
The goal is to provide our fuzzer a runtime that intercept any system calls.
Difficulty
- Intercept only system calls that originates from the fuzzed program and not from the fuzzer
- Try to not impact performance too much
System calls
Syscalls on Linux
- in x86 asm:
int $0x80
orsyscall
with syscall number in eax/rax - through the libc
Types of system calls
- Process control
- create process:
fork
- terminate process
- load, execute
- get/set process attributes
- wait for time/event, signal event
- allocate and free memory
- create process:
- File management
- Device management
- Information maintenance
- get
- Communication
- Protection
- get/set file permissions
Intercepting system calls
- using frida
- track for
int 0x80
orsyscalls
- calls to
libc
- track for
- tools to intercept syscalls
With LibAFL Frida intercept any instruction
syscall_intercept
- library to intercept and hook on system calls
- not maintained
- only on Linux
extrasafe
- wrapper around seccomp
- only Linux
LD_PRELOAD
- Load specified shared object instead of default one
- Can be used to override libc
- This is specific to Unix systems
- on Windows you may use DLL injection
Tools used
- capstone
- multi-platform, multi-architecture disassembly framework
- frida is used for binary analysis and the rely on capstone to disassemble the instruction to be able to operate on them
- frida
- dynamic code instrumentation toolkit
- allows you to inject snippet of code in native apps
- [frida-core]
- its role it to attach/hijack the target program to be able to interact with it
- package
frida-gum
as a shared lib which is injected into the target program - then provide a two way communication to interact with
frida-gum
with your scripts
- package
- this is the common way to use frida
- sometimes it's not possible to do so (jail iOS or Android)
- in this situation you can use
frida-gadget
- in this situation you can use
- its role it to attach/hijack the target program to be able to interact with it
- frida-gadget
- shared library meant to be loaded by the target program
- multiple way to load this lib
- modify the source code
- LD_PRELOAD
- patching one of the target program library
- it's started as soon as the dynamic linker call its constructor function
- frida-gum
- instrumentation and introspection lib
- C lib but provide a JS api to interact with it
- 3 instrumentation core
- Stalker
- code tracing enging
- capture every function/code/instruction that is executed
- Interceptor
- function hooking engine
- MemoryAccessMonitor
- Stalker
Panic in Rust
panic!
std::panic::panic_any(msg)
- if exists, panic hook is called
std::panic::set_hook
- if panic hook returns, unwind the thread stack
- if the registers are messed up
- the unwinding fails and thread aborts
- else, per frame the data is dropped
- if a panic is hit while dropping data then thread aborts
- some frames may be marked as "catching" the unwind
- marked via
std::panic::catch_unwind()
- marked via
- When the thread has finished unwinding
- if it's main thread then
core::intrisics::abort
- else, thread is terminated and can be collected with
std::thread::join
- if it's main thread then
panic is memory costly
To unwind the stack some debugging information is added to the stack
- debug information in DWARF format
- in embedded
panic = abort
is used