CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Dashboard
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-22866
2.7

Identity Theft by Cube Root: Forging DNSSEC in Ethereum Name Service

Alon Barad
Alon Barad
Software Engineer

Feb 25, 2026·6 min read·5 visits

PoC Available

Executive Summary (TL;DR)

The ENS DNSSEC oracle failed to verify RSA PKCS#1 v1.5 padding, checking only the hash suffix. This allowed attackers to use basic math (cube roots) to forge signatures for TLDs using $e=3$, enabling the theft of domains like `target.cc` on the Ethereum network.

A critical cryptographic oversight in the Ethereum Name Service (ENS) DNSSEC oracle allowed attackers to bypass RSA signature verification. By exploiting a lazy validation implementation in `RSASHA256Algorithm` and `RSASHA1Algorithm` contracts, adversaries could forge valid-looking signatures for specific Top-Level Domains (TLDs) like `.cc` and `.name` that utilize a low public exponent ($e=3$). This flaw essentially permitted the hijacking of ENS domains rooted in these TLDs without possessing the actual DNS private keys.

The Hook: Trust, but Don't Verify

The Ethereum Name Service (ENS) is the phonebook of the decentralized web, turning arcane hexadecimal addresses into human-readable names like vitalik.eth. But ENS isn't just an island; it builds bridges to the legacy DNS world. If you own example.com, you can claim example.com on ENS. To do this securely, ENS relies on a DNSSEC Oracle—a set of smart contracts that verify the chain of trust from the root DNS keys down to your domain.

This mechanism sounds robust on paper. It uses RSA cryptography, the bedrock of internet security. However, cryptography is brittle. It's not enough to use the right algorithms; you have to implement them with paranoid precision. In CVE-2026-22866, the developers made a classic mistake: they assumed that if the math works out at the end of the equation, the input must be valid.

This vulnerability is a resurrection of a ghost from 2006—Daniel Bleichenbacher's RSA signature forgery. It’s a stark reminder that in the unforgiving world of smart contracts, skipping a few bytes of validation to save gas can result in a total collapse of trust for affected domains.

The Flaw: A Crayon Drawing with a Picasso Signature

To understand the exploit, we have to look at how RSA PKCS#1 v1.5 signatures work. When a signer creates a signature, they don't just encrypt the hash of the message. They format a specific block of data:

0x00 0x01 [Padding of 0xFFs] 0x00 [ASN.1 OID] [Hash]

This structure prevents mathematical malleability. A verifier computes $M = S^e \pmod N$ (where $S$ is the signature, $e$ is the public exponent, and $N$ is the modulus). The verifier MUST check that the resulting $M$ matches the strict format above, byte for byte.

Here is where the ENS contracts failed. The implementation of RSASHA256Algorithm and RSASHA1Algorithm performed the modular exponentiation, but then it got lazy. It looked at the result and effectively asked, "Does the last 20 bytes match the hash of the DNS record?" If yes, it returned true.

This is the cryptographic equivalent of authenticating a painting by only looking at the signature in the bottom corner. An attacker doesn't need to paint a masterpiece; they can draw a stick figure (garbage data), as long as they glue a convincing signature (the correct hash) at the very end. When the public exponent is small—like $e=3$, which is used by .cc and .name TLDs—finding a number that cubes to a value ending in a specific suffix is trivial.

The Code: The Smoking Gun

Let's look at the vulnerable logic. In the unpatched versions of RSASHA1Algorithm.sol, the verification logic was dangerously concise. It delegated the heavy lifting of RSA recovery but fumbled the check.

Vulnerable Code Pattern

function verify(bytes calldata key, bytes calldata data, bytes calldata sig) external view returns (bool) {
    // ... key parsing ...
    (bool ok, bytes memory result) = RSAVerify.rsarecover(modulus, exponent, sig);
    
    // CRITICAL FLAW: Ignores everything before the last 20 bytes
    return ok && SHA1.sha1(data) == result.readBytes20(result.length - 20);
}

As you can see, readBytes20(result.length - 20) extracts only the tail of the decrypted message. The padding, the structure, the ASN.1 Object Identifier—all ignored.

The Fix

The patch, introduced in commit c76c5ad0dc9de1c966443bd946fafc6351f87587, rips out this naive check and replaces it with a rigorous validation library, RSAPKCS1Verify. The new logic explicitly walks through the decrypted byte array:

  1. Prefix Check: Must start with 0x00 0x01.
  2. Padding Scan: Must have at least 8 bytes of 0xFF.
  3. Separator: Must find a 0x00 byte after the padding.
  4. OID Check: Must contain the correct ASN.1 header for the hash algorithm.

This forces the attacker to generate a signature that, when cubed, matches the entire block, which requires breaking RSA itself.

The Exploit: Cube Roots and Hensel Lifting

So, how does a hacker exploit this? We need to forge a signature $S$ for a malicious DNS record (claiming we own google.cc, for example). The target TLD .cc uses a public key with exponent $e=3$.

Since the contract only checks the suffix, we need to find an integer $S$ such that: $S^3 \equiv \text{Garbage} \ || \ \text{TargetHash} \pmod N$

If we can make $S^3$ end with the TargetHash, the contract accepts it. Because we don't care about the "Garbage" part (the higher-order bytes), we aren't constrained by the modulus $N$ in the same way a legitimate signer is. We can treat this as finding a cube root in modular arithmetic over a power of 2, specifically $2^{hash_bits}$.

The Attack Script

Using Hensel lifting, we can iteratively construct the root bit by bit (or byte by byte). Here is the conceptual attack flow:

  1. Compute Target: Calculate H = SHA256(MaliciousDNSData).
  2. Solve: Find $x$ such that $x^3 \equiv H \pmod{2^{256}}$. This is computationally cheap for small exponents.
  3. Pad: The resulting $x$ will be much smaller than the modulus $N$. We pad it to the correct length.
  4. Submit: Send $x$ as the signature to the ENS oracle.

The oracle computes $x^3$, sees the result ends in $H$, ignores the fact that the rest of the result is mathematical noise, and hands over the domain.

The Impact: Hijacking the Namespace

While the CVSS score sits at a seemingly low 2.7 (likely due to the high complexity of setting up the DNSSEC environment and the limitation to specific TLDs), the functional impact is severe for the affected zones.

An attacker successfully exploiting this could claim ownership of any domain under TLDs that use $e=3$ for their Key Signing Keys (KSK) or Zone Signing Keys (ZSK). Known vulnerable TLDs include .cc and .name.

Imagine an attacker claiming exchange.cc on ENS and setting the resolution address to a wallet they control. Users trusting ENS to resolve that domain would be sending funds directly to the attacker. It undermines the core promise of ENS: that it is a secure, trustless naming system. The vulnerability allows for a complete bypass of the DNS ownership proof for these specific zones.

Mitigation: Stopping the Bleeding

For developers and integrators running their own ENS infrastructure or forks, the path is clear: Upgrade immediately.

The fix is available in ens-contracts versions following 1.6.2. If you are utilizing the RSASHA256Algorithm or RSASHA1Algorithm contracts directly:

  1. Deploy the patched contracts that utilize RSAPKCS1Verify.sol.
  2. Update your DNSSECImpl configuration to point to these new algorithm verifiers via setAlgorithm.

This vulnerability highlights a broader lesson for Solidity developers: Never roll your own crypto verification logic without strictly adhering to the RFCs. The "happy path" is not enough. You must validate the entire structure of cryptographic primitives, or the math will find a way to bite you.

Official Patches

ENSGitHub Commit fixing the issue

Fix Analysis (1)

Technical Appendix

CVSS Score
2.7/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:U

Affected Systems

ens-contracts <= 1.6.2ENS DNSSEC Oracle (RSASHA256Algorithm)ENS DNSSEC Oracle (RSASHA1Algorithm)

Affected Versions Detail

Product
Affected Versions
Fixed Version
ens-contracts
ENS Domains
<= 1.6.21.6.3
AttributeDetail
CWE IDCWE-347
CVSS Score2.7 (Low)
Attack VectorNetwork
Key FactorRSA Public Exponent e=3
Exploit StatusPoC Available
ImpactDomain Hijacking / Signature Forgery

MITRE ATT&CK Mapping

T1587Develop Capabilities
Resource Development
T1557Adversary-in-the-Middle
Credential Access
CWE-347
Improper Verification of Cryptographic Signature

The product verifies a cryptographic signature but does not verify or incorrectly verifies that the signature is valid.

Known Exploits & Detection

Internal ResearchBleichenbacher's variant using cube root calculation for e=3

Vulnerability Timeline

Vulnerability Disclosed
2026-02-25
Patch Merged
2026-02-25
CVE Assigned
2026-02-25

References & Sources

  • [1]GitHub Security Advisory
  • [2]RFC 8017: PKCS #1 v1.5

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.