ineedcodes 1.6.1 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/skills/401-403-bypass-techniques/SKILL.md +348 -0
- package/skills/active-directory-acl-abuse/BLOODHOUND_PATHS.md +281 -0
- package/skills/active-directory-acl-abuse/SKILL.md +295 -0
- package/skills/active-directory-certificate-services/ADCS_ESC_MATRIX.md +197 -0
- package/skills/active-directory-certificate-services/SKILL.md +303 -0
- package/skills/active-directory-kerberos-attacks/KERBEROS_ATTACK_CHAINS.md +226 -0
- package/skills/active-directory-kerberos-attacks/SKILL.md +311 -0
- package/skills/ai-ml-security/SKILL.md +425 -0
- package/skills/android-pentesting-tricks/FRIDA_SCRIPTS.md +394 -0
- package/skills/android-pentesting-tricks/SKILL.md +369 -0
- package/skills/anti-debugging-techniques/ANTI_DEBUG_MATRIX.md +117 -0
- package/skills/anti-debugging-techniques/SKILL.md +407 -0
- package/skills/api-auth-and-jwt-abuse/SKILL.md +76 -0
- package/skills/api-authorization-and-bola/SKILL.md +48 -0
- package/skills/api-recon-and-docs/SKILL.md +61 -0
- package/skills/api-sec/SKILL.md +49 -0
- package/skills/arbitrary-write-to-rce/SKILL.md +361 -0
- package/skills/auth-sec/SKILL.md +41 -0
- package/skills/authbypass-authentication-flaws/SKILL.md +441 -0
- package/skills/bba-ad-attacker/SKILL.md +420 -0
- package/skills/bba-api-security/SKILL.md +95 -0
- package/skills/bba-attack-planner/SKILL.md +186 -0
- package/skills/bba-binary-exploit/SKILL.md +65 -0
- package/skills/bba-bizlogic-hunter/SKILL.md +304 -0
- package/skills/bba-bug-bounty/SKILL.md +245 -0
- package/skills/bba-cicd-redteam/SKILL.md +515 -0
- package/skills/bba-cloud-security/SKILL.md +97 -0
- package/skills/bba-container-escape/SKILL.md +161 -0
- package/skills/bba-credential-tester/SKILL.md +346 -0
- package/skills/bba-crypto-analyst/SKILL.md +54 -0
- package/skills/bba-ctf-solver/SKILL.md +166 -0
- package/skills/bba-detection-engineer/SKILL.md +93 -0
- package/skills/bba-engagement-planner/SKILL.md +68 -0
- package/skills/bba-exploit-chainer/SKILL.md +280 -0
- package/skills/bba-exploit-guide/SKILL.md +96 -0
- package/skills/bba-forensics-analyst/SKILL.md +512 -0
- package/skills/bba-graphql-hunter/SKILL.md +145 -0
- package/skills/bba-hardware-hacker/SKILL.md +57 -0
- package/skills/bba-jwt-cracker/SKILL.md +133 -0
- package/skills/bba-llm-redteam/SKILL.md +149 -0
- package/skills/bba-malware-analyst/SKILL.md +305 -0
- package/skills/bba-mobile-pentester/SKILL.md +350 -0
- package/skills/bba-osint-collector/SKILL.md +645 -0
- package/skills/bba-payload-crafter/SKILL.md +347 -0
- package/skills/bba-phishing-operator/SKILL.md +516 -0
- package/skills/bba-poc-validator/SKILL.md +249 -0
- package/skills/bba-privesc-advisor/SKILL.md +98 -0
- package/skills/bba-purple-team/SKILL.md +56 -0
- package/skills/bba-recon-advisor/SKILL.md +215 -0
- package/skills/bba-red-team-operator/SKILL.md +61 -0
- package/skills/bba-report-generator/SKILL.md +145 -0
- package/skills/bba-reverse-engineer/SKILL.md +298 -0
- package/skills/bba-social-engineer/SKILL.md +341 -0
- package/skills/bba-ssrf-hunter/SKILL.md +120 -0
- package/skills/bba-stig-analyst/SKILL.md +108 -0
- package/skills/bba-subdomain-takeover/SKILL.md +141 -0
- package/skills/bba-swarm-orchestrator/SKILL.md +351 -0
- package/skills/bba-threat-modeler/SKILL.md +574 -0
- package/skills/bba-vuln-scanner/SKILL.md +305 -0
- package/skills/bba-web-hunter/SKILL.md +285 -0
- package/skills/bba-wireless-pentester/SKILL.md +539 -0
- package/skills/binary-protection-bypass/PROTECTION_BYPASS_MATRIX.md +168 -0
- package/skills/binary-protection-bypass/SKILL.md +295 -0
- package/skills/browser-exploitation-v8/SKILL.md +334 -0
- package/skills/browser-exploitation-v8/V8_EXPLOITATION_PATTERNS.md +288 -0
- package/skills/business-logic-vuln/SKILL.md +33 -0
- package/skills/business-logic-vulnerabilities/CHECKLIST.md +375 -0
- package/skills/business-logic-vulnerabilities/METHODOLOGY.md +337 -0
- package/skills/business-logic-vulnerabilities/SCENARIOS.md +1095 -0
- package/skills/business-logic-vulnerabilities/SKILL.md +711 -0
- package/skills/classical-cipher-analysis/SKILL.md +663 -0
- package/skills/clickjacking/SKILL.md +163 -0
- package/skills/cmdi-command-injection/SKILL.md +687 -0
- package/skills/code-obfuscation-deobfuscation/SKILL.md +391 -0
- package/skills/container-escape-techniques/DOCKER_ESCAPE_CHAINS.md +296 -0
- package/skills/container-escape-techniques/SKILL.md +339 -0
- package/skills/cors-cross-origin-misconfiguration/SCENARIOS.md +152 -0
- package/skills/cors-cross-origin-misconfiguration/SKILL.md +270 -0
- package/skills/crlf-injection/SKILL.md +179 -0
- package/skills/csp-bypass-advanced/SKILL.md +259 -0
- package/skills/csrf-cross-site-request-forgery/SKILL.md +526 -0
- package/skills/csv-formula-injection/SKILL.md +144 -0
- package/skills/dangling-markup-injection/SKILL.md +321 -0
- package/skills/defi-attack-patterns/SKILL.md +355 -0
- package/skills/dependency-confusion/SKILL.md +178 -0
- package/skills/deserialization-insecure/JAVA_GADGET_CHAINS.md +511 -0
- package/skills/deserialization-insecure/SKILL.md +725 -0
- package/skills/dns-rebinding-attacks/SKILL.md +337 -0
- package/skills/email-header-injection/SKILL.md +349 -0
- package/skills/expression-language-injection/SKILL.md +243 -0
- package/skills/file-access-vuln/SKILL.md +33 -0
- package/skills/format-string-exploitation/SKILL.md +312 -0
- package/skills/ghost-bits-cast-attack/PAYLOAD_COOKBOOK.md +448 -0
- package/skills/ghost-bits-cast-attack/SKILL.md +799 -0
- package/skills/graphql-and-hidden-parameters/SKILL.md +50 -0
- package/skills/hack/SKILL.md +162 -0
- package/skills/hash-attack-techniques/SKILL.md +491 -0
- package/skills/heap-exploitation/HOUSE_OF_TECHNIQUES.md +244 -0
- package/skills/heap-exploitation/IO_FILE_EXPLOITATION.md +256 -0
- package/skills/heap-exploitation/SKILL.md +217 -0
- package/skills/http-host-header-attacks/SKILL.md +323 -0
- package/skills/http-parameter-pollution/SKILL.md +208 -0
- package/skills/http2-specific-attacks/SKILL.md +350 -0
- package/skills/idor-broken-object-authorization/SKILL.md +336 -0
- package/skills/injection-checking/EXTRA_INJECTION_TYPES.md +450 -0
- package/skills/injection-checking/SKILL.md +50 -0
- package/skills/insecure-source-code-management/SKILL.md +161 -0
- package/skills/ios-pentesting-tricks/IOS_RUNTIME_TRICKS.md +411 -0
- package/skills/ios-pentesting-tricks/SKILL.md +418 -0
- package/skills/jndi-injection/SKILL.md +265 -0
- package/skills/jwt-oauth-token-attacks/SKILL.md +301 -0
- package/skills/kernel-exploitation/KERNEL_HEAP_TECHNIQUES.md +293 -0
- package/skills/kernel-exploitation/KERNEL_MITIGATION_BYPASS.md +224 -0
- package/skills/kernel-exploitation/SKILL.md +307 -0
- package/skills/kubernetes-pentesting/SKILL.md +348 -0
- package/skills/lattice-crypto-attacks/SKILL.md +497 -0
- package/skills/linux-lateral-movement/SKILL.md +348 -0
- package/skills/linux-privilege-escalation/KERNEL_EXPLOITS_CHECKLIST.md +260 -0
- package/skills/linux-privilege-escalation/SKILL.md +346 -0
- package/skills/linux-privilege-escalation/SUID_CAPABILITIES_TRICKS.md +305 -0
- package/skills/linux-security-bypass/SKILL.md +345 -0
- package/skills/llm-prompt-injection/JAILBREAK_PATTERNS.md +306 -0
- package/skills/llm-prompt-injection/SKILL.md +357 -0
- package/skills/macos-process-injection/DYLIB_XPC_TECHNIQUES.md +373 -0
- package/skills/macos-process-injection/SKILL.md +384 -0
- package/skills/macos-security-bypass/SKILL.md +337 -0
- package/skills/macos-security-bypass/TCC_BYPASS_MATRIX.md +200 -0
- package/skills/memory-forensics-volatility/SKILL.md +323 -0
- package/skills/memory-forensics-volatility/VOLATILITY_CHEATSHEET.md +225 -0
- package/skills/mobile-ssl-pinning-bypass/SKILL.md +531 -0
- package/skills/network-protocol-attacks/NAME_RESOLUTION_POISONING.md +226 -0
- package/skills/network-protocol-attacks/SKILL.md +330 -0
- package/skills/nosql-injection/SKILL.md +341 -0
- package/skills/ntlm-relay-coercion/COERCION_METHODS.md +253 -0
- package/skills/ntlm-relay-coercion/SKILL.md +267 -0
- package/skills/oauth-oidc-misconfiguration/SKILL.md +46 -0
- package/skills/open-redirect/SKILL.md +380 -0
- package/skills/path-traversal-lfi/SKILL.md +802 -0
- package/skills/prototype-pollution/SKILL.md +190 -0
- package/skills/prototype-pollution-advanced/KNOWN_GADGETS.md +253 -0
- package/skills/prototype-pollution-advanced/SKILL.md +338 -0
- package/skills/race-condition/SKILL.md +526 -0
- package/skills/recon-and-methodology/SKILL.md +389 -0
- package/skills/recon-for-sec/SKILL.md +29 -0
- package/skills/request-smuggling/H2_SMUGGLING_VARIANTS.md +498 -0
- package/skills/request-smuggling/SKILL.md +314 -0
- package/skills/reverse-shell-techniques/SHELL_CHEATSHEET.md +196 -0
- package/skills/reverse-shell-techniques/SKILL.md +290 -0
- package/skills/rsa-attack-techniques/RSA_ATTACK_CATALOG.md +432 -0
- package/skills/rsa-attack-techniques/SKILL.md +437 -0
- package/skills/saml-sso-assertion-attacks/SKILL.md +41 -0
- package/skills/sandbox-escape-techniques/PYTHON_SANDBOX_ESCAPE.md +349 -0
- package/skills/sandbox-escape-techniques/SECCOMP_BYPASS.md +332 -0
- package/skills/sandbox-escape-techniques/SKILL.md +250 -0
- package/skills/smart-contract-vulnerabilities/SKILL.md +314 -0
- package/skills/smart-contract-vulnerabilities/SOLIDITY_VULN_PATTERNS.md +460 -0
- package/skills/sqli-sql-injection/SCENARIOS.md +575 -0
- package/skills/sqli-sql-injection/SKILL.md +489 -0
- package/skills/sqli-sql-injection/SQLMAP_ADVANCED.md +642 -0
- package/skills/ssrf-server-side-request-forgery/SCENARIOS.md +226 -0
- package/skills/ssrf-server-side-request-forgery/SKILL.md +323 -0
- package/skills/ssrf-server-side-request-forgery/URL_PARSER_TRICKS.md +650 -0
- package/skills/ssti-server-side-template-injection/ENGINE_PAYLOADS.md +456 -0
- package/skills/ssti-server-side-template-injection/SCENARIOS.md +319 -0
- package/skills/ssti-server-side-template-injection/SKILL.md +344 -0
- package/skills/stack-overflow-and-rop/ROP_ADVANCED_TECHNIQUES.md +249 -0
- package/skills/stack-overflow-and-rop/SKILL.md +304 -0
- package/skills/steganography-techniques/SKILL.md +348 -0
- package/skills/steganography-techniques/STEGO_TOOLS_GUIDE.md +335 -0
- package/skills/subdomain-takeover/SKILL.md +247 -0
- package/skills/symbolic-execution-tools/ANGR_COOKBOOK.md +437 -0
- package/skills/symbolic-execution-tools/SKILL.md +419 -0
- package/skills/symmetric-cipher-attacks/BLOCK_CIPHER_ATTACKS.md +364 -0
- package/skills/symmetric-cipher-attacks/SKILL.md +462 -0
- package/skills/traffic-analysis-pcap/SKILL.md +341 -0
- package/skills/tunneling-and-pivoting/SKILL.md +343 -0
- package/skills/type-juggling/SKILL.md +291 -0
- package/skills/unauthorized-access-common-services/PORT_SERVICE_MATRIX.md +340 -0
- package/skills/unauthorized-access-common-services/SKILL.md +388 -0
- package/skills/upload-insecure-files/SCENARIOS.md +158 -0
- package/skills/upload-insecure-files/SKILL.md +543 -0
- package/skills/vm-and-bytecode-reverse/SKILL.md +450 -0
- package/skills/vr-cheatsheet-authentication_bypass/SKILL.md +184 -0
- package/skills/vr-cheatsheet-dangerous_functions/SKILL.md +200 -0
- package/skills/vr-cheatsheet-linux_commands/SKILL.md +40 -0
- package/skills/vr-cheatsheet-rce/SKILL.md +177 -0
- package/skills/vr-cheatsheet-reverse_engineering/SKILL.md +144 -0
- package/skills/vr-cheatsheet-sqli/SKILL.md +270 -0
- package/skills/vr-cheatsheet-ssrf/SKILL.md +173 -0
- package/skills/vr-cheatsheet-xss/SKILL.md +177 -0
- package/skills/vr-methodology-mindset_and_tips/SKILL.md +51 -0
- package/skills/vr-template-vulnerability_report_template/SKILL.md +59 -0
- package/skills/vr-writeup-CVE-2026-9136/SKILL.md +171 -0
- package/skills/vr-writeup-ZVE-2026-3795/SKILL.md +350 -0
- package/skills/vr-writeup-api_key_leak/SKILL.md +103 -0
- package/skills/waf-bypass-techniques/SKILL.md +290 -0
- package/skills/waf-bypass-techniques/WAF_PRODUCT_MATRIX.md +202 -0
- package/skills/web-cache-deception/CACHE_POISONING_TECHNIQUES.md +637 -0
- package/skills/web-cache-deception/SKILL.md +222 -0
- package/skills/websocket-security/SKILL.md +454 -0
- package/skills/windows-av-evasion/AMSI_BYPASS_TECHNIQUES.md +289 -0
- package/skills/windows-av-evasion/SKILL.md +342 -0
- package/skills/windows-lateral-movement/CREDENTIAL_DUMPING.md +308 -0
- package/skills/windows-lateral-movement/SKILL.md +335 -0
- package/skills/windows-privilege-escalation/SKILL.md +328 -0
- package/skills/windows-privilege-escalation/TOKEN_POTATO_TRICKS.md +216 -0
- package/skills/windows-privilege-escalation/UAC_BYPASS_METHODS.md +225 -0
- package/skills/xslt-injection/SKILL.md +281 -0
- package/skills/xss-cross-site-scripting/ADVANCED_XSS_TRICKS.md +276 -0
- package/skills/xss-cross-site-scripting/SCENARIOS.md +278 -0
- package/skills/xss-cross-site-scripting/SKILL.md +379 -0
- package/skills/xxe-xml-external-entity/SCENARIOS.md +112 -0
- package/skills/xxe-xml-external-entity/SKILL.md +554 -0
- package/src/agent.js +1 -1
- package/src/session.js +5 -3
- package/src/skills.js +37 -6
- package/src/ui.js +1 -1
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: classical-cipher-analysis
|
|
3
|
+
description: >-
|
|
4
|
+
Classical cipher analysis playbook. Use when encountering substitution
|
|
5
|
+
ciphers, Vigenere, transposition, XOR, or encoded text in CTF challenges
|
|
6
|
+
that requires frequency analysis, Kasiski examination, or known-plaintext
|
|
7
|
+
cryptanalysis.gated: true
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# SKILL: Classical Cipher Analysis — Expert Cryptanalysis Playbook
|
|
11
|
+
|
|
12
|
+
> **AI LOAD INSTRUCTION**: Expert classical cipher identification and breaking techniques for CTF. Covers cipher identification methodology (frequency analysis, IC, Kasiski), monoalphabetic substitution, Caesar/ROT, Vigenere, Enigma, affine, Hill, transposition ciphers, Bacon/Polybius/Playfair, and XOR ciphers. Base models often skip the identification step and jump to the wrong cipher type, or fail to recognize encoded (base64/hex) ciphertext that needs decoding before analysis.
|
|
13
|
+
|
|
14
|
+
## 0. RELATED ROUTING
|
|
15
|
+
|
|
16
|
+
- [symmetric-cipher-attacks](../symmetric-cipher-attacks/SKILL.md) when dealing with modern symmetric ciphers (AES/DES) rather than classical
|
|
17
|
+
- [hash-attack-techniques](../hash-attack-techniques/SKILL.md) when the challenge involves hash-based constructions
|
|
18
|
+
- [lattice-crypto-attacks](../lattice-crypto-attacks/SKILL.md) when knapsack-based ciphers are encountered
|
|
19
|
+
|
|
20
|
+
### Quick identification guide
|
|
21
|
+
|
|
22
|
+
| Observation | Likely Cipher | First Action |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| All uppercase letters, uneven frequency | Monoalphabetic substitution | Frequency analysis |
|
|
25
|
+
| All uppercase, flat frequency distribution | Polyalphabetic (Vigenere) | IC + Kasiski |
|
|
26
|
+
| Only A-Z shifted uniformly | Caesar/ROT | Brute force 25 shifts |
|
|
27
|
+
| Base64 alphabet (A-Za-z0-9+/=) | Base64 encoded (decode first) | Base64 decode |
|
|
28
|
+
| Hex string (0-9a-f) | Hex encoded (decode first) | Hex decode |
|
|
29
|
+
| Binary (0s and 1s) | Binary encoded | Convert to ASCII |
|
|
30
|
+
| Dots and dashes | Morse code | Morse decode |
|
|
31
|
+
| Raised/normal text pattern | Bacon cipher | Map to A/B, decode |
|
|
32
|
+
| 2-digit number pairs (11-55) | Polybius square | Grid lookup |
|
|
33
|
+
| Text appears scrambled (right letters, wrong order) | Transposition | Anagram analysis |
|
|
34
|
+
| Non-printable bytes XOR-like | XOR cipher | Single/repeating key XOR analysis |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 1. CIPHER IDENTIFICATION METHODOLOGY
|
|
39
|
+
|
|
40
|
+
### 1.1 Step 1: Character Set Analysis
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
def analyze_charset(ciphertext):
|
|
44
|
+
"""Identify encoding/cipher by character set."""
|
|
45
|
+
chars = set(ciphertext.strip())
|
|
46
|
+
|
|
47
|
+
if chars <= set('01 \n'):
|
|
48
|
+
return "Binary encoding"
|
|
49
|
+
if chars <= set('.-/ \n'):
|
|
50
|
+
return "Morse code"
|
|
51
|
+
if chars <= set('0123456789abcdef \n'):
|
|
52
|
+
return "Hex encoding"
|
|
53
|
+
if chars <= set('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n'):
|
|
54
|
+
if '=' in ciphertext or len(ciphertext) % 4 == 0:
|
|
55
|
+
return "Base64 encoding"
|
|
56
|
+
if chars <= set('ABCDEFGHIJKLMNOPQRSTUVWXYZ \n'):
|
|
57
|
+
return "Uppercase only — classical cipher"
|
|
58
|
+
if all(c in '12345' for c in ciphertext.replace(' ', '').replace('\n', '')):
|
|
59
|
+
return "Polybius square (digits 1-5)"
|
|
60
|
+
|
|
61
|
+
return "Mixed charset — needs further analysis"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 1.2 Step 2: Frequency Analysis
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from collections import Counter
|
|
68
|
+
|
|
69
|
+
def frequency_analysis(text):
|
|
70
|
+
"""Compute letter frequency distribution."""
|
|
71
|
+
text = text.upper()
|
|
72
|
+
letters = [c for c in text if c.isalpha()]
|
|
73
|
+
total = len(letters)
|
|
74
|
+
freq = Counter(letters)
|
|
75
|
+
|
|
76
|
+
print("Letter frequencies:")
|
|
77
|
+
for letter, count in freq.most_common():
|
|
78
|
+
pct = count / total * 100
|
|
79
|
+
bar = '#' * int(pct)
|
|
80
|
+
print(f" {letter}: {pct:5.1f}% {bar}")
|
|
81
|
+
|
|
82
|
+
return freq
|
|
83
|
+
|
|
84
|
+
# English letter frequency (for comparison):
|
|
85
|
+
# E T A O I N S H R D L C U M W F G Y P B V K J X Q Z
|
|
86
|
+
# 12.7 9.1 8.2 7.5 7.0 6.7 6.3 6.1 6.0 4.3 4.0 2.8 ...
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 1.3 Step 3: Index of Coincidence (IC)
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
def index_of_coincidence(text):
|
|
93
|
+
"""
|
|
94
|
+
IC ≈ 0.065 → English / monoalphabetic substitution
|
|
95
|
+
IC ≈ 0.038 → random / polyalphabetic cipher
|
|
96
|
+
"""
|
|
97
|
+
text = [c for c in text.upper() if c.isalpha()]
|
|
98
|
+
N = len(text)
|
|
99
|
+
freq = Counter(text)
|
|
100
|
+
|
|
101
|
+
ic = sum(f * (f - 1) for f in freq.values()) / (N * (N - 1))
|
|
102
|
+
return ic
|
|
103
|
+
|
|
104
|
+
# Interpretation:
|
|
105
|
+
# IC > 0.060 → monoalphabetic (Caesar, simple substitution, Playfair)
|
|
106
|
+
# IC ≈ 0.045-0.055 → polyalphabetic with short key (Vigenere key < 10)
|
|
107
|
+
# IC ≈ 0.038-0.042 → polyalphabetic with long key or random
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 1.4 Step 4: Kasiski Examination (for Polyalphabetic)
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
from math import gcd
|
|
114
|
+
from functools import reduce
|
|
115
|
+
|
|
116
|
+
def kasiski(ciphertext, min_len=3):
|
|
117
|
+
"""Find repeated sequences and their distances → key length."""
|
|
118
|
+
text = ''.join(c for c in ciphertext.upper() if c.isalpha())
|
|
119
|
+
distances = []
|
|
120
|
+
|
|
121
|
+
for length in range(min_len, min(20, len(text) // 3)):
|
|
122
|
+
for i in range(len(text) - length):
|
|
123
|
+
seq = text[i:i+length]
|
|
124
|
+
j = text.find(seq, i + 1)
|
|
125
|
+
while j != -1:
|
|
126
|
+
distances.append(j - i)
|
|
127
|
+
j = text.find(seq, j + 1)
|
|
128
|
+
|
|
129
|
+
if not distances:
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
# Key length is likely GCD of common distances
|
|
133
|
+
common_gcds = Counter()
|
|
134
|
+
for d in distances:
|
|
135
|
+
for factor in range(2, min(d + 1, 30)):
|
|
136
|
+
if d % factor == 0:
|
|
137
|
+
common_gcds[factor] += 1
|
|
138
|
+
|
|
139
|
+
print("Likely key lengths (by frequency):")
|
|
140
|
+
for length, count in common_gcds.most_common(5):
|
|
141
|
+
print(f" Key length {length}: {count} occurrences")
|
|
142
|
+
|
|
143
|
+
return common_gcds.most_common(1)[0][0]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 2. MONOALPHABETIC SUBSTITUTION
|
|
149
|
+
|
|
150
|
+
### 2.1 Frequency Analysis Attack
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
def solve_substitution(ciphertext, interactive=False):
|
|
154
|
+
"""Solve monoalphabetic substitution via frequency analysis."""
|
|
155
|
+
freq = frequency_analysis(ciphertext)
|
|
156
|
+
|
|
157
|
+
# English frequency order
|
|
158
|
+
eng_order = "ETAOINSRHLDCUMWFGYPBVKJXQZ"
|
|
159
|
+
cipher_order = ''.join(c for c, _ in freq.most_common())
|
|
160
|
+
|
|
161
|
+
# Initial mapping (frequency-based guess)
|
|
162
|
+
mapping = {}
|
|
163
|
+
for i, c in enumerate(cipher_order):
|
|
164
|
+
if i < len(eng_order):
|
|
165
|
+
mapping[c] = eng_order[i]
|
|
166
|
+
|
|
167
|
+
# Apply mapping
|
|
168
|
+
result = ""
|
|
169
|
+
for c in ciphertext.upper():
|
|
170
|
+
result += mapping.get(c, c)
|
|
171
|
+
|
|
172
|
+
return result, mapping
|
|
173
|
+
|
|
174
|
+
# Better approach: use automated solvers
|
|
175
|
+
# quipqiup.com — online substitution solver
|
|
176
|
+
# dcode.fr/monoalphabetic-substitution — with word pattern matching
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 2.2 Known Plaintext (Crib Dragging)
|
|
180
|
+
|
|
181
|
+
If part of the plaintext is known (e.g., "flag{" prefix):
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
def crib_drag_substitution(ciphertext, known_plain, known_cipher):
|
|
185
|
+
"""Build partial mapping from known plaintext-ciphertext pair."""
|
|
186
|
+
mapping = {}
|
|
187
|
+
for p, c in zip(known_plain.upper(), known_cipher.upper()):
|
|
188
|
+
mapping[c] = p
|
|
189
|
+
|
|
190
|
+
# Apply partial mapping
|
|
191
|
+
result = ""
|
|
192
|
+
for c in ciphertext.upper():
|
|
193
|
+
result += mapping.get(c, '?')
|
|
194
|
+
|
|
195
|
+
return result, mapping
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 3. CAESAR / ROT CIPHERS
|
|
201
|
+
|
|
202
|
+
### 3.1 Brute Force
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
def caesar_bruteforce(ciphertext):
|
|
206
|
+
"""Try all 25 shifts, score by English frequency."""
|
|
207
|
+
results = []
|
|
208
|
+
for shift in range(26):
|
|
209
|
+
decrypted = ""
|
|
210
|
+
for c in ciphertext:
|
|
211
|
+
if c.isalpha():
|
|
212
|
+
base = ord('A') if c.isupper() else ord('a')
|
|
213
|
+
decrypted += chr((ord(c) - base - shift) % 26 + base)
|
|
214
|
+
else:
|
|
215
|
+
decrypted += c
|
|
216
|
+
|
|
217
|
+
# Chi-squared scoring against English frequency
|
|
218
|
+
score = chi_squared_score(decrypted)
|
|
219
|
+
results.append((shift, score, decrypted))
|
|
220
|
+
|
|
221
|
+
results.sort(key=lambda x: x[1])
|
|
222
|
+
return results[0] # best match
|
|
223
|
+
|
|
224
|
+
def chi_squared_score(text):
|
|
225
|
+
"""Lower score = closer to English."""
|
|
226
|
+
expected = {
|
|
227
|
+
'E': 12.7, 'T': 9.1, 'A': 8.2, 'O': 7.5, 'I': 7.0,
|
|
228
|
+
'N': 6.7, 'S': 6.3, 'H': 6.1, 'R': 6.0, 'D': 4.3,
|
|
229
|
+
'L': 4.0, 'C': 2.8, 'U': 2.8, 'M': 2.4, 'W': 2.4,
|
|
230
|
+
'F': 2.2, 'G': 2.0, 'Y': 2.0, 'P': 1.9, 'B': 1.5,
|
|
231
|
+
'V': 1.0, 'K': 0.8, 'J': 0.2, 'X': 0.2, 'Q': 0.1, 'Z': 0.1,
|
|
232
|
+
}
|
|
233
|
+
text = text.upper()
|
|
234
|
+
letters = [c for c in text if c.isalpha()]
|
|
235
|
+
total = len(letters)
|
|
236
|
+
if total == 0:
|
|
237
|
+
return float('inf')
|
|
238
|
+
|
|
239
|
+
freq = Counter(letters)
|
|
240
|
+
score = sum(
|
|
241
|
+
(freq.get(c, 0) / total * 100 - expected.get(c, 0)) ** 2 / max(expected.get(c, 0.1), 0.1)
|
|
242
|
+
for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
243
|
+
)
|
|
244
|
+
return score
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 3.2 ROT13 and ROT47
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
import codecs
|
|
251
|
+
|
|
252
|
+
# ROT13 (letters only)
|
|
253
|
+
rot13 = codecs.decode(ciphertext, 'rot_13')
|
|
254
|
+
|
|
255
|
+
# ROT47 (ASCII 33-126)
|
|
256
|
+
def rot47(text):
|
|
257
|
+
return ''.join(
|
|
258
|
+
chr(33 + (ord(c) - 33 + 47) % 94) if 33 <= ord(c) <= 126 else c
|
|
259
|
+
for c in text
|
|
260
|
+
)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 4. VIGENERE CIPHER
|
|
266
|
+
|
|
267
|
+
### 4.1 Full Attack Workflow
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
Step 1: Confirm polyalphabetic (IC ≈ 0.04-0.05)
|
|
271
|
+
Step 2: Find key length (Kasiski + IC per period)
|
|
272
|
+
Step 3: For each key position, solve as single Caesar cipher
|
|
273
|
+
Step 4: Assemble key → decrypt
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 4.2 IC-Based Key Length Detection
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
def find_vigenere_key_length(ciphertext, max_key=20):
|
|
280
|
+
"""Use IC to find Vigenere key length."""
|
|
281
|
+
text = [c for c in ciphertext.upper() if c.isalpha()]
|
|
282
|
+
results = []
|
|
283
|
+
|
|
284
|
+
for kl in range(1, max_key + 1):
|
|
285
|
+
# Split text into kl columns
|
|
286
|
+
columns = [[] for _ in range(kl)]
|
|
287
|
+
for i, c in enumerate(text):
|
|
288
|
+
columns[i % kl].append(c)
|
|
289
|
+
|
|
290
|
+
# Average IC across columns
|
|
291
|
+
avg_ic = sum(
|
|
292
|
+
index_of_coincidence(''.join(col)) for col in columns
|
|
293
|
+
) / kl
|
|
294
|
+
|
|
295
|
+
results.append((kl, avg_ic))
|
|
296
|
+
print(f" Key length {kl:2d}: IC = {avg_ic:.4f}")
|
|
297
|
+
|
|
298
|
+
# Key length with IC closest to 0.065
|
|
299
|
+
best = max(results, key=lambda x: x[1])
|
|
300
|
+
return best[0]
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### 4.3 Per-Position Frequency Attack
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
def crack_vigenere(ciphertext, key_length):
|
|
307
|
+
"""Crack Vigenere given known key length."""
|
|
308
|
+
text = [c for c in ciphertext.upper() if c.isalpha()]
|
|
309
|
+
key = ""
|
|
310
|
+
|
|
311
|
+
for pos in range(key_length):
|
|
312
|
+
column = ''.join(text[i] for i in range(pos, len(text), key_length))
|
|
313
|
+
# Solve as Caesar cipher
|
|
314
|
+
shift, score, _ = caesar_bruteforce(column)
|
|
315
|
+
key += chr(shift + ord('A'))
|
|
316
|
+
|
|
317
|
+
# Decrypt
|
|
318
|
+
plaintext = ""
|
|
319
|
+
ki = 0
|
|
320
|
+
for c in ciphertext:
|
|
321
|
+
if c.isalpha():
|
|
322
|
+
shift = ord(key[ki % key_length]) - ord('A')
|
|
323
|
+
base = ord('A') if c.isupper() else ord('a')
|
|
324
|
+
plaintext += chr((ord(c) - base - shift) % 26 + base)
|
|
325
|
+
ki += 1
|
|
326
|
+
else:
|
|
327
|
+
plaintext += c
|
|
328
|
+
|
|
329
|
+
return key, plaintext
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 5. AFFINE CIPHER
|
|
335
|
+
|
|
336
|
+
### 5.1 Definition
|
|
337
|
+
|
|
338
|
+
`E(x) = (a·x + b) mod 26` where gcd(a, 26) = 1.
|
|
339
|
+
|
|
340
|
+
Valid a values: 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25 (12 values).
|
|
341
|
+
|
|
342
|
+
### 5.2 Brute Force (312 combinations)
|
|
343
|
+
|
|
344
|
+
```python
|
|
345
|
+
def crack_affine(ciphertext):
|
|
346
|
+
"""Brute force affine cipher: 12 × 26 = 312 combinations."""
|
|
347
|
+
valid_a = [a for a in range(1, 26) if gcd(a, 26) == 1]
|
|
348
|
+
|
|
349
|
+
for a in valid_a:
|
|
350
|
+
a_inv = pow(a, -1, 26)
|
|
351
|
+
for b in range(26):
|
|
352
|
+
plaintext = ""
|
|
353
|
+
for c in ciphertext.upper():
|
|
354
|
+
if c.isalpha():
|
|
355
|
+
y = ord(c) - ord('A')
|
|
356
|
+
x = (a_inv * (y - b)) % 26
|
|
357
|
+
plaintext += chr(x + ord('A'))
|
|
358
|
+
else:
|
|
359
|
+
plaintext += c
|
|
360
|
+
|
|
361
|
+
score = chi_squared_score(plaintext)
|
|
362
|
+
if score < 50: # reasonable English
|
|
363
|
+
print(f"a={a}, b={b}: {plaintext[:50]}...")
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 5.3 Known Plaintext
|
|
367
|
+
|
|
368
|
+
```python
|
|
369
|
+
def affine_from_known(plain1, cipher1, plain2, cipher2):
|
|
370
|
+
"""Recover (a, b) from two known plaintext-ciphertext pairs."""
|
|
371
|
+
p1, c1 = ord(plain1) - ord('A'), ord(cipher1) - ord('A')
|
|
372
|
+
p2, c2 = ord(plain2) - ord('A'), ord(cipher2) - ord('A')
|
|
373
|
+
|
|
374
|
+
# c1 = a*p1 + b, c2 = a*p2 + b
|
|
375
|
+
# c1 - c2 = a*(p1 - p2) mod 26
|
|
376
|
+
diff_p = (p1 - p2) % 26
|
|
377
|
+
diff_c = (c1 - c2) % 26
|
|
378
|
+
|
|
379
|
+
if gcd(diff_p, 26) != 1:
|
|
380
|
+
return None
|
|
381
|
+
|
|
382
|
+
a = (diff_c * pow(diff_p, -1, 26)) % 26
|
|
383
|
+
b = (c1 - a * p1) % 26
|
|
384
|
+
return a, b
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 6. HILL CIPHER
|
|
390
|
+
|
|
391
|
+
Matrix-based cipher: `C = K · P mod 26` where K is an n×n key matrix.
|
|
392
|
+
|
|
393
|
+
### 6.1 Known-Plaintext Attack
|
|
394
|
+
|
|
395
|
+
```python
|
|
396
|
+
import numpy as np
|
|
397
|
+
|
|
398
|
+
def crack_hill(known_plain, known_cipher, n=2):
|
|
399
|
+
"""Recover Hill cipher key from known plaintext-ciphertext (mod 26)."""
|
|
400
|
+
# Convert to numbers
|
|
401
|
+
P = [ord(c) - ord('A') for c in known_plain.upper()]
|
|
402
|
+
C = [ord(c) - ord('A') for c in known_cipher.upper()]
|
|
403
|
+
|
|
404
|
+
# Build matrices (need at least n pairs of n-grams)
|
|
405
|
+
P_matrix = np.array(P[:n*n]).reshape(n, n).T
|
|
406
|
+
C_matrix = np.array(C[:n*n]).reshape(n, n).T
|
|
407
|
+
|
|
408
|
+
# K = C · P⁻¹ mod 26
|
|
409
|
+
# Need modular matrix inverse
|
|
410
|
+
from sympy import Matrix
|
|
411
|
+
P_mat = Matrix(P_matrix.tolist())
|
|
412
|
+
C_mat = Matrix(C_matrix.tolist())
|
|
413
|
+
|
|
414
|
+
P_inv = P_mat.inv_mod(26)
|
|
415
|
+
K = (C_mat * P_inv) % 26
|
|
416
|
+
|
|
417
|
+
return K
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## 7. TRANSPOSITION CIPHERS
|
|
423
|
+
|
|
424
|
+
### 7.1 Rail Fence
|
|
425
|
+
|
|
426
|
+
```python
|
|
427
|
+
def rail_fence_decrypt(ciphertext, rails):
|
|
428
|
+
"""Decrypt rail fence cipher."""
|
|
429
|
+
n = len(ciphertext)
|
|
430
|
+
# Build the zigzag pattern
|
|
431
|
+
pattern = []
|
|
432
|
+
for i in range(n):
|
|
433
|
+
row = 0
|
|
434
|
+
cycle = 2 * (rails - 1)
|
|
435
|
+
pos = i % cycle
|
|
436
|
+
row = pos if pos < rails else cycle - pos
|
|
437
|
+
pattern.append((row, i))
|
|
438
|
+
|
|
439
|
+
pattern.sort()
|
|
440
|
+
|
|
441
|
+
# Fill in characters
|
|
442
|
+
result = [''] * n
|
|
443
|
+
ci = 0
|
|
444
|
+
for _, orig_pos in pattern:
|
|
445
|
+
result[orig_pos] = ciphertext[ci]
|
|
446
|
+
ci += 1
|
|
447
|
+
|
|
448
|
+
return ''.join(result)
|
|
449
|
+
|
|
450
|
+
# Brute force all rail counts
|
|
451
|
+
for rails in range(2, 20):
|
|
452
|
+
print(f"Rails {rails}: {rail_fence_decrypt(ct, rails)[:50]}")
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### 7.2 Columnar Transposition
|
|
456
|
+
|
|
457
|
+
```python
|
|
458
|
+
def columnar_decrypt(ciphertext, key):
|
|
459
|
+
"""Decrypt columnar transposition given key word."""
|
|
460
|
+
n_cols = len(key)
|
|
461
|
+
n_rows = -(-len(ciphertext) // n_cols) # ceiling division
|
|
462
|
+
|
|
463
|
+
# Determine column order from key
|
|
464
|
+
order = sorted(range(n_cols), key=lambda i: key[i])
|
|
465
|
+
|
|
466
|
+
# Calculate column lengths (some may be shorter)
|
|
467
|
+
full_cols = len(ciphertext) % n_cols
|
|
468
|
+
if full_cols == 0:
|
|
469
|
+
full_cols = n_cols
|
|
470
|
+
|
|
471
|
+
# Split ciphertext into columns (in key order)
|
|
472
|
+
columns = [''] * n_cols
|
|
473
|
+
pos = 0
|
|
474
|
+
for col_idx in order:
|
|
475
|
+
col_len = n_rows if col_idx < full_cols else n_rows - 1
|
|
476
|
+
columns[col_idx] = ciphertext[pos:pos + col_len]
|
|
477
|
+
pos += col_len
|
|
478
|
+
|
|
479
|
+
# Read off row by row
|
|
480
|
+
plaintext = ''
|
|
481
|
+
for row in range(n_rows):
|
|
482
|
+
for col in range(n_cols):
|
|
483
|
+
if row < len(columns[col]):
|
|
484
|
+
plaintext += columns[col][row]
|
|
485
|
+
|
|
486
|
+
return plaintext
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
---
|
|
490
|
+
|
|
491
|
+
## 8. XOR CIPHER
|
|
492
|
+
|
|
493
|
+
### 8.1 Single-Byte XOR
|
|
494
|
+
|
|
495
|
+
See [symmetric-cipher-attacks](../symmetric-cipher-attacks/SKILL.md) Section 4.2 for full implementation.
|
|
496
|
+
|
|
497
|
+
### 8.2 Multi-Byte XOR (xortool)
|
|
498
|
+
|
|
499
|
+
```bash
|
|
500
|
+
# Automatic key length detection and cracking
|
|
501
|
+
xortool ciphertext.bin -l 5 # try key length 5
|
|
502
|
+
xortool ciphertext.bin -b # brute force key length
|
|
503
|
+
xortool ciphertext.bin -c 20 # assume most common char is space (0x20)
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### 8.3 Known Plaintext XOR
|
|
507
|
+
|
|
508
|
+
```python
|
|
509
|
+
def xor_known_plaintext(ciphertext, known_plain, offset=0):
|
|
510
|
+
"""Recover XOR key from known plaintext at given offset."""
|
|
511
|
+
key_fragment = bytes(
|
|
512
|
+
c ^ p for c, p in zip(ciphertext[offset:], known_plain)
|
|
513
|
+
)
|
|
514
|
+
print(f"Key fragment: {key_fragment}")
|
|
515
|
+
|
|
516
|
+
# If repeating key, infer full key from fragment
|
|
517
|
+
return key_fragment
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## 9. SPECIAL CIPHERS
|
|
523
|
+
|
|
524
|
+
### 9.1 Bacon Cipher
|
|
525
|
+
|
|
526
|
+
Binary encoding using two typefaces (A=normal, B=bold/italic).
|
|
527
|
+
|
|
528
|
+
```python
|
|
529
|
+
BACON = {
|
|
530
|
+
'AAAAA': 'A', 'AAAAB': 'B', 'AAABA': 'C', 'AAABB': 'D',
|
|
531
|
+
'AABAA': 'E', 'AABAB': 'F', 'AABBA': 'G', 'AABBB': 'H',
|
|
532
|
+
'ABAAA': 'I', 'ABAAB': 'J', 'ABABA': 'K', 'ABABB': 'L',
|
|
533
|
+
'ABBAA': 'M', 'ABBAB': 'N', 'ABBBA': 'O', 'ABBBB': 'P',
|
|
534
|
+
'BAAAA': 'Q', 'BAAAB': 'R', 'BAABA': 'S', 'BAABB': 'T',
|
|
535
|
+
'BABAA': 'U', 'BABAB': 'V', 'BABBA': 'W', 'BABBB': 'X',
|
|
536
|
+
'BAAAA': 'Y', 'BAAAB': 'Z',
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
def decode_bacon(text):
|
|
540
|
+
"""Decode Bacon cipher: uppercase=B, lowercase=A (or similar mapping)."""
|
|
541
|
+
binary = ''.join('B' if c.isupper() else 'A' for c in text if c.isalpha())
|
|
542
|
+
result = ''
|
|
543
|
+
for i in range(0, len(binary) - 4, 5):
|
|
544
|
+
chunk = binary[i:i+5]
|
|
545
|
+
result += BACON.get(chunk, '?')
|
|
546
|
+
return result
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### 9.2 Polybius Square
|
|
550
|
+
|
|
551
|
+
```
|
|
552
|
+
1 2 3 4 5
|
|
553
|
+
┌──────────
|
|
554
|
+
1 │ A B C D E
|
|
555
|
+
2 │ F G H I/J K
|
|
556
|
+
3 │ L M N O P
|
|
557
|
+
4 │ Q R S T U
|
|
558
|
+
5 │ V W X Y Z
|
|
559
|
+
|
|
560
|
+
"HELLO" = "23 15 31 31 34"
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### 9.3 Playfair
|
|
564
|
+
|
|
565
|
+
5×5 grid cipher encrypting digraphs.
|
|
566
|
+
|
|
567
|
+
```
|
|
568
|
+
Key: "MONARCHY" → grid:
|
|
569
|
+
M O N A R
|
|
570
|
+
C H Y B D
|
|
571
|
+
E F G I/J K
|
|
572
|
+
L P Q S T
|
|
573
|
+
U V W X Z
|
|
574
|
+
|
|
575
|
+
Rules:
|
|
576
|
+
Same row → shift right: HE → FE → "GF"
|
|
577
|
+
Same col → shift down
|
|
578
|
+
Rectangle → swap columns
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
## 10. DECISION TREE
|
|
584
|
+
|
|
585
|
+
```
|
|
586
|
+
Unknown ciphertext — how to identify and break?
|
|
587
|
+
│
|
|
588
|
+
├─ Step 1: Check encoding
|
|
589
|
+
│ ├─ Base64 alphabet with padding? → Decode first, then re-analyze
|
|
590
|
+
│ ├─ Hex string? → Convert to bytes, re-analyze
|
|
591
|
+
│ ├─ Binary (01)? → Convert to ASCII
|
|
592
|
+
│ ├─ Morse (.-/)? → Decode Morse
|
|
593
|
+
│ └─ Printable text? → Continue to Step 2
|
|
594
|
+
│
|
|
595
|
+
├─ Step 2: Character set
|
|
596
|
+
│ ├─ Only letters (A-Z)?
|
|
597
|
+
│ │ ├─ Compute IC
|
|
598
|
+
│ │ │ ├─ IC ≈ 0.065 → Monoalphabetic
|
|
599
|
+
│ │ │ │ ├─ Uniform shift in freq? → Caesar → brute force 25
|
|
600
|
+
│ │ │ │ ├─ Random-looking mapping? → Simple substitution → frequency analysis
|
|
601
|
+
│ │ │ │ └─ Digraph patterns? → Playfair → digraph analysis
|
|
602
|
+
│ │ │ │
|
|
603
|
+
│ │ │ ├─ IC ≈ 0.04-0.05 → Polyalphabetic
|
|
604
|
+
│ │ │ │ ├─ Kasiski → find key length
|
|
605
|
+
│ │ │ │ └─ Per-position frequency → crack Vigenere
|
|
606
|
+
│ │ │ │
|
|
607
|
+
│ │ │ └─ IC ≈ 0.038 → Very long key or one-time pad
|
|
608
|
+
│ │ │ └─ Look for key reuse or weak key generation
|
|
609
|
+
│ │ │
|
|
610
|
+
│ │ └─ Letters appear scrambled (right freq, wrong order)?
|
|
611
|
+
│ │ └─ Transposition
|
|
612
|
+
│ │ ├─ Rail fence → brute force rail count
|
|
613
|
+
│ │ └─ Columnar → try common key lengths
|
|
614
|
+
│ │
|
|
615
|
+
│ ├─ Numbers (digit pairs)?
|
|
616
|
+
│ │ ├─ Pairs in range 11-55 → Polybius square
|
|
617
|
+
│ │ └─ Numbers mod 26 → numeric substitution
|
|
618
|
+
│ │
|
|
619
|
+
│ ├─ Mixed case with pattern?
|
|
620
|
+
│ │ └─ Upper/lower encodes binary → Bacon cipher
|
|
621
|
+
│ │
|
|
622
|
+
│ └─ Non-printable bytes?
|
|
623
|
+
│ └─ XOR cipher
|
|
624
|
+
│ ├─ Single-byte key → brute force 256
|
|
625
|
+
│ ├─ Repeating key → xortool / Hamming distance
|
|
626
|
+
│ └─ Known plaintext → direct key recovery
|
|
627
|
+
│
|
|
628
|
+
└─ Step 3: Apply specific attack
|
|
629
|
+
├─ Substitution → quipqiup.com / frequency analysis
|
|
630
|
+
├─ Caesar → dcode.fr / brute force
|
|
631
|
+
├─ Vigenere → Kasiski + per-column Caesar
|
|
632
|
+
├─ Affine → brute force 312 combinations
|
|
633
|
+
├─ Hill → known-plaintext matrix attack
|
|
634
|
+
├─ Transposition → pattern analysis + brute force
|
|
635
|
+
└─ XOR → xortool / crib dragging
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
## 11. TOOLS
|
|
641
|
+
|
|
642
|
+
| Tool | Purpose | URL/Usage |
|
|
643
|
+
|---|---|---|
|
|
644
|
+
| **CyberChef** | Universal encoding/cipher Swiss army knife | gchq.github.io/CyberChef |
|
|
645
|
+
| **dcode.fr** | 200+ cipher solvers online | dcode.fr |
|
|
646
|
+
| **quipqiup** | Automated substitution cipher solver | quipqiup.com |
|
|
647
|
+
| **xortool** | XOR cipher analysis and cracking | `pip install xortool` |
|
|
648
|
+
| **RsaCtfTool** | RSA + some classical cipher support | GitHub |
|
|
649
|
+
| **Ciphey** | Automated cipher detection and decryption | `pip install ciphey` |
|
|
650
|
+
| **hashID** | Identify hash types | `pip install hashid` |
|
|
651
|
+
| **Python** | Custom frequency analysis and scripting | All attacks above |
|
|
652
|
+
|
|
653
|
+
### CyberChef Recipes (Common)
|
|
654
|
+
|
|
655
|
+
```
|
|
656
|
+
ROT13: ROT13
|
|
657
|
+
Caesar brute force: ROT13 (with offset slider)
|
|
658
|
+
Base64 decode: From Base64
|
|
659
|
+
Hex decode: From Hex
|
|
660
|
+
XOR: XOR (key as hex/utf8)
|
|
661
|
+
Vigenere: Vigenère Decode
|
|
662
|
+
Morse: From Morse Code
|
|
663
|
+
```
|