Enumerate, then enumerate again
Most boxes fall to enumeration, not exploits. When you're stuck, you almost always missed something — re-scan all ports, re-read every page, re-check every service version.
RatCTF
RatCTF
Battle-tested hunting wisdom — recon, web, privesc, AD, crypto, and the mindset to stay sharp. Filter by category, steal what you need, go pop a box.
Most boxes fall to enumeration, not exploits. When you're stuck, you almost always missed something — re-scan all ports, re-read every page, re-check every service version.
Hints get you unstuck, but the players who improve fastest reconstruct the intended path themselves. Treat each box as a puzzle the author left clues for.
Log every credential, port, and odd response as you go. Half of privesc is remembering something you already saw three steps ago.
Designed boxes have an intended route. Brute-forcing a wall usually means the real door is somewhere you haven't looked.
Default scans hit the top 1000. The interesting service is often on a high, non-standard port. Do a full TCP sweep, then version-scan what you find.
Anonymous FTP is shockingly common. `anonymous` / blank password — browse the share before assuming it's locked down.
An initial TTL near 64 suggests Linux/Unix; near 128 suggests Windows. A quick fingerprint before you commit tooling.
Disallowed paths are a map of what the admin didn't want indexed — often exactly what you want to find.
One IP can serve many sites by Host header. Fuzz vhosts — the vulnerable app is frequently on a hostname the default page never mentions.
If user input is reflected and the app uses a template engine, try SSTI alongside XSS — same root cause (input concatenated server-side), much bigger impact.
Many GraphQL APIs leave introspection enabled. Pull the full schema before guessing — it hands you every type and field.
Any `id=`, `user=`, `order=` in a URL or body is worth incrementing/decrementing. Authorization checks are skipped more often than you'd think.
A file-read (LFI) that can reach a log you control (User-Agent, access log) can become code execution when the log is interpreted by the language runtime.
Decode JWTs (base64) and look at the alg. `none`, weak HMAC secrets, and kid path-traversal are all classic forging routes.
Content-Type, extension, and magic-byte checks each fail in isolation. Double extensions, null bytes, polyglots, and case tricks all still work somewhere.
After any foothold, run `sudo -l`. A single NOPASSWD binary is often the whole privesc — check it on GTFOBins.
`find / -perm -4000 2>/dev/null` lists SUID binaries. Cross-reference each against GTFOBins — many have a documented shell escape.
`getcap -r / 2>/dev/null`. A binary with cap_setuid or cap_dac_read_search can be as good as SUID root and is easy to overlook.
Root-owned cron jobs that run a writable script or use a relative path are a clean, repeatable root. Check `/etc/crontab` and `/etc/cron.*`.
Passwords in config files, bash_history, and .env files get reused for SSH, DB, and sudo. Grep web roots and home dirs before anything fancy.
A world-writable script that a privileged process runs (cron, service, .bashrc sourced by root) is a direct path up. `find / -writable -type f 2>/dev/null`.
Any authenticated user can request a TGS for an SPN and crack it offline. Service accounts often have weak, never-rotated passwords.
Accounts with 'do not require Kerberos preauth' hand you a crackable AS-REP without any creds. Always enumerate for them.
Don't hand-walk ACLs. Collect with SharpHound, then let BloodHound show you the shortest path to Domain Admin.
On a compromised host, LSASS memory yields hashes, tickets, and sometimes plaintext (legacy WDigest). Credential Guard is the mitigation to watch for.
Add `role`, `isAdmin`, `verified` to a JSON body the API didn't ask for. Frameworks that bind the whole object will happily set them.
Object-level auth (another user's id) and function-level auth (an admin-only verb) are the two most-paid API bugs. Test both on every endpoint.
Loose redirect_uri matching + an open redirect on the client = token theft. Always inspect the full OAuth dance for where the code lands.
No rate limit on login/OTP turns a 6-digit code into a 5-minute attack. Check whether the limit is per-account, per-IP, or absent.
Identical plaintext blocks → identical ciphertext blocks. Repeating 16-byte patterns in a token usually mean ECB and copy-paste attacks.
A server that distinguishes 'bad padding' from 'bad MAC' on CBC ciphertext lets you decrypt (and forge) without the key. Watch for differing error responses.
Small e with no padding, shared primes across keys, or a factorable N (try FactorDB) all break RSA. Always look at the actual parameters.
Once you own a jump host, `ssh -L` / `-D` reaches segments you can't touch directly. Local, remote, and dynamic forwarding cover almost every pivot.
The password you found is the start of lateral movement. Spray it across every host and service you can see before escalating locally.
Run `ss -tlnp` after a foothold. Services listening only on localhost (admin panels, Redis, debug ports) are invisible from outside but yours now.