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
clr — Comprobador de duraciones y otros tipos de refinamiento | Kitploit
Herramientas/GitHubGitHub/ityonemo/clr
Análisis EstáticoAnálisis de VulnerabilidadesAnálisis de CódigoFuzzingAnálisis de BinariosAprendizaje y Educación
GitHubityonemo/clr

clr

Comprobador de duraciones y otros tipos de refinamiento

Ver Repositorio
2772hace 19 díasRevisado 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 →
Compartir

CLR

Comprobador de

Lifetimes (vida útil) y otros

Refinement types (tipos de refinamiento)

para Zig

Vídeo: https://www.youtube.com/watch?v=mf0WzTOe-40 Patrocinio: https://buymeacoffee.com/dnautics

discutir en hn: https://news.ycombinator.com/item?id=42923829

discutir en lobste.rs: https://lobste.rs/s/9sitsj/clr_checker_for_lifetimes_other

vídeo de demostración en vivo: https://www.youtube.com/watch?v=ZY_Z-aGbYm8

Resumen

Este proyecto crea un transpilador Zig para el compilador Zig, que transforma AIR (Intermediate Representation Abstracta) en código fuente Zig que realiza análisis estático en tiempo de compilación. El analizador generado detecta problemas de seguridad de memoria como uso antes de asignación, uso después de liberación, fugas de puntero de pila, así como UB específicos de Zig como aserciones de no nulidad, violaciones de uniones etiquetadas o mal uso de fieldParentPtr.

El objetivo es aportar garantías de seguridad de memoria al nivel de Rust a Zig mediante análisis estático de AIR, sin cambiar el lenguaje en sí.

CLR depende de una versión bifurcada del compilador Zig (incluida como submódulo en zig/) que agrega soporte para enrutar AIR a complementos externos. Cuando se invoca con -ofmt=air -fair-out=<plugin.so>, el compilador carga la biblioteca compartida especificada y le pasa el AIR generado para su procesamiento.

Arquitectura orientada a la seguridad

CLR está diseñado para empujar los programas hacia patrones de ciclo de vida que sean explícitos y verificables localmente, no simplemente para reconocer todo programa Zig técnicamente válido. Cuando dos representaciones son posibles, CLR prefiere aquella que hace visible el estado del recurso en el tipo y en la estructura de flujo de control.

Por ejemplo, evite cerrar condicionalmente un descriptor de archivo no opcional:

root@kitploit:~
const file = try std.fs.cwd().openFile(path, .{});
if (should_close) {
    file.close(); // Mal: el archivo queda ambiguamente abierto después de esta rama.
}

Prefiera representar la propiedad condicional con un opcional:

root@kitploit:~
var file: ?std.fs.File = null;
if (should_open) {
    file = try std.fs.cwd().openFile(path, .{});
}

if (file) |open_file| {
    open_file.close();
}

Cerrar condicionalmente un descriptor no opcional deja su ciclo de vida ambiguo después de la rama. La política prevista de CLR es rechazar ese patrón en lugar de llevar un estado permanente de "tal vez cerrado".

El mismo principio se aplica a los punteros asignados. No libere a través de un puntero derivado:

root@kitploit:~
const allocation = try allocator.alloc(u8, size);
const payload = allocation[header_size..];
allocator.free(payload); // Mal: payload no es la base de la asignación.

Mantenga disponible el puntero base de la asignación para la desasignación, y use los punteros derivados solo para acceso:

root@kitploit:~
const allocation = try allocator.alloc(u8, size);
defer allocator.free(allocation);

const payload = allocation[header_size..];
use(payload);

Liberar un puntero de campo, subsegmento o puntero producido por aritmética es rechazado a menos que una regla interna documentada restablezca la procedencia de la base de asignación.

Estas políticas son estrictas por defecto porque producen código con ciclos de vida de recursos más simples y más revisables. Un mecanismo futuro de anotación unsafe permitirá que GIDs u operaciones seleccionadas opten por no participar en análisis individuales. Eso respaldará código que acepta deliberadamente comprobaciones más débiles a cambio de rendimiento, sin debilitar el modelo predeterminado para el resto del programa.

Estado

Esta es una reescritura activa del prototipo original basado en Elixir en Zig. La implementación en Zig se carga como un complemento del compilador y analiza AIR directamente.

Actualmente implementado:

  • Seguimiento de valores no definidos (uso antes de asignación, seguimiento a nivel de campo para estructuras)
  • Análisis de seguridad de memoria (uso después de liberación, doble liberación, fugas de memoria, desajuste de asignador, fugas de pila)
  • Cobertura completa de la interfaz std.mem.Allocator:
    • create/destroy - asignación de un solo elemento
    • alloc/free - asignación de segmentos (incluyendo alignedAlloc, allocSentinel, etc.)
    • realloc/remap - reasignación de segmentos con seguimiento de segmento anterior liberado
    • dupe/dupeZ - duplicación de segmentos
    • Detección de desajuste de asignador (liberar con asignador incorrecto, create/destroy vs alloc/free)
    • Tipos de asignador complejo (GPA, ArenaAllocator, FixedBufferAllocator)
  • Seguimiento del ciclo de vida de ArenaAllocator:
    • // - ciclo de vida completo del arena

Planeado (consulte LIMITATIONS.md para más detalles):

  • async/await
  • Seguridad de alias (detección de referencias mutables en conflicto)
  • Refinamientos de puntero de múltiples fuentes para procedencia de puntero fusionada o indirecta
  • Análisis de alias de descriptor más allá de los patrones de propagación de fd actualmente cubiertos
  • Resúmenes de mutación interprocedimental/global más completos
  • Reconocimiento de reducción de conversión de alineación
  • Seguridad de mutex (emparejamiento lock/unlock, detección de interbloqueo)
  • Capacidad de coerción personalizada (reglas de refinamiento definidas por el usuario)

Requisitos previos

  • Zig 0.15.2 (instalación del sistema con soporte LLVM)
  • Linux (actualmente solo Linux debido al uso directo de syscall)
  • BATS (para pruebas de integración): sudo apt install bats

Compilación

El compilador Zig incluido y el complemento libclr deben compilarse con niveles de optimización coincidentes. Los niveles de optimización no coincidentes causarán fallos de segmentación.

root@kitploit:~
# Compilar el compilador Zig personalizado con ReleaseFast (solo la primera vez, o después de cambios en el submódulo)
cd zig && zig build --zig-lib-dir lib -Doptimize=ReleaseFast && cd ..

# Compilar el complemento CLR con optimización coincidente
zig build -Doptimize=ReleaseFast

Para desarrollo/depuración, use ReleaseSafe o Debug para ambos:

root@kitploit:~
# ReleaseSafe (con comprobaciones de seguridad, ligeramente más lento)
cd zig && zig build --zig-lib-dir lib -Doptimize=ReleaseSafe && cd ..
zig build -Doptimize=ReleaseSafe

# Debug (información de depuración completa, más lento)
cd zig && zig build --zig-lib-dir lib && cd ..
zig build

Uso

root@kitploit:~
# Compilar un archivo Zig usando el backend AIR
zig/zig-out/bin/zig build-exe -fair-out=zig-out/lib/libclr.so -ofmt=air -femit-bin=output.air.zig your_file.zig

# Ejecutar el analizador generado
zig run --dep clr -Mroot=output.air.zig -Mclr=lib/lib.zig

La salida va a stderr.

Pruebas

root@kitploit:~
# Pruebas unitarias (código generado/DLL)
zig build test

# Pruebas unitarias (biblioteca en tiempo de ejecución)
zig test lib/lib.zig

# Un archivo de prueba de integración enfocado
bats test/integration/fd.bats

# Pruebas de integración (requiere BATS)
# Por defecto ReleaseFast; anular con OPTIMIZE=ReleaseSafe o OPTIMIZE=Debug
./run_integration.sh

# Prueba manual de un solo archivo
./run_one.sh test/cases/undefined/use_before_assign.zig

Nota: Las pruebas de integración reconstruyen libclr con el nivel de optimización especificado (por defecto: ReleaseFast). Asegúrese de que su compilador Zig incluido se haya compilado con un nivel de optimización coincidente.

Estructura del proyecto

root@kitploit:~
clr/
├── src/                     # Código DLL/complemento (genera .air.zig)
│   ├── clr.zig              # Punto de entrada principal del complemento CLR
│   ├── codegen.zig          # Genera código fuente .air.zig a partir de instrucciones AIR
│   └── allocator.zig        # Envoltorio de asignador seguro para DLL
├── lib/                     # Biblioteca de análisis en tiempo de ejecución
│   ├── lib.zig              # Punto de entrada de la biblioteca
│   ├── tag.zig              # Unión AnyTag, Tipo, manejadores de etiquetas, envío splat
│   ├── Inst.zig             # Resultados de instrucciones y análisis interprocedimental
│   ├── Refinements.zig      # Tipos de refinamiento (puntero, estructura, opcional, etc.)
│   ├── Analyte.zig          # Contenedor de estado de análisis
│   ├── Context.zig          # Contexto de ejecución (metadatos, informes de errores)
│   └── analysis/            # Módulos de análisis
│       ├── undefined_safety.zig  # Seguimiento de uso antes de asignación
│       ├── memory_safety.zig     # Seguimiento de asignación/liberación
│       ├── null_safety.zig       # Comprobación de desenvolvimiento opcional
│       ├── variant_safety.zig    # Acceso a campos de unión etiquetada
│       └── fd_safety.zig         # Seguimiento de descriptores de archivo
├── test/
│   ├── integration/         # Pruebas de integración BATS
│   │   ├── test_helper.bash
│   │   └── *.bats
│   └── cases/               # Archivos de entrada de prueba (.zig)
├── zig/                     # Submódulo del compilador Zig (bifurcación instrumentada)
├── build.zig                # Configuración de compilación
└── build.zig.zon            # Dependencias del paquete

La idea general

diagrama

Zig es un lenguaje famosamente "inseguro". La gestión de memoria se realiza manualmente, lo que abre la posibilidad de errores de implementación. Si bien Zig reduce los problemas de seguridad en relación con C al eliminar el acceso a matrices fuera de límites y la desreferencia de punteros nulos en código con comprobaciones de seguridad, sigue siendo menos seguro que Rust, que elimina el uso después de liberación, la doble liberación y las condiciones de carrera mediante análisis estático.

Inspirado en el proyecto MIRI de Rust, CLR realiza análisis estático en la representación intermedia AIR de Zig para lograr un mayor grado de seguridad del que Zig proporciona de serie. A diferencia de MIRI, que interpreta el MIR de Rust en un pseudoejecutable en caja de arena, CLR transpila AIR a código fuente Zig que ejecuta análisis estáticamente. Tenga en cuenta que el código zig de salida de AIR de CLR podría, en principio, ejecutarse en tiempo de compilación, pero al pasar a través de un intermediario zig, producimos un flujo lógico fácil de entender y depurar. Una persona ambiciosa podría usar este enfoque general para emitir un destino de salida diferente, como un lenguaje de asistente de pruebas, o refactorizarlo para que se ejecute completamente en el compilador zig.

La idea clave: si de todas formas necesita MIRI para proyectos de Rust que requieren seguridad, ¿por qué no elegir un lenguaje más simple y hacer un análisis al estilo MIRI para obtener comprobación de préstamos y otros análisis de tipos de refinamiento? Este proyecto muestra que ese futuro es una posibilidad real para Zig.

El pipeline de compilación de Zig es:

  1. Código Zig / AST
  2. Zig ZIR (no tipificado, representación intermedia por archivo)
  3. Zig AIR (tipificado, IR por función, reificado para funciones polimórficas)
  4. Destinos del compilador

AIR es el nivel ideal para el análisis porque está tipificado, es interpretable como una lista "mínima viable" de instrucciones de programación generalizadas y permite extender tipos con metadatos de refinamiento.

Para una mirada en profundidad sobre cómo funciona AIR de Zig, consulte la publicación del blog de Mitchell Hashimoto: https://mitchellh.com/zig/sema

Licencia

Licencia MIT - consulte LICENSE para más detalles.

Descargar herramienta
init
deinit
allocator
  • Asignaciones del arena liberadas en deinit (sin falsos positivos de fuga)
  • Detección de uso después de deinit, doble deinit, asignación después de deinit
  • Desajuste entre asignadores (arena vs page_allocator)
  • Seguimiento de punteros derivados (no se pueden liberar punteros de campo, subsegmentos - solo asignaciones raíz)
  • Seguridad aritmética de punteros (bloquea ptr_add/ptr_sub en punteros de un solo elemento)
  • Seguridad nula (detección de desenvolvimiento opcional sin comprobar)
  • Seguridad de variantes (acceso a campos de unión inactivos, variante ambigua después de ramas)
  • Seguridad de FieldParentPtr (detección de recuperación de contenedor inválida desde punteros de campo)
  • Análisis interprocedimental (seguimiento de valores a través de llamadas a funciones mediante argumentos de puntero)
  • Seguimiento de punteros a funciones (las llamadas indirectas se envían a los objetivos posibles)
  • Seguimiento de campos de estructuras y uniones (campos de puntero, tipos anidados)
  • Seguimiento de segmentos (alloc/free con regiones, derivación de subsegmentos)
  • Soporte de uniones de error (expresiones try, envoltura/desenvolvimiento de carga útil)
  • Soporte de sentencias switch (fusión en N vías con seguimiento de variantes)
  • Soporte de switch etiquetado/dispositivo de Duff
  • Seguimiento de ubicación fuente y nombre de variable para mensajes de error
  • Ramificación/flujo de control con fusión de estados
  • Análisis de bucles (for, while, for-else, while-else con iteración de punto fijo)
  • Seguimiento de variables globales (indefinidas, variantes y seguridad de memoria)
  • Tipos de datos recursivos (listas enlazadas, árboles, uniones recursivas)
  • Reducciones de límites de stdlib para patrones comunes como std.process.args, std.mem.asBytes, std.HashMap y APIs de asignador/archivo
  • Refinamientos privilegiados de std.HashMap con identidad de metadatos canónicos/almacenamiento clave/valor a través de put, get, getPtr e iteración de valores
  • Seguridad de descriptores de archivo:
    • Seguimiento de posix.open/close/dup/dup2/socket/accept/epoll_create/pipe
    • Detección de uso después de cerrar (lectura/escritura/dup en fd cerrado)
    • Detección de doble cierre
    • Detección de fuga de fd en la salida de función y finalización de módulo
    • Seguimiento de identificadores locales descontextualizados para que los alias que permanecen vivos supriman informes de fuga prematuros
    • Propagación de retorno y agregado para patrones de descriptor cubiertos
    • Detección de argumento fd indefinido (close/read/write con fd sin definir)