Skip to main content

Cryptography Weaknesses

Overview

Cryptography is a key area of security used to keep secrets confidential. However, when implemented incorrectly, these secrets can be leaked or the cryptographic protections can be manipulated to bypass security controls. This module explores three critical cryptographic weaknesses:
  1. Encoding vs. Encryption - Using XOR encoding instead of proper encryption
  2. ECB Mode Vulnerabilities - Block cipher exploitation through cut-and-paste attacks
  3. Padding Oracle Attacks - Exploiting CBC mode padding validation

Objective

Exploit weak cryptographic implementations at each security level to gain unauthorized access or elevate privileges.

Security Levels

Low Level: XOR “Encryption”

Vulnerable Code

The low level uses XOR encoding, which is fundamentally insecure:
function xor_this($cleartext, $key) {
    $outText = '';
    for($i=0; $i<strlen($cleartext);) {
        for($j=0; ($j<strlen($key) && $i<strlen($cleartext)); $j++,$i++) {
            $outText .= $cleartext[$i] ^ $key[$j];
        }
    }
    return $outText;
}

$key = "wachtwoord";  // Dutch for "password"

if ($_SERVER['REQUEST_METHOD'] == "POST") {
    if (array_key_exists('message', $_POST)) {
        $message = $_POST['message'];
        if ($_POST['direction'] == "decode") {
            $encoded = xor_this(base64_decode($message), $key);
        } else {
            $encoded = base64_encode(xor_this($message, $key));
        }
    }
}
```bash

**Location**: `vulnerabilities/cryptography/source/low.php:3-50`

#### Exploitation

**Challenge**: Decode the intercepted message:
Lg4WGlQZChhSFBYSEB8bBQtPGxdNQSwEHREOAQY=

**Step 1: Identify the encoding method**

Test encoding patterns:
encode(“hello”) → HwQPBBs= Base64 decode → 0x1f 0x04 0x0f 0x04 0x1b encode(“a secret”) → FkEQDRcFChs= Base64 decode → 0x16 0x41 0x10 0x0d 0x17 0x05 0x0a 0x1b

Notice: Output length equals input length. This suggests XOR encoding.

**Step 2: Recover the key using XOR properties**

XOR is associative: `plaintext ⊕ key = ciphertext`

Therefore: `plaintext ⊕ ciphertext = key`

encode(“hello”) → HwQPBBs= XOR(“hello”, base64decode(“HwQPBBs=”)) → “wacht” encode(“a secret”) → FkEQDRcFChs= XOR(“a secret”, base64decode(“FkEQDRcFChs=”)) → “wachtwoo”

**Step 3: Confirm with longer string**

encode(“thisisaverylongstringtofindthepassword”) → AwkKGx0EDhkXFg4NDAYTBBsdGwoQFQwOHRkLGxoBBwAQGwMYHQs= XOR with plaintext → “wachtwoordwachtwoordwachtwoordwachtwoo”

Key identified: **`wachtwoord`**

**Step 4: Decrypt the challenge**

XOR(base64decode(“Lg4WGlQZChhSFBYSEB8bBQtPGxdNQSwEHREOAQY=”), “wachtwoord”) → “Your new password is: Olifant”

**Password**: `Olifant`

#### Key Vulnerability

XOR encoding is **NOT encryption**:
- No authentication
- Key recovery is trivial with known plaintext
- Repeating key creates patterns
- Provides no confidentiality against basic cryptanalysis

---

### Medium Level: ECB Mode Block Cipher

#### Vulnerable Code

The medium level uses AES-128-ECB (Electronic Code Book):

```php
function decrypt($ciphertext, $key) {
    $e = openssl_decrypt($ciphertext, 'aes-128-ecb', $key, OPENSSL_PKCS1_PADDING);
    if ($e === false) {
        throw new Exception("Decryption failed");
    }
    return $e;
}

$key = "ik ben een aardbei";  // "I am a strawberry" in Dutch

if ($_SERVER['REQUEST_METHOD'] == "POST") {
    $token = $_POST['token'];
    if (strlen($token) % 32 != 0) {
        throw new Exception("Token is in wrong format");
    }
    
    $decrypted = decrypt(hex2bin($token), $key);
    $user = json_decode($decrypted);
    
    if ($user->user == "sweep" && $user->ex > time() && $user->level == "admin") {
        $success = "Welcome administrator Sweep";
    }
}
Location: vulnerabilities/cryptography/source/medium.php:2-42

Token Format

{
    "user": "example",
    "ex": 1723620372,
    "level": "user",
    "bio": "blah"
}
```bash

#### Captured Tokens

**Sooty (admin, expired)**:
e287af752ed3f9601befd45726785bd9b85bb230876912bf3c66e50758b222d0837d1e6b16bfae07b776feb7afe576305aec34b41499579d3fb6acc8dc92fd5fcea8743c3b2904de83944d6b19733cdb48dd16048ed89967c250ab7f00629dba

**Sweep (user, expired)**:
3061837c4f9debaf19d4539bfa0074c1b85bb230876912bf3c66e50758b222d083f2d277d9e5fb9a951e74bee57c77a3caeb574f10f349ed839fbfd223903368873580b2e3e494ace1e9e8035f0e7e07

**Soo (user, valid)**:
5fec0b1c993f46c8bad8a5c8d9bb9698174d4b2659239bbc50646e14a70becef83f2d277d9e5fb9a951e74bee57c77a3c9acb1f268c06c5e760a9d728e081fab65e83b9f97e65cb7c7c4b8427bd44abc16daa00fd8cd0105c97449185be77ef5

#### Exploitation

**Understanding ECB**:
- Block size: AES-128 = 128 bits = 16 bytes = 32 hex characters
- Each block is encrypted independently
- Identical plaintext blocks produce identical ciphertext blocks
- Blocks can be mixed and matched (cut-and-paste attack)

**Step 1: Break tokens into 32-character blocks**

**Sooty (admin, expired)**:
e287af752ed3f9601befd45726785bd9 ← Username: “Sooty” b85bb230876912bf3c66e50758b222d0 ← Expiry (same as Sweep) 837d1e6b16bfae07b776feb7afe57630 ← Level: “admin” 5aec34b41499579d3fb6acc8dc92fd5f ← Bio cea8743c3b2904de83944d6b19733cdb 48dd16048ed89967c250ab7f00629dba

**Sweep (user, expired)**:
3061837c4f9debaf19d4539bfa0074c1 ← Username: “Sweep” b85bb230876912bf3c66e50758b222d0 ← Expiry (same as Sooty) 83f2d277d9e5fb9a951e74bee57c77a3 ← Level: “user” (same as Soo) caeb574f10f349ed839fbfd223903368 ← Bio 873580b2e3e494ace1e9e8035f0e7e07

**Soo (user, valid)**:
5fec0b1c993f46c8bad8a5c8d9bb9698 ← Username: “Soo” 174d4b2659239bbc50646e14a70becef ← Expiry (still valid) 83f2d277d9e5fb9a951e74bee57c77a3 ← Level: “user” (same as Sweep) c9acb1f268c06c5e760a9d728e081fab ← Bio 65e83b9f97e65cb7c7c4b8427bd44abc 16daa00fd8cd0105c97449185be77ef5

**Step 2: Identify matching blocks**

- Sooty and Sweep share expiry block: `b85bb230876912bf3c66e50758b222d0`
- Sweep and Soo share level block: `83f2d277d9e5fb9a951e74bee57c77a3`

**Step 3: Forge token (Sweep + admin + valid expiry)**

3061837c4f9debaf19d4539bfa0074c1 ← Sweep’s username 174d4b2659239bbc50646e14a70becef ← Soo’s valid expiry 837d1e6b16bfae07b776feb7afe57630 ← Sooty’s admin level caeb574f10f349ed839fbfd223903368 ← Sweep’s bio (filler) 873580b2e3e494ace1e9e8035f0e7e07 ← Sweep’s bio (filler)

**Forged Token**:
3061837c4f9debaf19d4539bfa0074c1174d4b2659239bbc50646e14a70becef837d1e6b16bfae07b776feb7afe57630caeb574f10f349ed839fbfd223903368873580b2e3e494ace1e9e8035f0e7e07

This token decrypts to valid JSON showing Sweep as admin with valid expiry.

#### Key Vulnerability

ECB mode encrypts each block independently, allowing:
- Block reordering attacks
- Cut-and-paste attacks
- Pattern analysis (identical blocks reveal identical plaintext)

**Never use ECB mode for anything beyond single-block encryption.**

---

### High Level: Padding Oracle Attack

#### Vulnerable Code

The high level uses AES-128-CBC with token-based authentication:

```php
require("token_library_high.php");

$token_data = create_token();

// JavaScript fetch to check_token_high.php
// Validates token and returns user info
Location: vulnerabilities/cryptography/source/high.php:3-69

Exploitation

The system is vulnerable to padding oracle attacks against AES-CBC:
  1. Server validates PKCS#7 padding
  2. Different errors reveal padding validity
  3. Attacker can decrypt ciphertext byte-by-byte
  4. Attacker can forge valid ciphertexts
Attack Process:
  1. Intercept encrypted token
  2. Modify ciphertext bytes systematically
  3. Observe server responses (valid/invalid padding)
  4. Use padding information to decrypt or forge tokens
Resources:

Key Vulnerability

Padding oracle attacks exploit the difference in error messages when:
  • Padding is invalid → “Padding error”
  • Padding is valid but data is wrong → “Authentication error”
This side-channel leaks information about the decrypted plaintext.

Impossible Level: Secure Implementation

The impossible level uses modern authenticated encryption:
class Token {
    private const ENCRYPTION_CIPHER = "aes-128-gcm";
    private const ENCRYPTION_KEY = "Paintbrush";
    
    private static function encrypt($cleartext) {
        $ivlen = openssl_cipher_iv_length(self::ENCRYPTION_CIPHER);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext = openssl_encrypt(
            $cleartext, 
            self::ENCRYPTION_CIPHER, 
            self::ENCRYPTION_KEY, 
            $options=0, 
            $iv, 
            $tag
        );
        $ret = base64_encode($tag . ":::::" . $iv . ":::::" . $ciphertext);
        return $ret;
    }
}
```bash

**Location**: `vulnerabilities/api/src/Token.php:9-28`

#### Protection Mechanisms

1. **AES-GCM**: Authenticated encryption (no padding oracle)
2. **Unique IV**: Generated for each encryption
3. **Authentication tag**: Prevents tampering
4. **256-bit keys recommended**: Stronger than 128-bit

---

## Cryptographic Best Practices

<Warning>
**NEVER**:
- Use XOR as encryption
- Use ECB mode (except for single blocks)
- Implement custom crypto without expertise
- Reveal padding validation errors
- Use static IVs or keys
</Warning>

<Check>
**ALWAYS**:
- Use authenticated encryption (AES-GCM, ChaCha20-Poly1305)
- Generate cryptographically random IVs
- Use unique IVs for every encryption
- Prefer 256-bit keys over 128-bit
- Use established libraries (libsodium, OpenSSL)
- Validate authentication tags before processing data
</Check>

## Recommended Algorithms

| Use Case | Recommended Algorithm |
|----------|----------------------|
| Symmetric encryption | AES-256-GCM, ChaCha20-Poly1305 |
| Password hashing | Argon2id, bcrypt, scrypt |
| Key derivation | PBKDF2, HKDF |
| Message authentication | HMAC-SHA256, Poly1305 |
| Digital signatures | Ed25519, ECDSA P-256 |

## Testing Tools

- **CyberChef**: https://gchq.github.io/CyberChef/ - Crypto operations
- **Padding Oracle Attack Scripts**: Available in DVWA source
- **OpenSSL CLI**: Command-line crypto testing

## References

- [Wikipedia: Block Cipher Modes](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation)
- [Padding Oracle Attack Explained](https://robertheaton.com/2013/07/29/padding-oracle-attack/)
- [AES-ECB Padding Attack](https://exploit-notes.hdks.org/exploit/cryptography/algorithm/aes-ecb-padding-attack)
- [PKCS#7 Padding](https://yurichev.org/pkcs7/)
- [Video Walkthrough by CryptoCat](https://www.youtube.com/watch?v=7WySPRERN0Q)

---

*This module demonstrates real-world cryptographic vulnerabilities for educational purposes only.*

Build docs developers (and LLMs) love