syzkaller - Fuzzer de kernel guiado por cobertura
syzkaller es el fuzzer de kernel no supervisado y guiado por cobertura de Google. Genera secuencias de syscalls descritas en un lenguaje declarativo (syzlang), las ejecuta dentro de VMs, usa cobertura de kernel (KCOV) para dirigir la mutación hacia código no explorado, y detecta crashes vía sanitizers del kernel. Se ejecuta continuamente sin entrada humana y ha encontrado miles de bugs del kernel Linux — el sistema de fuzzing continuo syzbot está construido sobre él. También soporta otros kernels incluyendo BSDs, Fuchsia y Windows.
El fuzzing crashes kernels por diseño. Siempre ejecuta dentro de VMs desechables, nunca en una máquina que te importe.
Prerequisitos
| Requisito | Nota |
|---|
| Toolchain Go | Para compilar syzkaller |
| Fuente del kernel | Compilado con KCOV, KASAN e info de debug |
| Soporte de VM | QEMU/KVM, GCE o boards físicas |
| Imagen de disco | Un rootfs mínimo para el guest |
Compilando
git clone https://github.com/google/syzkaller
cd syzkaller && make
| Binario | Rol |
|---|
syz-manager | Orquesta VMs, corpus y reporte |
syz-fuzzer | Se ejecuta dentro del guest, genera programas |
syz-executor | Ejecuta programas de syscalls en el guest |
syz-repro | Minimiza un crash en un reproductor |
syz-prog2c | Convierte un programa syz a C |
Configuración de kernel requerida
| Opción | Propósito |
|---|
CONFIG_KCOV=y | Feedback de cobertura (esencial) |
CONFIG_KASAN=y | Detección de errores de memoria |
CONFIG_DEBUG_INFO=y | Reportes simbolizados |
CONFIG_KASAN_INLINE=y | KASAN más rápido |
CONFIG_FAULT_INJECTION=y | Explorar rutas de error |
CONFIG_DEBUG_KMEMLEAK=y | Detección de leak (opcional) |
Sin KCOV el fuzzer está ciego — el feedback de cobertura es lo que lo hace efectivo en lugar de aleatorio.
Configuración de manager
{
"target": "linux/amd64",
"http": "127.0.0.1:56741",
"workdir": "/home/user/syzkaller/workdir",
"kernel_obj": "/home/user/linux",
"image": "/home/user/image/bullseye.img",
"sshkey": "/home/user/image/bullseye.id_rsa",
"syzkaller": "/home/user/syzkaller",
"procs": 8,
"type": "qemu",
"vm": { "count": 4, "kernel": "/home/user/linux/arch/x86/boot/bzImage", "cpu": 2, "mem": 2048 }
}
./bin/syz-manager -config my.cfg
| Campo | Propósito |
|---|
target | OS/arch bajo test |
kernel_obj | Directorio de build del kernel (para simbolización) |
image / sshkey | Rootfs del guest y acceso |
procs | Procesos de fuzzing paralelos por VM |
vm.count | Número de VMs concurrentes |
http | Dirección del dashboard web |
El dashboard web
| Vista | Muestra |
|---|
| Crashes | Títulos únicos de crash + conteos |
| Corpus | Programas que contribuyen cobertura |
| Coverage | Qué líneas/archivos del kernel se alcanzan |
| Stats | Tasa de exec, salud de VM |
Cobertura es el número a observar: si se meseta, el fuzzer ha agotado lo que tus descripciones de syscalls pueden alcanzar.
syzlang (Descripciones de syscalls)
# Ejemplo simplificado: describir la estructura de argumentos de un syscall
open(file ptr[in, filename], flags flags[open_flags], mode flags[open_mode]) fd
read(fd fd, buf buffer[out], count len[buf])
Las buenas descripciones son lo que permite al fuzzer construir programas lo bastante válidos para alcanzar código profundo. Extender sys/linux/*.txt para un subsistema bajo-testeado es frecuentemente la contribución de mayor valor.
Reproduciendo crashes
| Comando | Propósito |
|---|
| Automático | El manager ejecuta syz-repro en crashes nuevos |
syz-repro -config my.cfg crash.log | Minimizar manualmente |
syz-prog2c -prog repro.syz | Emitir un reproductor C standalone |
| Reproductor C | Lo que adjuntas a un reporte de bug |
syzkaller vs otros fuzzers
| Aspecto | syzkaller | AFL++ | libFuzzer |
|---|
| Objetivo | OS kernels (syscalls) | Binarios userspace | Librerías in-process |
| Entrada | Programas de syscalls | Archivos/stdin | Buffers de bytes |
| Feedback | KCOV | Cobertura de edge | SanitizerCoverage |
| Mejor para | Búsqueda de bugs del kernel | Fuzzing binario general | APIs de librería |
Para objetivos userspace usa AFL++ o honggfuzz; syzkaller está propósito-construido para el límite de syscall del kernel.
Recursos