The Meterpreter that we have known and loved for years has always had the ability to specify the type of transport that is to be used for the session. `reverse_tcp` and `reverse_https` are the favorites. Previously, the flexibility for transport selection is only available at the time the payloads are created, or when the exploit is launched, effectively locking the Meterpreter session into a single type of transport for the lifetime of the session.
Recent modifications to Meterpreter have changed this. Meterpreter has a new [[configuration system|Meterpreter-Configuration]] that supports multiple transports and it now supports the addition of new transports while the session is still running. With the extra transports configured, Meterpreter allows the user to cycle through those transports without shutting down the session.
Not only that, but Meterpreter will cycle through these transports automatically when communication fails. For more information on the session resiliency features, please view the [[Meterpreter Reliable Network Communication|[[reliable network communication documentation|./Meterpreter-Reliable-Network-Communication.md]].
It is not possible to add multiple transports to payloads or exploits prior to launching them. This is due to the fact that `msfvenom` the built-in payload mechanisms in Metasploit need to be modified to allow for multiple transports to be selected prior to the generation of the payload. This work is ongoing, and hopefully, it'll be implemented soon. For now, a single transport has to be chosen, using the same mechanism that has always been in use.
Meterpreter has a new base command called `transport`. This is the hub of all transport-related commands and will allow you to list them, add new ones, cycle through them on the fly, and remove those which are no longer valid or useful.
The simplest of all the sub-commands in the `transport` set is `list`. This command shows the full list of currently enabled transport, and an indicator of which one is the "current" transport. The following shows the non-verbose output with just the default transport running:
The above output shows that we have one transport enabled that is using `TCP`. We can infer that the transport was a `reverse_tcp` (rather than `bind_tcp`) due to the fact that there is a host IP address in the transport URL. If it was a `bind_tcp`, this would be blank.
`Comms T/O` refers to the communications timeout value. `Retry Total` is the total time to attempt reconnects on this transport, and `Retry Wait` indicates how often a retry of the current transport should happen. Each of these is documented in depth in the [[Timeout documentation|./meterpreter-timeout-control.md]].
The verbose version of this command shows more detail about the transport, but only in cases where extra detail is available (such as `reverse_http/s`). The following command shows the output of the `list` sub-command with the verbose flag (`-v`) after an `HTTP` transport has been added:
Adding transports gives Meterpreter the ability to work on different transport mechanisms with the goal of keeping the sessions alive for longer. The command for adding new transports varies slightly depending on the transport that is being added.
The following command shows a simple example that adds a `reverse_http` transport to an existing Meterpreter session. It specifies a custom communications timeout, retry total and retry wait, and also specifies a custom user-agent string to be used for the HTTP requests:
This command is what was used to create the transport that was listed in the sample verbose output for the `transport list` command. Here's a deeper explanation of the parameters:
* The `-t` option is what tells Metasploit what type of transport to add. The options are `bind_tcp`, `reverse_tcp`, `reverse_http` and `reverse_https`. These match those that are used for the construction of the original payloads. Given that we are not dealing with stages, there is no `reverse_winhttps` because Meterpreter always uses the WinHTTP API behind the scenes anyway.
* The `-T` option matches the `retry total` parameter. The measure of this value is in seconds, and should be a positive integer that is more than `-W`.
* The `-u` option allows the addition of a local URI (`LURI`) value that is prepended to the UUID URI that is used for all requests. This URI value helps segregate listeners and payloads based on a URI.
* The `-H` option specifies a proxy host/IP. This parameter is optional.
* The `-B` option specifies a proxy type, and needs to be set to `http` or `socks`. If not specified alongside the `-H` parameter, the default type is `http`.
* The `-P` option specifies the port that the proxy is listening on. This should be set when `-H` is set.
* The `-U` option specifies the username to use to authenticate with the proxy. This parameter is optional.
* The `-N` option specifies the password to use to authenticate with the proxy. This parameter is optional.
* The `-X` option specifies the overall Meterpreter session timeout value. While this value is not transport-specific, the option is provided here so that it can be set alongside the other transport-specific timeout values for ease of use.
* Finally the `-c` parameter can be used to indicate the expected SSL certificate. This parameter expects a file path to an SSL certificate in `PEM` format. The SHA1 hash of the certificate is extracted from the file, and this is used during the request validation process. If this file doesn't exist or doesn't contain a valid certificate, then the request should fail.
Note that these examples only add new transports, they do not change the current transport mechanism. When a transport is added to the list of transports, they are always added at the _end_ of the list, and not the start.
There are three different ways to change transports. One thing they do have in common is that transport switching assumes that you have listeners set up to receive the connections. If no listener or handler is present, then the resiliency features in Meterpreter will cause it to constantly attempt to establish connectivity on that transport using the transport timeout values that were configured. If the transport ultimately fails, then Meterpreter will cycle to the next transport on the list and try again. This will continue until a transport connection is successful, or the session timeout expires. More information on this can be found in the **session resiliency documentation** (link coming soon).
The three different ways to change transports are:
*`transport next` - This command will cause Meterpreter to shut down the current transport, and attempt to reconnect to Metasploit using the next transport in the list of transports.
*`transport prev` - This command is the same as `transport next`, except that it will move to the previous transport on the list, and not the next one.
*`transport change ...` - This command is equivalent to running `transport add`, and requires all the parameters that `transport add` requires (resulting in a new transport at the end of the list), and then `transport prev` (which is the same as going from the start of the list to the end). The net effect is the same as creating a new transport and immediately switching to it.
It is also possible to remove transports from the underlying transport list. This is valuable in cases where you want Meterpreter to always callback on stageless listeners (allowing you to avoid the unnecessary upload of the second stage), or when you have a listener located at an IP address that may have been blacklisted by your target as a result of your post-exploitation shenanigans.
The command is similar to `add` in that it takes a subset of the parameters, and then adds a new one on top of it:
*`-t` - The transport type.
*`-l` - The `LHOST` value (unless it's `bind_tcp`).
*`-p` - The `LPORT` value.
*`-u` - This value is only required for `reverse_http/s` transports and needs to contain the URI of the transport in question. This is important because there might be multiple listeners on the same IP and port, so the URI is what differentiates each of the sessions.
Previously, Meterpreter only had built-in resiliency in the `HTTP/S` payloads and this was due to the nature of `HTTP/S` as a stateless protocol. Meterpreter now has resiliency features baked into `TCP` transports as well, both `reverse` and `bind`. If communication fails on a given transport, Meterpreter will roll over to the next one automatically.
With Metasploit closed, the Meterpreter session has detected that the transport is no longer functioning. Behind the scenes, Meterpreter has shut down this `TCP` transport, and has automatically moved over to the `HTTP` transport as this was the next transport in the list. From here, Meterpreter continues to try to re-establish connectivity with Metasploit on this transport a per the transport timeout settings.
The following output shows Metasploit being re-launched with the appropriate listeners, and the existing Meterpreter instance establishing a session automatically:
In the case where Meterpreter is configured with only a single transport mechanism, this process still takes place. Meterpreter's transport list implementation is a cyclic linked-list, and once the end of the list has been reached, it simply starts from the beginning again. This means that if there's a list of one transport then Meterpreter will continually attempt to use that one transport until the session expires. This works for both `TCP` and `HTTP/S`.
For important detail on network resiliency, please see the [[reliable network communication documentation|./Meterpreter-Reliable-Network-Communication.md]]