The exploit opens the door; the payload walks through it
It helps to keep two ideas cleanly separated. The exploit is the key — the technique that abuses a vulnerability to hijack a program's execution. The payload is what you do once you have that control: the code that runs on the target after the vulnerability is triggered. The exploit gets you in; the payload decides what "in" is worth.
This separation is the reason a single exploit can be reused for wildly different outcomes. The same memory-corruption bug might be paired with a payload that simply adds a user account, one that spawns a command shell, or one that loads a full remote-administration agent into memory. You choose the payload to match the goal of the engagement, the constraints of the target, and how much noise you can afford to make.
Bind shells vs. reverse shells
The most common payload is a shell — command-line access to the target. There are two ways to wire up that connection, and the difference comes down to who calls whom. A bind shell opens a network listener on the target and waits; the attacker then connects in to it. A reverse shell flips the direction: the target reaches back out to a listener the attacker is already running. That single design choice decides whether your shell works at all.
| Type | How it connects | When it works |
|---|---|---|
| Bind shell | Opens a listener on the target and waits. The attacker initiates the connection inbound to the target's IP and port. | Only when the attacker can actually reach that port. Fails the moment an ingress firewall or NAT in front of the target blocks inbound connections — which today is nearly always. |
| Reverse shell | The target connects back out to a listener the attacker is already running. The connection is outbound from the target's perspective. | Beats NAT and most egress filtering, because outbound traffic on common ports is usually allowed. This is why a reverse shell is the default choice in the real world. |
The parameters you set follow directly from the direction of the connection. For a reverse payload you supply LHOST and LPORT — the listener host and port, meaning your machine, the address the target will call home to. For a bind payload you instead point at RHOST and the target's port — the remote host you are connecting into. Mix these up and you will sit on a dead listener wondering why nothing connected: a reverse shell with LHOST set to the target instead of yourself will never come back.
Staged vs. stageless payloads
Beyond direction, payloads differ in how they are delivered. A staged payload is split in two: the exploit first drops a tiny stager — just enough code to open the connection — and that stager then pulls the rest of the payload (the stage) down over the network. A stageless payload skips the round trip: everything is packed into a single self-contained blob that runs the moment it lands.
You can read which one you are dealing with straight from the name. Watch the punctuation:
- Staged — windows/meterpreter/reverse_tcp. Note the slashes: the extra / separating meterpreter from reverse_tcp marks it as staged. A small stager lands first, then fetches the full Meterpreter stage.
- Stageless — windows/meterpreter_reverse_tcp. Note the underscore: meterpreter_reverse_tcp is one fused token, signalling a single self-contained payload with nothing left to download.
The trade-offs decide which to reach for:
- Size — a staged payload's initial footprint is tiny, which matters when the exploit only gives you a few hundred bytes of buffer to work with. A stageless blob is large because it carries everything at once.
- Reliability over flaky links — staged payloads need a second network transfer to succeed; on a slow, lossy, or intermittently filtered connection that second leg can fail and leave you with a dead foothold. A stageless payload has no second leg to lose, so it is the safer bet over an unreliable link.
- Detection surface — the staged second transfer is a recognizable network event that defenders can catch, while a stageless payload moves everything in one shot but presents a much larger, more conspicuous artifact on disk or in memory for endpoint tooling to inspect. Each style trades one kind of exposure for another.
Generating payloads with msfvenom
Sometimes you are not firing a payload through an exploit module at all — you need a standalone file to deliver another way: an attachment, a download, a malicious macro's drop, a file copied onto a USB stick. msfvenom is the tool that turns a payload into exactly that, packaging it into whatever format your delivery method needs.
The shape of the command is always the same:
You pick the payload with -p, set the callback details (LHOST / LPORT) just as you would inside the framework, and choose an output format with -f. The format list is long — exe and elf for native Windows and Linux binaries, raw for shellcode you will embed elsewhere, python or war for scripted and web-app delivery, and many more — so the same payload can be shaped to fit almost any drop method.
A concrete example: to build a Windows executable that fires a staged reverse Meterpreter shell calling back to 10.10.14.5 on port 4444, you would run
That writes a standalone shell.exe you can deliver however the engagement allows. Start a matching listener on your side, get the file to run on the target, and the callback arrives — no exploit module required.
Encoders and the honest truth about evasion
This is where a lot of bad folklore lives, so let us be direct. Encoders — the most famous being shikata_ga_nai — transform a payload's bytes while leaving its behavior intact. Historically they served two real purposes: removing bad characters (bytes like a null that would break the exploit by terminating a string early), and dodging the crude, signature-based antivirus of an earlier era by changing the payload's static byte pattern each time.
Here is the part people get wrong: encoding is not evasion anymore. Modern antivirus and EDR recognize encoded Metasploit payloads trivially — the encoder stubs themselves are signatured, the decoded payload is caught in memory the instant it unpacks, and behavioral detection flags what the payload does regardless of how its bytes were scrambled. Running shikata_ga_nai over a stock payload and expecting it to slip past a current endpoint product is wishful thinking. It will be caught.
Genuine evasion is a different discipline entirely. It comes from custom loaders written to look like ordinary software, in-memory execution that never touches disk, and purpose-built command-and-control frameworks — tools like Sliver, Havoc, and Brute Ratel — engineered from the ground up to defeat modern detection rather than to scramble a few bytes. That is where serious offensive work goes once stock payloads stop getting through, and it is the subject of the next lesson on Command & Control Frameworks.