Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
SPiCa — Detector de rootkits en Linux basado en eBPF que utiliza análisis de vista cruzada multicanal (sched_switch, NMI, /proc) para detectar DKOM, manipulación de tracepoints y ocultación de procesos con verificación de integridad a nivel de hardware. | Kitploit
Herramientas/GitHubGitHub/0xkirisame/spica
Herramientas DefensivasGestión de Indicadores de Compromiso (IOC)Análisis ForenseAnálisis de MalwareAnálisis de BinariosDetección de IntrusionesPapers e InvestigaciónAprendizaje y EducaciónRespuesta a IncidentesDetección de Anomalías
GitHub0xkirisame/spica
104616hace 1 mesRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →

SPiCa

Detector de rootkits en Linux basado en eBPF que utiliza análisis de vista cruzada multicanal (sched_switch, NMI, /proc) para detectar DKOM, manipulación de tracepoints y ocultación de procesos con verificación de integridad a nivel de hardware.

Ver Repositorio
Compartir

SPiCa

Integridad de Procesos del Sistema y Análisis entre Vistas

SPiCa

"Voy a cantar, así que brilla fuerte, SPiCa..."

SPiCa es un detector de rootkits de Linux basado en eBPF escrito en Rust. El nombre proviene de la canción de Hatsune Miku SPiCa y la estrella a la que hace referencia — Spica (Alfa Virginis), el punto más brillante de Virgo. Lo que a simple vista parece una sola estrella es en realidad una binaria espectroscópica: dos estrellas en órbita mutua, indistinguibles como objetos separados sin medir sus espectros. SPiCa aplica el mismo principio a la observación del núcleo: múltiples canales independientes miden el mismo estado del núcleo desde mecanismos físicamente distintos, y un rootkit que suprime uno es expuesto por los demás.

Descargo de responsabilidad: Partes significativas de este código fueron generadas o refactorizadas con asistencia de GLM. Se aplicaron pruebas rigurosas y diseño iterativo, pero revise el código para seguridad y rendimiento antes del uso en producción.


Tabla de Contenidos

  1. Modelo de Amenazas
  2. Descripción General de la Arquitectura
  3. El Canal de Observación sched_switch
  4. El Canal de Integridad NMI
  5. Lógica de Detección
  6. Secreto de Direcciones Limitado por Verificador
  7. Puerta de Acceso a Mapas LSM
  8. Gestión de Claves y Ofuscación
  • Sellado TPM Vinculado a PCR (Diseño)
  • Defensa en Profundidad
  • El Incidente del Bug BTF
  • Limitaciones Conocidas y Superficie de Ataque
  • Compilar y Ejecutar
  • Hoja de Ruta
  • Glosario

  • 1. Modelo de Amenazas

    El adversario restringido: el rootkit eBPF

    SPiCa está diseñado para derrotar al adversario restringido por eBPF — un atacante con privilegios elevados (CAP_BPF o CAP_SYS_ADMIN) que carga un programa eBPF privilegiado en el núcleo. Este adversario es fundamentalmente más débil que un rootkit LKM porque el verificador BPF impone restricciones estrictas:

    RestricciónEfecto sobre el adversario
    Bucles acotados (~1M instrucciones por programa)No puede escanear toda la memoria del núcleo
    Seguridad de punteros (desreferenciación directa requiere objetivo comprobablemente válido y acotado)No puede seguir punteros arbitrarios
    Ayudantes restringidos (lista blanca por tipo de programa)No puede llamar a kmalloc, vmalloc ni a ninguna función de asignación del núcleo
    Sin escritura arbitraria en el núcleo (bpf_probe_write_kernel muy restringido)No puede modificar task_struct, arreglos de funciones de tracepoints ni bytecode de programas BPF
    Acceso a mapas limitado a referencias cargadasNo puede acceder a mapas pertenecientes a otros programas (a menos que se enumeren por ID — ver §7)

    Con los LKMs bloqueados por la puerta LSM después del arranque, este adversario restringido es la amenaza realista restante. La maquinaria anti-evasiva de SPiCa está calibrada para esta amenaza — cada defensa es honesta sobre lo que cubre y lo que no.

    No objetivos

    • Exploits de núcleo a nivel de estado-nación — corrupción de memoria que produce escritura arbitraria en el núcleo sin init_module. SPiCa eleva el piso al bloquear el vector LKM más fácil, pero no limita al adversario superior.
    • LKMs hostiles cargados antes de que SPiCa se inicie — se requiere defensa en profundidad (Arranque Seguro, firma de módulos, IMA) para la ventana de arranque.
    • Exploits del verificador — si el verificador BPF es defectuoso (CVEs históricos: CVE-2020-27194, CVE-2022-23222, CVE-2023-2163), el adversario escapa del modelo restringido hacia ejecución de código arbitrario en el núcleo. Esta es una clase de amenaza separada. Las defensas de SPiCa se mantienen bajo un verificador correcto.

    SPiCa es la capa de último recurso en una pila de defensa en profundidad, no un sustituto de las capas superiores.


    2. Descripción General de la Arquitectura

    SPiCa ejecuta cuatro programas eBPF adjuntos a ganchos del núcleo, más un motor de detección en espacio de usuario que correlaciona su salida con la vista del sistema sobre sí mismo (/proc).

    Tres canales de observación, cada uno suprimible solo por un mecanismo de costo creciente

    CanalMecanismoQué lo suprimeCosto de supresión
    /procEnumeración de directorio procfsDKOM (desenlace del proceso de la lista de tareas)Bajo — técnica de rootkit bien conocida
    sched_switchTracepoint eBPF en el planificadorDesadjuntar programa del arreglo funcs; filtrar contextoMedio — requiere escritura en el núcleo al arreglo funcs
    NMIInterrupción de contador de rendimiento hardware → evento eBPF perfEnganchar el manejador IDT/NMIPánico del núcleo casi seguro — interrupción hardware, no enmascarable

    La propiedad arquitectónica clave: un rootkit no puede suprimir los tres canales simultáneamente sin que la supresión misma se vuelva detectable o desestabilizadora. Suprimir NMI requiere parchear la IDT (Tabla de Descriptores de Interrupción), lo que provoca pánico en la mayoría de los núcleos. Esta es la "bomba viva" — el único camino del atacante hacia la ceguera total es uno que probablemente bloquee el sistema.

    Modelo de detección — tres oraciones```

    sched sees it, /proc doesn't → DKOM NMI finds sched's heartbeat stopped → TAMPER sched goes globally silent, /proc != empty → SILENT

    root@kitploit:~
    Cada clase de detección es un veredicto diferencial: una discrepancia entre dos o más canales. El motor de detección es una función pura sobre el registro + la instantánea de /proc + las marcas de tiempo de los canales — sin E/S, sin efectos secundarios, totalmente comprobable mediante pruebas unitarias.
    
    ### El rediseño del NMI: de la observación a la integridad
    
    En el diseño original, NMI era un segundo canal de observación de procesos que muestreaba la CPU e informaba qué tarea se estaba ejecutando. Esto era redundante: sched\_switch ya observa la planificación, y NMI muestreaba los mismos datos mediante un mecanismo diferente. La redundancia costaba ~1000+ eventos ring-buffer/segundo/CPU de datos de proceso que el 99.999% del tiempo confirmaban "sí, el planificador está haciendo lo que hace el planificador".
    
    En la arquitectura rediseñada, **NMI se reutiliza de la observación de procesos a la verificación de integridad de los tracepoints.** Ya no informa qué proceso está en la CPU. En su lugar, verifica que `sched_switch` se esté ejecutando realmente leyendo un heartbeat compartido en `.bss`. Esto:
    
    1. Elimina ~99% del tráfico del ring-buffer del NMI (eventos de estado estacionario casi nulos)
    2. Detecta directamente desconexión de tracepoints, supresión y fallos de BTF/attach (el error original de BTF — ver [§11](#11-the-btf-bug-incident))
    3. Se ejecuta desde una interrupción de hardware, fuera de la ruta de despacho de tracepoints — inmune a `bpf_override_return`, interceptación de kprobes y manipulación de arrays de funciones
    4. Lee variables globales de `.bss` mediante acceso directo a memoria, no helpers de BPF — inmune a `fmod_ret` en funciones helper
    
    ---
    
    ## 3. El canal de observación de sched\_switch
    
    Un programa eBPF adjunto al tracepoint `sched_switch` se dispara cada vez que el kernel planifica un proceso en una CPU. Lee el PID y el comm de la tarea entrante directamente de los argumentos del tracepoint utilizando lecturas tradicionales de desplazamiento fijo (no BTF):```
    ctx.read_at::<u32>(56)    → next_pid
    ctx.read_at::<[u8;16]>(40) → next_comm
    

    Deliberadamente no es BTF/CO-RE. La disposición de los argumentos de tracepoint es estable entre versiones del kernel (es parte de la ABI de tracepoint). Usar offsets fijos evita la fragilidad entre versiones del kernel de la navegación de estructuras resueltas con BTF. Esta es una decisión de diseño deliberada documentada en §11.

    En cada invocación, el programa:

    1. Lee next_pid y next_comm del contexto de tracepoint
    2. Filtra la tarea idle (PID 0)
    3. Ofusca con XOR la estructura ProcessInfo con BASE_KEY
    4. Envía al ring buffer sc_sched
    5. Escribe bpf_ktime_get_ns() en la variable global .bss SCHED_HEARTBEAT — el latido que el verificador de integridad NMI monitorea

    El programa evita deliberadamente bpf_get_current_pid_tgid() en este contexto. En el momento de sched_switch, "current" es la tarea saliente, no la entrante. Los argumentos del tracepoint proporcionan la identidad correcta del proceso (entrante).

    Disciplina de base temporal

    El motor de detección utiliza una única base de tiempo monotónica: nanosegundos desde el inicio del proceso de SPiCa (Instant::now() desde la entrada de run_detection()). Cuando llega un evento sched, el manejador del evento almacena el now proporcionado por el llamante (nanos locales del proceso), no el valor de bpf_ktime_get_ns() de eBPF incrustado en el evento. Esto evita la discrepancia de base temporal que ocurriría si el tiempo de arranque del kernel se mezclara con el tiempo local del proceso — un error que estuvo presente en versiones anteriores y que causó que todos los predicados de actividad fallaran silenciosamente.


    4. El Canal de Integridad NMI

    Diseño: latido .bss, sin BTF, sin recorrido de estructuras del kernel

    El programa NMI está adjunto a un contador perf de hardware (HW_CPU_CYCLES) que se dispara a nivel de interrupción de hardware. Las NMI no pueden deshabilitarse con cli — suprimirlas requiere reprogramar la PMU o enganchar la IDT, ambas acciones ruidosas y desestabilizadoras.

    El mecanismo de verificación de integridad es extremadamente simple:``` .bss (shared within SPiCa's ELF object — all programs see the same memory): SCHED_HEARTBEAT ← written by sched_switch on every invocation NMI_LAST_HB ← NMI's record of the last heartbeat it observed NMI_FIRST_TICK ← first NMI invocation timestamp (grace period reference) NMI_LAST_EMIT ← throttle: last event emission timestamp

    sched_switch runs → SCHED_HEARTBEAT = bpf_ktime_get_ns()

    NMI fires (once per second, throttled): if SCHED_HEARTBEAT == NMI_LAST_HB: if past grace period (5 seconds since first NMI tick): → sched_switch stopped running → emit event_type=1 (TAMPER) else: → sched_switch is alive → emit event_type=0 (heartbeat OK) NMI_LAST_HB = SCHED_HEARTBEAT

    root@kitploit:~
    ### Por qué esto detecta todos los ataques en el ámbito
    
    | Ataque | Qué sucede | Qué ve el NMI |
    |---|---|---|
    | Tracepoint desvinculado del array de funciones | sched\_switch deja de ejecutarse | `SCHED_HEARTBEAT` se congela → TAMPER |
    | Error de BTF / fallo de attach (silencioso) | sched\_switch nunca se ejecuta | `SCHED_HEARTBEAT` permanece en 0 → TAMPER (después del período de gracia) |
    | `bpf_override_return` en una función del planificador | Si evita que el tracepoint se active | `SCHED_HEARTBEAT` se congela → TAMPER |
    | Bytecode parcheado in situ | Requiere escritura arbitraria del kernel (a nivel de LKM) | Fuera del modelo de amenazas de eBPF |
    | Puntero de consumidor del ring buffer manipulado | Los eventos de sched no llegan al espacio de usuario | `SCHED_HEARTBEAT` sigue avanzando (el programa se ejecuta) → no hay falso TAMPER; el espacio de usuario detecta mediante `max(sched_last)` obsoleto → SILENT |
    
    ### Por qué `.bss` específicamente
    
    Las globales `.bss` se almacenan en la sección de datos interna del programa BPF, respaldadas por un mapa de array interno que el cargador gestiona. Son:
    
    - **No se pueden anclar por separado** — no aparecen como mapas con nombre en `/sys/fs/bpf/`
    - **No interceptables mediante hooks de `bpf_map_update_elem`** — las escrituras en `.bss` son almacenamientos directos en memoria, no llamadas al sistema de actualización de mapas. El antiguo mecanismo `sc_canary` (que comparaba una copia de `.bss` con una copia de un mapa con nombre para detectar la intercepción de `bpf_map_update_elem`) ya no es necesario.
    - **Compartidas entre programas en el mismo objeto ELF** — sched\_switch y NMI se comunican a través de `.bss` sin ninguna interfaz externa
    
    ### Inmunidad a la intercepción basada en BPF
    
    El verificador de integridad NMI es estructuralmente inmune a los ataques de anulación de BPF debido a una propiedad fundamental: `bpf_override_return` intercepta **llamadas** a funciones, pero el verificador NMI no *llama* a las cosas que verifica — *lee directamente la memoria `.bss`*. No se puede anular el valor de retorno de una lectura de memoria porque una lectura de memoria no es una llamada a función.
    
    Además:
    - `bpf_probe_read_kernel` (usado para lecturas de estructuras del kernel en diseños alternativos) es un auxiliar seguro contra fallos que acepta cualquier dirección — pero el diseño de latido `.bss` de SPiCa ni siquiera lo necesita. El verificador lee las globales `.bss` mediante instrucciones de carga directa.
    - El programa NMI se ejecuta en contexto NMI, donde las kprobes son estructuralmente poco fiables (el kernel las aplaza o las suprime). Un ataque basado en kprobes contra la ejecución del verificador lucha contra el hardware.
    
    ### Semántica de eventos NMI
    
    El ring buffer NMI (`sc_nmi`) transporta eventos ligeros:
    
    | `event_type` | Significado | Acción del espacio de usuario |
    |---|---|---|
    | 0 | Latido — NMI vivo, sched\_switch vivo | Actualizar la marca de tiempo `last_nmi_heartbeat` |
    | 1 | TAMPER — NMI vivo, latido de sched\_switch congelado | Imprimir `[TAMPER]` inmediatamente |
    
    Los eventos se emiten como máximo una vez por segundo (limitados por `NMI_LAST_EMIT`). Si el ring buffer NMI queda en silencio durante más de 5 segundos, el espacio de usuario dispara `[SILENT]` — el canal NMI en sí está muerto.
    
    ---
    
    ## 5. Lógica de Detección```mermaid
    graph TD
        subgraph RING0["Kernel Space: Four eBPF Programs"]
            direction TB
            SCHED_P["TracePoint, sched_switch<br/>read next_pid, next_comm<br/>write SCHED_HEARTBEAT (.bss)<br/>XOR obfuscate → sc_sched"]
            NMI_P["PerfEvent hardware NMI<br/>read SCHED_HEARTBEAT (.bss)<br/>compare to NMI_LAST_HB<br/>frozen → event_type=1 (TAMPER)<br/>alive → event_type=0 (heartbeat)<br/>→ sc_nmi"]
            LSM_P["BPF LSM, kernel_read_file<br/>READING_MODULE<br/>gate=0: allow + log<br/>gate=1: EPERM + log → sc_lsm"]
            WATCH_P["TracePoint, sched_process_exit<br/>current == SPICA_PID (.bss)? → sc_wd flag"]
        end
    
        subgraph RING3["User Space: Differential Engine"]
            ENGINE["SPiCa (Tokio async)"] -->|XOR deobfuscate| RB_S[(sc_sched RingBuf)]
            ENGINE -->|event_type=0: heartbeat<br/>event_type=1: TAMPER| RB_N[(sc_nmi RingBuf)]
            ENGINE -->|raw read| RB_L[(sc_lsm RingBuf)]
            ENGINE -->|read_dir| PROC[" /proc"]
            RB_S --> FSM{Detection FSM}
            PROC --> FSM
            FSM -->|scheduled, absent /proc, >2s| D1["[DKOM]"]
            FSM -->|in /proc, never seen by sched, >5s| D2["[GHOST]"]
            RB_N -->|event_type = 1| D3["[TAMPER]"]
            FSM -->|sched channel silent, /proc ≠∅| D4["[SILENT]"]
            FSM -->|raw getdents64 ≠ libc readdir| D9["[HOOK]"]
            RB_S -->|same TGID, different start_time_ns| D5["[DUPE]"]
            RB_L -->|allowed = 1| D7["[LKM-ALLOW]"]
            RB_L -->|allowed = 0| D8["[LKM-DENY]"]
            WATCH_P -.->|pin exists at startup| D6["[WATCHDOG]"]
        end
    
        classDef kernbox  fill:#fdf2f8,stroke:#9333ea,stroke-width:2px,color:#581c87;
        classDef userbox  fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a;
        classDef alertbox fill:#fff7ed,stroke:#ea580c,stroke-width:1px,color:#7c2d12;
        classDef storage  fill:#f8fafc,stroke:#64748b,stroke-width:1px;
        class RING0 kernbox;
        class RING3 userbox;
        class D1,D2,D3,D4,D5,D6,D7,D8,D9 alertbox;
        class RB_S,RB_N,RB_L,PROC storage;
    
    AlertaCondiciónQué detecta
    [DKOM]TGID programado por el kernel ausente de /proc por >2 sManipulación Directa de Objetos del Kernel — proceso oculto de la enumeración de espacio de usuario
    [GHOST]TGID presente en /proc pero nunca visto por sched_switch por >5 sSuplantación de /proc — entrada falsa insertada para pasar las comprobaciones de DKOM
    [TAMPER]NMI detecta que el latido de sched_switch está congelado (event_type=1)Tracepoint desconectado, suprimido o error de BTF/attach
    [SILENT]max(sched_last) obsoleto en todo el registro mientras /proc no está vacío; o latido NMI ausente por >5 sPérdida de observación a nivel de canal — el canal sched o NMI está muerto
    [DUPE]Mismo TGID, diferente start_time_ns entre eventosSuplantación de campo task_struct — el rootkit parchea tgid para hacerse pasar por un proceso legítimo
    [HOOK]PIDs visibles mediante getdents64 sin formato pero ausentes de libc readdirRootkit LD_PRELOAD — interceptación de bibliotecas de espacio de usuario que oculta procesos de ps, ls y otras herramientas (Symbiote, JynxKit, Azazel, Medusa/OrBit)
    [WATCHDOG]El pin /sys/fs/bpf/spica_watchdog existe al inicioLa instancia anterior fue terminada de forma no controlada (SIGKILL, OOM, crash)
    [LKM-ALLOW]READING_MODULE interceptado mientras la puerta está abierta (ventana de arranque)Registro de auditoría: módulo cargado antes de cerrar la puerta
    [LKM-DENY]READING_MODULE interceptado mientras la puerta está cerradainsmod/modprobe bloqueado después del inicio

    Detección SILENT a nivel de canal

    SILENT es un veredicto a nivel de canal, no por proceso. Se dispara cuando:

    1. Canal sched muerto: max(sched_last) sobre todos los registros del registro está obsoleto más allá de CHANNEL_DEAD_NANOS mientras /proc no está vacío. La protección de /proc no vacío es la garantía de actividad: en cualquier sistema Linux en ejecución, /proc no está vacío (init, hilos del kernel, kworkers), y el planificador nunca está realmente inactivo (tics de temporizador, esperas de E/S, callbacks de RCU). Un max(sched_last) obsoleto en un sistema no vacío significa que el canal murió, no que el sistema está inactivo.

    2. Canal NMI muerto: No ha llegado ningún evento de latido (event_type=0) del búfer circular NMI durante >5 segundos. Esto significa que el evento perf NMI dejó de dispararse — ya sea que el evento perf se desconectó o la PMU fue reprogramada.

    Ambas comprobaciones tienen un período de enfriamiento de 30 segundos para evitar inundaciones de alertas.

    Detección de rootkit LD_PRELOAD ([HOOK])

    SPiCa lee /proc mediante dos mecanismos independientes en cada tick:

    1. Llamada al sistema getdents64 sin formato (read_tgids()) — std::fs::read_dir de Rust lo llama directamente a través de libc::syscall(SYS_getdents64, ...), evitando todos los hooks de funciones libc. Los rootkits LD_PRELOAD no pueden interceptar esta ruta.

    2. libc readdir (read_tgids_libc()) — llama a libc::opendir / libc::readdir a través de FFI, que pasa por el enlazador dinámico y es completamente interceptable mediante los hooks de /etc/ld.so.preload.

    Si getdents64 ve PIDs que libc readdir no ve, un rootkit de espacio de usuario está interceptando readdir para ocultar procesos. SPiCa dispara [HOOK]:``` [HOOK] 3 PID(s) hidden from libc readdir — LD_PRELOAD rootkit suspected

    root@kitploit:~
    This technique turns SPiCa's kernel-level privilege into an active detection of userspace rootkits. The raw syscall path is the ground truth — no userspace hook can blind it. The libc path is the "perceived" view that a normal tool (ps, ls) would see. The discrepancy is unambiguous proof of library interception.
    
    **Rootkits detected by `[HOOK]`:**
    
    | Rootkit | Mecanismo de ocultación | Detectado |
    |---------|-------------------------|-----------|
    | Symbiote | Parasitic LD_PRELOAD, hooks `readdir` | Sí (cuando se oculta activamente) |
    | JynxKit | LD_PRELOAD, `MAGIC_GID` hiding via `readdir` | Sí |
    | Azazel | LD_PRELOAD, `readdir` + `stat` hooks | Sí |
    | Medusa/OrBit | LD_PRELOAD, `readdir` + credential theft | Sí |
    
    **Probado contra Symbiote real:** Una muestra viva de Symbiote (SHA256 `f55af21f...`, MalwareBazaar) fue desplegada mediante `/etc/ld.so.preload` en una VM Ubuntu 24.04. La muestra engancha `readdir`, `readdir64`, `stat`, `fstatat`, `pam_authenticate`, `pcap_loop`, `recvmsg`, `fopen`, `read`, `execve`. Cuando el hook LD_PRELOAD oculta activamente un PID de `readdir`, SPiCa dispara `[HOOK]` en un ciclo de tick (<1 s). Cuando Symbiote está cargado pero pasivo (sin ocultar activamente), SPiCa produce cero falsos positivos.
    
    ### Ventana de gracia
    
    Una ventana de gracia de 50 ms evita falsos positivos en procesos recién bifurcados. Las comprobaciones SILENT a nivel de canal tienen un período de gracia de 5 segundos (la referencia `NMI_FIRST_TICK` del programa NMI) para que la latencia de inicio no produzca alertas TAMPER falsas.
    
    ---
    
    ## 6. Secreto de Dirección Limitado por el Verificador
    
    ### Definición
    
    **Secreto de dirección limitado por el verificador** es una propiedad de seguridad computacional que se cumple bajo el modelo de adversario restringido por eBPF. Establece que:
    
    > Dado un adversario que puede cargar programas eBPF (CAP\_BPF) pero está restringido por el verificador BPF (bucles acotados, helpers limitados, sin escritura arbitraria en el kernel), la dirección del kernel de la sección de datos `.bss` de un programa BPF es computacionalmente inviable de descubrir.
    
    ### Los cuatro mecanismos
    
    La propiedad es una composición de cuatro barreras independientes:
    
    1. **kASLR** — La aleatorización del diseño del espacio de direcciones del kernel aleatoriza la región del heap del kernel donde se asigna la memoria de los mapas BPF (incluyendo los mapas de respaldo de `.bss`). La dirección exacta cambia en cada arranque.
    
    2. **Límite de instrucciones del verificador** — El verificador BPF limita las instrucciones totales por programa a ~1 millón y requiere bucles que terminan demostrablemente. Un programa de escaneo del adversario puede sondear como máximo N ≈ 10^6 direcciones por carga mediante `bpf_probe_read_kernel`. Dado un espacio de búsqueda aleatorizado por kASLR, la probabilidad de éxito por programa es insignificante.
    
    3. **Puerta de acceso a mapas LSM** (ver [§7](#7-lsm-map-access-gate)) — Sin la puerta, un adversario podría enumerar los mapas BPF por ID (`BPF_MAP_GET_NEXT_ID` → `BPF_MAP_GET_FD_BY_ID` → `BPF_MAP_LOOKUP_ELEM`) y leer el contenido de `.bss` directamente. La puerta elimina este camino fácil, forzando al adversario a la ruta de escaneo de memoria limitada por el verificador.
    
    4. **Ubicación de `.bss`** — Las variables globales de `.bss` no aparecen en las interfaces de enumeración de mapas con nombres. El mapa de respaldo interno de `.bss` se llama `.bss` por libbpf/aya, pero su contenido (las variables globales reales) solo es accesible si se tiene el fd del mapa. El fd del mapa requiere o la tabla de fds del proceso cargador o el ID del mapa (bloqueado por la puerta).
    
    ### Estructura del argumento formal```
    Adversary's goal:    locate SPiCa's .bss in kernel virtual memory
    Search space:        kernel heap region, kASLR-randomized (~2^30 entropy)
    
    Path A — map enumeration (blocked):
      BPF_MAP_GET_NEXT_ID → BPF_MAP_GET_FD_BY_ID → BPF_MAP_LOOKUP_ELEM
      → blocked by LSM gate (§7) for non-SPiCa processes
    
    Path B — memory scan (bounded):
      bpf_probe_read_kernel(addr, buf, len) — fault-safe, accepts any addr
      Per-program capacity: N ≈ 10^6 probes (instruction limit)
      Success probability per load: N / |search space| ≈ 10^6 / 2^30 ≈ 10^-24
      Can reload programs, but: each load is a syscall (observable), and
      the target address doesn't change between loads (same boot session)
    
    Path C — timing side channel (theoretical):
      bpf_probe_read_kernel timing varies on fault vs success
      Binary search over the heap could reduce scan complexity to O(log |A|)
      → O(30) probes, well within instruction budget
      LIMITATION: must be acknowledged. Mitigated by rate-limiting BPF_PROG_LOAD
      via the LSM gate (future work).
    

    Qué hace esto novedoso

    La mayoría de las investigaciones de seguridad sobre BPF tratan al verificador como una superficie de ataque (bugs del verificador, falta de solidez, JIT spray). Este trabajo invierte el marco: las restricciones del verificador son una primitiva defensiva que acota el espacio de búsqueda del adversario. El secreto no es criptográfico (no es AES); es computacional — limitado por lo que el verificador permite al adversario computar.

    Limitaciones (deben declararse honestamente)

    • Explotaciones del verificador — Si el verificador no es sólido, el límite de instrucciones se rompe y el adversario puede realizar cómputo arbitrario. Esto está fuera del modelo de amenazas de eBPF.
    • Canales laterales de temporización — bpf_probe_read_kernel es observable en el tiempo (fallo vs. éxito toma diferentes ciclos). Una búsqueda binaria basada en temporización sobre el montón es teóricamente más eficiente que un escaneo lineal. El límite de instrucciones restringe las sondas por programa, pero la búsqueda binaria podría reducir la cantidad de sondas a O(log |A|) ≈ 30. Esta es una limitación real. Mitigación: limitar la tasa de BPF_PROG_LOAD mediante la puerta LSM.
    • Root de espacio de usuario — Un proceso root de espacio de usuario (no restringido por el verificador) puede enumerar mapas por ID. La puerta LSM bloquea esto, pero solo para procesos que no son SPiCa. Un proceso que compromete el PID propio de SPiCa tiene acceso completo.

    7. Puerta de acceso a mapas LSM

    El problema

    Los globales .bss están respaldados por un mapa BPF interno. Cualquier proceso con CAP_BPF puede enumerar todos los mapas del sistema:``` bpf(BPF_MAP_GET_NEXT_ID, …) → iterate all map IDs bpf(BPF_MAP_GET_FD_BY_ID, id) → get fd to any map bpf(BPF_MAP_LOOKUP_ELEM, fd, key, value) → read map contents

    root@kitploit:~
    Contra el adversario eBPF (que no puede llamar syscalls), `.bss` está oculto. Contra el root de userspace, es un mapa estándar — completamente legible. El gate LSM cierra esta brecha.
    
    ### La defensa
    
    Un hook LSM de BPF en el syscall `bpf` verifica los comandos de acceso a mapas:```
    hook = "bpf"
      read cmd (arg 0)
      if cmd == BPF_MAP_GET_FD_BY_ID:
        read map_id from userspace bpf_attr (bpf_probe_read_user)
        if map_id matches any of SPiCa's stored IDs (.bss):
          if caller_tgid != SPICA_PID:
            return -EPERM
    

    Los IDs de mapa son escritos en .bss por el cargador de espacio de usuario inmediatamente después de la carga del programa, antes de que el hook de LSM esté armado (mismo patrón de temporización que el sc_gate existente para el bloqueo de LKM). No se necesita BTF — cmd y map_id provienen de argumentos de llamada al sistema, no de estructuras del kernel.

    Quirúrgico: solo bloquea el acceso a los IDs de mapa específicos de SPiCa. Otras herramientas BPF de otros procesos (tcpdump, bpftrace, bcc) acceden a sus propios mapas y no se ven afectadas.

    Lo que no cubre

    • ptrace / /proc/pid/mem — Otro proceso root podría leer la memoria del proceso de SPiCa directamente a través de ptrace, evitando por completo la llamada al sistema BPF. Esta es una limitación fundamental: no se puede proteger contra un proceso con el mismo nivel de privilegio que lea tu memoria a través de /proc/pid/mem. Defensa: envío de registros fuera del host (si el atacante puede leer la memoria local, también puede suprimir alertas locales — solo el registro remoto ayuda).
    • PID propio de SPiCa comprometido — Si el atacante obtiene el control del proceso de SPiCa, tiene acceso legítimo a los mapas.

    8. Gestión de Claves y Ofuscación

    Clave generada por TPM

    En hosts equipados con TPM, la clave de ofuscación XOR de 64 bits se obtiene de TPM2_GetRandom a través de la crate tss-esapi (llamada directa a la biblioteca libtss2-esys). La clave no transita por tuberías, ni por línea de comandos de subprocesos, ni por disco. Existe solo en el hardware TPM y en la memoria volátil del kernel (mapa de respaldo .bss) durante la duración del proceso SPiCa.

    En hosts sin TPM (VMs sin vTPM, contenedores, máquinas sin chip TPM), SPiCa recurre a una clave de tiempo de compilación por compilación generada desde /dev/urandom por el script de construcción. El fallback es visiblemente ruidoso al inicio con un banner de advertencia.

    Ubicación en .bss

    Los siguientes valores residen en la sección .bss del programa eBPF, escritos por el espacio de usuario a través de set_global() antes de cargar cualquier programa:

    GlobalPropósitoEscrito por
    BASE_KEYClave de ofuscación XORespacio de usuario al cargar
    SPICA_PIDTGID propio de SPiCa (watchdog)espacio de usuario al cargar
    SCHED_HEARTBEATMarca de tiempo de viveza de sched_switchprograma sched_switch en cada invocación
    NMI_LAST_HBRegistro del NMI del último heartbeat de schedprograma NMI en cada verificación
    NMI_FIRST_TICKktime de la primera invocación del NMI (período de gracia)programa NMI en la primera invocación
    NMI_LAST_EMITLímite: ktime de la última emisión de eventoprograma NMI en cada emisión

    Los mapas BPF nombrados son enumerables a través de la interfaz de iteración de mapas de la llamada al sistema bpf() (bloqueada por la puerta LSM — ver §7); las globales de .bss se acceden a través del mismo mapa interno pero no tienen nombre separado ni son anclables.

    Ofuscación XOR — defensa contra fugas de lectura, no cifrado

    Todos los campos de ProcessInfo se pliegan con XOR usando la BASE_KEY de 64 bits antes de escribirlos en los buffers circulares. El campo event_type se deja intencionalmente sin ofuscar para que el espacio de usuario pueda leerlo como centinela antes de desofuscar el resto.

    Esto es ofuscación contra fugas de lectura, no cifrado contra un adversario capaz. XOR con una clave repetitiva de 8 bytes es estructuralmente vulnerable a texto plano conocido: valores predecibles de comm ("bash", "systemd", "kthreadd") aplicados XOR contra el texto cifrado recuperan los bytes de la clave directamente. La defensa es apropiada para el adversario eBPF (que no puede leer fácilmente el buffer circular — requiere la misma brecha de capacidad que protege .bss), no para un adversario con acceso binario e interceptación del buffer circular.


    9. Sellado TPM Vinculado a PCR (Diseño)

    Estado: Fase de diseño. Aún no implementado. Esta sección documenta la arquitectura objetivo para el artículo de investigación.

    Descripción general

    El sellado TPM vinculado a PCR mueve el límite de distribución de claves de la capa de software al silicio. La clave se sella en el momento de la instalación contra valores esperados del Registro de Configuración de Plataforma (PCR), y solo se puede desellar si el estado de arranque del sistema coincide con las mediciones esperadas.

    Cadena de medición de arranque

    Durante el arranque, el firmware, el gestor de arranque y el kernel miden componentes críticos en los PCR:

    PCRQué mideEstabilidad
    PCR 4Código del gestor de arranque + imagen del kernel (GRUB mide ambos)Cambia en actualización del kernel
    PCR 5Tabla de particiones GPT/MBR, configuración de arranqueEstable entre actualizaciones
    PCR 7Política de Secure Boot (política SI, MOK, db/dbx)Estable entre actualizaciones del kernel
    PCR 8Línea de comandos del kernel (mediciones de systemd-stub)Estable a menos que cmdline cambie
    PCR 9Initramfs (GRUB mide initrd aquí)Cambia en actualización de initramfs
    PCR 10Lista de mediciones de IMACambia a medida que se miden ejecutables

    Nota: La asignación de PCR depende de la cadena de arranque. GRUB mide el kernel en PCR 4; systemd-stub mide en PCR 4 y la línea de comandos en PCR 8. La política de sellado debe coincidir con la cadena de arranque objetivo.

    El flujo de sellar → desellar → inyectar → modo seguro

    1. Sellar (tiempo de instalación): La clave de 64 bits se sella contra valores de PCR esperados usando TPM2_Create con una sesión TPM2_PolicyPCR. El blob sellado se almacena en disco. Está cifrado con la clave interna del TPM y solo se puede descifrar cuando los PCR especificados coinciden.

    2. Desellar (arranque temprano, etapa de initramfs): Antes de que se ejecute cualquier código de espacio de usuario no confiable, el hook de initramfs de SPiCa solicita TPM2_Unseal. Si los valores actuales de PCR coinciden con la política de sellado, el TPM libera la clave.

    3. Inyectar: La clave se escribe en .bss a través de set_global() antes de cargar los programas.

    4. La trampa: Si un atacante ha modificado el kernel (PCR 4 no coincide), intercambiado el initramfs (PCR 9 no coincide) o alterado la política de Secure Boot (PCR 7 no coincide), los hashes de PCR divergen. El TPM se niega a desellar, y SPiCa falla de forma segura — se niega a iniciar en lugar de ejecutarse a ciegas con una clave comprometida.

    Opciones de política de PCR

    PolíticaSellado contraFortalezaCosto operativo
    FuertePCR 4 + 7 + 9 + 10Captura cambios en kernel, initramfs, Secure Boot e IMARe-sellar después de cada actualización de kernel/initramfs
    EquilibradaPCR 7 + 10Captura cambios en Secure Boot y evaluación de IMA; estable entre actualizaciones del kernelRe-sellar solo en cambios de política Secure Boot o política IMA
    MínimaPCR 7 soloCaptura solo cambios en el estado de Secure BootMuy estable; vinculación más débil

    Para el artículo de investigación, presentar la política fuerte y discutir la compensación del re-sellado en las limitaciones.

    Relación con el secreto de direcciones limitado por el verificador

    Los dos mecanismos son complementarios:

    • El sellado PCR protege la clave en el arranque — asegura que la clave solo esté disponible en un estado de sistema confiable.
    • Secreto de direcciones limitado por el verificador + puerta LSM protegen la clave en tiempo de ejecución — aseguran que el adversario eBPF no pueda localizar ni leer el .bss donde reside la clave.

    Ninguno es suficiente por sí solo. El sellado PCR no ayuda si la clave se ve comprometida en tiempo de ejecución (enumeración de mapas). El secreto de direcciones no ayuda si el sistema fue comprometido antes de que SPiCa iniciara (initramfs hostil).

    Lo que el sellado PCR NO captura

    • Desprendimiento de programa LSM en tiempo de ejecución — Los programas BPF LSM (spica_lsm_modblock, la puerta de acceso a mapas) se cargan en tiempo de ejecución y NO se miden en ningún PCR. Un rootkit que los desconecte después del arranque no es capturado por el sellado PCR. Lo que captura eso es el heartbeat NMI (detectando que el propio sistema de detección dejó de ejecutarse).
    • Explotación del kernel posterior al arranque — Si el kernel es explotado después del arranque (corrupción de memoria → escritura arbitraria), los PCR no cambian. Este es el no-objetivo de "estado-nación".

    10. Defensa en Profundidad

    SPiCa es la última capa de cumplimiento. Complementa un sistema correctamente configurado, no reemplaza las capas superiores.```mermaid flowchart TD SB["UEFI Secure Boot
    ─────────────────────────────
    Verifies bootloader signature against
    the UEFI db certificate store
    Measured to PCR 7"] MS["Kernel Module Signing
    ─────────────────────────────
    CONFIG_MODULE_SIG_FORCE=y
    Kernel rejects unsigned .ko at load time"] IMA["IMA, Integrity Measurement Architecture
    ─────────────────────────────
    Measures file hashes to TPM PCR10
    Appraise policy blocks non-matching signatures"] SPICA["SPiCa
    ─────────────────────────────
    LSM gate: blocks LKM loads + map enumeration
    sched_switch + NMI integrity channels
    Differential detection: DKOM · GHOST · TAMPER · SILENT · DUPE
    PCR-bound key sealing (design phase)"]

    root@kitploit:~
    SB  -->|"boot chain verified"| MS
    MS  -->|"signed modules only"| IMA
    IMA -->|"measured + appraised"| SPICA
    
    classDef firmware fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#78350f
    classDef kernel   fill:#fdf2f8,stroke:#9333ea,stroke-width:2px,color:#581c87
    classDef spica    fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a
    class SB firmware
    class MS,IMA kernel
    class SPICA spica
    
    root@kitploit:~
    SPiCa verifica las cuatro capas al inicio e imprime su estado.
    
    ---
    
    ## 11. El incidente del error BTF
    
    ### Lo que sucedió
    
    Durante las pruebas en Ubuntu (kernel más reciente), una incompatibilidad BTF provocó que el programa de tracepoint `sched_switch` se adjuntara correctamente pero **nunca disparara un solo evento.** La llamada al sistema `attach()` devolvió `Ok(())`, por lo que SPiCa continuó normalmente — pero el búfer de anillo sched permaneció vacío. No se dispararon alertas de detección porque el motor de detección no tenía datos de planificación. **SPiCa funcionó a ciegas sin ninguna indicación de fallo.**
    
    Este es el peor modo de fallo para una herramienta de seguridad: ceguera silenciosa.
    
    ### Por qué no se detectó
    
    El motor de detección original razonaba **por proceso**: cada registro de proceso tenía marcas de tiempo `sched_last` y `nmi_last`, y la vivacidad se calculaba por registro. Cuando sched\_switch falló globalmente:
    
    1. `sched_live` se volvió falso para cada registro (sin nuevos eventos sched → todos los valores `sched_last` envejecen)
    2. El predicado `TAMPER` por proceso (`in_proc && nmi_live && !sched_live`) podía dispararse, pero requería que `nmi_live` se mantuviera *continuamente* durante 2 segundos. El NMI muestrea de forma dispersa (período de 10M ciclos), por lo que `suspect_since` se reiniciaba constantemente debido a la fluctuación del muestreo y nunca maduraba.
    3. El predicado `SILENT` por proceso requería `sched_live`, que ahora era falso para todo — el predicado se invertía exactamente bajo la condición que debía detectar.
    4. No había **verificación de vivacidad a nivel de canal** — ningún mecanismo "¿ha disparado sched ALGUNA VEZ?" o "¿está obsoleto max(sched_last)?".
    
    Además, se descubrió una falta de coincidencia en la base de tiempo: `sched_last` almacenaba `bpf_ktime_get_ns()` (nanosegundos de arranque del kernel) mientras que `evaluate()` comparaba con `nanos_since_startup()` (nanosegundos locales del proceso). La `wrapping_sub` de estas diferentes bases de tiempo producía valores enormes, haciendo que todos los predicados de vivacidad fueran trivialmente falsos. La lógica de detección nunca había funcionado correctamente en producción — el error BTF simplemente lo enmascaró al evitar que los eventos llegaran en absoluto.
    
    ### Cómo el rediseño lo soluciona
    
    | Problema | Solución |
    |---|---|
    | Sin verificación de vivacidad a nivel de canal | `evaluate()` ahora calcula `max(sched_last)` y dispara `[SILENT]` si está obsoleto mientras `/proc` no está vacío |
    | TAMPER por proceso nunca maduraba (reinicio por fluctuación) | TAMPER ahora es una señal directa del programa NMI (comparación de heartbeat `.bss`), no una FSM por proceso con umbrales |
    | SILENT por proceso se invertía cuando sched fallaba | SILENT ahora es a nivel de canal, calculado a partir de agregados, no predicados por registro |
    | Desajuste de base de tiempo | `sched_last` ahora almacena tiempo local del proceso (parámetro `now`), no `bpf_ktime_get_ns()` |
    | NMI era una observación redundante | NMI ahora es un verificador de integridad — detecta la muerte de sched directamente a través del heartbeat `.bss` |
    
    ---
    
    ## 12. Limitaciones conocidas y superficie de ataque
    
    ### Dentro del modelo de amenazas eBPF
    
    | Ataque | Estado | Notas |
    |---|---|---|
    | **Manipulación del puntero consumidor del búfer de anillo** | **Detectado** (SILENT) | `max(sched_last)` se vuelve obsoleto → SILENT. `SCHED_HEARTBEAT` aún avanza (el programa se ejecuta) → no hay falso TAMPER. |
    | **DKOM de la estructura de evento Perf** (campo `state` en cero) | **Detectado** (SILENT) | NMI deja de disparar → sin eventos de heartbeat → SILENT en el canal NMI |
    | **Suplantación de campo `task_struct`** (sobrescribir pid/tgid) | **Parcial** (DUPE) | Si el TGID suplantado coincide con un registro existente con un `start_time_ns` diferente, DUPE se dispara. Si `start_time_ns` también es suplantado, esto pasa desapercibido. |
    | **Desvinculación de programa eBPF** (eliminar del array funcs) | **Detectado** (TAMPER) | El heartbeat de NMI se congela → TAMPER |
    | **Bytecode parcheado in situ** | **No detectado** | Requiere escritura arbitraria del kernel (nivel LKM) — fuera del modelo de amenazas eBPF |
    | **Canal lateral de temporización en `bpf_probe_read_kernel`** | **Riesgo teórico** | La búsqueda binaria en el heap podría encontrar `.bss` en ~30 sondas. Ver limitaciones en [§6](#6-verifier-bounded-address-secrecy). |
    
    ### Fuera del modelo de amenazas eBPF (reconocido, no resuelto)
    
    | Ataque | Estado | Notas |
    |---|---|---|
    | **Hook del manejador IDT/NMI** | **La bomba activa** | Bypass arquitectónicamente completo. Pánico de kernel casi seguro. |
    | **Supresión de doble canal** | **La bomba activa** | Suprime simultáneamente sched + NMI. Hereda la inestabilidad del hooking de NMI. |
    | **Exploit del verificador** | **No objetivo** | Escapa a ejecución de código arbitrario del kernel. Clase de amenaza separada. |
    | **ptrace / `/proc/pid/mem`** | **Limitación fundamental** | Lectura de memoria con el mismo privilegio. Solo ayuda el envío de registros fuera del host. |
    | **Parche de puntero consumidor + heartbeat** | **Nivel LKM** | Si el atacante tiene escritura arbitraria del kernel, puede avanzar el puntero consumidor Y escribir heartbeats falsos. Pero escritura arbitraria del kernel = nivel LKM = fuera del modelo de amenazas. |
    
    ---
    
    ## 13. Construcción y ejecución
    
    ### Prerrequisitos
    
    - Kernel Linux >= 5.15 con `CONFIG_DEBUG_INFO_BTF=y` (solo para el hook LSM)
    - Para bloqueo de módulos: `CONFIG_BPF_LSM=y` y `lsm=bpf` en la línea de comandos del kernel
    - Chip TPM 2.0 + biblioteca `tpm2-tss` (opcional; retrocede con advertencia visible)
    - Cadena de herramientas Rust nightly
    
    > **Nota:** El paso `generate-vmlinux` **ya no es necesario**. Los programas eBPF utilizan offsets de tracepoint tradicionales y variables globales `.bss` — no se necesita navegación de estructuras CO-RE/BTF. El comando xtask `generate-vmlinux` se conserva para uso futuro pero no forma parte del pipeline de construcción.
    
    Verificar que BPF LSM esté activo: `cat /sys/kernel/security/lsm` debe contener `bpf`.
    
    ### Configuración```shell
    make install-deps     # system packages + nightly Rust (pacman/apt/dnf auto-detected)
    make install-tools    # bpf-linker
    make build            # compiles eBPF + userspace (no vmlinux generation needed)
    

    Ejecutar```shell

    make run # sudo ./target/release/spica

    root@kitploit:~
    ### Instalar en initramfs (protección de arranque temprano)```shell
    sudo make install     # spica install — auto-detects Debian (initramfs-tools) or Fedora (dracut)
    

    Verificar que funciona```shell

    sudo insmod some_module.ko # should fail with EPERM (gate locked) cat /sys/kernel/security/lsm # should contain 'bpf' ls /sys/fs/bpf/spica_watchdog # exists if previous run was killed ungracefully

    root@kitploit:~
    ### Desarrollo (macOS o Linux)
    
    Los programas eBPF no pueden ejecutarse en macOS. `cargo check` y las pruebas unitarias para la lógica de detección funcionan; la verificación completa en tiempo de ejecución requiere Linux.```shell
    make check      # cargo check for workspace
    make check-ebpf # cargo check for the eBPF crate (bpfel-unknown-none)
    make test       # unit tests for detection FSM, key derivation, obfuscation
    

    14. Hoja de ruta

    • Sellado de clave vinculada a PCR — atestación real de hardware. En el momento de la instalación, sellar la clave a los valores esperados de PCR (PCR 4/7/9/10). En tiempo de ejecución, el desellado falla si los PCR cambiaron. Reemplaza el uso actual de TPM solo con GetRandom por una raíz de confianza completa basada en hardware. Consulte §9.
    • Puerta de acceso a mapas LSM — Hook LSM de BPF en la llamada al sistema bpf que bloquea la enumeración de mapas del estado interno de SPiCa desde procesos que no son SPiCa. Consulte §7.
    • Limitación de velocidad de BPF_PROG_LOAD — Extender la puerta LSM para limitar la velocidad de carga de programas BPF desde procesos que no son SPiCa, mitigando el riesgo de canal lateral de tiempo en el descubrimiento de .bss. Consulte las limitaciones en §6.
    • Actualización de ofuscación PRF SipHash — Si el modelo de amenazas crece para incluir adversarios con acceso de lectura al búfer circular, intercambie XOR por un flujo de claves SipHash-1-3 (la dependencia siphasher ya está en el árbol para el token de integridad).
    • Backend de registro empresarial — Envío opcional a Elasticsearch/Elastic SIEM para entornos SOC. Todas las alertas, eventos de terminación y anomalías del contador de reinicios se envían fuera del host en tiempo real.
    • Soporte adicional para distribuciones — Arch (mkinitcpio), openSUSE.
    • Pipeline de CI — Pruebas de humo de Linux que ejercitan carga real de eBPF + adjuntar + flujo de búfer circular.

    15. Glosario

    TérminoDefinición
    BPFBerkeley Packet Filter — motor de ejecución dentro del kernel para programas en espacio aislado. El BPF moderno (eBPF) se extiende más allá de los paquetes hacia el rastreo, la seguridad y las redes.
    BTFBPF Type Format — información de depuración del kernel que permite que los programas CO-RE (Compile Once, Run Everywhere) naveguen por las estructuras del kernel de forma portátil.
    CO-RECompile Once, Run Everywhere — técnica BPF que utiliza BTF para escribir programas portátiles que se adaptan a diferentes versiones del kernel.
    DKOMDirect Kernel Object Manipulation — técnica de rootkit que elimina un proceso de la lista enlazada del kernel para ocultarlo de /proc.
    fmod_retTipo de programa BPF que modifica el valor de retorno de una función del kernel a través del trampolín BPF.
    freplaceExtensión de programa BPF — se adjunta a una (sub)función específica de otro programa BPF, interceptando su ejecución.
    funcs arrayEl arreglo de punteros a función en una estructura de tracepoint del kernel que contiene funciones de devolución de llamada (incluidos programas BPF) para invocar cuando se activa el tracepoint.
    IDTInterrupt Descriptor Table — estructura de la CPU que asigna vectores de interrupción a funciones de manejo. Enganchar la entrada NMI requiere parchear la IDT.
    kASLRKernel Address Space Layout Randomization — aleatoriza las direcciones de código/datos del kernel en cada inicio para dificultar la explotación.
    NMINon-Maskable Interrupt — interrupción de hardware que no puede ser deshabilitada por software (cli). Utilizada por los contadores de rendimiento para la observación a nivel de hardware.
    PCRPlatform Configuration Register — registro TPM que acumula mediciones (hashes) de los componentes de arranque. No se puede restablecer (excepto reinicio), solo extender.
    PMUPerformance Monitoring Unit — contadores de hardware en la CPU que cuentan eventos (ciclos, fallos de caché, etc.) y pueden activar interrupciones (NMI) en umbrales.
    TPMTrusted Platform Module — coprocesador criptográfico que proporciona almacenamiento de claves basado en hardware, generación de números aleatorios y atestación de mediciones.

    Licencia

    Licencia del Motor SPiCa: MIT O Apache-2.0 (espacio de trabajo). El programa eBPF exporta una licencia GPL a través del estático _license — este es un requisito del kernel para programas eBPF que usan ayudantes con licencia GPL, y se aplica solo al bytecode eBPF cargado, no al binario de espacio de usuario.

    Atribución del Personaje: "Hatsune Miku" y las ilustraciones de personajes asociadas son propiedades con derechos de autor de Crypton Future Media, INC. (www.piapro.net). Este proyecto es una herramienta de investigación independiente y no comercial, no afiliada a Crypton Future Media. Personaje utilizado bajo la Licencia de Personajes Piapro (PCL).

    El nombre del proyecto SPiCa está inspirado en la canción original de Toku-P.

    Descargar herramienta
    VerifierEl verificador BPF — componente del kernel que analiza estáticamente los programas BPF antes de cargarlos para asegurar que terminen y no accedan a memoria no segura.