Skip to content

Commit 9068636

Browse files
committed
Fix a logic error in HttpServer
When a module is configured to listen on the INADDR_ANY interface, with a payload that does not have an LHOST option, it attempts to determine the srvhost from a client socket which would only be available when the module has included the TcpClient mixin (i.e., it is both passive and aggressive stance), causing a NameError for the undefined +sock+. This commit fixes the problem in two ways: 1. It changes the default cli in get_uri to be the module's self.cli, which should always be set when passive modules would need it (e.g., in the on_request_uri method). 2. It adds a check to make sure that the calling module has a sock before trying to get its peerhost. This was @marthieubean's suggested solution in rapid7#1775. [Closes rapid7#1775]
1 parent d857b81 commit 9068636

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

lib/msf/core/exploit/http/server.rb

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,9 @@ def get_resource
376376
# Return a full url of the form <tt>http://1.1.1.1:8080/resource/</tt>
377377
#
378378
# The address portion should be something a client would be able to route,
379-
# but see +srvhost_addr+ for caveats.
379+
# but see {#srvhost_addr} for caveats.
380380
#
381-
def get_uri(cli=nil)
381+
def get_uri(cli=self.cli)
382382
ssl = !!(datastore["SSL"])
383383
proto = (ssl ? "https://" : "http://")
384384
if (cli and cli.peerhost)
@@ -405,7 +405,7 @@ def get_uri(cli=nil)
405405
end
406406

407407
#
408-
# Return an address to which the client can route.
408+
# An address to which the client can route.
409409
#
410410
# If available, return LHOST which should be the right thing since it
411411
# already has to be an address the client can route to for the payload to
@@ -416,28 +416,39 @@ def get_uri(cli=nil)
416416
# bind payload but there's nothing we can do about it.
417417
#
418418
# NOTE: The address will be *incorrect* in the following two situations:
419-
# 1) LHOST is pointed at a multi/handler on some other box.
420-
# 2) SRVHOST has a value of '0.0.0.0', the user is behind NAT, and we're
419+
# 1. LHOST is pointed at a multi/handler on some other box.
420+
# 2. SRVHOST has a value of '0.0.0.0', the user is behind NAT, and we're
421421
# using a bind payload. In that case, we don't have an LHOST and
422422
# the source address will be internal.
423423
#
424424
# This can potentially be dealt with in a module by using the Host header
425425
# from a request if such a header exists.
426426
#
427+
# @return [String]
427428
def srvhost_addr
428-
if (datastore['LHOST'])
429+
if (datastore['LHOST'] and (!datastore['LHOST'].strip.empty?))
429430
host = datastore["LHOST"]
430431
else
431432
if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::")
432-
if (sock and sock.peerhost)
433+
if (respond_to?(:sock) and sock and sock.peerhost)
434+
# Then this is a Passive-Aggressive module. It has a socket
435+
# connected to the remote server from which we can deduce the
436+
# appropriate source address.
433437
host = Rex::Socket.source_address(sock.peerhost)
434438
else
439+
# Otherwise, this module is only a server, not a client, *and*
440+
# the payload does not have an LHOST option. This can happen,
441+
# for example, with a browser exploit using a download-exec
442+
# payload. In that case, just use the address of the interface
443+
# with the default gateway and hope for the best.
435444
host = Rex::Socket.source_address
436445
end
437446
else
438447
host = datastore['SRVHOST']
439448
end
440449
end
450+
451+
host
441452
end
442453

443454
#
@@ -1094,10 +1105,14 @@ def on_request_uri(cli, request, headers={})
10941105
end
10951106

10961107
#
1097-
# Return the PHP include URL (pre-encoded)
1108+
# The PHP include URL (pre-encoded)
10981109
#
1099-
# Does not take SSL into account. For the reasoning behind this, see +exploit+.
1110+
# Does not take SSL into account. For the reasoning behind this, see
1111+
# {#exploit}.
11001112
#
1113+
# @return [String] The URL to be used as the argument in a call to
1114+
# +require+, +require_once+, or +include+ or +include_once+ in a
1115+
# vulnerable PHP app.
11011116
def php_include_url(sock=nil)
11021117
host = srvhost_addr
11031118
if Rex::Socket.is_ipv6?(host)

0 commit comments

Comments
 (0)