VulHunt
VulHunt is Binarly’s open-source binary vulnerability detection and analysis framework designed for firmware security, UEFI analysis, and supply chain risk assessment. It uses Lua-based detection rules on top of the BIAS (Binary Analysis and Inspection System) engine to identify vulnerabilities in compiled binaries.
Installation
Section titled “Installation”Clone and build VulHunt from the official repository:
# Clone the repository
git clone https://github.com/vulhunt-re/vulhunt.git
cd vulhunt
# View build requirements
cat README.md
# System prerequisites (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install -y build-essential cmake cargo rustc git
# macOS prerequisites
brew install cmake rust git
# Build with cargo
cargo build --release
# Binary location
./target/release/vulhunt --version
Build Requirements:
- C++17-compatible compiler (GCC 7+, Clang 6+, MSVC 2015+)
- Rust toolchain (latest stable via rustup)
- CMake 3.12+
- Git
Quick Start
Section titled “Quick Start”Begin scanning binaries with VulHunt’s command-line interface:
# Scan a POSIX binary
vulhunt scan /path/to/binary
# Scan UEFI firmware module
vulhunt scan --target uefi /path/to/firmware.efi
# Use specific rule set
vulhunt scan --rules custom_rules.lua /path/to/binary
# Generate JSON report
vulhunt scan --output json /path/to/binary > report.json
# Verbose output with debug info
vulhunt scan --verbose /path/to/binary
# List available rules
vulhunt list-rules
# Display rule details
vulhunt rule-info rule_name
Scanning Targets
Section titled “Scanning Targets”VulHunt supports multiple binary formats and architectures for comprehensive coverage:
Target Types
Section titled “Target Types”# POSIX executable (ELF, Mach-O)
vulhunt scan /path/to/binary
# UEFI firmware
vulhunt scan --target uefi firmware.efi
# Firmware image (raw binary)
vulhunt scan --target raw --arch x86-64 firmware.bin
# Library (shared object)
vulhunt scan /usr/lib/libexample.so
# Windows PE binary (experimental)
vulhunt scan --target pe application.exe
Supported Architectures
Section titled “Supported Architectures”# x86 (32-bit Intel)
vulhunt scan --arch x86 binary_32bit
# x86-64 (64-bit Intel)
vulhunt scan --arch x86-64 binary_64bit
# ARM (32-bit)
vulhunt scan --arch arm binary_arm
# AArch64 (ARM 64-bit)
vulhunt scan --arch aarch64 binary_aarch64
# Auto-detection (recommended)
vulhunt scan binary # Automatically detects architecture
Rule System
Section titled “Rule System”VulHunt’s detection engine is driven by Lua-based rules that define vulnerability patterns:
Rule Structure
Section titled “Rule Structure”-- Basic rule structure
rule {
metadata = {
id = "VULN_001",
name = "Buffer Overflow Detection",
description = "Detects potential buffer overflow vulnerabilities",
severity = "high",
cve = "CVE-2024-12345",
author = "security-team",
date = "2026-01-15"
},
filter = {
-- Filter conditions (optional)
function_size_min = 100,
function_size_max = 5000,
has_loop = true
},
scope = "function",
check = function(func)
-- Analysis logic here
return results
end
}
Scope Types
Section titled “Scope Types”-- Project scope: analyze entire binary
scope = "project"
check = function(binary) ... end
-- Function scope: analyze individual functions
scope = "function"
check = function(func) ... end
-- Call site scope: analyze function calls
scope = "call_site"
check = function(call) ... end
-- Basic block scope: analyze control flow blocks
scope = "basic_block"
check = function(block) ... end
Metadata Fields
Section titled “Metadata Fields”metadata = {
id = "RULE_ID", -- Unique identifier
name = "Rule Name", -- Human-readable name
description = "...", -- Detailed description
severity = "critical", -- critical|high|medium|low|info
cve = "CVE-XXXX-XXXXX", -- Optional CVE reference
cwe = "CWE-123", -- Optional CWE reference
author = "team", -- Rule author
date = "2026-01-15", -- Creation date
tags = {"buffer", "overflow"}, -- Classification tags
references = { -- Optional references
"https://binarly.io/...",
"https://nvd.nist.gov/..."
}
}
Writing Custom Rules
Section titled “Writing Custom Rules”Create targeted vulnerability detection rules tailored to your codebase:
Basic Rule Template
Section titled “Basic Rule Template”rule {
metadata = {
id = "CUSTOM_001",
name = "Insecure Function Usage",
description = "Detects dangerous function calls",
severity = "high",
author = "your-team",
date = "2026-04-17"
},
scope = "call_site",
check = function(call_site)
-- Get function being called
local func_name = call_site:function_name()
-- Check for dangerous functions
local dangerous = {
"strcpy",
"strcat",
"sprintf",
"gets"
}
for _, name in ipairs(dangerous) do
if func_name == name then
return {
match = true,
message = "Use of unsafe function: " .. func_name
}
end
end
return { match = false }
end
}
Advanced Rule with Filtering
Section titled “Advanced Rule with Filtering”rule {
metadata = {
id = "CUSTOM_002",
name = "Unchecked Buffer Write",
description = "Detects potential buffer writes without bounds checking",
severity = "critical"
},
filter = {
min_instructions = 50,
has_memory_operations = true
},
scope = "function",
check = function(func)
local instructions = func:instructions()
local has_alloc = false
local has_write = false
local has_check = false
for _, instr in ipairs(instructions) do
if instr:contains("malloc") or instr:contains("alloca") then
has_alloc = true
end
if instr:is_memory_write() then
has_write = true
end
if instr:contains("cmp") or instr:contains("test") then
has_check = true
end
end
if has_alloc and has_write and not has_check then
return { match = true }
end
return { match = false }
end
}
Rule with Dataflow Analysis
Section titled “Rule with Dataflow Analysis”rule {
metadata = {
id = "CUSTOM_003",
name = "Tainted Data Usage",
description = "Detects untrusted data flowing to sensitive operations"
},
scope = "function",
check = function(func)
-- Track data sources
local sources = func:find_sources({"user_input", "network"})
-- Track sinks (sensitive operations)
local sinks = func:find_calls_to({
"memcpy",
"strcpy",
"system",
"exec"
})
-- Analyze dataflow
for _, source in ipairs(sources) do
for _, sink in ipairs(sinks) do
if func:can_reach(source, sink) then
return {
match = true,
source = source:address(),
sink = sink:address()
}
end
end
end
return { match = false }
end
}
Analysis Engine (BIAS)
Section titled “Analysis Engine (BIAS)”The Binary Analysis and Inspection System (BIAS) is VulHunt’s core analysis engine:
BIAS Capabilities
Section titled “BIAS Capabilities”# BIAS intermediate representation generation
vulhunt bias-export binary.elf > binary.ir
# Disassembly with control flow
vulhunt bias-disasm binary.elf --arch x86-64
# Type inference and reconstruction
vulhunt bias-types binary.elf
# Cross-reference database
vulhunt bias-xrefs binary.elf
Intermediate Representation (IR)
Section titled “Intermediate Representation (IR)”-- Access IR in rules
rule {
scope = "function",
check = function(func)
-- Get IR instructions
local ir = func:ir()
-- Iterate through IR ops
for _, op in ipairs(ir) do
-- Analyze IR operations
if op:is_call() then
local target = op:target()
-- Analyze call
elseif op:is_load() then
local memory = op:address()
-- Analyze memory load
elseif op:is_store() then
local memory = op:address()
-- Analyze memory store
end
end
end
}
Decompiled Code Analysis
Section titled “Decompiled Code Analysis”-- Access high-level decompiled code
rule {
scope = "function",
check = function(func)
-- Get pseudo-code representation
local pseudo = func:pseudocode()
-- Pattern matching on source level
if pseudo:contains("while(1)") then
-- Infinite loop detected
end
-- Get variable information
local vars = func:variables()
for _, var in ipairs(vars) do
local ty = var:type()
local uses = var:uses()
end
end
}
Dataflow Analysis
Section titled “Dataflow Analysis”VulHunt includes a dataflow analysis engine for tracking data movement:
Basic Dataflow Engine
Section titled “Basic Dataflow Engine”rule {
metadata = {
id = "DATAFLOW_001",
name = "Format String Vulnerability"
},
scope = "function",
check = function(func)
-- Create dataflow engine
local df = func:dataflow()
-- Find format string functions
local printf_calls = func:find_calls_to({"printf", "fprintf", "sprintf"})
for _, call in ipairs(printf_calls) do
-- Get argument at position 0 (format string)
local arg = call:argument(0)
-- Trace backwards to source
local sources = df:trace_back(arg)
for _, source in ipairs(sources) do
if source:is_external_input() then
return {
match = true,
vuln_type = "Format String",
location = call:address()
}
end
end
end
return { match = false }
end
}
Tracking Data Through Functions
Section titled “Tracking Data Through Functions”rule {
scope = "function",
check = function(func)
-- Initialize dataflow
local df = func:dataflow()
-- Define sources (entry points for data)
local sources = {
function_params = true,
global_reads = true,
external_calls = true
}
-- Define sinks (sensitive operations)
local sinks = {
memory_writes = true,
system_calls = true,
cryptographic_ops = true
}
-- Run full dataflow analysis
local flows = df:analyze({
sources = sources,
sinks = sinks,
max_depth = 10
})
-- Report findings
if #flows > 0 then
return {
match = true,
dataflows = flows
}
end
return { match = false }
end
}
Function Signatures and Type Libraries
Section titled “Function Signatures and Type Libraries”VulHunt supports signature matching and type information:
Signature Matching
Section titled “Signature Matching”# Generate function signatures
vulhunt signatures extract binary.elf > sigs.json
# Apply signature database
vulhunt scan --signatures sigs.json binary.elf
# Library signature matching
vulhunt scan --match-libs openssl zlib binary.elf
Type Library Support
Section titled “Type Library Support”rule {
metadata = {
id = "TYPEINFER_001",
name = "Type-based Vulnerability Detection"
},
scope = "function",
check = function(func)
-- Get function signature
local sig = func:signature()
local params = sig:parameters()
-- Analyze parameter types
for i, param in ipairs(params) do
local ty = param:type()
-- Check for dangerous types
if ty:is_pointer() and ty:pointee():is_void() then
-- Void pointer usage
end
if ty:is_array() then
local size = ty:size()
-- Bounded array
end
end
-- Get return type
local ret_type = sig:return_type()
return { match = false }
end
}
Module Support
Section titled “Module Support”# Identify linked modules
vulhunt modules binary.elf
# Analyze specific module
vulhunt scan --analyze-module libc.so binary.elf
# Module compatibility checking
vulhunt compat-check binary.elf
Output and Reporting
Section titled “Output and Reporting”VulHunt generates detailed reports in multiple formats:
Scan Results
Section titled “Scan Results”# Default text output
vulhunt scan binary.elf
# JSON format (machine-readable)
vulhunt scan --format json binary.elf > results.json
# HTML report with visualizations
vulhunt scan --format html --output report.html binary.elf
# CSV for spreadsheet import
vulhunt scan --format csv binary.elf > findings.csv
# SARIF format (standard reporting format)
vulhunt scan --format sarif binary.elf > results.sarif
Severity Levels
Section titled “Severity Levels”# Filter by severity
vulhunt scan --min-severity high binary.elf
# Custom severity threshold
vulhunt scan --severity-filter "critical,high" binary.elf
# Severity mapping
# critical - Immediate exploitation risk
# high - Likely exploitable vulnerability
# medium - Potential security impact
# low - Minor security issue
# info - Informational finding
CVE Mapping
Section titled “CVE Mapping”{
"finding_id": "VULN_001",
"title": "Stack Buffer Overflow",
"severity": "critical",
"cve": ["CVE-2024-12345", "CVE-2024-12346"],
"cwe": ["CWE-121"],
"location": {
"file": "binary.elf",
"function": "process_input",
"offset": "0x1234"
},
"evidence": "strcpy without bounds checking",
"remediation": "Use strncpy or safer alternatives"
}
AI Integration
Section titled “AI Integration”VulHunt integrates with Claude Skills for automated analysis and report generation:
Claude Skills for VulHunt
Section titled “Claude Skills for VulHunt”# Automated vulnerability analysis
vulhunt analyze --ai binary.elf
# Generate detailed technical report
vulhunt report --ai --depth full binary.elf
# Interactive analysis session
vulhunt console --ai binary.elf
MCP Tools for Automated Analysis
Section titled “MCP Tools for Automated Analysis”-- MCP-integrated analysis
rule {
metadata = {
id = "MCP_ANALYSIS",
name = "AI-Assisted Vulnerability Analysis"
},
scope = "project",
check = function(binary)
-- Use MCP tools for external analysis
local mcp_result = call_mcp_tool("analyze_codebase", {
binary = binary:path(),
rules = binary:active_rules(),
depth = "comprehensive"
})
return mcp_result
end
}
Configuration
Section titled “Configuration”VulHunt uses configuration files to customize scanning behavior:
Config File Format
Section titled “Config File Format”# vulhunt.yaml - Main configuration
version: 1.0
analysis:
architecture: x86-64
target: elf
optimization_level: 2
enable_dataflow: true
rules:
builtin: true
custom_paths:
- ./rules/custom.lua
- ./rules/firmware.lua
reporting:
format: json
min_severity: medium
include_context: true
performance:
parallel_threads: 4
cache_ir: true
memory_limit_mb: 4096
Scan Profiles
Section titled “Scan Profiles”# Use predefined profiles
vulhunt scan --profile firmware binary.efi
vulhunt scan --profile uefi binary.efi
vulhunt scan --profile supply-chain dependency.so
# List available profiles
vulhunt list-profiles
# Create custom profile
cat > myprofile.yaml << 'EOF'
rules:
- buffer_overflow
- format_string
- integer_overflow
- use_after_free
output:
format: html
severity_threshold: medium
EOF
vulhunt scan --profile myprofile.yaml binary.elf
Troubleshooting
Section titled “Troubleshooting”Common Issues and Solutions
Section titled “Common Issues and Solutions”# Issue: "Architecture detection failed"
# Solution: Specify explicitly
vulhunt scan --arch x86-64 binary.elf
# Issue: "Rule compilation error"
# Solution: Validate rule syntax
vulhunt validate-rule custom.lua
# Issue: "Out of memory"
# Solution: Increase limit or reduce scope
vulhunt scan --memory-limit 8192 large_binary.elf
# Issue: "No vulnerabilities found"
# Solution: Enable all rules and verbose output
vulhunt scan --all-rules --verbose binary.elf
# Issue: "UEFI firmware not recognized"
# Solution: Specify UEFI target type
vulhunt scan --target uefi firmware.efi
Debug Mode
Section titled “Debug Mode”# Enable debug logging
vulhunt scan --debug binary.elf 2>&1 | tee debug.log
# Dump intermediate representation
vulhunt scan --dump-ir binary.elf > ir_dump.txt
# Trace rule execution
vulhunt scan --trace-rules custom.lua binary.elf
# Profile performance
vulhunt scan --profile-perf binary.elf
Best Practices
Section titled “Best Practices”Rule Development
Section titled “Rule Development”- Start simple: Begin with call_site scope before function or project
- Test incrementally: Validate rules on known-vulnerable binaries
- Document thoroughly: Use clear descriptions and references
- Avoid false positives: Use multiple conditions and filtering
- Version rules: Track changes with metadata dates
Scanning Strategy
Section titled “Scanning Strategy”# Baseline scan with built-in rules
vulhunt scan baseline.elf > baseline.json
# Enhanced scan with custom rules
vulhunt scan --rules ./custom_rules/ enhanced.elf > enhanced.json
# Comparative analysis
vulhunt compare baseline.json enhanced.json
# Supply chain scanning
vulhunt scan --profile supply-chain \
--sbom dependencies.json \
--output audit_report.html
Firmware Analysis Workflow
Section titled “Firmware Analysis Workflow”# 1. Extract modules from firmware
binwalk -e firmware.bin
# 2. Scan each module
for module in _firmware.bin.extracted/*/; do
vulhunt scan --target uefi "$module" >> results.json
done
# 3. Aggregate findings
vulhunt merge results.json --output firmware_audit.html
# 4. Generate CVE report
vulhunt cve-report firmware_audit.html
Continuous Integration
Section titled “Continuous Integration”# Integrate into CI/CD pipeline
vulhunt scan --ci-mode \
--fail-on critical \
--report ci_report.sarif \
binary.elf
# Exit codes:
# 0 - No vulnerabilities
# 1 - Low/medium findings
# 2 - High severity findings
# 3 - Critical vulnerability found
Related Tools
Section titled “Related Tools”Binarly Transparency Platform
- Cloud-based firmware analysis
- Historical vulnerability tracking
- Supply chain risk assessment
Ghidra
- NSA’s reverse engineering framework
- Decompilation and code analysis
- Compatible with VulHunt findings
Binary Ninja
- Commercial binary analysis platform
- Advanced disassembly and patching
- Scriptable analysis environment
radare2
- Open-source reverse engineering framework
- Hexadecimal editor and disassembler
- Scripting capabilities for automation