Resources
    When a Valid TLS Chain Li ...
    26 October 26

    When a Valid TLS Chain Lies

    Posted byAshish Bhangale
    news-featured

    The certificate was valid. The identity was not.

    Publication detail

    Value

    Category

    PKI / TLS / applied cryptography

    Evidence current through

    26 October 2026

    Estimated reading time

    approximately 35 minutes at 200 words per minute

    Executive Summary

    GHOSTTRUST LAB synthetic training evidence. The opening banking scenario and every GhostTrust name, certificate, key and transaction are fictional. They reproduce a failure class without using real compromised material.

    Imagine that Meridian Bank uses a clearing service to decide whether a $48,750 transfer should be released. A separate query to the genuine comparison origin returns HOLD. In the simulated attack path, the bank is preconfigured to contact a synthetic gateway controlled by Mallory. Network position alone should not be enough: the bank's TLS client is supposed to reject a server that cannot prove its identity. Mallory instead recovers the private key of a trusted intermediate certificate authority, signs a new certificate for the clearing hostname, and presents it to a stale client. The client reports a valid TLS chain and accepts the gateway-generated APPROVED response. GhostTrust assumes this attacker position; it does not demonstrate acquiring it or transparently intercepting the genuine origin.

    REAL INCIDENT confirmed public evidence. The public record establishes recoverable eMudhra intermediate CA keys, the affected certificate classes, the root-program response and the limits described below. It does not establish a real bank attack.

    GhostTrust demonstrates the cryptographic and trust-policy portion of that attack: weak-key recovery, unauthorized issuance, stale-chain acceptance and consumption of attacker-controlled data. It is also the central risk created by the October 2026 eMudhra incident: eight intermediate CA private keys were recoverable from public certificate material. Chrome's incident response classified six as TLS-issuing intermediates and two as Code Signing intermediates. The eMudhra root private keys were not compromised. The root failure carries no CVE of its own; it was a certificate-authority key-generation failure, not a flaw in TLS, P-384, or any cryptographic library, and not evidence that ordinary elliptic-curve keys can be guessed. The CVEs that do exist, Firefox’s CVE-2026-113470 and Go’s CVE-2026-111943, track client software that kept trusting the compromised certificates until updated, not a cryptographic break.

    It was a key-generation failure that reduced supposedly strong private values to a tiny search space. Chrome Root Program response eMudhra incident update

    The real attack also has hard prerequisites. Mallory must be in an active adversary-in-the-middle position, and the victim client must still accept a chain through an affected authority. Possession of an intermediate key does not passively decrypt recorded TLS sessions, recover historical plaintext, or place an attacker on the network path. Chrome reported that its CRLSet block and Certificate Transparency enforcement protected default Chrome before any certificate chaining to the six TLS intermediates had appeared in CT. The difficult tail was and remains in incidents like this non-browser software with stale or private trust bundles. Chrome Root Program response public client-remediation tracker

    I reviewed the public Mozilla incident record, the Chrome and Mozilla root-program discussion, the published certificate inventory, eMudhra's update current on 26 October, the GhostTrust target and helper source, and a supplied end-to-end lab transcript. I did not recover or use any real eMudhra private key, test a public service, or reproduce eMudhra's infrastructure. The runtime claims below are limited to the supplied, verified GhostTrust execution record.

    At a glance

    Question

    Evidence-backed answer

    Incident type

    Recoverable intermediate CA private keys caused by catastrophically small P-384 private scalars

    Affected material

    Six TLS-issuing and two Code Signing intermediate CA keys

    Root private keys

    Not part of the reported compromise

    TLS impersonation prerequisite

    An active adversary-in-the-middle position plus a client that still accepts an affected path

    Passive or historical decryption

    Not enabled by possession of an intermediate CA signing key

    Malicious pre-disclosure exploitation

    No public evidence identified; absence of evidence is not proof that no unseen attempt occurred

    GhostTrust

    A synthetic, controlled training implementation not eMudhra infrastructure and not a CVE

    Chrome's response provides the six-TLS/two-Code-Signing classification and its CT and CRLSet findings. eMudhra says it found no evidence that the weak keys were recovered or exploited before disclosure, while its full root-cause analysis remained pending on 26 October. Chrome Root Program response eMudhra incident statement

    Background

    The certificate in the middle

    A browser or application rarely receives a leaf certificate signed directly by a root CA. More often, trust is delegated:

    trusted root CA
        └── intermediate CA
                └── server certificate for api.example

    The root is the long-lived trust anchor. The intermediate performs day-to-day issuance. If an intermediate's signing key is recovered, an attacker can create new leaf certificates that appear to descend from that trusted hierarchy. TLS can still negotiate modern ciphers and encrypt every byte; the failed property is authentication. The client has established a confidential channel to the wrong endpoint.

    For an elliptic-curve key, the certificate publishes a public point Q, while the private scalar d should remain secret:

    Q = dG

    Here, G is the curve's standard generator. Recovering a properly generated P-384 scalar from Q is infeasible with current methods. That protection disappears when d comes from a tiny candidate set: derive dG for each candidate and compare it with the public point already present in the certificate. The algorithm has not failed; the private value never had the expected entropy.

    How the incident surfaced

    The public reporter identifies only as Wayne. According to Wayne's Bugzilla timeline, a test against a CCADB certificate corpus first detected the broken EC keys at 16:27 UTC on 17 October 2026. At 18:05 UTC, Wayne sent the report and signed attestations to Apple, Chrome, Microsoft, Mozilla and eMudhra. Wayne later explained that Google's open-source paranoid_crypto found the weakness “out of the box”; CCADB had initially been intended as a quick corpus test. Wayne's discovery timeline Wayne's discovery explanation

    The attestations mattered because they did more than point at suspicious public keys. Wayne signed a fixed message with each recovered intermediate private key, and the signatures could be checked against the corresponding public certificates. That establishes control of each signing key without publishing the private keys themselves. public proof description

    Incident timeline

    Date and time (UTC)

    Event

    30 April 2025

    eMudhra says the eight intermediates were created during a key-generation ceremony.

    17 October 2026, 16:27

    Wayne's CCADB corpus test detects the weak EC keys.

    17 October 2026, 18:05

    Wayne reports the issue and sends per-key attestations to the root programs and eMudhra.

    17 October 2026, 19:45

    Chrome says it completed corroboration and landed an SPKI-based CRLSet block for the six TLS-issuing keys.

    18 October 2026, by 09:38

    The eight intermediate certificates are recorded as revoked for CA compromise.

    20 October 2026

    Mozilla publicly describes its response and publishes an NSS trust-store update removing the signing root for downstream users.

    26 October 2026

    eMudhra confirms a script error produced weak keys; its full root-cause analysis remains pending.

    Sources: Mozilla Bugzilla incident, Mozilla and Chrome root-program discussion, and eMudhra's incident statement.

    What is known and what is not

    The published inventory identifies eight affected certificates using P-384 keys. Chrome's response separates them into six TLS-issuing and two Code Signing intermediates; the Code Signing constraints did not permit Chrome to construct a TLS path through those two. The affected intermediates were created on 30 April 2025. eMudhra says a script error during a key wrap/unwrap step produced a second, weak set of keys alongside the intended strong keys, and the weak set was published. Chrome Root Program response eMudhra's 26 October update

    That is the current boundary of the confirmed root cause. As of 26 October, eMudhra says the exact mechanism is still under investigation and promises a full analysis through the CCADB process. Speculation about test vectors, reference files or HSM behavior should not be presented as settled fact. The confirmed failure is weak published intermediate keys; the precise code path that produced them remains pending.

    In Bugzilla comment 43, eMudhra also stated that it had decided to exit the public TLS business. That is eMudhra's own incident-response statement; it is not a regulator sanction, and it does not mean customer migration was complete on 26 October. The same comment says the full report was still being prepared. eMudhra statement in Bugzilla comment 43

    eMudhra says it had not issued publicly trusted end-entity certificates from the eight affected CAs before disclosure. Researchers later created certificates with recovered keys as proof and research activity; those post-disclosure certificates demonstrate that the signing capability was real, not that malicious exploitation occurred before disclosure. eMudhra incident statement Mozilla Bugzilla discussion

    Vulnerability Details

    From a public certificate to a signing capability

    A certificate is designed to publish its subject, issuer, validity period, permitted uses and public key. That normally reveals nothing practical about the private scalar. The eMudhra intermediates broke that assumption because the scalar space was extremely small. Anyone who obtained the public certificates could test candidate scalars offline, compare each derived public point with the certificate's public point, and stop on a match.

    Once recovered, the intermediate key carries the authority encoded in the certificate. For a TLS-capable intermediate, Mallory can generate a new leaf key, construct a certificate naming a service she does not own, and sign it with the recovered intermediate key. The forged leaf is not self-signed; it forms a cryptographically valid chain to the same root that a stale client already trusts.

    The following is a possible real-world abuse path, not the literal GhostTrust service topology:

    Possible real-world abuse path from weak intermediate key recovery to an accepted attacker response

    The diagram contains two different failures that must coincide. The CA failure gives Mallory a signing capability. The relying-party failure leaves the affected trust path usable. Neither one places Mallory on the network path, so DNS manipulation, a malicious proxy, BGP interference, gateway control or some equivalent active position is still required.

    Why a green lock can be the wrong answer

    Certificate validation answers a specific question: can the presented leaf be linked, under current policy, to an accepted trust anchor for the requested hostname? It does not independently know whether an intermediate key was generated safely. If the signature is mathematically correct and the affected intermediate is still accepted, the client can return “verification OK” even though an unauthorized party created the leaf.

    This distinction explains the urgency of root-program blocklists. Chrome says it blocked the SPKI hashes of all six TLS-issuing keys, covering both eMudhra-issued intermediates and Sectigo cross-certificates that shared those keys. Mozilla used OneCRL and then removed the relevant root from NSS for downstream consumers that do not receive Firefox's live protections. Chrome Root Program response Mozilla response

    The browser response and the client long tail

    Chrome reported an important negative finding: before its 17 October block, no TLS certificates chaining to the six intermediates had been logged to Certificate Transparency. Because default Chrome requires CT for roots in the Chrome Root Store, such an unlogged forged certificate would have been rejected. That substantially narrows the demonstrated browser impact; it does not prove that every non-browser client was safe.

    Command-line tools, embedded devices, application containers, language runtimes and applications can carry their own CA bundle, omit CT enforcement, or handle revocation differently. Updating a desktop browser does not update a CA file baked into an old image. The public remediation tracker documents this distributed patch problem across operating systems, bundles, runtimes and libraries. client-remediation tracker

    Exploitability Analysis

    What the evidence establishes

    The public attestations establish recovery of the eight intermediate signing keys. The inventory and root-program responses establish that six keys were associated with TLS-issuing intermediates and two with Code Signing intermediates. This is a real signing primitive, not merely a malformed-certificate observation.

    Impact versus evidence

    Statement

    Classification

    What the record supports

    Eight intermediate signing keys were recoverable

    Confirmed fact

    Wayne's signed attestations and independent Mozilla recovery established control of the keys

    Six keys could issue TLS chains; two were Code Signing constrained

    Confirmed fact

    Chrome's root-program response distinguishes the two certificate classes

    An unauthorized certificate can support TLS service impersonation

    Realistic conditional impact

    The attacker must also control the network path, choose a valid hostname and reach a client that still accepts the affected chain

    GhostTrust's stale connector accepted an attacker-controlled APPROVED response while the separately queried genuine origin returned HOLD

    Confirmed lab-only result

    The supplied transcript records the synthetic legacy connector accepting APPROVED while the genuine origin returned HOLD

    The weak keys were maliciously exploited before disclosure

    Not demonstrated

    eMudhra reports no evidence of pre-disclosure recovery or exploitation; the public record does not prove an unseen attempt was impossible

    Root keys, P-384 or TLS itself were broken

    Non-claim

    The reported compromise concerned intermediate keys generated with tiny scalar values, not a cryptanalytic break of the curve or protocol

    Recorded TLS sessions can now be passively decrypted

    Non-claim

    An intermediate CA signing key enables certificate issuance; it is not the session secret or a server's historical leaf private key

    For TLS impersonation, Mallory still needs all of the following:

    1. A recoverable TLS intermediate key. The six TLS-capable keys satisfy this condition; Code Signing constraints do not automatically become TLS authority.

    2. An active network position. Mallory must cause Alice's connection to reach Mallory's endpoint or otherwise intercept and terminate it.

    3. A client that still accepts the affected path. A current browser with the emergency block and CT enforcement is a different target from a stale service using a bundled CA file.

    4. A matching leaf certificate. The certificate must satisfy hostname and relevant usage checks.

    5. A useful application exchange. Mallory can only read or modify traffic that the intercepted client sends through the impersonated endpoint.

    Under those conditions, the plausible impact includes service impersonation, credential capture, malicious update or API responses, and modification of application data in transit. The concrete GhostTrust result is narrower: one synthetic bank connector accepts an attacker-controlled settlement decision that differs from the separate genuine-origin response.

    What this does not prove

    This incident should not be described as passive decryption. Eve, a passive observer with packet captures, does not gain historical plaintext simply because an intermediate signing key becomes known. Modern ephemeral TLS key exchange is not reversed by possession of a CA signing key.

    It also does not prove:

    • compromise of an eMudhra root private key;

    • compromise of eMudhra infrastructure or customer data;

    • prior malicious exploitation of the weak keys;

    • universal exposure of browsers after the emergency blocks;

    • a flaw in the P-384 curve, OpenSSL or TLS itself;

    • that every application trusting an eMudhra root would accept every affected chain; or

    • that certificate possession alone supplies DNS, routing or proxy control.

    eMudhra says the affected intermediates had not issued publicly trusted end-entity certificates before disclosure and that it found no compromise of infrastructure or customer data. Chrome's CT review found no pre-block entries chaining to the six TLS intermediates. Those are meaningful negative findings, while not being a proof about unlogged, non-CT clients. eMudhra's 26 October update Chrome Root Program response

    Detection: find trust that outlived the incident

    Defenders should start with the exact affected-certificate fingerprints and SPKI values in the published JSON inventory, then answer where those chains can still validate.

    Useful checks include:

    • inventory OS, runtime, application, container, proxy and appliance trust stores separately;

    • identify images or binaries that embed their own CA bundle rather than using the host store;

    • compare bundle versions with the relevant vendor's patched release;

    • test whether revocation is checked for intermediates, not only leaf certificates;

    • inspect outbound TLS telemetry for affected issuer names, certificate fingerprints or SPKI hashes;

    • search certificate inventories and CT monitoring for unexpected leaves chaining to the affected keys, while remembering that absence from CT does not clear non-CT traffic; and

    • verify that emergency distrust reaches long-lived workloads after rebuild and redeployment, not merely the build host.

    The question is not just “did we patch Chrome?” It is “which TLS verifier made this connection, and which trust state did that verifier actually load?”

    Lab-value clarification: The private scalar 173 is an intentionally selected fictional value used only in GhostTrust. It is not an eMudhra private-key value. The real incident involved eight weak intermediate CA keys, six TLS-issuing and two Code Signing whose private scalars were reportedly below 256; the lab reproduces this vulnerability class without using real compromised key material.

    Proof of Concept

    GHOSTTRUST LAB  synthetic training evidence. This walkthrough uses only the fictional GhostTrust target and the supplied Kali desktop. It does not recover or distribute a real eMudhra key, contact eMudhra, or test a real bank.

    Screenshot provenance. Every image in this walkthrough is a curated lab-manual illustration captured from the synthetic GhostTrust environment. The screenshots are not raw evidence from the public eMudhra incident and should not be interpreted as such.

    Overview

    The 2026 eMudhra certificate incident involved intermediate CA private keys whose values had catastrophically low entropy. Public reporting described P-384 private values small enough to recover by testing only the candidate range 1..255. Control of a TLS-issuing intermediate key whose constraints permit server authentication can allow an attacker to issue unauthorized TLS certificates for sites they do not control.

    This lab safely recreates the same vulnerability class and exploitation mechanism with fictional certificates, domains, organizations, and banking records. The target is one standalone container, while you work from the separately provided Kali GUI.

    Task

    Investigate Meridian Bank’s settlement-verification path. Recover the weak private scalar belonging to the supplied fictional intermediate CA certificate, issue a certificate for the lab clearing hostname, demonstrate that the legacy connector accepts a response from the simulated attacker endpoint, and verify that the patched connector rejects the same certificate chain.

    Objective

    By completing the exercise, you will demonstrate:

    • recovery of an extremely low-entropy P-384 private scalar;

    • unauthorized leaf-certificate issuance from a compromised intermediate;

    • TLS impersonation in a simulated, preconfigured attacker position;

    • acceptance of attacker-controlled business data despite successful TLS validation; and

    • mitigation through an updated trust policy.

    How the simulated scenario works

    The standalone target contains several logical services on one IP. The lab’s configured routing places a synthetic clearing gateway in the bank application’s clearing path. After the student-generated certificate is installed, that gateway presents the unauthorized chain and returns its own controlled settlement response.

    The genuine origin is a separate comparison endpoint. The gateway does not transparently fetch, decrypt, modify, or re-encrypt the genuine origin’s traffic. The exercise proves unauthorized certificate issuance, acceptance of an impersonating endpoint, and the security difference between stale and patched trust policies. It does not independently create or demonstrate a real network interception position.

    Lab Scenario

    The diagram below shows the complete GhostTrust workflow. The student first recovers the deliberately weak private scalar associated with the fictional Atlas intermediate CA. That recovered signing key is then used to issue an unauthorized TLS certificate for clearing.meridian-bank.local, which is installed on the simulated attacker gateway.

    The Meridian Bank application is already configured to contact this gateway for settlement verification. Its legacy connector accepts the unauthorized certificate because the stale trust bundle still contains the Atlas root. The gateway can therefore return attacker-controlled settlement data through a TLS connection that validates successfully. The patched connector removes the Atlas authority from its trust policy and rejects the same certificate chain.

    The genuine clearing origin is provided only as a comparison endpoint. The simulated gateway does not fetch, intercept, decrypt, modify, relay, or re-encrypt traffic from the genuine origin.

    Complete GhostTrust attack and validation workflow

    Diagram-label clarification. The tested standalone lab uses clearing-origin.local for the separate genuine comparison endpoint, and the simulated gateway returns the decision APPROVED. The labels clearing.meridian-bank.local and SETTLED in this supplied overview graphic are schematic; the commands, captured outputs and written walkthrough below are authoritative.

    Solution

    Step 1: Start from the provided Kali GUI

    Use the Kali desktop supplied by the lab platform. Do not SSH into Kali. The target names have already been mapped to the single target IP, so do not edit /etc/hosts.

    Provided Kali GUI desktop

    Open a terminal and confirm the four names resolve to the same target address:

    getent hosts meridian-bank.local
    getent hosts clearing.meridian-bank.local
    getent hosts clearing-origin.local
    getent hosts gateway-status.local

    All four GhostTrust hostnames resolving to one target IP

    Using one IP is intentional. The standalone target separates its logical services through HTTP host names and TLS Server Name Indication (SNI).

    Step 2: Download the student evidence kit

    Create a working directory and retrieve the kit directly from the target:

    mkdir -p ~/ghosttrust-lab
    cd ~/ghosttrust-lab
    curl -fsS http://gateway-status.local:8080/lab/lab-kit.tar.gz | tar -xz
    find . -maxdepth 2 -type f | sort

    Downloading and extracting the GhostTrust student kit

    lab-kit.tar.gz is the downloadable student-material bundle for the fictional GhostTrust exercise. The target serves it over port 8080 so every student receives the same public evidence, trust policies, and restricted helper scripts. The archive is not a running service and downloading or extracting it does not exploit the target.

    The archive contains:

    • README.txt   summarizes the fictional endpoints, starting workflow, and safety boundary.

    • evidence/atlas-root.crt   the fictional Atlas root CA certificate used to understand the affected trust hierarchy.

    • evidence/atlas-weak-intermediate.crt   the public P-384 intermediate CA certificate audited in the lab. It contains the public key, not the private scalar.

    • trust/legacy-trust.pem   the stale trust bundle containing both the fictional Meridian and Atlas roots. After the controlled certificate installation, this bundle accepts the student-generated Atlas chain.

    • trust/meridian-root.crt   the fictional Meridian root used by curl to authenticate the genuine clearing-origin.local endpoint.

    • trust/patched-trust.pem   the updated trust bundle containing only the Meridian root. Atlas has been removed, so the same student-generated chain is rejected.

    • recover_weak_key.py   an offline helper that tests the deliberately restricted scalar range 1..255 against the public point in atlas-weak-intermediate.crt. When it finds the matching lab value, it creates recovered-intermediate.key locally.

    • forge_lab_certificate.py   a restricted helper hard-coded to issue only for clearing.meridian-bank.local. It creates artifacts/forged-leaf.pem, artifacts/forged-fullchain.pem, and artifacts/forged-key.pem, then sends the chain and leaf key to the lab-only /install endpoint.

    The following files are generated while the student performs the exercise; they are not shipped inside the archive:

    • recovered-intermediate.key   the recovered fictional intermediate private key; and

    • artifacts/forged-leaf.pem, artifacts/forged-fullchain.pem, and artifacts/forged-key.pem   the fictional leaf certificate, complete presented chain, and matching leaf private key.

    The kit contains no real CA material, real compromised private key, packet capture, eMudhra certificate, or real bank data. It is lab scaffolding, not the vulnerability itself. The result is demonstrated only after the controlled recovery, issuance, installation, legacy-validation, and patched-rejection steps are completed inside GhostTrust.

    Confirm the required Python library is available:

    python3 -c "import cryptography; print(cryptography.__version__)"

    Confirming the installed Python cryptography library

    This one-line Python command only imports the required library and prints its installed version. It is a dependency check; it does not contact or exploit the target.

    Step 3: Inspect the Meridian Bank application

    Open Firefox and visit:

    http://meridian-bank.local/

    The portal shows a pending transfer with reference MB-20481, beneficiary ACME-SUPPLIES, and amount $48,750.00. It also reveals that the clearing connector uses a legacy trust bundle whose last refresh was 28 days ago.

    Meridian Bank treasury portal

    The browser-facing portal uses HTTP in this standalone package so it does not require changes to the platform’s Kali trust store. The security exercise concerns the bank application’s authenticated outbound TLS connection to the clearing service.

    Step 4: Enumerate the standalone target

    Scan the relevant ports:

    nmap -Pn -sT --version-light -p 80,443,8080 meridian-bank.local

    Nmap enumeration of ports 80, 443, and 8080

    The ports represent:

    • 80/tcp   bank portal and application API;

    • 443/tcp   SNI-routed bank, clearing gateway, and genuine origin endpoints; and

    • 8080/tcp   lab-kit and target-status service.

    Check the clean gateway state:

    curl -sS http://gateway-status.local:8080/status | jq .

    Clean gateway status before certificate installation

    forged_material_present should be false and certificate_profile should be untrusted-bootstrap.

    Step 5: Establish the clean TLS behavior

    Ask the bank’s legacy connector to validate the transfer:

    curl -sS "http://meridian-bank.local/api/transfer-preview?mode=legacy" | jq .

    Legacy connector failing against the bootstrap certificate

    The gateway is in the application’s configured path, but its bootstrap certificate cannot chain to a root in the legacy trust bundle. Network position alone is therefore insufficient.

    Step 6: Inspect the weak intermediate

    Inspect the fictional certificate identity:

    openssl x509 \
      -in evidence/atlas-weak-intermediate.crt \
      -noout -subject -issuer -serial -dates

    Identity and validity details of the fictional intermediate certificate

    Inspect its key type and CA extensions:

    openssl x509 \
      -in evidence/atlas-weak-intermediate.crt \
      -noout -text | \
      grep -E "Public Key Algorithm|ASN1 OID|CA:TRUE|Key Usage"

    P-384 algorithm and CA extensions in the fictional intermediate certificate

    The certificate uses P-384 (secp384r1) and has CA:TRUE. For an elliptic-curve key, the public point is Q = dG, where d is the private scalar. A correctly generated P-384 scalar has an enormous candidate space. In this exercise, d is known to be between 1 and 255, making direct comparison practical.

    Step 7: Recover the private scalar

    Run the supplied audit helper:

    How the recovery script works

    recover_weak_key.py reads the public P-384 point from the supplied intermediate certificate. It derives a public point for every candidate scalar from 1 through 255 and compares each result with the certificate’s public key. When the points match, the corresponding scalar is written locally as recovered-intermediate.key.

    This operation is performed entirely offline and does not modify any target service.

    Recovery of the deliberately weak P-384 private scalar

    python3 recover_weak_key.py

    Recovering the deliberately weak private scalar

    What recover_weak_key.py does and why

    This is a supplied cryptographic audit helper, not a programming exercise. It works entirely offline against the fictional certificate:

    1. It opens evidence/atlas-weak-intermediate.crt and extracts the P-384 public point Q. A certificate contains this public value; it does not contain the private scalar.

    2. It tests the deliberately restricted lab range 1..255. In Python, range(1, 256) includes 1 and stops before 256, so exactly 255 candidates are tested.

    3. For each candidate scalar d, the cryptography library derives the corresponding public point dG on the secp384r1 curve.

    4. It compares that candidate point with Q. An exact coordinate match means the candidate belongs to the certificate’s public key.

    5. When candidate 173 matches, the helper serializes it as an unencrypted PKCS#8 PEM file named recovered-intermediate.key and restricts the file to mode 0600. If no candidate matches, the script exits without producing a key.

    The recovered intermediate key is needed for the next step because it supplies the fictional CA signing authority used to issue the unauthorized leaf certificate. This works only because the exercise deliberately limits the search to 255 known candidates. It is not extraction of a secret field from the certificate, an ECDSA nonce attack, a general elliptic-curve attack, or a break of P-384.

    Confirm that the recovered key matches the certificate public key:

    openssl pkey -in recovered-intermediate.key -pubout -outform DER | sha256sum
    openssl x509 -in evidence/atlas-weak-intermediate.crt -pubkey -noout | \
      openssl pkey -pubin -outform DER | sha256sum

    The first command derives the public key from recovered-intermediate.key. The second extracts the public key embedded in the certificate. Both are normalized to DER before SHA-256 hashing. Matching hashes show that the two public keys are byte-for-byte identical, confirming that the recovered private key corresponds to the certificate without displaying the private scalar itself.

    Step 8: Issue, inspect, and install the lab certificate

    The kit was extracted directly into ~/ghosttrust-lab, so the forging helper is located at ~/ghosttrust-lab/forge_lab_certificate.py. Run it from the extracted kit directory:

    cd ~/ghosttrust-lab
    python3 forge_lab_certificate.py

    How certificate forging and installation work

    forge_lab_certificate.py generates a new leaf key pair and constructs a TLS server certificate restricted to clearing.meridian-bank.local. It signs that certificate using the recovered fictional intermediate key.

    The helper creates the leaf certificate, the presented certificate chain, and the matching leaf private key. It then uploads the full chain and leaf key to the lab-only /install endpoint. After installation, the simulated gateway can present the unauthorized chain during a TLS handshake for the clearing hostname.

    Issuing and installing the unauthorized lab certificate

    Issuing and installing the restricted GhostTrust leaf certificate

    What forge_lab_certificate.py does and why

    This second supplied helper demonstrates what possession of the fictional intermediate signing key permits. Students run it as provided; they do not need to write or modify Python code.

    The helper loads the Atlas intermediate certificate and recovered-intermediate.key, generates a fresh P-384 private key for the server, and builds a 30-day leaf certificate restricted to clearing.meridian-bank.local. The leaf is marked CA:FALSE, contains that exact DNS Subject Alternative Name, includes TLS server-authentication usage, receives a random serial number, and is signed by the recovered intermediate key using SHA-384.

    It then writes the leaf certificate, the presented leaf-plus-intermediate chain, and the new leaf private key beneath artifacts/. Finally, it sends the chain and matching leaf key to the lab-only /install endpoint so the disposable target can present them on the next TLS handshake for the clearing SNI hostname.

    The /install endpoint is exercise orchestration not the real vulnerability. It does not recover a key, create a network interception position, contact the genuine origin, or proxy its traffic. Its only purpose is to activate the student-generated identity inside this controlled target so the legacy and patched verification policies can be compared.

    The certificate construction happens on Kali. On the target, the installation endpoint checks that the uploaded certificate and private key can be loaded as a pair and that the certificate’s DNS SAN is exactly clearing.meridian-bank.local. It then stores that material in the lab’s temporary state. For a new TLS connection using that SNI hostname, the clearing service selects the installed certificate instead of the bootstrap certificate. The /install endpoint does not decide whether the chain is trusted; that decision is made later by the bank connector using either the legacy or patched CA bundle.

    The helper is hard-coded to issue only for clearing.meridian-bank.local. It creates these runtime files beneath the extracted kit:

    • artifacts/forged-leaf.pem - the generated server certificate;

    • artifacts/forged-fullchain.pem - the leaf followed by the fictional Atlas intermediate; and

    • artifacts/forged-key.pem - the matching leaf private key, stored with mode 0600.

    Inspect the generated leaf certificate before testing it:

    openssl x509 \
      -in artifacts/forged-leaf.pem \
      -noout -subject -issuer -serial -dates -ext subjectAltName

    Subject issuer validity and SAN of the generated leaf certificate

    Confirm that the subject identifies the fictional clearing service, the issuer is Atlas DV TLS CA - G3B, and the Subject Alternative Name contains DNS:clearing.meridian-bank.local.

    The helper defines BASE = Path(__file__).resolve().parent, so it resolves every path from the directory containing the script not from an arbitrary shell working directory. It reads evidence/atlas-weak-intermediate.crt and recovered-intermediate.key beside the script, creates artifacts/ beside the script, and then POSTs the full chain and leaf key to the lab-only http://gateway-status.local:8080/install endpoint.

    Standalone path warning: Do not use student-kit/ or drop/ in this student workflow. Those names belong to the source-delivery layout and the older multi-container range. The archive downloaded from the standalone target extracts forge_lab_certificate.py, recover_weak_key.py, evidence/, and trust/ directly into ~/ghosttrust-lab.

    Verify the clearing endpoint through the legacy trust bundle:

    openssl s_client \
      -connect clearing.meridian-bank.local:443 \
      -servername clearing.meridian-bank.local \
      -CAfile trust/legacy-trust.pem \
      -verify_return_error </dev/null 2>/dev/null | \
      grep -E "subject=|issuer=|Verification"

    Legacy trust bundle accepting the unauthorized certificate chain

    Verification: OK confirms that the unauthorized leaf is valid according to the stale trust policy.

    Why the legacy and patched results differ

    Both connectors receive the same server name, forged leaf certificate, intermediate certificate, and gateway-controlled response. The difference is their trust policy.

    The legacy bundle still contains the fictional Atlas root, allowing the forged leaf to build a trusted path through the compromised intermediate. TLS validation succeeds, and the application consumes the gateway-controlled business response. The patched bundle contains only the Meridian root. Because the Atlas chain can no longer reach a trusted root, certificate validation fails and the response is blocked.

    The genuine clearing origin remains a separate comparison endpoint and is authenticated using the fictional Meridian root.

    Legacy acceptance and patched rejection of the same certificate chain

    Diagram-label clarification. In the captured lab response, the legacy connector accepts the gateway-controlled decision APPROVED; SETTLED in this supplied conceptual graphic is shorthand for the attacker-controlled settlement outcome.

    Step 9: Compare the genuine and attacker-controlled responses

    Query the genuine clearing origin using its fictional Meridian root:

    curl -sS --cacert trust/meridian-root.crt \
      "https://clearing-origin.local/v1/validate?reference=MB-20481&beneficiary=ACME-SUPPLIES&amount=48750.00" | jq .

    Genuine clearing origin returning the HOLD decision

    The genuine origin returns beneficiary ACME-SUPPLIES, decision HOLD, fraud score 87, and intercepted: false.

    Now repeat the bank’s legacy verification:

    curl -sS "http://meridian-bank.local/api/transfer-preview?mode=legacy" | jq .

    Legacy connector accepting the simulated attacker response

    The response accepted from the simulated gateway contains beneficiary HARBOR-CONSULTING-8821, decision APPROVED, fraud score 3, and intercepted: true. These values differ from the independently queried genuine origin. The intercepted field is an explicit lab marker; it is not evidence that the gateway transparently proxied and modified the genuine origin response.

    Record the first flag:

    LAB{a_valid_chain_can_still_be_untrustworthy}

    TLS encryption still operated. The failure was authentication: the reconstructed intermediate key allowed the simulated gateway to present a chain accepted by the stale client, after which the client consumed content supplied by that impersonating endpoint.

    Step 10: Verify the patched trust policy

    Send the same request through the patched connector:

    curl -sS "http://meridian-bank.local/api/transfer-preview?mode=patched" | jq .

    Patched connector rejecting the unauthorized Atlas chain

    The patched trust bundle excludes the fictional Atlas authority, so the certificate path fails. Record the second flag:

    LAB{every_tls_client_needs_revocation_updates}

    Step 11: Review the audit trail

    curl -sS http://meridian-bank.local/api/audit | jq .

    Audit trail containing the clean failure legacy acceptance and patched rejection

    The events show the clean blocked request, the accepted legacy request after certificate installation, and the patched rejection. The same events can be viewed from the portal.

    Step 12: Connect the lab to real remediation work

    The real incident required action in more places than browsers. An application might verify certificates through its operating system, a language runtime, a bundled CA file, a container base image, a proxy, an SDK, or custom code. Updating one verifier does not update all the others.

    A defensible response should include:

    1. Distrust the affected intermediate keys or issuing hierarchy in every active verification path, using the narrowest reliable control available.

    2. Update shared trust stores, language and runtime CA bundles, container base images, VPN clients, proxies, API clients, and embedded systems.

    3. Reload, restart, rebuild, or redeploy applications so the new policy is actually active.

    4. Test the application's real TLS path; a successful browser or unrelated curl test does not prove that another verifier is protected.

    5. Monitor Certificate Transparency and other available issuance telemetry for unauthorized certificates.

    6. Replace affected certificates and keys where required, and investigate whether interception occurred.

    7. Never work around new certificate errors by disabling verification.

    Summary

    You enumerated one standalone target image containing several realistic logical services. You retrieved only public evidence, recovered a deliberately weak P-384 intermediate private scalar, issued a lab-restricted clearing certificate, and proved that a stale application verifier accepted it.

    The legacy path consumed an attacker-controlled banking decision even though TLS verification succeeded. The patched path rejected the same certificate after the affected authority was removed from its trust policy. The lab does not implement transparent interception of the genuine origin; it demonstrates acceptance of an impersonating endpoint under a stale trust policy. This shows why CA-key compromise response must reach every browser, operating system, language runtime, application bundle, container image, proxy, and embedded verifier that authenticates TLS endpoints.

    References

    Remediation

    For relying parties: distrust must reach the process that verifies TLS

    Revocation is useful only when the verifier that makes the connection actually obtains and enforces it. A response plan therefore has to follow the trust decision into every application, not stop at the browser or operating-system update.

    1. Apply vendor emergency updates and rebuild workloads with current trust bundles.

    2. Block affected SPKI hashes where supported. Because an SPKI block follows the key, it also covers cross-signed certificates that reuse that key the property Chrome relied on in its CRLSet response.

    3. Verify that revocation processing checks intermediate CAs, not only leaf certificates, and understand whether the application fails closed when revocation data is unavailable.

    4. Inventory independent and bundled stores in containers, language runtimes, appliances, proxies and long-lived processes; a host update does not automatically replace them.

    5. Remove the affected root only where a narrower block is unavailable and the resulting availability impact has been assessed.

    6. Enforce Certificate Transparency for public WebPKI use where the client ecosystem supports it.

    7. Retest the exact application connection after deployment. A successful browser test on the same machine does not prove that the application loaded the same trust state.

    Chrome's SPKI block and Mozilla's OneCRL response illustrate fast centralized controls. Their root-store changes addressed downstream consumers that did not receive those live blocklists. Chrome and Mozilla response thread

    For certificate authorities: verify what was generated, not what the ceremony expected

    The key-generation process needs controls that survive script and wrap/unwrap mistakes:

    • validate every generated public key for known weak-key classes before certificate issuance and publication;

    • independently verify that the public key certified is the key pair intended by the ceremony;

    • test wrap/unwrap and backup/restore steps as security-critical code paths;

    • require two-person review and durable audit evidence for deviations from the approved ceremony procedure;

    • continuously scan all disclosed CA certificates, not only roots, with tools such as paranoid_crypto or an actively maintained equivalent;

    • compare CRL and OCSP signing behavior with the certified keys; and

    • rehearse emergency intermediate distrust across root programs and downstream trust-store consumers.

    These are remediation principles, not a claim that eMudhra has completed them. As of 26 October, eMudhra says its full root-cause analysis and independent review are still pending. eMudhra incident statement

    Regression tests for GhostTrust

    For the training target, the meaningful regression sequence is:

    • bootstrap certificate is rejected;

    • scalar recovery matches the fictional intermediate public key;

    • the legacy bundle accepts the forged lab chain;

    • the genuine and attacker-generated business responses differ;

    • the patched bundle rejects the same chain; and

    • reset removes the forged material and clears state.

    The lab should keep the exact-SAN restriction on /install and its fictional trust hierarchy. Expanding that endpoint would not improve fidelity; it would only broaden the training tool beyond its stated safety boundary.

    Summary

    The eMudhra incident was a failure of intermediate CA key generation, not a break in TLS or elliptic-curve cryptography. Wayne's publicly documented CCADB scan found recoverable keys on 17 October 2026; signed attestations established control, root programs reacted quickly, and eMudhra revoked the eight intermediates. Chrome classified six as TLS-issuing and two as Code Signing, while confirming that the root private keys were not the compromised material. eMudhra now attributes the weak published keys to a script error around a wrap/unwrap step, but its exact root-cause analysis remains pending as of 26 October.

    The potential TLS impact is serious but conditional: Mallory needs both an active network position and a client that still accepts the affected chain. That combination can turn a cryptographically valid connection into authenticated communication with the wrong endpoint. It cannot retroactively decrypt captured sessions, and the evidence does not establish malicious exploitation before disclosure.

    GhostTrust makes that narrow mechanism visible with fictional material. It recovers synthetic scalar 173, signs a leaf for a fictional clearing hostname, shows Verification: OK under a stale bundle, records acceptance of a different attacker-controlled settlement decision, and then shows the patched client rejecting the same chain. The most important operational lesson is simple: encryption can remain mathematically sound while authentication fails because the client's trust state is stale. A root-program response protects only the clients that receive and enforce it. Incident response is complete only after the exact verifier making the real application connection has loaded a trust policy that rejects the compromised authority.

    References

    Explore Training on INE at https://my.ine.com/

    Share this post with your network

    twitter Logofacebook Logolinkedin Logowhatsapp Logoemail Logo
    © 2026 INE. All Rights Reserved. All logos, trademarks and registered trademarks are the property of their respective owners.
    instagram Logofacebook Logox Logolinkedin Logoyoutube Logo