Exploitation A02

Cryptographic Failures (OWASP A02)

Cryptographic failures (formerly "Sensitive Data Exposure") encompass weak encryption, poor key management, insufficient transport security, and plaintext storage of sensitive data. This is the #2 risk in the OWASP Top 10 2021 because cryptographic failures directly lead to data breaches.

TLS/SSL Configuration Testing

bash
# Test SSL/TLS configuration:

# Use testssl.sh (comprehensive):
testssl.sh https://target.com

# Or sslyze:
sslyze target.com

# Quick nmap scan:
nmap --script ssl-enum-ciphers -p 443 target.com

# Check for specific weaknesses:

# Test for SSLv2/SSLv3 (should be disabled):
openssl s_client -ssl2 -connect target.com:443 2>&1 | head -5
openssl s_client -ssl3 -connect target.com:443 2>&1 | head -5

# Test for TLS 1.0/1.1 (should be disabled):
openssl s_client -tls1 -connect target.com:443 2>&1 | head -5
openssl s_client -tls1_1 -connect target.com:443 2>&1 | head -5

# Check certificate details:
openssl s_client -connect target.com:443 2>/dev/null | openssl x509 -noout -text

# Check for weak ciphers:
nmap --script ssl-enum-ciphers -p 443 target.com | grep -E 'RC4|DES|NULL|EXPORT|anon'

# Check for HSTS header:
curl -sI https://target.com | grep -i strict-transport
# Test SSL/TLS configuration:

# Use testssl.sh (comprehensive):
testssl.sh https://target.com

# Or sslyze:
sslyze target.com

# Quick nmap scan:
nmap --script ssl-enum-ciphers -p 443 target.com

# Check for specific weaknesses:

# Test for SSLv2/SSLv3 (should be disabled):
openssl s_client -ssl2 -connect target.com:443 2>&1 | head -5
openssl s_client -ssl3 -connect target.com:443 2>&1 | head -5

# Test for TLS 1.0/1.1 (should be disabled):
openssl s_client -tls1 -connect target.com:443 2>&1 | head -5
openssl s_client -tls1_1 -connect target.com:443 2>&1 | head -5

# Check certificate details:
openssl s_client -connect target.com:443 2>/dev/null | openssl x509 -noout -text

# Check for weak ciphers:
nmap --script ssl-enum-ciphers -p 443 target.com | grep -E 'RC4|DES|NULL|EXPORT|anon'

# Check for HSTS header:
curl -sI https://target.com | grep -i strict-transport

Password Storage Analysis

If you obtain password hashes (via SQL injection, database leak, backup files), first identify the algorithm, then assess its strength. The hash format prefix reveals the algorithm:

Hash Prefix / LengthAlgorithmStrength
$2b$12$...bcryptStrong
$6$...SHA-512 cryptOK (salted)
$5$...SHA-256 cryptOK (salted)
$1$...MD5 cryptWeak
32 hex charsMD5Very weak
40 hex charsSHA-1Weak
64 hex charsSHA-256Weak if unsalted

Quick indicators of bad password storage:

  • The application can email you your existing password → stored in plaintext or reversible encryption
  • Admin panel can display decrypted passwords → reversible encryption, not hashing
  • Two users with the same password have the same hash → no salt
Hashcat Commands for Cracking Weak Hashes
hashcat-examples.sh
bash
hashcat -m 0 hashes.txt /usr/share/wordlists/rockyou.txt    # MD5
hashcat -m 100 hashes.txt /usr/share/wordlists/rockyou.txt  # SHA-1
hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt # bcrypt
hashcat -m 0 hashes.txt /usr/share/wordlists/rockyou.txt    # MD5
hashcat -m 100 hashes.txt /usr/share/wordlists/rockyou.txt  # SHA-1
hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt # bcrypt

Data in Transit

bash
# Check for mixed content (HTTPS page loading HTTP resources):
curl -s https://target.com | grep -i 'http://' | grep -v 'https://'

# Check if HTTP redirects to HTTPS:
curl -sI http://target.com
# Should return 301/302 to https://
# If it returns 200 over HTTP → sensitive data sent in cleartext

# Check for sensitive data in URLs:
# URLs are logged in server logs, browser history, proxy logs
# BAD: https://target.com/login?token=abc123
# BAD: https://target.com/reset?email=user@example.com

# Check API authentication over HTTP:
curl -sI http://target.com/api/users -H 'Authorization: Bearer TOKEN'
# If API works over HTTP → credentials sent in cleartext

# Check for sensitive cookies without Secure flag:
curl -sI https://target.com/login -X POST -d 'user=test&pass=test' | grep -i set-cookie
# Cookies should have: Secure; HttpOnly; SameSite=Lax
# Check for mixed content (HTTPS page loading HTTP resources):
curl -s https://target.com | grep -i 'http://' | grep -v 'https://'

# Check if HTTP redirects to HTTPS:
curl -sI http://target.com
# Should return 301/302 to https://
# If it returns 200 over HTTP → sensitive data sent in cleartext

# Check for sensitive data in URLs:
# URLs are logged in server logs, browser history, proxy logs
# BAD: https://target.com/login?token=abc123
# BAD: https://target.com/reset?email=user@example.com

# Check API authentication over HTTP:
curl -sI http://target.com/api/users -H 'Authorization: Bearer TOKEN'
# If API works over HTTP → credentials sent in cleartext

# Check for sensitive cookies without Secure flag:
curl -sI https://target.com/login -X POST -d 'user=test&pass=test' | grep -i set-cookie
# Cookies should have: Secure; HttpOnly; SameSite=Lax

Data at Rest

Check whether sensitive data is stored without encryption. PCI DSS requires encryption of stored cardholder data, and applications should never store full card numbers (only last 4 digits).

Where to Check for Unencrypted Sensitive Data

  • • Database backups — are they encrypted?
  • • Log files — do they contain passwords, tokens, PII?
  • • Error messages — do they reveal database data?
  • • Browser localStorage / sessionStorage — plaintext tokens or PII?
  • • Cookies — are sensitive values encrypted?
data-at-rest-checks.sh
bash
# Check for sensitive data in HTML source:
curl -s https://target.com/account | grep -iE 'ssn|credit.card|password|secret'

# Check for autocomplete on sensitive fields:
curl -s https://target.com/login | grep -i autocomplete
# Password fields should have autocomplete="off" or autocomplete="new-password"
# Check for sensitive data in HTML source:
curl -s https://target.com/account | grep -iE 'ssn|credit.card|password|secret'

# Check for autocomplete on sensitive fields:
curl -s https://target.com/login | grep -i autocomplete
# Password fields should have autocomplete="off" or autocomplete="new-password"

Weak Cryptographic Implementations

ECB mode encryption preserves patterns — if the same input always produces the same output (e.g., in encrypted cookies), the application likely uses ECB mode. Also check for predictable tokens: if password reset tokens are sequential or time-based, they can be guessed.

weak-crypto-tests.sh
bash
# Generate multiple password reset tokens and look for patterns:
for i in $(seq 1 10); do
  curl -s -X POST https://target.com/forgot-password \
    -d 'email=test@example.com' \
    -c - | grep token
done

# Padding oracle test:
# If error messages differ between bad padding and bad data,
# a padding oracle attack is possible.
padbuster https://target.com/api ENCRYPTED_COOKIE 8 -encoding 0
# Generate multiple password reset tokens and look for patterns:
for i in $(seq 1 10); do
  curl -s -X POST https://target.com/forgot-password \
    -d 'email=test@example.com' \
    -c - | grep token
done

# Padding oracle test:
# If error messages differ between bad padding and bad data,
# a padding oracle attack is possible.
padbuster https://target.com/api ENCRYPTED_COOKIE 8 -encoding 0

Information

Tokens should use a CSPRNG (crypto.randomBytes in Node.js, secrets.token_hex in Python). If tokens appear to be based on timestamps, PIDs, or sequential counters, report as a predictable token vulnerability.

Testing Checklist

  1. 1. Test TLS configuration (versions, ciphers, certificate validity)
  2. 2. Check HTTP→HTTPS redirect and HSTS header
  3. 3. Verify cookie security flags (Secure, HttpOnly, SameSite)
  4. 4. Test password storage (hash algorithm, salting, strength)
  5. 5. Check for sensitive data in URLs, logs, and error messages
  6. 6. Check for sensitive data in browser storage
  7. 7. Test token/nonce predictability
  8. 8. Check for deprecated crypto (MD5, SHA-1, DES, RC4)
  9. 9. Test for padding oracle vulnerabilities

Evidence Collection

TLS Report: testssl.sh or sslyze output showing weak configuration

Hash Analysis: Identified hash algorithm and demonstrated weakness

Data Exposure: Screenshots of sensitive data in cleartext

CVSS Range: Weak TLS: 5.3–7.5 | Plaintext passwords: 7.5–9.1 | No encryption on PII: 7.5–8.6

Remediation

  • TLS 1.2+ only: Disable SSLv2, SSLv3, TLS 1.0, and TLS 1.1. Use strong cipher suites.
  • HSTS: Enable Strict-Transport-Security with max-age=31536000 and includeSubDomains.
  • bcrypt/Argon2: Hash passwords with bcrypt (cost 12+) or Argon2id. Never use MD5, SHA-1, or unsalted hashes.
  • Encrypt PII at rest: Use AES-256-GCM for sensitive data encryption. Manage keys via KMS/HSM.
  • CSPRNG: Use cryptographically secure random number generators for all tokens and secrets.

False Positive Identification

  • SHA-256 for non-password hashing: SHA-256 is inappropriate for passwords but perfectly fine for integrity checking, HMAC, and file hashing — assess usage context.
  • Short RSA keys in test environments: 1024-bit RSA keys in development/test may be intentional for speed — verify the production deployment uses appropriate key sizes.
  • CBC mode with proper IV: AES-CBC is not inherently broken — only report if the IV is static/predictable or if a padding oracle is exploitable.