From f93210ca747269f0cc1552aaea715cb34075053f Mon Sep 17 00:00:00 2001 From: Raphael Mudge Date: Sat, 4 Jan 2014 15:16:22 -0500 Subject: [PATCH 1/4] Always Use LHOST for Full URL in HTTP/S Stage Redmine #8726 documents a change where the reverse HTTP/S tries to bind LHOST and if it can not it does a hard stop If it's expected that users will use ReverseListenerBind- -Address then this commit addresses #8726 by patching the HTTP/S stage with the host provided by the user in LHOST. Currently ReverseListenerBindAddress (if used) is patched into the stage. This makes for a broken HTTP/S session if the user sets this option to 0.0.0.0. With this commit--users can provide any LHOST they like and set ReverseListenerBindAddress to 0.0.0.0 and things will work. This commit does not attempt to bring the HTTP/S handler back to the old behavior of falling back to 0.0.0.0 when it can't bind LHOST. I'd welcome the old behavior but I leave it to you to decide what makes sense. :) --- lib/msf/core/handler/reverse_http.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index 94e9376fae..574909c5de 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -86,7 +86,7 @@ module ReverseHttp addrs = bind_address local_port = bind_port scheme = (ssl?) ? "https" : "http" - "#{scheme}://#{addrs[0]}:#{local_port}/" + "#{scheme}://#{datastore['LHOST']}:#{local_port}/" end # From 6f55579acd0c93bdd5139eb914d8d84b13dc36b9 Mon Sep 17 00:00:00 2001 From: Raphael Mudge Date: Sat, 4 Jan 2014 15:50:06 -0500 Subject: [PATCH 2/4] HTTP Handler Bind to 0.0.0.0 or ReverseListenerBindAddress This commit returns the HTTP/S handler to its former semantic glory. By default the HTTP/S handler will bind to :: or 0.0.0.0. If the user specifies a ReverseListenerBindAddress then, instead, the server will bind to that address. The previous commit to change the URL to always reference LHOST should go with this too. LHOST is always my intent of where the stage should call home too. ReverseListenerBindAddress would make sense as my intent as to where I want to bind to. The two options shouldn't take on each other's meanings. --- lib/msf/core/handler/reverse_http.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index 574909c5de..009fc08db1 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -83,7 +83,6 @@ module ReverseHttp # addresses. # def full_uri - addrs = bind_address local_port = bind_port scheme = (ssl?) ? "https" : "http" "#{scheme}://#{datastore['LHOST']}:#{local_port}/" @@ -175,12 +174,18 @@ module ReverseHttp end local_port = bind_port - addrs = bind_address + + # Determine where to bind the HTTP(S) server to + bindaddrs = ipv6 ? '::' : '0.0.0.0' + + if not datastore['ReverseListenerBindAddress'].to_s.empty? + bindaddrs = datastore['ReverseListenerBindAddress'] + end # Start the HTTPS server service on this host/port self.service = Rex::ServiceManager.start(Rex::Proto::Http::Server, local_port, - addrs[0], + bindaddrs, ssl?, { 'Msf' => framework, From 3c9d68475908bcbec2e12425127fa365aaccb691 Mon Sep 17 00:00:00 2001 From: Raphael Mudge Date: Sat, 4 Jan 2014 16:02:32 -0500 Subject: [PATCH 3/4] Cleanup - Remove bind_address from reverse_http.rb This commit removes the now unused bind_address function from reverse_http.rb. This function returns an array of hosts the handler should attempt to bind to (e.g., [LHOST value, any]) Other handlers (e.g., reverse_tcp.rb) loop through these values until they're able to start a server with that bind address. The HTTP server doesn't work this way. It's setup to try one address and that's it. It makes sense to have the HTTP server always bind to 0.0.0.0 by default as future modules run by the user may register resources with the same HTTP server. --- lib/msf/core/handler/reverse_http.rb | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index 009fc08db1..a064c9c3b9 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -409,27 +409,6 @@ protected port > 0 ? port : datastore['LPORT'].to_i end - def bind_address - # Switch to IPv6 ANY address if the LHOST is also IPv6 - addr = Rex::Socket.resolv_nbo(datastore['LHOST']) - # First attempt to bind LHOST. If that fails, the user probably has - # something else listening on that interface. Try again with ANY_ADDR. - any = (addr.length == 4) ? "0.0.0.0" : "::0" - - addrs = [ Rex::Socket.addr_ntoa(addr), any ] - - if not datastore['ReverseListenerBindAddress'].to_s.empty? - # Only try to bind to this specific interface - addrs = [ datastore['ReverseListenerBindAddress'] ] - - # Pick the right "any" address if either wildcard is used - addrs[0] = any if (addrs[0] == "0.0.0.0" or addrs == "::0") - end - - addrs - end - - end end From 6034c26fa7fb57c71f07dbc1236b7b0722ef3e63 Mon Sep 17 00:00:00 2001 From: Raphael Mudge Date: Sat, 4 Jan 2014 18:52:19 -0500 Subject: [PATCH 4/4] Honor LPORT as callback port for HTTP/S handler This commit completes our quest to (optionally) decouple the stage's callback parameters from the interface/port our handler binds to. LPORT is now patched into the stage over ReverseListenerBindPort. --- lib/msf/core/handler/reverse_http.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index a064c9c3b9..4278d2122d 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -85,7 +85,7 @@ module ReverseHttp def full_uri local_port = bind_port scheme = (ssl?) ? "https" : "http" - "#{scheme}://#{datastore['LHOST']}:#{local_port}/" + "#{scheme}://#{datastore['LHOST']}:#{datastore['LPORT']}/" end #