metasploit-framework
metasploit-framework copied to clipboard
Meterpreter Portforward Breaks When Route is Added
Steps to reproduce
How'd you do it?
- Get a Meterpreter session (I used
windows/x64/meterpreter/reverse_tcpbut IT DOESN'T MATTER) - Start a Python HTTP server on port 80:
python3 -m http.server 80 - Start a reverse port forward on the Meterpreter session:
portfwd add -R -l 80 -L 127.0.0.1 -p 8888 - Observe the successful portforward on the Windows victim host:
curl 127.0.0.1:8888 - Create a new route in Metasploit:
route add 0 0 -1 - Re-observe the portforward on the Windows victim host:
curl 127.0.0.1:8888. The portforward is now broken :(
Environment: Meterpreter executed on Windows 10 Enterprise, 20H2 OS Build 19042.1110
Expected behavior
The reverse port forward should not break when creating a new route.
Current behavior
The reverse port forward no longer functions after creating a new route.
Metasploit version
Framework: 6.2.28-dev-de8a396b3af4aafc62121da0e5c67b8eeaa68ffd Console : 6.2.28-dev-de8a396b3af4aafc62121da0e5c67b8eeaa68ffd
@smcintyre-r7 :)
I wonder if this is a bug, or just unexpected behavior? It seems like you're globally setting the routing table to send all traffic destined 0.0.0.0 0 (i.e. everything) to go through your Meterpreter instance, so the incoming portfwd request gets sent back out to Meterpreter
I only took a quick glance, but enabling the tlv logging with setg sessiontlvlogging true after adding the route and I can see the following requests are made made from Meterpreter to msfconsole:
msf6 payload(windows/x64/meterpreter/reverse_tcp) >
vvvvvvvvvvvvvvvvvvv incoming request from Meterpreter vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
RECV: #<Rex::Post::Meterpreter::Packet type=Request tlvs=[
#<Rex::Post::Meterpreter::Tlv type=COMMAND_ID meta=INT value=1027 command=stdapi_net_tcp_channel_open>
#<Rex::Post::Meterpreter::Tlv type=CHANNEL_ID meta=INT value=4>
#<Rex::Post::Meterpreter::Tlv type=CHANNEL_PARENTID meta=INT value=1>
#<Rex::Post::Meterpreter::Tlv type=LOCAL_HOST meta=STRING value="">
#<Rex::Post::Meterpreter::Tlv type=LOCAL_PORT meta=INT value=8888>
#<Rex::Post::Meterpreter::Tlv type=PEER_HOST meta=STRING value="">
#<Rex::Post::Meterpreter::Tlv type=PEER_PORT meta=INT value=54749>
#<Rex::Post::Meterpreter::Tlv type=REQUEST_ID meta=STRING value="}8%X9=]rPgn<5;S{oM4s9*}Lv-M/x|H">
#<Rex::Post::Meterpreter::Tlv type=UUID meta=RAW value="\xC98\xF7b\x8Da\x88\xD3\xEF\xAB\xEE\xA9\x8C\xD6\x ...">
]>
RECV: #<Rex::Post::Meterpreter::Packet type=Request tlvs=[
#<Rex::Post::Meterpreter::Tlv type=COMMAND_ID meta=INT value=8 command=core_channel_write>
#<Rex::Post::Meterpreter::Tlv type=CHANNEL_ID meta=INT value=4>
#<Rex::Post::Meterpreter::Tlv type=CHANNEL_DATA meta=RAW value="GET / HTTP/1.1\r\nUser-Agent: Mozilla/5.0 (Window ...">
#<Rex::Post::Meterpreter::Tlv type=LENGTH meta=INT value=4>
#<Rex::Post::Meterpreter::Tlv type=REQUEST_ID meta=STRING value="JLEwx;+?o9bH`\"|6r%BoXCQ\\+e@+i^z">
#<Rex::Post::Meterpreter::Tlv type=UUID meta=RAW value="\xC98\xF7b\x8Da\x88\xD3\xEF\xAB\xEE\xA9\x8C\xD6\x ...">
]>
vvvvvvvvvvvvvvvvvvv Request going back out to Meterpreter vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
SEND: #<Rex::Post::Meterpreter::Packet type=Request tlvs=[
#<Rex::Post::Meterpreter::Tlv type=COMMAND_ID meta=INT value=4 command=core_channel_open>
#<Rex::Post::Meterpreter::Tlv type=REQUEST_ID meta=STRING value="87220724851553125233311755194209">
#<Rex::Post::Meterpreter::Tlv type=CHANNEL_TYPE meta=STRING value="stdapi_net_tcp_client">
#<Rex::Post::Meterpreter::Tlv type=CHANNEL_CLASS meta=INT value=1>
#<Rex::Post::Meterpreter::Tlv type=FLAGS meta=INT value=1>
#<Rex::Post::Meterpreter::Tlv type=PEER_HOST meta=STRING value="127.0.0.1">
#<Rex::Post::Meterpreter::Tlv type=PEER_PORT meta=INT value=80>
#<Rex::Post::Meterpreter::Tlv type=LOCAL_HOST meta=STRING value="0.0.0.0">
#<Rex::Post::Meterpreter::Tlv type=LOCAL_PORT meta=INT value=0>
#<Rex::Post::Meterpreter::Tlv type=CONNECT_RETRIES meta=INT value=0>
]>
RECV: #<Rex::Post::Meterpreter::Packet type=Response tlvs=[
#<Rex::Post::Meterpreter::Tlv type=COMMAND_ID meta=INT value=4 command=core_channel_open>
#<Rex::Post::Meterpreter::Tlv type=REQUEST_ID meta=STRING value="87220724851553125233311755194209">
#<Rex::Post::Meterpreter::Tlv type=RESULT meta=INT value=10061>
#<Rex::Post::Meterpreter::Tlv type=UUID meta=RAW value="\xC98\xF7b\x8Da\x88\xD3\xEF\xAB\xEE\xA9\x8C\xD6\x ...">
]>
It looks like msfconsole reads the request for a connection to 8888, then attempts to connect back out to port 80 on the Meterpreter instance, as I believe that's what you've configured msfconsole to do with route add 0 0 -1. I believe msfconsole's internal routing logic is global, so the incoming request to 127.0.0.1 gets sent back out to Meterpreter with that routing configuration.
When I use a more specific route add command, it works as expected for me:
route add 172.17.0.1/32 -1
Thanks! It does seem like this is just unintended behavior. Feel free to close the issue! :)
I wouldn't have expected it to work this way either 😄
I don't know if there's a better UX for this. Potentially generating a warning? Or if there was an easier way to configure msfconsole's routing table to say 'route everything to comm 1, apart from localhost'