Inocula: Weaponize the Trust Graph. Then Inoculate It.

Inspiration

Modern laptops are fortresses. Firewalls, sandboxing, and encrypted connections harden the perimeter.

But there is a blind spot nobody talks about: Bluetooth peripherals.

Once a device is paired, the operating system grants it permanent trust. No re-authentication. No verification. A mouse, keyboard, or headset all receive the same blind credential.

We set out to prove how fragile that assumption is, then build the system that fixes it.

The name comes from immunology. You expose the system to a controlled threat to build immunity. Inocula follows the same idea. We built the attack to build the defense.


What It Does

Inocula is a full-spectrum Bluetooth attack and defense lab running across three physical machines.

Raspberry Pi: The Scout

  • Passive BLE scanning and classic Bluetooth probing
  • GATT reads for device intelligence
  • On-command MAC cloning using btmgmt
  • Reports all scan data back to the C2
  • Executes commands without hosting any inbound listener

Laptop B: The Attacker C2 (Inocula Orchestrator)

A Jac walker chain coordinates the entire operation:

  • Polls the Pi for target liveness
  • Selects attack strategy
  • Enforces a 90-second cooldown
  • Streams events to a live operator dashboard

Attack Tracks

Track NOISY

  • Clones the victim mouse MAC address over BLE
  • Creates two radios with the same identity
  • Triggers duplicate-MAC and RSSI anomaly detectors

Track STEALTH

  • Sends a network-triggered payload directly to the victim
  • No Bluetooth activity
  • No radio signals
  • Bypasses all classical Bluetooth detection

Track BOTH

  • NOISY triggers detection systems
  • STEALTH delivers payload immediately after
  • Simulates a real compound attack

Payload Behavior

  • Opens Notepad with a prewritten file
  • Launches Calculator
  • Uses SendInput with focus-steal to bypass Windows 11 protections
  • Waits for 10 seconds of user inactivity before execution

Laptop A: The Victim (Inocula Sentinel)

The defended endpoint with a full SOC-style interface.

Each Bluetooth device becomes a node in a live trust graph. Detection logic is implemented as walkers traversing that graph.

Detection Signals

  1. RSSI Anomaly
    Detects signal strength deviation beyond ±2σ

  2. Timing Anomaly
    Flags abnormal reconnection latency

  3. Duplicate Identity
    Detects multiple devices using the same MAC

  4. HID Profile Validation
    Flags impossible behavior such as a mouse sending keyboard input

  5. Sleep Cycle Violation
    Detects unrealistic wake timing

  6. NetworkSentinel
    Identifies unauthorized inbound traffic and rogue listeners

  7. ProcessSentinel
    Detects suspicious process combinations and synthetic input bursts


Automated Response

When the threat score exceeds 0.70, the system executes:

  • BlockInput(True) to freeze HID input
  • pnputil /remove-device to unbind the device
  • LockWorkStation() to secure the session
  • netsh advfirewall to block malicious ports
  • taskkill to terminate rogue processes

Response time: ~15 ms from first malicious input

An attacker may land only 1 to 3 characters. That is not enough to execute a meaningful payload.


AI Threat Analysis

A Claude-powered ThreatAnalyst walker:

  • Aggregates all signal scores
  • Classifies the attack
  • Estimates attacker proximity
  • Produces remediation steps

This is implemented using by llm(), where the function signature defines the behavior. No manual prompt engineering is required.


How We Built It

Jac 0.13.5 End to End

  • Graph traversal is the detection algorithm
  • Walkers serve as both logic and API endpoints
  • walker:pub automatically exposes endpoints
  • Frontend calls backend with root spawn walker_name()

No REST boilerplate. One language across the entire stack.


jac-client Frontend

  • cl {} blocks compile directly to React
  • Shared component system across Sentinel and C2 dashboards
  • Each machine runs a single main.jac file
  • Compiler separates client and server automatically

AI Integration

  • by llm() powers threat classification, risk scoring, and remediation
  • Each stage feeds into the next
  • Type signatures define behavior instead of prompts

Real Hardware Integration

  • Windows Bluetooth enumeration via WinRT APIs
  • PowerShell STA adapter for async calls
  • BLE scanning with bleak
  • MAC cloning via btmgmt on Raspberry Pi
  • Tested with real devices (mouse and earbuds)

Cross-Machine Protocol

  • Shared X-Inocula-Token authentication
  • Strict JSON contracts
  • Retry logic in integration layer

Challenges

Jac Syntax Migration

  • Major syntax changes caused 140+ errors
  • Edge traversal and imports required full refactoring
  • Graph initialization patterns changed completely

Root Isolation

  • Each API request had its own root
  • Graph state did not persist
  • Solved with lazy initialization:
can ensure_graph() {
    if not has_node(LaptopNode) {
        rebuild_demo_graph();
    }
}

Built With

Share this project:

Updates