“We found a zero-day” is a great line, but behind it sits a long, iterative process: patch analysis, fuzzing, variant tracking, crash triage and root-cause analysis, and finally an assessment of real exploitability. For scale: Google's Threat Intelligence Group (GTIG) counted 75 zero-days exploited in the wild in 2024 (98 in 2023, 63 in 2022), with targeting shifting toward enterprise security and networking appliances.
This is the process GOTROOT’s research team follows to discover and register high-impact vulnerabilities (RCE, memory corruption) as CVEs, grounded in public research and standards. One question drives all of it: can we find the flaw an attacker doesn’t know yet, before they do?
Definitions: 0-day, N-day, and the patch gap
0-day — unknown to vendor and public, with no patch yet; no detection rules exist, so it is the hardest to defend.
N-day (1-day) — disclosed and patched but not yet applied in production; during that gap attackers reuse public PoCs.
One worth noting: 2024’s regreSSHion (CVE-2024-6387) was actually a regression of a bug fixed back in 2006 (CVE-2006-5051). Variants of already-patched flaws returning as new zero-days is more common than you’d think.
The big picture: most flaws come from memory safety
To prioritize discovery, look at the data — and it points one way: a large share of high-severity flaws stem from memory-safety issues.
Source | Key figure |
|---|---|
Chromium | ~70% of high/critical bugs are memory-safety issues (912 bugs since 2015) |
Microsoft | ~70% of security patches over 12 years addressed memory-safety flaws |
Android (Google) | Rust drove memory-safety share 76% (2019) → below 20% (2025) |
GTIG (2024) | 75 in-the-wild 0-days; top types: use-after-free, command injection, XSS |
So 0-day hunting concentrates on where corruption happens — parsers, decoders, memory management. Meanwhile the shift to memory-safe languages (strongly urged by CISA) is structurally shrinking this surface. Offense and defense read the same data.
1) Patch analysis — reading the patch backwards
When a vendor ships a patch, the before/after diff is a map of what was vulnerable. BinDiff or Diaphora isolate changed functions so you can reconstruct an exploit path before a public PoC exists — an added bounds/sign/integer check is the tell. Why it matters: Log4Shell (CVE-2021-44228) slept in code since 2013. The moment a patch ships, reading it in reverse becomes a race between defender and attacker.
2) Variant analysis — the most underrated technique
This is where research depth shows. Per Project Zero, many in-the-wild zero-days aren’t brand-new bugs but variants of already-patched ones — the same mistake repeated elsewhere, which fuzzing often misses. So fixing one bug isn’t the end; you query the whole codebase for “where else does this pattern live?”
# Query the codebase for the same pattern (conceptual CodeQL)
from FunctionCall memcpy, Expr len
where memcpy.getTarget().getName() = "memcpy"
and not exists(BoundsCheck bc | bc.guards(len)) // no bounds check
select memcpy, "memcpy with unvalidated length — variant candidate"
Project Zero recently even paired LLM agents with this approach to review real codebases like SQLite. The point isn’t the tool but the mindset: this bug is probably not alone.
3) Coverage-guided fuzzing — driving out flaws with unexpected input
Many zero-days come from inputs nobody expected. Coverage-guided fuzzers (AFL++, libFuzzer) evolve inputs that reach new code paths, surfacing memory corruption in parsers and protocol handlers. The craft is designing a harness that calls the target directly.
// libFuzzer harness skeleton — call the target parser directly
#include <stddef.h>
#include <stdint.h>
extern int parse_packet(const uint8_t *buf, size_t len);
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size == 0) return 0;
parse_packet(data, size); // build with ASAN to catch memory errors instantly
return 0;
}
// clang -g -O1 -fsanitize=fuzzer,address harness.c target.c -o fuzz
Continuous fuzzing: OSS-Fuzz fuzzes hundreds of OSS projects around the clock and has found tens of thousands of bugs — it shines as a standing process, not a one-off.
Kernel: Linux relies on syzkaller with KASAN to surface flaws continuously.
When stuck: dictionary-based, grammar-aware, and structure-aware fuzzing reach deeper paths.
4) Static, taint, and symbolic analysis — from input to the dangerous sink
Where fuzzing throws inputs dynamically, static and taint analysis trace, in code, how external input reaches a dangerous function without validation. Write dataflow queries in CodeQL/Semgrep; for complex conditions, reason about reachability with symbolic execution (angr). Efficient for narrowing suspects in large codebases.
5) Crash triage and root-cause analysis
The hundreds of crashes a fuzzer produces are mostly duplicates of the same bug or unexploitable NULL derefs. To isolate the valuable ones, minimize each input to a smallest reproducer, group duplicates by stack hash, then rank by likely exploitability.
# 1) minimize the input (libFuzzer)
./fuzz -minimize_crash=1 -runs=100000 crash-abcd
# 2) group duplicates by stack hash
for c in crash-*; do
./fuzz -runs=1 "$c" 2>&1 | grep -m1 "#0" | md5sum
done | sort | uniq -c
# 3) classify corruption type from the ASAN report
Corruption type | Exploitation view |
|---|---|
NULL deref / simple crash | Usually availability (DoS) only |
Stack/heap out-of-bounds write | Can seize control flow → RCE candidate |
Use-after-free / type confusion | Weaponizable via heap grooming (the #1 in-the-wild type in 2024) |
6) Exploitability and the mitigation arms race
A flaw becomes a vulnerability only when impact and controllability are proven. Real exploitation chains small primitives against several mitigations.
One address leak defeats ASLR; add an arbitrary write and you can seize control flow.
ROP/JOP to bypass DEP/NX; heap grooming to align a use-after-free with a controllable object.
On mobile/modern targets: CFI (Android), pointer authentication (PAC, iOS 12+), memory tagging (MTE), and kernel SMEP/SMAP/KPTI.
These mitigations clearly make exploitation harder — but not impossible. In 2024 researchers presented TikTag, bypassing ARM MTE with speculative execution to push success rates near 100% against real Chrome and Linux-kernel targets. Defense steps forward; offense follows. Assessing realistic difficulty is precisely the researcher’s job.
7) A new front — supply chain and the vulnerability of trust
2024’s most shocking case wasn’t a memory bug but the XZ Utils backdoor (CVE-2024-3094). An actor contributed to an OSS project for ~2 years to earn maintainer trust, then planted a backdoor in a compression library to target OpenSSH RCE. It nearly succeeded — uncovered when one engineer found a ~0.5-second SSH login delay suspicious and dug in.
The lesson is clear: discovery must look beyond code to the components it leans on and the chain of trust around them — exactly the supply-chain view we stress in pentesting. (Related: supply-chain & OSS vulnerability management)
8) Responsible disclosure — the ethics after discovery
Once exploitability is confirmed, we coordinate disclosure with the vendor to allow a patch window before CVE assignment. Client-system findings stay strictly confidential. The stronger the discovery capability, the more the ethics and process around it matter.
Why this changes pentest outcomes
A team that has found its own zero-days sees undiscovered flaws and chaining even where a scanner reports “clean.” Reproducing N-days in days via patch analysis, finding “the same mistake elsewhere” via variant analysis, and catching unknown flaws via fuzzing all translate into depth on client engagements — including N-days in the components a client leans on (APT-perspective testing) and the same mindset in LLM red teaming. That is why GOTROOT has registered multiple CVEs — and the essential gap between a scanner report and real penetration testing.
The truth we meet most in discovery is that a bug is never alone. Find one and a sibling sits nearby. Good research is less about “popping one” and more about mapping where the same mistake recurs.
FAQ
Isn’t vulnerability research separate from pentesting?
They connect — the root-cause, variant, and exploitation intuition built in discovery finds deeper, chained flaws in client environments.
Do you publish findings?
We follow coordinated disclosure with vendors; client-system findings remain confidential.
Does widespread Rust end zero-day research?
Memory corruption shrinks, but logic, authorization, supply-chain, and design flaws remain. The surface shifts; research follows it.
Closing
A team that has built exploits delivers deeper results. To see how far your service and its underlying components hold up under a real attacker’s eyes, reach out at penetration testing or red teaming.