Lab 02: OWASP A02 — Cryptographic Failures

Objective

Attack a live server with real cryptographic weaknesses using Kali Linux: harvest MD5 password hashes and crack them with hashcat and john, break single-byte XOR "encryption" by brute-forcing the key, forge JWT tokens using a leaked weak secret, and exfiltrate cleartext credit cards and SSNs — then understand why each failure occurs and what the correct fix is.

Background

Cryptographic Failures (formerly "Sensitive Data Exposure") is OWASP #2. It covers using broken algorithms (MD5, SHA1, DES, RC4), transmitting sensitive data unencrypted, hardcoding secrets, and weak key management. MD5 was broken in 2004 — a GPU can try 10 billion MD5 hashes per second, cracking any dictionary password in seconds. In 2016, Yahoo's breach exposed 3 billion MD5-hashed passwords. In 2019, Facebook stored 600 million passwords in plaintext logs.

Architecture

┌─────────────────────┐        Docker Network: lab-a02         ┌─────────────────────┐
│   KALI ATTACKER     │ ─────── HTTP attacks ─────────────▶   │   VICTIM SERVER     │
│  innozverse-kali    │                                         │  innozverse-cybersec│
│  hashcat, john,     │ ◀────── responses ───────────────────  │  Flask API :5000    │
│  curl, python3      │                                         │  (MD5, weak JWT,   │
└─────────────────────┘                                         │   XOR, cleartext)   │
                                                                └─────────────────────┘

Time

45 minutes

Prerequisites

  • Lab 01 completed (familiar with two-container setup)

Tools

  • Victim: zchencow/innozverse-cybersec:latest

  • Attacker: zchencow/innozverse-kali:latest (hashcat, john, curl, python3)


Lab Instructions

Step 1: Environment Setup — Launch Victim Server

📸 Verified Output:


Step 2: Launch Kali Attacker

All subsequent commands run inside this Kali container:


Step 3: Service Recon — nmap + gobuster

📸 Verified Output:

💡 /config returning 200 with no auth is immediately suspicious. Any endpoint returning full server configuration is a critical finding. In this case it exposes database passwords, AWS keys, and the JWT signing secret — everything needed to fully compromise the application.


Step 4: Harvest MD5 Password Hashes

📸 Verified Output:


Step 5: Crack MD5 Hashes — hashcat

📸 Verified Output:

💡 All 3 MD5 hashes cracked in under 3 seconds. hashcat on a GPU can test 10 billion MD5 candidates per second. The entire rockyou.txt wordlist (14 million passwords) is exhausted in milliseconds. MD5 was designed for speed — exactly the wrong property for password hashing. bcrypt, Argon2id, and scrypt are designed to be deliberately slow (tunable to 100ms per attempt), making brute-force infeasible.


Step 6: Crack MD5 Hashes — john (Alternative)

📸 Verified Output:


Step 7: Cleartext Sensitive Data — Credit Cards and SSNs

📸 Verified Output:


Step 8: Break XOR "Encryption" by Brute Force

📸 Verified Output:

💡 Single-byte XOR is trivially broken. There are only 256 possible keys — a loop from 0 to 255 tests them all in microseconds. Real encryption (AES-256-GCM) has a 256-bit keyspace: 2²⁵⁶ possible keys, computationally infeasible to brute-force. The lesson: never invent your own encryption. Use a vetted library with a standard algorithm.


Step 9: Exploit Leaked JWT Secret — Forge Admin Token

📸 Verified Output:


Step 10: Cleanup

On your host:


Remediation — What the Correct Fix Looks Like

Vulnerability
Broken Implementation
Secure Fix

MD5 password hashing

hashlib.md5(password)

bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))

Hash exposed in API

Returned password_md5 in response

Never return any hash field in API responses

Cleartext PII in API

credit_card_cleartext in JSON

Mask at rest: ****-****-****-9012; serve via HTTPS only

XOR "encryption"

Single-byte XOR + base64

AES-256-GCM via cryptography library

Weak JWT secret

secret = 'secret123'

secrets.token_bytes(32) from environment variable

No JWT expiry check

verify_jwt() ignores exp

Always validate exp, iat, algorithm server-side

Hardcoded secrets

Secrets in source code

Environment variables or secrets manager (Vault, AWS Secrets Manager)

Config endpoint

/api/config returns all secrets

Remove entirely from production

Summary

Attack
Kali Tool
Finding

Service fingerprint

nmap, whatweb

Python/Flask, Werkzeug 3.1.6

Dir enumeration

gobuster

Found /config, /payment, /report

MD5 hash harvest

curl

3 password hashes collected

Hash cracking

hashcat

All 3 cracked in seconds: admin, alice, bob

Hash cracking (alt)

john

Confirmed: 3/3 cracked

Cleartext PII

curl

Credit cards and SSNs in API response

XOR crack

python3

256-key brute force — all cards decrypted

JWT forge

python3

Leaked secret → forged admin token → admin access

Further Reading

Last updated