64 lines
3.4 KiB
Markdown
64 lines
3.4 KiB
Markdown
# CTF Cheatsheet — distilled from p4-team/ctf (784 writeups)
|
|
|
|
## GENERAL WORKFLOW (their consistent pattern)
|
|
1. **Read the source first.** 80% of solutions = one logic bug. Binary/PHP/Py/Ruby.
|
|
2. **Identify category**, then apply the matching recipe below.
|
|
3. **Modular solver**: separate file `solve.py` / `exploit.py` / `attack.py` / `*.sage`.
|
|
4. **Verify each step with asserts** (like `check_jump()` in their sage code).
|
|
5. Print the flag; never hardcode it.
|
|
6. Use `scaffold.py` to generate event + task skeletons.
|
|
|
|
## WEB
|
|
- **Sanitization order bug (piapiapia)**: `filter()` ran AFTER `serialize()` ->
|
|
string-length change lets you inject into serialized object. Bypass validation
|
|
with arrays (`nickname[]=`).
|
|
- **Read provided source/PHP** — vuln is almost always visible. SQLi/filter bypass/
|
|
SSRF/LFI derive from the source, not black-box.
|
|
- **Tools**: requests, beautifulsoup, burp, sometimes selenium.
|
|
|
|
## BINARY / PWN
|
|
- **Leak first**: format string `%p %p %p...` or GOT leak, then ROP.
|
|
- **ret2libc**: leak libc base -> one_gadget / system("/bin/sh").
|
|
- **Stack overflow + CET (smash)**: emulator CET config block at fixed offset from
|
|
libc; write 0 to disable, then free ROP.
|
|
- **Arbitrary write primitive**: overwrite saved RBP to control a later frame pointer.
|
|
- **Debugger harness**: script a remote debugger (breakpoints, read/mod registers)
|
|
to dump memory (registers_matter).
|
|
- **Tools**: pwntools (remote/ELF/ROP/context), gdb+gef/pwndbg, checksec, ROPgadget.
|
|
|
|
## RE (reverse engineering)
|
|
- **Static-first**: IDA/Ghidra; extract `.rodata` bytes -> often just RSA params.
|
|
- **RSA-from-dump (reversing_is_amazing)**: parse `db XXh` lines -> `RSA.importKey`
|
|
-> decrypt given ciphertext.
|
|
- **Symbolic execution**: angr to reach a "win" state, avoiding "fail" states.
|
|
- **Emulation / patching**: unicorn to emulate a function; lief to patch binaries.
|
|
- **Tools**: IDA, ghidra, radare2, lief, pyelftools, angr, unicorn, capstone.
|
|
|
|
## MISC
|
|
- **Oracle byte-by-byte (heXdump)**: `xxd -r -ps` does NOT truncate -> overwrite 1
|
|
byte, match output, recover flag char-by-char over CHARSET.
|
|
- **Encoding chains**: brute b64/b32/b16/hex until "flag"/"CTF" appears.
|
|
- **PRNG reversing (xor_and_shift)**: linear PRNG over GF(2) -> symbolic exec +
|
|
matrix exponentiation in sage to "jump" the state.
|
|
- **Constraint solving**: z3 when inputs must satisfy arithmetic conditions.
|
|
|
|
## FORENSICS
|
|
- **PCAP**: tshark/scapy to extract streams; look for exfil/TLS keys.
|
|
- **Memory**: volatility (imageinfo, pslist, dump).
|
|
- **Stego**: PIL for pixel work; binwalk for appended data; audio via spectrogram.
|
|
- **Tools**: scapy, tshark/wireshark, volatility, PIL, binwalk.
|
|
|
|
## CRYPTO (bonus — most common, 123 challenges in p4)
|
|
- **RSA recover n (lost_modulus)**: have e,d,ipmq=inv(p,q),iqmp=inv(q,p), not n ->
|
|
derive quadratic in phi -> `gmpy2.iroot` -> p,q. (lib.crypto_utils.recover_n_from_keys)
|
|
- **Common modulus**: same m, same n, coprime e -> CRT combine.
|
|
- **Wiener**: small d -> continued fractions on e/n. (lib.crypto_utils.wiener)
|
|
- **Håstad broadcast**: same small m^e across moduli with small e -> CRT + e-th root.
|
|
- **Lattice/LLL**: small roots, Coppersmith, hidden-number problem.
|
|
- **Reduced-round block cipher (a2s)**: differential cryptanalysis; 2^16-bit DeltaSet.
|
|
- **Tools**: pycryptodome, gmpy2, sage, numpy, z3, angr (rare).
|
|
|
|
## QUICK SETUP
|
|
pip install pwntools pycryptodome gmpy2 requests beautifulsoup4 pillow scapy
|
|
# + sage, z3-solver, angr, capstone, unicorn, lief (as needed)
|