github.com/azqzazq1/lid-framework
main / published May 25, 2026 / repository
Linux Integrity Drift Scanner — tests what your kernel actually enforces, not what it claims to.
██╗ ██╗██████╗
██║ ██║██╔══██╗
██║ ██║██║ ██║
██║ ██║██║ ██║
███████╗██║██████╔╝
╚══════╝╚═╝╚═════╝
LID — Linux Integrity Drift Scanner
LID tests what your kernel actually enforces, not what it claims to. It ships modular C probes for known Linux behavioral gaps — LSM bypasses, missing security hooks, container escape primitives — orchestrated by a Crystal CLI that handles environment detection, prerequisite checking, and structured output.
Think of it as nuclei for kernel security: each probe is a self-contained test with a YAML manifest and a statically-compiled C binary.
Quick Start
# Build everything (Crystal >= 1.10, GCC required)
make
# Run all probes
./build/lid scan
# Filter by severity
./build/lid scan --severity critical,high
# JSON output for automation
./build/lid scan --json
# List available probes
./build/lid list --verbose
# Check detected environment
./build/lid env
Requirements
| Component | Version |
|---|---|
| Crystal | >= 1.10 |
| GCC | any (static linking) |
| Linux | >= 4.18 (probe-dependent) |
Probes are compiled statically — the resulting lid binary + probe
directory is portable across x86_64 Linux systems without additional
dependencies.
Installation
make
sudo make install # installs to /usr/local/bin/lid + /usr/local/share/lid/probes
Or just run from the build directory:
./build/lid scan
Architecture
lid-framework/
├── src/ # Crystal orchestrator
│ ├── lid.cr # Entry point
│ ├── cli/ # CLI parser, runner, output formatter
│ ├── engine/ # Loader, executor, environment detection
│ └── models/ # ProbeModule, ProbeResult, Report
├── probes/
│ ├── common/probe.h # Shared C probe interface
│ ├── lid-001-*/ # Each probe: manifest.yml + check.c + Makefile
│ └── ...
└── contrib/TEMPLATE/ # Skeleton for writing new probes
How It Works
- Loader scans
probes/lid-*/manifest.ymland builds the probe list - Environment detects kernel version, LSM stack, capabilities, container state
- Executor checks each probe's prerequisites; skips if unmet
- Matching probes are fork+exec'd as separate processes
- Probes report via exit code + JSON stdout
Exit Code Protocol
| Code | Status | Meaning |
|---|---|---|
| 0 | VULNERABLE | Condition confirmed exploitable |
| 1 | NOT_VULNERABLE | Tested and not affected |
| 2 | SKIPPED | Prerequisites not met |
| 3 | ERROR | Probe failed to run |
JSON Output
Probes print a single JSON line to stdout:
{"status":"vulnerable","evidence":"AF_XDP copy-mode TX succeeded without CAP_NET_ADMIN"}
Optional details field for structured data:
{"status":"vulnerable","evidence":"...","details":{"fd":3,"lsm":"apparmor"}}
Current Probes
| ID | Finding | Severity | Type |
|---|---|---|---|
| LID-001 | eBPF Pathname Rewrite LSM Bypass | CRITICAL | Detection |
| LID-002 | io_uring MSG_RING Missing LSM Hook | HIGH | Active |
| LID-003 | New Mount API AppArmor Bypass | HIGH | Active |
| LID-004 | BPF Token AppArmor Hook Gap | CRITICAL | Detection |
| LID-005 | AF_XDP tc Egress Bypass | MEDIUM | Active |
Detection probes check kernel config / capabilities only. Active probes attempt the operation and verify the result.
CLI Reference
lid scan [options] Run probes against current system
lid list [--verbose] List available probes
lid info <ID> Show probe details
lid env Print detected environment
Filters
--ids LID-001,LID-002 Run specific probes
--tags lsm-bypass Filter by tag
--severity critical,high Filter by severity
--category network Filter by category
--no-destructive Skip destructive probes
Output Formats
--json Full JSON report
--jsonl One JSON line per result (streaming)
--quiet Only print vulnerable findings
Writing a Probe
See contrib/TEMPLATE/ for a complete skeleton.
1. Create the directory
mkdir probes/lid-NNN-short-name
2. Write manifest.yml
id: LID-NNN
name: "Short Human-Readable Name"
version: 1
author: "Your Name"
category: lsm-bypass # lsm-bypass, network, container, permissions
severity: high # critical, high, medium, low, info
attack_surface: local # local, container, network
description: >
What the probe tests and why it matters.
reference: "https://..."
requires:
kernel_min: "5.0"
kernel_config:
- CONFIG_SOMETHING=y
capabilities:
- CAP_SYS_ADMIN
lsm_any:
- apparmor
probe:
binary: check
timeout: 10
args: []
destructive: false
remediation:
- "First remediation step"
tags:
- relevant-tag
3. Write check.c
#include "../common/probe.h"
int main(void)
{
LID_CHECK_KERNEL(5, 0, "Kernel < 5.0");
// Your test logic here
int fd = attempt_something();
if (fd >= 0) {
lid_result(LID_VULNERABLE, "operation succeeded unexpectedly");
return LID_VULNERABLE;
}
lid_result(LID_NOT_VULNERABLE, "operation correctly denied");
return LID_NOT_VULNERABLE;
}
4. Write Makefile
BUILD_DIR ?= .
CC ?= gcc
CFLAGS := -Wall -O2 -static
all: $(BUILD_DIR)/check
$(BUILD_DIR)/check: check.c
@mkdir -p $(BUILD_DIR)
$(CC) $(CFLAGS) -I../common $< -o $@
clean:
rm -f $(BUILD_DIR)/check
5. Build and test
make probes
./build/lid scan --ids LID-NNN
Research Repository
The findings behind these probes, including full write-ups, PoCs, and kernel analysis, live in the LID research repository.
License
MIT
Author
Azizcan Daştan — Milenium Security