PKI & Certificates for Pentesters
TL;DR: PKI is the trust infrastructure that makes HTTPS work. Certificates prove identity using cryptographic signatures. Misconfigurations and attacks against PKI can lead to MITM, impersonation, and data theft.
Table of Contents
Open Table of Contents
Quick Reference
Essential Commands
| Command | Purpose | Example |
|---|
openssl s_client | Connect and view cert | openssl s_client -connect host:443 |
openssl x509 | Parse certificate | openssl x509 -in cert.pem -text |
openssl verify | Verify cert chain | openssl verify -CAfile ca.pem cert.pem |
openssl req | Create CSR | openssl req -new -key key.pem -out csr.pem |
certutil (Windows) | Certificate operations | certutil -dump cert.pem |
Certificate Validation Checks
| Check | What It Verifies | Failure = |
|---|
| Chain of Trust | Signed by trusted CA | Untrusted certificate |
| Expiration | Not Before/After dates | Expired/not yet valid |
| Hostname | CN or SAN matches | Wrong certificate |
| Revocation | CRL or OCSP status | Certificate revoked |
| Key Usage | Allowed operations | Invalid use |
| Signature | Cryptographic validity | Tampered certificate |
Common Certificate Ports
| Port | Protocol | Certificate Use |
|---|
| 443 | HTTPS | Web server authentication |
| 636 | LDAPS | LDAP over TLS |
| 993 | IMAPS | Email over TLS |
| 995 | POP3S | Email over TLS |
| 8443 | HTTPS-alt | Alternative web |
| 3389 | RDP | Remote desktop (optional) |
Why PKI Matters for Pentesters
Security Impact
PKI provides three critical security properties:
| Property | How PKI Provides It | Attack If Broken |
|---|
| Authentication | Certificates prove identity | Impersonation |
| Confidentiality | Public key encryption | Eavesdropping |
| Integrity | Digital signatures | Data tampering |
Real-World PKI Breaches
| Incident | What Happened | Impact |
|---|
| DigiNotar (2011) | CA compromise, fake certs | Iranian surveillance |
| Comodo (2011) | RA breach, fake certs | Google, Yahoo impersonation |
| Symantec (2017) | Improper validation | Browsers distrust |
| Let’s Encrypt (2020) | Bug in issuance | 3M certs revoked |
| Kazakhstan (2020) | Govt-mandated root CA | National MITM capability |
What Pentesters Test
- Certificate validation - Does client properly verify?
- Trust boundaries - Are internal CAs trusted externally?
- Expired/weak certs - Old or misconfigured certificates
- Pinning bypass - Can we intercept pinned connections?
- Private key exposure - Keys in source code, backups
- CT monitoring - Are all issued certs visible?
How PKI Works
TL;DR: PKI uses asymmetric cryptography and trusted third parties (CAs) to establish identity without prior relationship.
The Trust Problem
Without PKI:
┌─────────┐ "I'm really bank.com" ┌─────────┐
│ User │ ◄────────────────────────────────────►│ Attacker│
│ │ How do you verify? │ │
└─────────┘ └─────────┘
With PKI:
┌─────────┐ ┌─────────┐
│ User │◄──────── Certificate ─────────────────│ Server │
│ │ Signed by DigiCert CA │ │
└────┬────┘ └─────────┘
│
│ Verifies signature using
│ DigiCert public key
│ (already trusted in browser)
▼
┌─────────────────────────────────────────────────────────────┐
│ "This certificate is valid and signed by a trusted CA" │
│ "The server is really bank.com" │
└─────────────────────────────────────────────────────────────┘
PKI Components
| Component | Role | Example |
|---|
| Certificate Authority (CA) | Issues and signs certificates | DigiCert, Let’s Encrypt |
| Registration Authority (RA) | Verifies identity before issuance | Part of CA |
| Certificate | Binds identity to public key | X.509 certificate |
| Certificate Revocation | Invalidates compromised certs | CRL, OCSP |
| Trust Store | Pre-trusted root CA certificates | Browser/OS trust store |
PKI Operation Flow
1. Server generates key pair
┌──────────┐
│ Server │ ──► Private Key (keep secret!)
│ │ ──► Public Key
└──────────┘
2. Server creates Certificate Signing Request (CSR)
┌──────────┐ CSR contains:
│ Server │ ──► - Public Key
│ │ - Organization info
└──────────┘ - Domain name
3. CA verifies and issues certificate
┌──────────┐ ┌──────────┐
│ Server │ ──CSR──►│ CA │
│ │◄─Cert───│ │
└──────────┘ └──────────┘
4. Server uses certificate
┌──────────┐ ┌──────────┐
│ Client │◄─Cert───│ Server │
│ │ │ │
└──────────┘ └──────────┘
│
▼ Validates against trusted CAs
Certificate Authority Hierarchy
TL;DR: CAs are organized in a hierarchy. Root CAs sign intermediate CAs, which sign end-entity certificates.
CA Chain Structure
┌───────────────────────────────────────────────────────────────┐
│ ROOT CA │
│ (Self-signed, offline) │
│ │
│ Subject: CN=DigiCert Global Root G2 │
│ Issuer: CN=DigiCert Global Root G2 (same = self-signed) │
│ Validity: 25 years │
│ │
│ Location: Browser/OS trust store │
└───────────────────────────┬───────────────────────────────────┘
│ Signs
▼
┌───────────────────────────────────────────────────────────────┐
│ INTERMEDIATE CA │
│ (Signed by Root, online) │
│ │
│ Subject: CN=DigiCert SHA2 Extended Validation Server CA │
│ Issuer: CN=DigiCert Global Root G2 │
│ Validity: 10 years │
│ │
│ Location: Sent by server in TLS handshake │
└───────────────────────────┬───────────────────────────────────┘
│ Signs
▼
┌───────────────────────────────────────────────────────────────┐
│ END-ENTITY CERT │
│ (The actual server certificate) │
│ │
│ Subject: CN=www.example.com │
│ Issuer: CN=DigiCert SHA2 Extended Validation Server CA │
│ Validity: 1-2 years │
│ │
│ Location: Server │
└───────────────────────────────────────────────────────────────┘
| Reason | Explanation |
|---|
| Security | Root stays offline, reducing compromise risk |
| Containment | Compromise of intermediate limits damage |
| Flexibility | Different intermediates for different purposes |
| Revocation | Can revoke intermediate without affecting root |
Chain Validation
Client receives certificate chain:
[End-Entity] ← [Intermediate] ← [Root in trust store]
Validation:
1. End-Entity signed by Intermediate? ✓
2. Intermediate signed by Root? ✓
3. Root in trust store? ✓
4. All dates valid? ✓
5. Hostname matches? ✓
6. Not revoked? ✓
Result: TRUSTED
X.509 Certificates Explained
TL;DR: X.509 is the standard format for digital certificates. Understanding the fields helps you identify misconfigurations.
Certificate Structure
┌─────────────────────────────────────────────────────────────────┐
│ X.509 Certificate │
├─────────────────────────────────────────────────────────────────┤
│ Version: 3 (0x2) │
│ │
│ Serial Number: 0a:bc:de:12:34:56:78:90 │
│ │
│ Signature Algorithm: sha256WithRSAEncryption │
│ │
│ Issuer: C=US, O=DigiCert Inc, CN=DigiCert SHA2 CA │
│ │
│ Validity: │
│ Not Before: Jan 1 00:00:00 2024 GMT │
│ Not After: Dec 31 23:59:59 2025 GMT │
│ │
│ Subject: C=US, ST=CA, L=SF, O=Example Inc, CN=www.example.com │
│ │
│ Subject Public Key Info: │
│ Public Key Algorithm: rsaEncryption │
│ RSA Public Key: (2048 bit) │
│ Modulus: 00:ab:cd:ef... │
│ Exponent: 65537 (0x10001) │
│ │
│ X509v3 Extensions: │
│ Basic Constraints: CA:FALSE │
│ Key Usage: Digital Signature, Key Encipherment │
│ Extended Key Usage: TLS Web Server Authentication │
│ Subject Alternative Name: │
│ DNS:www.example.com │
│ DNS:example.com │
│ DNS:*.example.com │
│ Authority Key Identifier: ... │
│ Subject Key Identifier: ... │
│ CRL Distribution Points: http://crl.digicert.com/... │
│ Authority Information Access: │
│ OCSP: http://ocsp.digicert.com │
│ CA Issuers: http://cacerts.digicert.com/... │
│ │
│ Signature Algorithm: sha256WithRSAEncryption │
│ Signature: 12:34:56:78:ab:cd:ef... │
└─────────────────────────────────────────────────────────────────┘
Key Fields Explained
| Field | Purpose | Pentester Interest |
|---|
| Serial Number | Unique identifier | Identify specific cert |
| Issuer | Who signed it | Verify trusted CA |
| Subject | Who it belongs to | Verify correct entity |
| Validity | Not Before/After | Check expiration |
| Public Key | Subject’s public key | Check key strength |
| SAN | Subject Alternative Names | All valid hostnames |
| Key Usage | Allowed operations | Certificate misuse |
| Basic Constraints | CA:TRUE/FALSE | Fake CA detection |
| CRL/OCSP | Revocation check URLs | Verify not revoked |
Subject Alternative Name (SAN)
Modern certificates use SAN for hostname validation:
Subject Alternative Name:
DNS:example.com
DNS:www.example.com
DNS:*.example.com <- Wildcard
DNS:mail.example.com
IP Address:93.184.216.34 <- IP can be in SAN
Important: CN (Common Name) is deprecated for hostname. SAN is required.
Certificate Validation Process
TL;DR: Clients validate certificates through a series of checks. Failures should reject the connection (but often don’t).
Validation Steps
┌─────────────────────────────────────────────────────────────────┐
│ Certificate Validation │
└─────────────────────────────────────────────────────────────────┘
│
┌───────────────────┴───────────────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ 1. Chain Valid? │ │ 4. Hostname OK? │
│ │ │ │
│ - Signatures OK │ │ - CN or SAN │
│ - Chain complete │ │ matches URL │
│ - Root trusted │ └────────┬─────────┘
└────────┬─────────┘ │
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ 2. Dates Valid? │ │ 5. Not Revoked? │
│ │ │ │
│ - Not Before │ │ - Check CRL │
│ - Not After │ │ - Check OCSP │
└────────┬─────────┘ └────────┬─────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ 3. Key Usage OK? │ │ 6. Constraints? │
│ │ │ │
│ - digitalSign │ │ - CA:FALSE for │
│ - keyEncipherment│ │ end-entity │
└────────┬─────────┘ └────────┬─────────┘
│ │
└──────────────┬───────────────────────┘
▼
┌──────────────────┐
│ All Passed? │
├──────────────────┤
│ YES → TRUSTED │
│ NO → REJECT │
└──────────────────┘
Common Validation Failures
| Failure | Error Message | Cause |
|---|
| Chain incomplete | Unable to verify | Missing intermediate |
| Untrusted root | Self-signed cert | Not in trust store |
| Expired | Certificate has expired | Past Not After date |
| Not yet valid | Certificate not yet valid | Before Not Before |
| Hostname mismatch | Hostname doesn’t match | Wrong cert or typo |
| Revoked | Certificate revoked | On CRL or OCSP revoked |
| Weak signature | Insecure algorithm | MD5 or SHA1 signature |
Certificate Types
By Validation Level
| Type | Validation | Visual Indicator | Use Case |
|---|
| DV (Domain Validated) | Domain ownership only | Padlock | Blogs, small sites |
| OV (Organization Validated) | Organization verified | Padlock | Business sites |
| EV (Extended Validation) | Extensive verification | Padlock (was green bar) | Banking, e-commerce |
By Scope
| Type | Covers | Example |
|---|
| Single Domain | One specific domain | www.example.com |
| Multi-Domain (SAN) | Multiple specific domains | www.example.com, api.example.com |
| Wildcard | One level of subdomains | *.example.com |
| Multi-Domain Wildcard | Multiple wildcards | *.example.com, *.example.org |
Wildcard Certificate Rules
Certificate: *.example.com
✓ Matches: www.example.com
✓ Matches: api.example.com
✓ Matches: mail.example.com
✗ Doesn't match: example.com (no subdomain)
✗ Doesn't match: sub.www.example.com (multi-level)
✗ Doesn't match: www.example.org (different domain)
By Purpose
| Type | Key Usage | Purpose |
|---|
| Server Auth | TLS Web Server Authentication | HTTPS servers |
| Client Auth | TLS Web Client Authentication | Client certificates |
| Code Signing | Code Signing | Software signatures |
| Email (S/MIME) | Email Protection | Encrypted email |
| CA Certificate | Certificate Sign, CRL Sign | Issuing certs |
| Format | Extension | Encoding | Contains |
|---|
| PEM | .pem, .crt, .cer | Base64 | Cert and/or key |
| DER | .der, .cer | Binary | Cert only |
| PKCS#7 | .p7b, .p7c | Base64/Binary | Cert chain (no key) |
| PKCS#12 | .pfx, .p12 | Binary | Cert + private key |
| JKS | .jks | Binary | Java keystore |
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiUMA0Gcx...
... base64 encoded data ...
Rw0NJsU9WRvYvN3MgBLjmgj/AAAAAA==
-----END CERTIFICATE-----
Conversion Commands
# PEM to DER
openssl x509 -in cert.pem -outform DER -out cert.der
# DER to PEM
openssl x509 -in cert.der -inform DER -outform PEM -out cert.pem
# PEM cert + key to PKCS#12
openssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pem -certfile ca.pem
# PKCS#12 to PEM
openssl pkcs12 -in cert.pfx -out cert.pem -nodes
# Extract private key from PKCS#12
openssl pkcs12 -in cert.pfx -nocerts -out key.pem
# Extract certificate from PKCS#12
openssl pkcs12 -in cert.pfx -clcerts -nokeys -out cert.pem
# View PKCS#7 certificates
openssl pkcs7 -in chain.p7b -print_certs
Common Misconfigurations
Testing Checklist
Misconfiguration Matrix
| Misconfiguration | Risk | Impact |
|---|
| Self-signed cert | High | MITM if client accepts |
| Expired cert | Medium | User warnings, MITM if bypassed |
| Missing intermediate | Medium | Validation failure |
| Weak key (<2048 bit) | High | Factorization attacks |
| SHA1 signature | Medium | Collision attacks |
| Wildcard overuse | Medium | Larger attack surface |
| Missing revocation | Low | Can’t revoke if compromised |
| Wrong hostname | Medium | Cert for wrong domain |
| Attack | Detect | Defend |
|---|
| Self-signed MITM | Check issuer | Reject self-signed |
| Expired cert exploitation | Monitor expiry | Auto-renewal (Let’s Encrypt) |
| Chain validation bypass | Test with curl —cacert | Send complete chain |
| Weak key factoring | Check key size | Use 2048+ bit keys |
Testing Commands
# === Check Certificate Details ===
# View certificate
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -text -noout
# Check expiration
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -dates
# Check subject and SANs
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -subject -ext subjectAltName
# Check key size
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -text | grep "Public-Key"
# Check signature algorithm
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -text | grep "Signature Algorithm"
# === Check Certificate Chain ===
# View full chain
openssl s_client -connect example.com:443 -showcerts
# Verify chain
openssl s_client -connect example.com:443 -verify 5
# === Check Revocation ===
# Get OCSP URL
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -ocsp_uri
# Check OCSP status
openssl s_client -connect example.com:443 -status 2>/dev/null | \
grep -A 20 "OCSP Response"
Certificate Attacks
1. Self-Signed Certificate MITM
If application accepts self-signed certificates, trivial MITM is possible.
Normal:
[Client] ◄──── Valid Cert (CA signed) ────► [Server]
Attack:
[Client] ◄── Self-Signed Cert ── [Attacker] ◄── Valid Cert ── [Server]
│
└── If client accepts, attacker decrypts all traffic
| Attack | Detect | Defend |
|---|
| Present self-signed cert | Check issuer is trusted CA | Reject self-signed |
| Use attacker CA | Verify CA in trust store | Certificate pinning |
| Exploit validation bypass | Log cert warnings | Proper validation |
Attack Commands
# Generate self-signed certificate
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \
-subj "/CN=www.target.com"
# Test if server accepts self-signed (as client)
curl -k https://api.target.com # -k ignores cert errors
# MITM with mitmproxy
mitmproxy --cert cert.pem
2. Null Byte Injection
Older implementations vulnerable to null bytes in CN/SAN.
Certificate CN: www.target.com\0.attacker.com
Vulnerable parser sees: www.target.com
CA validates: www.target.com\0.attacker.com (owned by attacker)
| Attack | Detect | Defend |
|---|
| Null byte in subject | Scan for \x00 in certs | Modern SSL libraries |
| Bypass hostname check | Log unusual certificates | Reject null bytes |
3. Certificate Confusion
Using certificate for wrong purpose.
Attack: Use code-signing cert for TLS server
Use email cert for server auth
Use CA cert for end-entity
If key usage not checked, impersonation possible.
| Attack | Detect | Defend |
|---|
| Wrong key usage | Check certificate purpose | Verify Extended Key Usage |
| CA cert as server cert | Check Basic Constraints | Reject CA:TRUE for servers |
4. Private Key Theft
Stolen private keys allow complete impersonation.
Common Exposure Points:
- Source code repositories
- Backup files
- Debug logs
- Configuration files
- Memory dumps
- Heartbleed exploitation
| Attack | Detect | Defend |
|---|
| Extract from source code | Scan repos for keys | Never commit keys |
| Memory extraction | Monitor for Heartbleed | Patch vulnerabilities |
| Backup theft | Audit backup security | Encrypt backups |
Detection Commands
# Search for private keys in directory
grep -r "BEGIN RSA PRIVATE KEY" /path/to/search
grep -r "BEGIN PRIVATE KEY" /path/to/search
grep -r "BEGIN EC PRIVATE KEY" /path/to/search
# Search git history
git log -p | grep -A 5 "BEGIN.*PRIVATE KEY"
# Using truffleHog
trufflehog git https://github.com/target/repo
# Using gitleaks
gitleaks detect --source=/path/to/repo
5. CA Compromise
If CA is compromised, all issued certificates are suspect.
Historical CA Compromises:
- DigiNotar (2011) - Complete compromise, 500+ fake certs
- Comodo (2011) - RA breach, 9 fake certs
- Symantec (2017) - Validation failures, distrust
| Attack | Detect | Defend |
|---|
| Issue fake certs | Certificate Transparency | Monitor CT logs |
| Modify CA systems | Audit CA operations | Multi-party controls |
| Social engineering CA | Verify cert ownership | Use CAA records |
6. OCSP Stapling Issues
If OCSP is not checked or stapled, revoked certs may be accepted.
Without OCSP Stapling:
[Client] ──── Check revocation ────► [OCSP Server]
│
May be blocked │
or slow │
▼
[Client] ◄──── "Still valid" or timeout ──┘
With OCSP Stapling:
[Server] ◄── Fresh OCSP response ── [OCSP Server]
│
└── Includes OCSP response in TLS handshake
│
[Client] ◄── Certificate + OCSP staple ── [Server]
| Attack | Detect | Defend |
|---|
| Use revoked cert | Check OCSP status | OCSP Must-Staple |
| Block OCSP checks | Monitor OCSP failures | Hard-fail on OCSP error |
Testing Commands
# Check OCSP stapling
openssl s_client -connect example.com:443 -status 2>/dev/null | \
grep -A 100 "OCSP Response"
# If empty, no stapling
# If present, check "Cert Status: good"
# Manual OCSP check
# 1. Get certificate
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -outform PEM > cert.pem
# 2. Get OCSP URL
openssl x509 -in cert.pem -noout -ocsp_uri
# 3. Query OCSP
openssl ocsp -issuer chain.pem -cert cert.pem \
-url http://ocsp.digicert.com -resp_text
Certificate Pinning
TL;DR: Pinning hardcodes expected certificate/key in client, preventing MITM even with fake CA-signed certs.
How Pinning Works
Without Pinning:
[Client] trusts any CA-signed cert
│
├── DigiCert CA? ✓ Trust
├── Let's Encrypt CA? ✓ Trust
└── Attacker's fake CA? ✓ Trust (if in trust store)
With Pinning:
[Client] only trusts specific cert/key
│
├── Expected certificate? ✓ Trust
├── Different valid cert? ✗ Reject
└── Attacker's cert? ✗ Reject
Pinning Types
| Type | What’s Pinned | Flexibility |
|---|
| Certificate Pin | Entire certificate | Must update pin on renewal |
| Public Key Pin | Subject Public Key Info | Survives cert renewal |
| CA Pin | Intermediate/Root CA | Only that CA can issue |
Pinning Implementations
| Platform | Method |
|---|
| iOS | Info.plist, URLSession |
| Android | Network Security Config |
| Web | Public-Key-Pins header (deprecated) |
| OkHttp | CertificatePinner |
| .NET | ServicePointManager |
Bypassing Certificate Pinning
For authorized testing, pinning bypass is often needed.
| Technique | Tool | Platform |
|---|
| Frida hooks | objection, frida-scripts | iOS, Android |
| Xposed modules | SSLUnpinning | Android |
| Proxy CA install | Burp, mitmproxy | All |
| Binary patching | apktool, Hopper | iOS, Android |
| Debug builds | - | Development |
Bypass Commands
# === Android ===
# Using Frida + objection
objection -g com.target.app explore
> android sslpinning disable
# Using Frida script
frida -U -f com.target.app -l universal-ssl-bypass.js
# Modify APK (network_security_config.xml)
apktool d app.apk
# Edit res/xml/network_security_config.xml
# Add: <certificates src="user"/>
apktool b app -o app-modified.apk
jarsigner -keystore debug.keystore app-modified.apk androiddebugkey
# === iOS ===
# Using objection
objection -g com.target.app explore
> ios sslpinning disable
# Using SSL Kill Switch 2 (jailbroken)
# Install via Cydia
# === General ===
# Install proxy CA
# 1. Export Burp CA
# 2. Install on device
# 3. Trust CA in settings
Certificate Transparency
TL;DR: CT logs publicly record all issued certificates, allowing detection of misissued or malicious certs.
How CT Works
Certificate Issuance:
┌──────────┐ ┌─────────┐ ┌──────────┐
│ CA │ ──────► │ CT Log │ ──────► │ SCT │
│ │ Submit │ Server │ Return │ (proof) │
└──────────┘ └─────────┘ └──────────┘
│
│ Public,
│ Append-only
▼
┌─────────┐
│ Monitor │ ◄── You can watch for
│ │ certs issued for
└─────────┘ your domains
TLS Handshake:
[Server] ── Certificate + SCT ──► [Client]
│
▼
Verify SCT is valid
(cert was logged)
Using CT for Reconnaissance
CT logs reveal all certificates for a domain:
# Find subdomains via CT logs
curl -s "https://crt.sh/?q=%25.example.com&output=json" | \
jq -r '.[].name_value' | sort -u
# Using certspotter
curl -s "https://api.certspotter.com/v1/issuances?domain=example.com" | \
jq -r '.[].dns_names[]' | sort -u
# Useful for:
# - Subdomain enumeration
# - Identifying internal domains
# - Finding staging/dev environments
Monitoring Your Domains
| Service | URL | Use |
|---|
| crt.sh | crt.sh | Manual search |
| Cert Spotter | sslmate.com/certspotter | Free monitoring |
| Facebook CT | developers.facebook.com/tools/ct | Monitoring |
| Google Transparency | transparencyreport.google.com/https/certificates | Search |
Testing Certificates
Comprehensive Testing Workflow
1. Retrieve Certificate
│
▼
2. Check Basic Info
- Subject, Issuer
- Validity dates
- Key size
│
▼
3. Verify Chain
- Complete chain?
- Trusted root?
│
▼
4. Check Extensions
- SAN matches hostname?
- Key usage correct?
- Basic constraints?
│
▼
5. Check Revocation
- OCSP status?
- CRL status?
- Stapling enabled?
│
▼
6. Test Known Issues
- Weak algorithms?
- Short key?
- Expired?
Testing Checklist
| Check | Command | Pass Criteria |
|---|
| Expiration | openssl x509 -noout -dates | Future date |
| Key size | openssl x509 -text | grep "Public-Key" | ≥2048 bit RSA |
| Signature | openssl x509 -text | grep "Signature Algorithm" | SHA256+ |
| Chain | openssl s_client -verify 5 | Verify return:0 |
| Hostname | openssl s_client -verify_hostname | OK |
| OCSP | openssl s_client -status | Cert Status: good |
Complete Testing Script
#!/bin/bash
# Certificate Testing Script
TARGET=${1:-"example.com"}
PORT=${2:-443}
echo "=== Certificate Test for $TARGET:$PORT ==="
# Get certificate
echo | openssl s_client -connect $TARGET:$PORT -servername $TARGET 2>/dev/null > /tmp/cert_test.txt
# Extract cert
openssl x509 -in /tmp/cert_test.txt -outform PEM > /tmp/cert.pem 2>/dev/null
echo ""
echo "=== Subject ==="
openssl x509 -in /tmp/cert.pem -noout -subject
echo ""
echo "=== Issuer ==="
openssl x509 -in /tmp/cert.pem -noout -issuer
echo ""
echo "=== Validity ==="
openssl x509 -in /tmp/cert.pem -noout -dates
echo ""
echo "=== Key Size ==="
openssl x509 -in /tmp/cert.pem -noout -text | grep "Public-Key:"
echo ""
echo "=== Signature Algorithm ==="
openssl x509 -in /tmp/cert.pem -noout -text | grep "Signature Algorithm" | head -1
echo ""
echo "=== Subject Alternative Names ==="
openssl x509 -in /tmp/cert.pem -noout -ext subjectAltName
echo ""
echo "=== Chain Verification ==="
openssl s_client -connect $TARGET:$PORT -servername $TARGET -verify 5 2>&1 | grep "Verify"
echo ""
echo "=== OCSP Stapling ==="
openssl s_client -connect $TARGET:$PORT -servername $TARGET -status 2>&1 | grep -A 5 "OCSP Response"
# Cleanup
rm -f /tmp/cert_test.txt /tmp/cert.pem
Command Line
| Tool | Purpose | Install |
|---|
| openssl | All certificate operations | Built-in |
| testssl.sh | Comprehensive TLS testing | git clone |
| sslscan | Quick certificate scan | apt install sslscan |
| sslyze | Python SSL scanner | pip install sslyze |
| certutil (Windows) | Windows certificate tool | Built-in |
| Tool | URL | Use |
|---|
| SSL Labs | ssllabs.com/ssltest | Full analysis |
| crt.sh | crt.sh | CT log search |
| Cert Spotter | sslmate.com/certspotter | Monitoring |
| Hardenize | hardenize.com | Security posture |
Mobile Testing
| Tool | Platform | Purpose |
|---|
| objection | iOS/Android | Pinning bypass |
| Frida | iOS/Android | Dynamic instrumentation |
| apktool | Android | APK modification |
| SSL Kill Switch | iOS (jailbreak) | Pinning bypass |
Practice Labs
Beginner
| Resource | Focus |
|---|
| TryHackMe - PKI | Certificate basics |
| HackTheBox Academy | TLS/PKI fundamentals |
| PortSwigger Academy | Certificate issues |
| Resource | Focus |
|---|
| PentesterLab | Certificate attacks |
| DVWA with HTTPS | Testing methodology |
| Own CA setup | Understanding PKI |
Create Your Own CA (Lab)
# 1. Create Root CA
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -key rootCA.key -days 3650 -out rootCA.crt \
-subj "/CN=My Test Root CA"
# 2. Create Server Key
openssl genrsa -out server.key 2048
# 3. Create CSR
openssl req -new -key server.key -out server.csr \
-subj "/CN=test.local"
# 4. Create Extension File
cat > server.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = DNS:test.local, DNS:*.test.local
EOF
# 5. Sign Certificate
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key \
-CAcreateserial -out server.crt -days 365 -extfile server.ext
# 6. Verify
openssl verify -CAfile rootCA.crt server.crt
Glossary
| Term | Definition |
|---|
| CA | Certificate Authority - issues certificates |
| Certificate | Digital document binding identity to public key |
| Chain | Sequence of certificates from end-entity to root |
| CRL | Certificate Revocation List |
| CSR | Certificate Signing Request |
| CT | Certificate Transparency |
| DER | Binary certificate encoding |
| DV/OV/EV | Domain/Organization/Extended Validation |
| Intermediate CA | CA signed by root, signs end-entity |
| OCSP | Online Certificate Status Protocol |
| PEM | Base64 certificate encoding |
| PKCS | Public Key Cryptography Standards |
| Pinning | Hardcoding expected certificate/key |
| Root CA | Top of trust hierarchy, self-signed |
| SAN | Subject Alternative Name |
| SCT | Signed Certificate Timestamp (CT proof) |
| Trust Store | Collection of trusted root CAs |
| X.509 | Certificate format standard |
What’s Next?
Now that you understand PKI and certificates:
Summary
PKI and certificates are fundamental to secure communications:
- Trust Hierarchy - Root → Intermediate → End-entity
- Validation - Chain, dates, hostname, revocation, key usage
- Common Issues - Self-signed, expired, weak keys, missing chain
- Attacks - MITM with fake certs, private key theft, CA compromise
- Pinning - Prevents MITM even with valid fake certs
- CT - Public logging enables monitoring and recon
Pentester Takeaways:
- Always check certificate configuration
- Look for validation bypasses in applications
- Use CT logs for subdomain enumeration
- Test pinning bypass for mobile apps
- Search for exposed private keys
Found this guide helpful? Check out the other posts in the SecureKhan penetration testing series.