Reading exploits: a practical method for understanding CVE writeups
A methodology for engineers who want to build intuition from real CVE writeups without becoming professional exploit developers or drowning in irrelevant detail.
Why read CVE writeups
You don't need to write exploits to benefit from reading them. The goal for most engineers is simpler: build enough intuition to recognize vulnerability patterns in code you write or review, understand the real-world impact of vulnerability classes before you encounter them in a pentest report, and have an honest mental model of what "this software is exploitable" actually means in practice.
The problem is that most CVE writeups are written for people who already know the vocabulary. They assume familiarity with memory layouts, protocol internals, or specific platform behavior. Reading them without a method means either spending hours on one report or skimming without retaining anything.
Here's the method I use.
Step 1: Read the CVE record first, not the writeup
Before the technical details, read the official CVE record (NVD or MITRE). Three things matter:
- CVSS vector string: This encodes the attack vector (network vs. local), privileges required, user interaction required, and impact on confidentiality/integrity/availability.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:Htells you "network-reachable, no auth, no user interaction, full compromise" before you read a single word of the writeup. - CWE classification: CWE-787 is an out-of-bounds write. CWE-89 is SQL injection. CWE-416 is use-after-free. The CWE gives you the vulnerability class, which tells you what mental model to activate.
- Affected versions and patch date: Tells you whether this is a recent vulnerability or historical context.
With these three pieces, you know what you're walking into before the writeup's prose gets in the way.
Step 2: Find the patch before reading the writeup
If the software is open source, look up the fix commit before reading the researcher's explanation. GitHub has a "Commits" view filtered by date range; most CVE database entries link to the fix advisory, which links to the commit.
Read the diff first. Just the diff — no explanation. Ask yourself:
- What changed?
- Where is the check being added, or the variable being constrained, or the initialization being added?
- What input path reaches this code?
You won't always be able to answer all three. That's fine. Note what you can't explain — that's what you're reading the writeup to learn.
# Example: look up a fix commit for a specific CVE
gh search commits "CVE-2024-XXXXX" --repo vendor/project --json sha,message \
| jq '.[] | {sha: .sha, message: .message}'
# Or just pull the tag diff between vulnerable and fixed release:
git diff v1.2.3..v1.2.4 -- src/affected_module.c | head -100
This step builds the habit of reading code changes critically. After a dozen CVEs, you start to recognize patterns: missing bounds checks on array indexing, unchecked return values from allocation functions, format string parameters passed directly to printf.
Step 3: Read the writeup in three passes
First pass — the setup: What software, what component, what conditions does the vulnerability require? Sketch the attack path at a high level. Don't get stuck on details you don't recognize yet.
Second pass — the primitive: What fundamental capability does the vulnerability give the attacker? For a heap overflow, the primitive is usually "write N bytes past the end of a heap allocation." For a type confusion, it's "treat object of type A as type B." The exploit technique is just the story of how the attacker turns that primitive into code execution or data exfiltration.
Third pass — the turning point: Where exactly does the program's security model break down? This is usually a single assumption that failed. "The developer assumed this length field would always be smaller than the buffer." "The parser trusted the content-type header without validating the actual content." Identifying the failed assumption is the most transferable lesson from any writeup.
Step 4: Map it to a class, not just an instance
After reading, don't just file away "CVE-2024-XXXXX: buffer overflow in libfoo's JPEG parser." Ask:
- What class does this belong to? (Out-of-bounds read, integer overflow leading to allocation undersize, off-by-one in loop bound...)
- What language/runtime properties let this happen? (C/C++ lack bounds checking by default; Rust makes this a compile-time error in safe code; Python makes it impossible at the language level)
- Where have I seen similar patterns in code I've written or reviewed?
This is where the writeup becomes transferable knowledge instead of a one-off story.
Sources worth reading systematically
- Google Project Zero blog (googleprojectzero.blogspot.com): Long-form, technically deep, usually includes the full exploitation path. Start here for learning technique.
- NCC Group publications: More applied, often covers configuration and deployment issues alongside pure code bugs.
- Pwn2Own and CTF writeups: Competition-context writeups are often more concise and focus on the aha-moment rather than full disclosure.
- CISA Known Exploited Vulnerabilities catalog: Not writeups, but a prioritized list of vulnerabilities with confirmed in-the-wild exploitation. Useful for knowing which vulnerability classes are being actively weaponized.
What not to do
Don't try to reproduce exploits for software you don't own or haven't set up a legal test environment for. The point is building a mental model, not building a toolkit. Attempting to reproduce without proper setup usually ends with a broken environment and no learning anyway.
Don't skip the writeups you don't fully understand. The ones that are most opaque are usually pointing at a gap in your mental model — that's exactly where the reading is most valuable. Note what's confusing, look up the prerequisite concept (heap layout, page table structure, whatever), then come back.
A systematic reader of CVE writeups who understands the vulnerability class and failed assumption for 50 real bugs has better security intuition than someone who can write a working exploit for one CVE but hasn't built breadth. The goal is pattern recognition at scale, not individual mastery.