Overview

Bug identification is the process of discovering potential vulnerabilities in software through various techniques including static analysis, dynamic analysis, and fuzzing. This document outlines methodologies and tools for effective vulnerability research.

For practical exploit development, see Exploit Development.

flowchart TD
    BugId["Bug Identification"]

    %% Main Methods
    Static["Static Analysis"]
    Dynamic["Dynamic Analysis"]
    Fuzzing["Fuzzing"]
    AI["AI-Assisted"]

    %% Static Analysis Methods
    CodeReview["Manual Code Review"]
    RevEng["Reverse Engineering"]
    PatchDiff["Patch Diffing"]
    StaticTools["Static Analysis Tools"]
    SBOM["Supply Chain Analysis"]

    %% Dynamic Analysis Methods
    DebugTrace["Debugging/Tracing"]
    DBI["Dynamic Binary Instrumentation"]
    Taint["Taint Analysis"]
    SymExec["Symbolic Execution"]
    Snapshot["Snapshot Analysis"]

    %% Fuzzing Methods
    DumbFuzz["Dumb Fuzzing"]
    SmartFuzz["Smart Fuzzing"]
    EvoFuzz["Evolutionary Fuzzing"]
    LLMFuzz["LLM-Guided Fuzzing"]

    %% AI Methods
    LLMTriage["LLM Crash Triage"]
    MLPattern["ML Pattern Recognition"]
    AutoVariant["Automated Variant Analysis"]

    %% Connections
    BugId --> Static
    BugId --> Dynamic
    BugId --> Fuzzing
    BugId --> AI

    Static --> CodeReview
    Static --> RevEng
    Static --> PatchDiff
    Static --> StaticTools
    Static --> SBOM

    Dynamic --> DebugTrace
    Dynamic --> DBI
    Dynamic --> Taint
    Dynamic --> SymExec
    Dynamic --> Snapshot

    Fuzzing --> DumbFuzz
    Fuzzing --> SmartFuzz
    Fuzzing --> EvoFuzz
    Fuzzing --> LLMFuzz

    AI --> LLMTriage
    AI --> MLPattern
    AI --> AutoVariant

    %% Combinations
    Taint -.-> Fuzzing
    SymExec -.-> Fuzzing
    RevEng -.-> Fuzzing
    AI -.-> Fuzzing
    AI -.-> Static

    class BugId primary

Vulnerability Research Methodology

Phase 1: Reconnaissance

Phase 2: Static Analysis

Phase 3: Dynamic Analysis

Phase 4: Fuzzing

Phase 5: Exploitation

Attack Surface Identification

Before diving into specific bug hunting techniques, it’s essential to understand where to look for vulnerabilities.

Windows User Mode

Kernel

Drivers

eBPF & XDP

Container & Micro‑VM Surface

Cloud‑Native & IAM Bugs

Network / Transport Protocol Parsers

WebAssembly Runtimes

Browser / JS Engine Exploitation

Modern V8 Architecture (2024-2025)

V8 now uses a multi-tier JIT pipeline with distinct exploitation characteristics:

V8 Maglev Exploitation

WebAssembly JSPI (JavaScript Promise Integration)

Spectre-BHB Browser Mitigations

Site Isolation Plus

Practical Browser Exploitation Workflow

  1. Target Selection:
    • V8 Maglev for Chrome/Edge (faster development cycle = more bugs)
    • JSC for Safari (less scrutiny than V8)
    • SpiderMonkey for Firefox (IonMonkey/Warp still viable)
  2. Primitive Development:
    • addrof: Leak object addresses (info leak)
    • fakeobj: Craft fake object (type confusion)
    • arbread/arbwrite: Arbitrary memory access
    • shellcode: RWX page or WASM JIT abuse
  3. Sandbox Escape:
    • Mojo IPC race conditions
    • GPU process exploitation via WebGL
    • Utility process TOCTOU (Chrome’s new architecture)
  4. Post-Exploitation:
    • Chrome: Target browser process via Mojo
    • Safari: XPC service exploitation for sandbox escape
    • Firefox: Target parent process via IPC

Firmware & Embedded

macOS / Apple‑Silicon Kernel

Mobile Platforms (iOS/Android)

iOS 17+ Exploitation

Android 14+ Exploitation

Cross-Platform Mobile

Supply Chain Attack Surface

Package Manager Vulnerabilities

CI/CD Pipeline Analysis

AI & LLM Application Security

Confidential‑Computing / TEE Surface

GPU & vGPU Surface

Hardware Security Attack Surface

Side-Channel Analysis

Fault Injection

Hardware Implants & Supply Chain

EDR Driver Vulnerability Research

Common vulnerability types in EDR drivers

Research methodology

  1. Identify accessible driver interfaces
  2. Reverse engineer IOCTL/message handlers
  3. Analyze authorization mechanisms
  4. Test for input validation flaws
  5. Look for race conditions and memory corruption

Tools for driver analysis

Quick triage rubric (post‑crash)

Coverage‑first recon checklist

Static Analysis Methods

Static analysis examines code without execution to identify potential vulnerabilities.

Manual Code Review

Patch Diffing

Patch diffing compares vulnerable and patched versions of binaries to identify security changes.

What is Patch Diffing

Patch diffing is a technique to identify changes across versions of binaries related to security patches. It compares a vulnerable version of a binary with a patched one to highlight the changes, helping to discover new, missing, and interesting functionality across versions.

Benefits
Challenges

Tools

Patch Diffing Workflow

The process of patch diffing typically follows these steps:

  1. Preparation
    • Create a diffing session
    • Load binary versions (vulnerable and patched)
    • Ensure binaries pass preconditions
    • Run auto-analysis on both binaries
  2. Evaluation
    • Run correlators to find similarities
    • Generate associations between binaries
    • Evaluate matches between functions
    • Accept matching functions
    • Analyze differences until sufficient understanding is reached
  3. Function Analysis
    • Identify new functions: Functions in the patched binary with no match in the original
    • Identify deleted functions: Functions in the original binary with no match in the patched version
    • Identify changed functions: Functions that exist in both versions but have been modified
    • Focus on functions with security relevance (often indicated by their names or based on CVE descriptions)
  4. Interpreting Results
    • New functions often indicate added security checks or validation
    • Changed functions may show modified logic for handling edge cases
    • Correlate changes with public CVE information when available
    • Remember that patches are not necessarily atomic - multiple issues may be fixed in one update

When using Ghidra’s Version Tracking:

Starting with Ghidra 11 (December 2024) a built-in Partial Match Correlator covers most PatchDiffCorrelator use-cases; install the plugin only if you need bulk-mnemonics scoring.

Minimal security‑relevant diff (simplified):
-bool IsSafePath(const UString &path)
+static bool IsSafePath(const UString &path, bool isWSL)
{
  CLinkLevelsInfo levelsInfo;
-  levelsInfo.Parse(path);
+  levelsInfo.Parse(path, isWSL);
  return !levelsInfo.IsAbsolute
      && levelsInfo.LowLevel >= 0
      && levelsInfo.FinalLevel > 0;
}

+bool IsSafePath(const UString &path);
+bool IsSafePath(const UString &path)
+{
+  return IsSafePath(path, false); // isWSL
+}

-void CLinkLevelsInfo::Parse(const UString &path)
+void CLinkLevelsInfo::Parse(const UString &path, bool isWSL)
{
-  IsAbsolute = NName::IsAbsolutePath(path);
+  IsAbsolute = isWSL ? IS_PATH_SEPAR(path[0]) : NName::IsAbsolutePath(path);
  LowLevel = 0;
  FinalLevel = 0;
}
Root cause (logic):
Practical triage checklist:
Quick repro (Windows, developer mode or elevated):

Apple Patch Diffing

# Downloading the correct IPSWs
ipsw download --device Macmini9,1 -V -b 23A344
ipsw download --device Macmini9,1 -V -b 23B74

# Comparing two different IPSWs
ipsw diff UniversalMac_14.0_23A344.ipsw UniversalMac_14.1_23B74.ipsw

# What is inside the DSC
ipsw extract -d IPSW

# Extracting files
ipsw extract -f -p file

# Extracting specific architecture file
ipsw macho lipo Contacts

Windows 11 Patch Diffing

This checklist mirrors the Apple IPSW workflow but uses Microsoft tooling and build numbers.

  1. Identify the target update
    • Open Settings → Windows Update → Update history or consult the Windows Release Health dashboard to note the KB and OS build numbers (e.g., KB5037778 → build 22631.3525).
    • Record the previous build you want to diff against (e.g., 22631.3447).
  2. Collect the binaries
winbindex download tcpip.sys 10.0.22631.3447 10.0.22631.3525

mkdir pre,post
wget -Uri https://www.catalog.update.microsoft.com/Download.aspx?q=KB5037778 -OutFile kb.msu
expand -F:* .\kb.msu .\post
# repeat for the older KB into .\pre
# Download both *UUP* bundles, then run
uup_download_windows.cmd --extract
# and copy changed PE files to *pre* / *post*
  1. Fetch matching symbols
# Requires Debugging Tools for Windows
foreach ($ver in '3447','3525') {
    symchk /r .\$ver /s SRV*https://msdl.microsoft.com/download/symbols
}
  1. Load in the disassembler
    • Open tcpip.sys from both pre and post folders in IDA 8+ or Ghidra 11; ensure PDB symbols resolve.
    • Save the IDA databases (e.g., tcpip_3447.i64, tcpip_3525.i64).
  2. Run the diff
    • BinDiff 7: Tools → BinDiff → Diff Database… and select the two IDBs to generate a .BinDiff report.
    • Ghidriff (headless):
      ghidriff diff pre/tcpip.sys post/tcpip.sys -o tcpip.diff
      
  3. Triage the results
    • Sort by Similarity % ascending; investigate anything below 95 %.
    • Focus on functions with names like Validate, Parse, Copy, Check, or protocol‑specific handlers (IppReceiveEsp, Ipv6pFragmentReassemble, etc.).
    • Determine whether changes add bounds checks, size validations, or privilege checks.
  4. Validate in a lab VM
    • Snapshot two Windows 11 VMs (build 3447 and 3525).
    • Attach WinDbg (kernel mode) using bcdedit /dbgsettings net hostip:<IP> port:<PORT>.
    • Reproduce the issue against the pre‑patch VM; confirm no crash or breakpoint triggers in the post‑patch VM.
  5. Automate monthly
    • Schedule a PowerShell script that, every Patch Tuesday (second Tuesday), downloads the latest Cumulative Update, extracts changed PE files, retrieves symbols, and launches a headless Diaphora diff.
    • Email the generated HTML report to quickly spot new attack surface.

[!TIP] For large modules like ntoskrnl.exe, diff only the .text section to save RAM:
bindiff –primary ntoskrnl_pre.i64 –secondary ntoskrnl_post.i64 –section .text

Linux Kernel Patch Diffing

Patch‑diffing Linux kernels is often faster at the source level, but for binary‑only targets (vendor kernels, modules) function‑level diffing is still practical.

  1. Identify target builds
    • Note distro and kernel build (e.g., Ubuntu 6.8.0-47-generic, RHEL 5.14.0-503).
    • Capture both pre and post versions (package changelogs or CVE bulletins help).
  2. Fetch kernel images and debug info
    • Ubuntu/Debian:
      # Discover versions
      apt list -a linux-image-generic | cat
      # Download image + modules dirs (repeat for both versions)
      apt-get download linux-image-unsigned-<ver>-generic linux-modules-<ver>-generic
      # Debug symbols via debuginfod (preferred to ddebs)
      export DEBUGINFOD_URLS="https://debuginfod.ubuntu.com https://debuginfod.debian.net"
      
    • Fedora/RHEL/CentOS:
      dnf download kernel-core-<ver> kernel-debuginfo-<ver>
      rpm2cpio kernel-core-<ver>.rpm | cpio -idmv
      rpm2cpio kernel-debuginfo-<ver>.rpm | cpio -idmv
      
  3. Extract vmlinux

    # If only vmlinuz is present, use the upstream helper
    /usr/src/linux-headers-<ver>/scripts/extract-vmlinux /boot/vmlinuz-<ver> > vmlinux-<ver>
    # Or take vmlinux directly from debuginfo package tree
    
  4. Identify changed modules quickly

    # Compare module trees (pre vs post)
    rsync -rcn --delete /lib/modules/<pre>/ /lib/modules/<post>/ | grep -E "\.ko$" | sed 's/^/chg: /'
    
  5. Function‑level binary diff
    • Open vmlinux-<pre> and vmlinux-<post> in Ghidra 11/IDA 8 and run Diaphora/BinDiff/Ghidriff.
    • For hot subsystems (e.g., io_uring, net/ipv6, fs/overlayfs), diff only the relevant .ko pairs to reduce noise.
  6. Source‑level triage (when sources are available)

    # Ubuntu example: unpack both source trees, then
    git diff --no-index -- function.c.orig function.c.patched | less
    # Or use diffoscope for enriched reports
    
  7. Symbolization and crash mapping (cheat‑sheet)

    # Decode kernel oops backtraces to lines
    ./scripts/decode_stacktrace.sh vmlinux /lib/modules/<ver>/build < dmesg.log
    # Map PC to file:line quickly
    addr2line -e vmlinux-<ver> 0xffffffff81234567
    

[!TIP] For modern distros built with Clang: KCFI and fine‑grained CFI thunks create many small stub changes; filter by real function body deltas to focus on security‑relevant logic.

[!NOTE] Syzkaller routinely bisects kernel bugs; consult syzbot reports for reproducers and fix commits, then confirm your diff isolates the same region before deeper RE.

Kernel network parser identification heuristics (SMB2-inspired, broadly applicable)

Cross-field invariants (length/offset/next)
Fixed-size buffers vs variable-length payloads
Type/width hazards
Loop structure around next
Allocation-size correlation
Patch-diff signals to prioritize
Static query seeds (Semgrep/CodeQL), to tune per codebase
Dynamic confirmation (cheap)
Reference (motivating example)

Case Study: EvilESP Vulnerability (CVE-2022-34718)

This case study demonstrates real-world patch diffing to identify a Windows TCP/IP RCE vulnerability.

Vulnerability Overview
Patch Diffing Process
  1. Binary Acquisition
    • Used Winbindex to obtain sequential versions of tcpip.sys (pre-patch and post-patch)
    • Loaded both files in Ghidra with PDB symbols
  2. Diff Analysis
    • Used BinDiff to compare the binaries
    • Identified only two functions with less than 100% similarity: IppReceiveEsp and Ipv6pReassembleDatagram
  3. Code Analysis
    • Ipv6pReassembleDatagram: Added bounds check comparing nextheader_offset against the header buffer length
    • IppReceiveEsp: Added validation for the Next Header field of ESP packets
  4. Root Cause Identification
    • Found an out-of-bounds 1-byte write vulnerability
    • ESP Next Header field is located after the encrypted payload data
    • A malicious packet could cause nextheader_offset to exceed the allocated buffer size

(Update: Server 2022 build 20349.2300, May 2024, hardened this code path; the original PoC needs a 2-byte pad tweak to reproduce the crash.)

Exploitation
Lessons Learned

When applying patch diffing to networking protocols:

  1. Understand the protocol specifications thoroughly
  2. Look for missing bounds checks in data processing
  3. Pay attention to buffer size calculations
  4. Check for proper validation of protocol field values and locations
  5. Consider evasion techniques for exploit deployment - see EDR
  6. Specs: ESP (RFC 4303) and IPv6 (RFC 8200) are essential references when reasoning about header placement and bounds

Semi-Automatic Patch Diffing

Manual Patch Diffing

mkdir 2022-09
mv *.msu 2022-09
cd 2022-09
mkdir extract
mkdir patch
expand -F:* .\*.msu .\extract
expand -F:* .\extract\<largest>.cab .\patch
expand -F:* .\patch\<largest>.cab .\patch
expand -F:* .\patch\Cab_* .\patch\

You can use Patch Extract instead

gci -Recurse c:\windows\WinSxS\ -Filter ntdll.dll
# copy the biggest file somewhere
.\delta_patch.py -i .\NTDLL\ntdll.dll -o ntdll.2020-10.dll .\NTDLL\r\ntdll.dll .\2020-10\x64\ntdll_<stuff>\f\ntdll.dll
.\delta_patch.py -i .\NTDLL\ntdll.dll -o ntdll.2020-11.dll .\NTDLL\r\ntdll.dll .\2020-11\x64\ntdll_<stuff>\f\ntdll.dll

Open unpatched version in IDA as the primary and the second, after that use BinDiff add-on to find the differences between them then right click on a different matched function and see the visual diff in bin diff also you can uncheck proximity browsing to see the entire function look at red blocks and then yellow blocks

With patch clean script you can only see the actual changed files

Static Analysis Tools

IDA Pro and Rust Tools for Vulnerability Research

Modern Static Analysis Tools

Deprecated Tools (Avoid)

For more details about these tools: Streamlining vulnerability research with IDA Pro and Rust

Dynamic Analysis Methods

Dynamic analysis examines code during execution to identify vulnerabilities in real-time operation.

Hybrid Reverse Engineering (dynamic)

Reverse engineering involves analyzing an application while it runs to understand its behavior.

Network Protocol Analysis Example

Hypervisor Debugging and Analysis

Binary Instrumentation

Binary instrumentation is a prerequisite for advanced dynamic analysis methods.

Dynamic Taint Analysis

Symbolic Execution

Challenges with Symbolic Execution

eBPF‑based Dynamic Tracing

Coverage Recon (quick)

# Collect light coverage then visualize
drrun -t drcov -- ./target @@
python3 drcov2lcov.py ./drcov.*.log > coverage.info
genhtml coverage.info -o cov_html

Fuzzing

Fuzzing is a technique where you feed the application malformed inputs and monitor for crashes or unintended behaviors. See the dedicated Fuzzing document for more detailed techniques.

Fuzzing Overview

What is Fuzzing?

What a Fuzzer Does

What a Harness Does

Fuzzer vs Harness Relationship

Crash Detection Techniques

Fuzzing Tools

Modern Fuzzing Frameworks

Instrumentation & Coverage

Specialized Fuzzers

Symbolic Execution Engines

Continuous-Integration Fuzzing

Snapshot Fuzzing

VMM Snapshot Fuzzing

Fuzzing Types

Dumb Fuzzing

Smart Fuzzing

Evolutionary Fuzzing

Concurrency Fuzzing

LLM‑Guided Fuzzing

Combined Method

The most effective approach often combines multiple techniques:

AI/ML-Assisted Vulnerability Discovery

Modern vulnerability research increasingly leverages machine learning and large language models to accelerate discovery and analysis.

LLM-Powered Triage and Analysis

AI-Powered Vulnerability Scanners

LLM-Assisted Fuzzing

Practical Integration

# Example: Using local LLM for crash triage (OPSEC-safe)
from transformers import AutoTokenizer, AutoModelForCausalLM

def analyze_crash_local(crash_log, binary_info):
    model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3-8b")
    tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3-8b")

    prompt = f"""Analyze this crash and suggest root cause:

Binary: {binary_info}
Crash Log:
{crash_log}

Provide: 1) Root cause hypothesis 2) Exploitability assessment 3) Suggested exploit primitive"""

    inputs = tokenizer(prompt, return_tensors="pt")
    outputs = model.generate(**inputs, max_length=1000)
    return tokenizer.decode(outputs[0])

Limitations and Considerations

Quick Reference: Tool Selection Guide

By Target Type

Target Primary Tools Secondary Tools
Linux Kernel Syzkaller, AFL++ KASAN, KCOV, ftrace
Windows Kernel ICICLE, WinAFL Verifier, KFUZZ
Browsers LibFuzzer, Domato ClusterFuzz, Dharma
Network Services AFL++, Boofuzz Peach, Sulley
Mobile Apps QARK, Frida MobSF, Objection
Web Apps Burp Suite, FFUF Nuclei, Semgrep
Firmware Binwalk, EMBA FACT, Firmwalker
Containers Trivy, Falco Grype, Syft

By Technique

Technique Recommended Tools Notes
Coverage Fuzzing AFL++ 4.21+ Cross-platform, CMPLOG support
Snapshot Fuzzing Nyx, QEMU+AFL++ Stateful target support
Concurrency Fuzzing RFF, ThreadSanitizer Race condition detection
Symbolic Execution Angr, Triton Path exploration
Taint Analysis DynamoRIO, Triton Data flow tracking
Binary Diffing BinDiff 8, Ghidriff Patch analysis
Static Analysis CodeQL, Semgrep Pattern matching
Dynamic Analysis Frida, DynamoRIO Runtime instrumentation

Tool Migration Path

Old Tool New Alternative Migration Notes
Intel Pin DynamoRIO Pin is sustain-only
WinAFL AFL++ 4.x Integrated Windows support
Radamsa LibAFL mutators Better coverage awareness
BinDiff 7 BinDiff 8/Ghidriff Improved algorithms
IDA 7.x IDA 8.x/Ghidra 11 Better decompilation