CVEReports
CVEReports

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

Product

  • Home
  • 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-25793
7.60.02%

Doppelgänger Certificates: Bypassing Nebula Blocklists with ECDSA Magic

Alon Barad
Alon Barad
Software Engineer

Feb 8, 2026·6 min read·20 visits

PoC Available

Executive Summary (TL;DR)

Nebula versions 1.7.0 through 1.10.2 using non-default P256 settings allow blocklist evasion. Because ECDSA signatures are malleable, an attacker can modify a blocked certificate's signature to generate a different SHA-256 fingerprint while maintaining validity. This bypasses blocklists that rely on static file hashes.

In the world of cryptography, two things can be mathematically identical yet look completely different to a computer. CVE-2026-25793 is a fascinating logic flaw in Slack's Nebula overlay network that exploits the malleability of ECDSA signatures on the NIST P-256 curve. By flipping the 's' value of a cryptographic signature, an attacker can generate a new binary representation of a certificate that remains cryptographically valid but results in a completely different file hash. Since Nebula's blocklist mechanism relied solely on SHA-256 fingerprints of the raw certificate bytes, this allowed banned attackers to simply 'flip a switch' and re-enter the network.

The Hook: When Is a Ban Not a Ban?

Nebula is one of the darling children of the mesh VPN world. It’s fast, it’s secure, and it usually defaults to modern, safe crypto like Curve25519. But, enterprise environments often have rigid compliance requirements that force them to use NIST standards, specifically the P-256 curve. If you were one of the unlucky admins forced to configure Nebula to use P-256, you were sitting on a ticking time bomb of cryptographic trivia.

The core promise of a blocklist is simple: "I don't like this certificate. I will calculate its fingerprint (hash), put it in a blocklist.yml file, and never speak to it again." It's the digital equivalent of a bouncer with a photo of a troublemaker taped to the door.

But what happens if the troublemaker is a shapeshifter? CVE-2026-25793 isn't a buffer overflow or a command injection. It's a failure to understand that in the weird world of Elliptic Curve Digital Signature Algorithm (ECDSA), a single identity can wear two different faces. You banned the face, but the math let them swap it out.

The Flaw: The Mirror Dimension of ECDSA

To understand this exploit, we have to endure a tiny bit of math. An ECDSA signature is composed of two integers: $(r, s)$. When you verify a signature, the math checks that these numbers correspond to the signer's public key and the message hash. However, elliptic curves over finite fields have a property called malleability.

For any valid signature $(r, s)$, there exists a second valid signature: $(r, n - s)$, where $n$ is the order of the curve. Think of it like a clock. If the time is 10:00, that's effectively the same position as -2:00 relative to 12:00. Both $s$ and its negative (modulo the curve order) are valid proofs of identity.

The vulnerability lies in how Nebula implemented its blocklist. Nebula calculated the "fingerprint" of a certificate by taking the SHA-256 hash of the entire serialized DER-encoded certificate. Since the signature bytes are part of that file, if you change $s$ to $n - s$, the binary content of the file changes. Consequently, the SHA-256 hash changes completely.

So, an attacker with a blocked certificate evil.crt (Fingerprint A) can simply do some math to generate evil_v2.crt (Fingerprint B). Nebula sees Fingerprint B, checks the blocklist, sees only Fingerprint A is banned, and rolls out the red carpet. The cryptographic signature is still valid, so the connection is established.

The Code: Fixing the Fingerprint

The fix, applied in commit f573e8a26695278f9d71587390fbfe0d0933aa21, is a lesson in defensive coding. The developers couldn't just change how fingerprints are calculated globally without breaking backward compatibility for every existing deployment. Instead, they had to make the verifier smarter.

First, they implemented a function to calculate the "alternate" fingerprint. This function parses the certificate, extracts the signature, calculates the inverted $s$ value, and re-serializes the certificate to see what its evil twin would look like:

// cert/p256/p256.go snippet from the patch
func swap(r, s []byte) ([]byte, []byte, error) {
    // ... setup big integers ...
    sNormalized := nMod.Nat().Sub(bigS, nMod) // Calculate n - s
    return r, sNormalized.Bytes(nMod), nil
}

Then, in the verification logic (cert/ca_pool.go), they check both possibilities. If the incoming certificate isn't on the blocklist, they calculate its doppelgänger and check if that is on the blocklist:

// The patch logic in VerifyCertificate
if ncp.IsBlocklisted(fp) {
    return nil, ErrBlockListed
}
 
// Check the alternate fingerprint for P256 malleability
fp2, err := CalculateAlternateFingerprint(c)
if fp2 != "" && ncp.IsBlocklisted(fp2) {
    return nil, ErrBlockListed
}

They essentially said: "We see you're wearing a blue shirt. Let's check if we banned you wearing a red shirt."

The Exploit: Bypassing the Ban

Let's walk through how a researcher (or attacker) would actually pull this off. Assume you have a valid certificate key pair that has been revoked by the administrator. You cannot get a new cert signed by the CA, so you must reuse your existing one.

Step 1: The Setup You try to connect. The Nebula lighthouse rejects you: handshake failed: certificate is blocklisted.

Step 2: The Transformation You don't need the CA's private key to do this; you just need your own certificate. You write a script (likely in Python using cryptography or Go) that:

  1. Parses your DER-encoded certificate.
  2. Extracts the ECDSA signature integers $(r, s)$.
  3. Retrieves the curve order $n$ for NIST P-256.
  4. Calculates $s' = n - s$.
  5. Replaces the signature in the certificate structure with $(r, s')$.

Step 3: The Re-entry You save this as bypass.crt. The SHA-256 hash is now completely different. You configure your Nebula node to use bypass.crt. When you initiate the handshake, the Nebula CA validates the signature (which is mathematically sound) and checks the blocklist. Since the admin only banned the hash of original.crt, bypass.crt slides right through.

> [!NOTE] > This only works because the underlying identity (the public key) is effectively immutable, but the container (the certificate bytes) is mutable via the signature.

The Impact: Zombies in the Network

The severity of this vulnerability (CVSS 7.6) is tempered only by the fact that P-256 is not the default configuration for Nebula. Most users are on Curve25519, which uses EdDSA. EdDSA signatures are deterministic and generally not malleable in this specific way (or at least, libraries are stricter about it).

However, for environments that do use P-256, the impact is high. A blocklist is the primary mechanism for revoking trust in a compromised node without rotating the entire CA. If a blocklist can be bypassed, revocation is broken. An attacker with a stolen laptop or a compromised server can persist in the network indefinitely, even after the security team thinks they have cut off access.

This is a classic "Zombie" vulnerability—you kill the threat, but it rises from the grave with a slightly different look.

The Fix: Normalization is Key

To mitigate this, you must upgrade to Nebula v1.10.3. The patch does two things: it catches the malleable signatures during verification (as shown above), and it enforces "Low-S" normalization for all new signatures generated by Nebula.

"Low-S" normalization means the software enforces a rule: if $s > n/2$, replace it with $n - s$. This forces a canonical representation of the signature, effectively killing the doppelgänger before it's born. If you are stuck on an older version, your only real mitigation is to rotate your CA authorities or migrate away from P-256 to Curve25519 (Ed25519), which is the superior choice for modern infrastructure anyway.

If migration isn't an option, ensure your monitoring alerts on successful connections from nodes that were recently attempted to be blocked. If you see a node ID connecting with a new hash immediately after a ban, you're witnessing the math in action.

Official Patches

SlackHQGitHub Commit: fix P256 signature malleability

Fix Analysis (1)

Technical Appendix

CVSS Score
7.6/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
EPSS Probability
0.02%
Top 97% most exploited

Affected Systems

Slack Nebula (v1.7.0 - v1.10.2) configured with P256 curves

Affected Versions Detail

Product
Affected Versions
Fixed Version
Nebula
SlackHQ
>= 1.7.0, <= 1.10.21.10.3
AttributeDetail
CWE IDCWE-347
Attack VectorNetwork
CVSS v4.07.6 (High)
ImpactSecurity Bypass / Revocation Failure
EPSS Score0.00017 (Low)
ConfigurationRequires non-default P256 curve

MITRE ATT&CK Mapping

T1578Modify Cloud Compute Infrastructure
Defense Evasion
T1027Obfuscated Files or Information
Defense Evasion
CWE-347
Improper Verification of Cryptographic Signature

Improper Verification of Cryptographic Signature

Known Exploits & Detection

HypotheticalExploitation involves local manipulation of ASN.1/DER certificate structures to invert the ECDSA 's' value.

Vulnerability Timeline

Vulnerable version 1.10.2 released
2026-01-21
GHSA-69x3-g4r3-p962 Published
2026-02-06
Patch v1.10.3 Released
2026-02-06

References & Sources

  • [1]GHSA Advisory
  • [2]NVD Detail

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.