Our Latest Black Hat Asia Talk: Introducing the RFC Analyzer

Our Latest Black Hat Asia Talk: Introducing the RFC Analyzer

Arad Inbar, a security researcher from our research group at DREAM, recently presented at Black Hat Singapore. The talk focused on using protocol specifications, specifically RFCs, as a primary surface for vulnerability discovery. This line of research started with a simple question. If we read the Kerberos RFC carefully, without knowing what “Kerberoasting” was, would we arrive at the same attack on our own? We tried it, and we did. Then we asked the same thing about AS-REP Roasting. Same result. That made us wonder: if well-known attacks are already sitting in the text, what is in there that nobody has named yet? The deeper we dug, the more we realized how complex the dependency web between RFCs actually is. Specs update other specs, obsolete them, extend them, and quietly depend on protocols written decades earlier. Implementations tend to follow one thread of that web and miss the rest, and that gap opens a wide surface for unknown vulnerabilities to hide in.That question led us to build a tool we call the RFC Analyzer. It treats RFCs as a first-class attack surface, builds a structured map of protocol behavior across long document chains, and produces security leads that aid vulnerability discovery. The approach helped us uncover many CVEs across major protocols, including remote code execution issues, and we used the talk to share both the methodology and a few of the case studies that came out of it. This post describes some of the RFC Analyzer’s components and the ideas behind them.

Where the Industry Focuses and Where It Does Not

Vulnerability research today concentrates on the implementation: source code review, fuzzing, binary analysis, static analysis, dynamic instrumentation, AI-assisted triage. That is where bugs execute, and that is where most tooling, most bug bounty programs, and most security teams measure success.

But almost any network protocol has an RFC behind it. These specifications define how the protocol should behave: states, message formats, error handling, extensions, security requirements, deprecations, and dependencies on other protocols. The specifications are spread across many documents, often updated over decades. Most tooling targets source or binary artifacts. Very little has been built for systematically analyzing the specification chain those artifacts are derived from.

Consider remote code execution. RCE is remote by definition. If it is remote, there is a network protocol carrying the traffic. If there is a network protocol, there is an RFC that defines it. Deep analysis of that RFC chain is an underused path to finding the bugs that matter most.

Why Implementations Drift from the Spec

Where implementations drift from RFC: deadline and cost pressure, RFCs are hard to implement, production reality, embedded constraints

Implementations rarely match their specification perfectly, and the reasons are practical:

  1. Deadline and cost pressure. Developers are not paid to implement every line of an RFC. They have deadlines, need to write clean modular code, and make practical trade-offs.
  2. RFCs are hard to implement and leave room for interpretation. The specifications are long, complex, spread across multiple documents, and full of cross-references that are easy to miss. On top of that, many RFCs leave room for interpretation. When the spec does not define what should happen in edge cases, retransmissions, or error conditions, the developer decides. The less clear the specification, the more freedom the implementation has, and the more likely it is that security-relevant behavior varies between implementations.
  3. Production reality. Real-world environments introduce edge cases, legacy compatibility requirements, and operational shortcuts that the spec did not anticipate.
  4. Embedded constraints. Some devices do not have enough memory or processing power to support heavy encryption or full protocol compliance.

Every one of these reasons creates a gap between what the spec says and what the code does. Sometimes vulnerabilities hide in that gap. Other times, the ambiguity the spec leaves behind is itself the source of the issue.

The Method: Analyze the Specification Chain

The RFC Analyzer: our focus covers the protocol intent and specification chain; the industry focuses on the code implementation

The RFC Analyzer works on the left side of this diagram: the protocol specifications. It maps how RFC sections relate to each other, builds a deep model of how the protocol works, and then asks what is missing. Here is how the three stages work.

Stage 1: Map How RFC Sections Relate

Protocol specifications are not flat. Sections depend on other sections, within the same RFC, across RFCs in the same protocol, and across protocols. The first thing the analyzer does is build a section-level dependency map. We divide these dependencies into three cases:

Case 1 – Within a single RFC. A behavior introduced in one section is restricted or qualified by another section of the same document. When a developer implements from one section without reading the other, the constraint is silently lost. Example: RFC 4120, Kerberos V5. In Section 1.3, “Choosing a Principal with Which to Communicate”, the spec warns:

“one should not rely on an unprotected DNS record to map a host alias to the primary name of a server, accepting the primary name as the party that one intends to contact, since an attacker can modify the mapping and impersonate the party.”

Later, in Section 7.2.3.2, “Specifying KDC Location Information with DNS SRV records”, the same RFC describes how a Kerberos client should locate a KDC by querying DNS SRV records at _kerberos._udp.REALMand _kerberos._tcp.REALM. It explains the record format, priority, weight, port conventions. It does not repeat the Section 1.3 warning. It does not cross-reference it. A developer implementing KDC discovery from Section 7.2.3 may never read Section 1.3. The section-level dependency map makes that implicit link explicit. That gap led to our disclosed CVE-2025-59088.

Case 2 – Across protocols. One protocol relies on another for naming, discovery, transport, or trust. The security assumption lives in the seam between the two specifications, and neither document fully owns it. Example: RFC 5321, Section 5.1, “Locating the Target Host”, specifies that an SMTP client performs a DNS MX lookup on the recipient’s domain to determine which server receives the mail. The entire routing decision depends on that DNS answer being truthful. The SMTP specification relies on DNS for routing but does not include any mechanism to verify the authenticity of the DNS response. In effect, SMTP delegates part of its security to DNS, which means understanding both RFCs and the gap between them is essential. If an attacker can poison or spoof DNS MX records, they can redirect mail to a server they control. This is not theoretical: the Sea Turtle campaign, documented by Cisco Talos in 2019, compromised DNS infrastructure to hijack MX records and redirect mail for government and intelligence targets across the Middle East.

Case 3 – Across RFCs in the same protocol. Individual sections inside one RFC may correlate to sections in a completely separate RFC for the same protocol. A later RFC can harden, deprecate, or replace a behavior from an earlier one. But it is not the case that every section in one RFC maps neatly to a whole other RFC. The relationships are section-to-section, and they form a complex web.

DNS – Connections Between RFCs: 37 RFCs with core, updater, and obsoleted nodes

DNS illustrates the complexity. The analyzer’s view of the DNS chain contains thirty-seven RFCs. Two core specifications, twenty-four that update or are updated, eleven obsoleted. Each of these is a long, complex document with its own internal sections, and individual sections may correlate to sections in other RFCs in the chain. Some RFCs extend earlier ones, some overwrite specific behavior, some are themselves later obsoleted. A developer reading one DNS RFC is getting one slice of a target that has been moving for decades.

Stage 2: Build a Deep Protocol Model

Once the section-level map is in place, the analyzer builds a state machine for the entire protocol. A single mechanism, like authentication or session setup, often spans more than one RFC and sometimes more than one protocol. The analyzer traces how each mechanism works end to end: what are the pre-authentication and post-authentication surfaces, how do the mechanisms connect, what are the message flows and transitions. The goal is to fully understand the protocol’s behavior as a whole before asking any security questions.

Stage 3: Ask What Is Missing

Once the model is built, the analyzer runs security-oriented questions against the spec. These questions are not run against code. They are run against the specification itself, and they produce leads that a researcher can later take against a specific target implementation. For example:

  • Are packet or message sizes validated and bounded, or can an attacker send an oversized payload that the spec never explicitly limits?
  • Are error responses leaking internal state? Kerberos error codes, for instance, can distinguish “user exists” from “user does not exist”, enabling user enumeration from the network.
  • Is there a replay protection mechanism described in the authentication section, or is the session vulnerable to replayed tokens?
  • Is too much information exposed before authentication? Some protocols negotiate capabilities or exchange metadata on the unauthenticated surface that an attacker can use to fingerprint or probe the implementation.

Each question is grounded in a specific section of the spec. The output is a set of leads, each pointing at a concrete area where an implementation might be vulnerable.

These stages, section dependency mapping, state machine extraction, and missing-check analysis, are all components of the RFC Analyzer. There are additional components beyond what we cover in this post. They all feed into each other. One such component detects the gap between RFC updates and real-world adoption, which we demonstrate with IPv6 fragmentation.

What the Analyzer Produces

For a typical major protocol, the analyzer produces a structured report with on average 50 to 200 rows. Each row is a lead for a potential attack: it includes the technique name, attack category, a step-by-step description of how the attack would work, the exact RFC section it is derived from, prerequisites, and the entities involved. The image below is a condensed snippet of a typical output row. The actual reports are more detailed, but this gives the general idea.

Snippet of typical output: one row showing technique name, attack category, description, detailed explanation, RFC reference, prerequisites, and entities

Once the report is generated, there are three ways we use it:

  1. Manual review against a target. A researcher takes leads from the report, reverses or reads the source code of a specific implementation, and looks for the vulnerabilities the report points to. This is the most traditional approach and predates LLMs.
  2. LLM-assisted vulnerability hunting. Instead of asking an LLM to “find vulnerabilities in this codebase” with no direction, we feed the structured report as context. The leads pinpoint potentially buggy areas, which focuses the search and produces better results. It also saves tokens and cost because the LLM is working on a narrow, well-defined question instead of scanning an entire codebase blind. This method is heavily used in our workflow to disclose zero-days. We found that doing thorough pre-analysis of the target’s protocol before starting vulnerability analysis produces significantly more accurate and richer findings.
  3. Pattern-based search at scale. Some leads from the report can be reduced to a single line of code that represents the violation. For example, the TLS 1.3 specification, RFC 8446 Appendix C.5, states that applications must not use TLS without certificate validation. In Python, that violation maps to one constant: ssl.CERT_NONE. We can then search large codebases for that pattern and check each hit. This method led to disclosed CVEs including CVE-2025-12765 in pgAdmin, CVE-2026-25644 in DataHub, and CVE-2026-31798 in JumpServer.

Case Study: IPv6 Fragmentation

There is a constant gap between the moment a hardening RFC is published and the moment implementations actually adopt it. Some products update slowly. Some update partially. Some never update at all.

IPv6 Fragmentation: RFC 2460 Flaws mapped to RFC Fixes mapped to CVEs, showing the full chain from 1998 to 2025

The diagram demonstrates the security updates to the original IPv6 fragmentation behavior over the years. Fragmentation is only one mechanism inside IPv6, and it alone has more than five hardening RFCs spanning two decades. As we can see, for each security update to the original fragmentation behavior, CVEs followed in implementations that had not adopted the new rules. The pattern repeats across the entire chain.

In many cases, the hardening RFC itself contains the recipe for the attack: it describes what the old behavior allowed and how it could be exploited. The analyzer takes that recipe and turns it into a concrete lead. For example, RFC 5722 in 2009 explicitly forbade overlapping fragments and described why the old behavior was dangerous. An attacker could craft two fragments where the first piece looks benign to a firewall but the second overwrites part of the first during reassembly, producing a different packet on the host. Three years later, the Linux kernel was still accepting overlapping fragments, resulting in CVE-2012-4444, a firewall bypass.

When we feed a protocol like IPv6 into the RFC Analyzer, part of the output is exactly this: for every mechanism, a set of security leads where each lead contains the recipe for the attack that can be taken against a target to check whether the hardening was adopted. In many cases, these updates take years to be implemented, are done partially, or are not done at all. The idea is to replicate at scale what the researchers who found these CVEs went through manually. The diagram shows similar gaps continuing through 2025 across Linux, Windows, FreeBSD, and IoT devices.

Case Study: From RFC to Memory Corruption in Telnet

Adiel Sol, a researcher on our team, used the analyzer to investigate the Telnet protocol. The analyzer performed deep analysis across the Telnet RFC chain, including RFC 854, RFC 855, RFC 857, RFC 858, and RFC 1184, covering the base protocol, option negotiation, echo handling, suppress go-ahead, and LINEMODE with the SLC (Set Local Character) sub-option. Five signals from the analysis converged on the SLC reply-building code path:

  1. Input asymmetry. A small SLC payload from the client triggers a large, content-dependent reply from the server.
  2. Structured parser surface. The payload is parsed into typed triplet records, not free-form bytes.
  3. Branchy reply construction. Each triplet can trigger a different output path, shaping the reply buffer differently.
  4. Pre-authentication reachability. The entire exchange happens before authentication takes place.
  5. Weak robustness guidance. The spec describes correct-case behavior but does not prescribe defensive checks for hostile input.

Five Signals funnel: small input large server work, structured parser surface, branchy reply state machine, early negotiation path, weak robustness guidance

These signals told us exactly where to focus: SLC negotiation. Following the leads, Adiel examined telnetd’s add_slc() function and uncovered CVE-2026-32746: by sending a large number of SLC triplets in a single pre-authentication LINEMODE sub negotiation, an attacker can trigger an out-of-bounds write that can lead to remote code execution, all before authentication takes place.

The full technical write-up of CVE-2026-32746 is available on the DREAM blog.

Key Takeaways

Effective vulnerability research needs ammunition before touching the code. Identify which services are exposed. Understand which protocols those services speak. Use RFC analysis to build a deep model of how the protocol works and what is missing. Then come back to the implementation with pinpointed leads.

By understanding how the protocol works, analyzing each section of the RFC chain and how they relate, and running the analyzer, we get leads as output. These leads help us find not just more bugs, but a different kind of bug. The RFC Analyzer is an additional method alongside fuzzing, code review, static analysis, and other existing approaches. We found it especially effective for complex vulnerabilities, including cross-protocol ones, that are hard to reach with traditional code-only methods.

That is where we have been hunting. We think more of the industry should hunt there too.

CONTACT US

Fill out the form to get in touch with our Expert Team.