All posts
Ethical Hacking

Anatomy of a Modern Web Exploit: From Recon to RCE

Follow a realistic attack chain from reconnaissance through SSRF and insecure deserialization to remote code execution — and how to break the chain at every stage.

SKSushan Khadka
June 10, 2026 (2mo ago)6 min read
Anatomy of a Modern Web Exploit: From Recon to RCE — article by Sushan Khadka (namelessnerd)

Real breaches are rarely one magic bug. They are a kill chain — small, individually survivable weaknesses linked into a path to your crown jewels. Understand the chain and you can cut it at any link.

Anatomy of a Modern Web Exploit: From Recon to RCE - diagram by Sushan Khadka (namelessnerd)

Why chains, not bugs

Defenders instinctively rank vulnerabilities in isolation: this one is "medium," that one is "low," we'll fix them next sprint. Attackers do the opposite — they look at how a "low" information leak feeds a "medium" SSRF that unlocks a "high" credential theft. The severity of a chain is not the max of its links; it is their product. That is why a mature review asks not just "is this bug exploitable?" but "what does this bug become when combined with the next one?"

The chain below is composited from patterns that show up over and over in real incident reports. Follow it link by link, and notice that every stage has a cheap, boring defense that would have stopped the whole thing.

Recon: mapping the surface

It starts quietly. An attacker enumerates subdomains, fingerprints frameworks, scrapes exposed endpoints, and reads your error messages for clues. Nothing is exploited yet — they are just drawing the map. A verbose stack trace that names your framework and version, a forgotten staging. subdomain still pointing at production data, an S3 bucket listed in a JavaScript bundle — each is a free gift.

The defense is to shrink the map. Retire forgotten subdomains, return generic errors, and stop leaking versions and stack traces. Put internal tools behind a VPN, not behind "nobody knows the URL." You cannot attack what you cannot find, and every asset you expose is one the attacker gets to probe for free.

The first crack: input that reaches somewhere it shouldn't

Between recon and the real foothold there is usually an injection-class bug — the app takes a value from the request and uses it in a context where it can change meaning. SQL injection turns a search box into a database console. Command injection turns a filename field into a shell. Server-side template injection turns a "hi, {{name}}" greeting into code execution inside the template engine.

The common root is string concatenation across a trust boundary. The fix is equally common: never build a query, a command, or a template out of raw user input. Parameterize queries, pass command arguments as an array rather than a shell string, and keep user data as data — never let it flow into a position where the interpreter treats it as instructions.

SSRF: your server as a proxy

The first real foothold is often Server-Side Request Forgery (SSRF) — a feature that fetches a URL on the user's behalf, tricked into requesting an internal address. A "fetch this image from a URL" or "import from this webhook" feature is the classic culprit. Point it at http://localhost:8080/admin or an internal service and suddenly the attacker is browsing your private network from inside, past the firewall that was supposed to keep them out.

The classic prize is the cloud metadata endpoint at 169.254.169.254, which on a misconfigured instance hands out temporary IAM credentials. One SSRF request:

GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/

and the response is a set of live cloud keys. Break this link with egress filtering (servers should not call arbitrary outbound hosts), strict allowlists for fetch features, blocking requests to private IP ranges and link-local addresses, and IMDSv2, which requires a signed token and defeats naive SSRF. Note the trap: validating the URL once and then following redirects re-opens the hole, because the attacker controls the redirect target. Re-validate every hop, or disable redirects entirely.

Deserialization: data that becomes code

With stolen creds or deeper access, the finale is often insecure deserialization. The app rebuilds objects from untrusted bytes, and a crafted payload turns that reconstruction into remote code execution — the moment data quietly becomes code. Java's native serialization, Python's pickle, PHP's unserialize, and .NET's BinaryFormatter have all been the vehicle. The attacker does not send data; they send a graph of objects whose reconstruction triggers a chain of method calls ending in a shell command.

untrusted bytes → deserialize → object graph rebuilt
             → gadget chain fires → RCE

Cut it by never deserializing untrusted input into rich objects. Prefer typed, schema-validated formats like JSON with strict parsing, and sign or encrypt any serialized blob that must round-trip through a client so a tampered payload fails verification before it is ever parsed.

Privilege escalation and lateral movement

RCE on one box is rarely the goal — it is a staging point. From there the attacker looks for lateral movement: reused credentials that unlock the next service, an over-permissioned service account that can read the whole database, a shared secret in an environment variable that opens a production system. This is where a single compromised container becomes a full breach.

The defenses here are the least glamorous and the most effective. Least privilege ensures a leaked credential can barely do anything — the SSRF-stolen IAM role should grant read access to one bucket, not admin over the account. Network segmentation keeps a foothold in the web tier from reaching the database tier directly. Short-lived credentials mean stolen keys expire before they are useful.

Defense in depth wins

No single fix saves you, and that is the point. Each layer you add is one more link the attacker has to break, and the beauty of defense in depth is that the layers are independent — beating your input validation does nothing to help beat your egress filter, which does nothing to help beat your least-privilege IAM policy. The attacker needs to win every round; you only need to win one.

That is also how you should prioritize as a defender. You do not need to be un-hackable at recon; you need to make sure that even if recon succeeds, SSRF is blocked — and even if SSRF succeeds, the credentials it steals are nearly worthless. Assume each layer will eventually fail and ask what catches the fall.

The takeaway

Read more posts