From 624e19fd8ba7b29f1391fdd90b42873ddf8da277 Mon Sep 17 00:00:00 2001 From: James Lee Date: Tue, 28 Feb 2012 18:28:47 -0700 Subject: [PATCH] Merge session-host-rework branch back to master Squashed commit of the following: commit 2f4e8df33c5b4baa8d6fd67b400778a3f93482aa Author: James Lee Date: Tue Feb 28 16:31:03 2012 -0700 Clean up some rdoc comments This adds categories for the various interfaces that meterpreter and shell sessions implement so they are grouped logically in the docs. commit 9d31bc1b35845f7279148412f49bda56a39c9d9d Author: James Lee Date: Tue Feb 28 13:00:25 2012 -0700 Combine the docs into one output dir There's really no need to separate the API sections into their own directory. Combining them makes it much easier to read. commit eadd7fc136a9e7e4d9652d55dfb86e6f318332e0 Author: James Lee Date: Tue Feb 28 08:27:22 2012 -0700 Keep the order of iface attributes the same accross rubies 1.8 doesn't maintain insertion order for Hash keys like 1.9 does so we end up with ~random order for the display with the previous technique. Switch to an Array instead of a Hash so it's always the same. commit 6f66dd40f39959711f9bacbda99717253a375d21 Author: James Lee Date: Tue Feb 28 08:23:35 2012 -0700 Fix a few more compiler warnings commit f39cb536a80c5000a5b9ca1fec5902300ae4b440 Author: James Lee Date: Tue Feb 28 08:17:39 2012 -0700 Fix a type-safety warning commit 1e52785f38146515409da3724f858b9603d19454 Author: James Lee Date: Mon Feb 27 15:21:36 2012 -0700 LHOST should be OptAddress, not OptAddressRange commit acef978aa4233c7bd0b00ef63646eb4da5457f67 Author: James Lee Date: Sun Feb 26 17:45:59 2012 -0700 Fix a couple of warnings and a typo commit 29d87f88790aa1b3e5db6df650ecfb3fb93c675b Author: HD Moore Date: Mon Feb 27 11:54:29 2012 -0600 Fix ctype vs content_type typo commit 83b5400356c47dd1973e6be3aa343084dfd09c73 Author: Gregory Man Date: Sun Feb 26 15:38:33 2012 +0200 Fixed scripts/meterpreter/enum_firefox to work with firefox > 3.6.x commit 49c2c80b347820d02348d694cc71f1b3028b4365 Author: Steve Tornio Date: Sun Feb 26 07:13:13 2012 -0600 add osvdb ref commit e18e1fe97b89c3a2b8c22bc6c18726853d2c2bee Author: Matt Andreko Date: Sat Feb 25 18:02:56 2012 -0500 Added aspx target to msfvenom. This in turn added it to msfencode as well. Ref: https://github.com/rapid7/metasploit-framework/pull/188 Tested on winxp with IIS in .net 1.1 and 2.0 modes commit e6aa5072112d79bbf8a4d2289cf8d301db3932f5 Author: Joshua J. Drake Date: Sat Feb 25 13:00:48 2012 -0600 Fixes #6308: Fall back to 127.0.0.1 when SocketError is raised from the resolver commit b3371e8bfeea4d84f9d0cba100352b57d7e9e78b Author: James Lee Date: Tue Feb 28 17:07:42 2012 -0700 Simplify logic for whether an inner iface has the same address commit 5417419f35a40d1c08ca11ca40744722692d3b0d Author: James Lee Date: Tue Feb 28 16:58:16 2012 -0700 Whitespace commit 9036875c2918439ae23e11ee7b958e30ccc29545 Author: James Lee Date: Tue Feb 28 16:53:45 2012 -0700 Set session info before worrying about address get_interfaces can take a while on Linux, grab uid and hostname earlier so we can give the user an idea of what they popped as soon as possible. commit f34b51c6291031ab25b5bfb1ac6307a516ab0ee9 Author: James Lee Date: Tue Feb 28 16:48:42 2012 -0700 Clean up rdoc commit e61a0663454400ec66f59a80d18b0baff4cb8cd9 Author: HD Moore Date: Tue Feb 28 04:54:45 2012 -0600 Ensure the architecture is only the first word (not the full WOW64 message in some cases) commit 4c701610976a92298c1182eecc9291a1b301e43b Author: HD Moore Date: Tue Feb 28 04:49:17 2012 -0600 More paranoia code, just in case RHOST is set to whitespace commit c5ff89fe3dc9061e0fa9f761e6530f6571989d28 Author: HD Moore Date: Tue Feb 28 04:47:01 2012 -0600 A few more small bug fixes to handle cases with an empty string target host resulting in a bad address commit 462d0188a1298f29ac83b10349aec6737efc5b19 Author: HD Moore Date: Tue Feb 28 03:55:10 2012 -0600 Fix up the logic (reversed by accident) commit 2b2b0adaec2448423dbd3ec54d90a5721965e2df Author: HD Moore Date: Mon Feb 27 23:29:52 2012 -0600 Automatically parse system information and populate the db, identify and report NAT when detected, show the real session_host in the sessions -l listing commit 547a4ab4c62dc3248f847dd5d305ad3b74157348 Author: HD Moore Date: Mon Feb 27 22:16:03 2012 -0600 Fix typo introduced commit 27a7b7961e61894bdecd55310a8f45d0917c5a5c Author: HD Moore Date: Mon Feb 27 22:11:38 2012 -0600 More session.session_host tweaks commit e447302a1a9915795e89b5e29c89ff2ab9b6209b Author: HD Moore Date: Mon Feb 27 22:08:20 2012 -0600 Additional tunnel_peer changes commit 93369fcffaf8c6b00d992526b4083acfce036bb3 Author: HD Moore Date: Mon Feb 27 22:06:21 2012 -0600 Additional changes to session.session_host commit c3552f66d158685909e2c8b51dfead7c240c4f40 Author: HD Moore Date: Mon Feb 27 22:00:19 2012 -0600 Merge changes into the new branch --- data/meterpreter/msflinker_linux_x86.bin | Bin documentation/msfconsole_rc_ruby_example.rc | 2 +- lib/msf/base/serializer/readable_text.rb | 2 +- lib/msf/base/sessions/meterpreter.rb | 82 ++++++++++- lib/msf/core/db.rb | 132 ++++++++++++++++-- lib/msf/core/framework.rb | 14 +- lib/msf/core/module.rb | 15 ++ lib/msf/core/rpc/v10/rpc_session.rb | 24 ++-- lib/msf/core/session.rb | 60 +++++++- lib/msf/ui/console/command_dispatcher/core.rb | 4 +- modules/payloads/stages/osx/x86/isight.rb | 2 +- modules/post/cisco/gather/enum_cisco.rb | 2 +- modules/post/osx/gather/enum_osx.rb | 2 +- modules/post/osx/gather/hashdump.rb | 2 +- .../post/windows/capture/lockout_keylogger.rb | 2 +- .../post/windows/gather/credentials/dyndns.rb | 2 +- modules/post/windows/gather/enum_chrome.rb | 4 +- modules/post/windows/gather/enum_computers.rb | 2 +- modules/post/windows/gather/enum_tokens.rb | 10 +- modules/post/windows/gather/screen_spy.rb | 2 +- modules/post/windows/gather/smart_hashdump.rb | 4 +- .../post/windows/manage/add_user_domain.rb | 10 +- modules/post/windows/manage/persistence.rb | 2 +- plugins/session_tagger.rb | 2 +- plugins/token_adduser.rb | 4 +- plugins/token_hunter.rb | 12 +- scripts/meterpreter/enum_chrome.rb | 2 +- scripts/meterpreter/enum_firefox.rb | 4 +- scripts/meterpreter/keylogrecorder.rb | 4 +- scripts/meterpreter/metsvc.rb | 6 +- scripts/meterpreter/netenum.rb | 4 +- scripts/meterpreter/prefetchtool.rb | 2 +- scripts/meterpreter/process_memdump.rb | 4 +- scripts/meterpreter/scraper.rb | 2 +- scripts/meterpreter/screenspy.rb | 2 +- scripts/meterpreter/winenum.rb | 4 +- scripts/resource/multi_post.rc | 4 +- 37 files changed, 346 insertions(+), 91 deletions(-) mode change 100644 => 100755 data/meterpreter/msflinker_linux_x86.bin diff --git a/data/meterpreter/msflinker_linux_x86.bin b/data/meterpreter/msflinker_linux_x86.bin old mode 100644 new mode 100755 diff --git a/documentation/msfconsole_rc_ruby_example.rc b/documentation/msfconsole_rc_ruby_example.rc index 4ade7762dd..5a99b6efb2 100644 --- a/documentation/msfconsole_rc_ruby_example.rc +++ b/documentation/msfconsole_rc_ruby_example.rc @@ -22,7 +22,7 @@ exploit -j print_status("Waiting on an incoming sessions...") while (true) framework.sessions.each_pair do |sid,s| - thost = s.tunnel_peer.split(":")[0] + thost = s.session_host # Ensure that stdapi has been loaded before running if s.ext.aliases['stdapi'] diff --git a/lib/msf/base/serializer/readable_text.rb b/lib/msf/base/serializer/readable_text.rb index 402a553bfa..34825c032e 100644 --- a/lib/msf/base/serializer/readable_text.rb +++ b/lib/msf/base/serializer/readable_text.rb @@ -416,7 +416,7 @@ class ReadableText framework.sessions.each_sorted { |k| session = framework.sessions[k] - row = [ session.sid.to_s, session.type.to_s, session.info.to_s, session.tunnel_to_s ] + row = [ session.sid.to_s, session.type.to_s, session.info.to_s, session.tunnel_to_s + " (#{session.session_host})" ] if session.respond_to? :platform row[1] += " " + session.platform end diff --git a/lib/msf/base/sessions/meterpreter.rb b/lib/msf/base/sessions/meterpreter.rb index 9606423086..8c148cd38c 100644 --- a/lib/msf/base/sessions/meterpreter.rb +++ b/lib/msf/base/sessions/meterpreter.rb @@ -293,6 +293,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client def load_session_info() begin ::Timeout.timeout(60) do + # Gather username/system information username = self.sys.config.getuid sysinfo = self.sys.config.sysinfo @@ -304,24 +305,103 @@ class Meterpreter < Rex::Post::Meterpreter::Client safe_info.gsub!(/[\x00-\x08\x0b\x0c\x0e-\x19\x7f-\xff]+/n,"_") self.info = safe_info + # Enumerate network interfaces to detect IP + ifaces = self.net.config.get_interfaces().flatten rescue [] + routes = self.net.config.get_routes().flatten rescue [] + shost = self.session_host + + # Try to match our visible IP to a real interface + # TODO: Deal with IPv6 addresses + found = ifaces.find {|i| i.ip == shost } + nhost = nil + hobj = nil + + if Rex::Socket.is_ipv4?(shost) and not found + + # Try to find an interface with a default route + default_routes = routes.select{ |r| r.subnet == "0.0.0.0" } + default_routes.each do |r| + ifaces.each do |i| + cidr = Rex::Socket.net2bitmask( i.netmask ) rescue "/32" + rang = Rex::Socket::RangeWalker.new( "#{i.ip}/#{cidr}" ) rescue nil + if rang and rang.include?( r.gateway ) + nhost = i.ip + break + end + end + break if nhost + end + + # Find the first non-loopback address + if not nhost + iface = ifaces.select{|i| t.ip != "127.0.0.1" } + if iface.length > 0 + nhost = iface.first.ip + end + end + end + + # If we found a better IP address for this session, change it up + # only handle cases where the DB is not connected here + if not (framework.db and framework.db.active) + self.session_host = nhost + end + + # The rest of this requires a database, so bail if it's not # there return if not (framework.db and framework.db.active) + wspace = framework.db.find_workspace(workspace) + + # Account for finding ourselves on a different host + if nhost and self.db_record + # Create or switch to a new host in the database + hobj = framework.db.report_host(:workspace => wspace, :host => nhost) + if hobj + self.session_host = nhost + self.db_record.host_id = hobj[:id] + end + end + framework.db.report_note({ :type => "host.os.session_fingerprint", :host => self, - :workspace => workspace, + :workspace => wspace, :data => { :name => sysinfo["Computer"], :os => sysinfo["OS"], :arch => sysinfo["Architecture"], } }) + if self.db_record self.db_record.desc = safe_info self.db_record.save! end + + framework.db.update_host_via_sysinfo(:host => self, :workspace => wspace, :info => sysinfo) + + if nhost + framework.db.report_note({ + :type => "host.nat.server", + :host => shost, + :workspace => wspace, + :data => { :info => "This device is acting as a NAT gateway for #{nhost}", :client => nhost }, + :update => :unique_data + }) + framework.db.report_host(:host => shost, :purpose => 'firewall' ) + + framework.db.report_note({ + :type => "host.nat.client", + :host => nhost, + :workspace => wspace, + :data => { :info => "This device is traversing NAT gateway #{shost}", :server => shost }, + :update => :unique_data + }) + framework.db.report_host(:host => nhost, :purpose => 'client' ) + end + end rescue ::Interrupt dlog("Interrupt while loading sysinfo: #{e.class}: #{e}") diff --git a/lib/msf/core/db.rb b/lib/msf/core/db.rb index 5f65413593..fa2e339117 100644 --- a/lib/msf/core/db.rb +++ b/lib/msf/core/db.rb @@ -275,6 +275,10 @@ class DBManager end wspace = opts.delete(:workspace) || workspace + if wspace.kind_of? String + wspace = find_workspace(wspace) + end + ret = { } if not addr.kind_of? Host @@ -329,6 +333,117 @@ class DBManager host end + + # + # Update a host's attributes via semi-standardized sysinfo hash (Meterpreter) + # + # The opts parameter MUST contain the following entries + # +:host+:: -- the host's ip address + # +:info+:: -- the information hash + # * 'Computer' -- the host name + # * 'OS' -- the operating system string + # * 'Architecture' -- the hardware architecture + # * 'System Language' -- the system language + # + # The opts parameter can contain: + # +:workspace+:: -- the workspace for this host + # + def update_host_via_sysinfo(opts) + + return if not active + addr = opts.delete(:host) || return + info = opts.delete(:info) || return + + # Sometimes a host setup through a pivot will see the address as "Remote Pipe" + if addr.eql? "Remote Pipe" + return + end + + wspace = opts.delete(:workspace) || workspace + if wspace.kind_of? String + wspace = find_workspace(wspace) + end + + if not addr.kind_of? Host + addr = normalize_host(addr) + addr, scope = addr.split('%', 2) + opts[:scope] = scope if scope + + unless ipv46_validator(addr) + raise ::ArgumentError, "Invalid IP address in report_host(): #{addr}" + end + + if opts[:comm] and opts[:comm].length > 0 + host = wspace.hosts.find_or_initialize_by_address_and_comm(addr, opts[:comm]) + else + host = wspace.hosts.find_or_initialize_by_address(addr) + end + else + host = addr + end + + res = {} + + if info['Computer'] + res[:name] = info['Computer'] + end + + if info['Architecture'] + res[:arch] = info['Architecture'].split(/\s+/).first + end + + if info['OS'] =~ /^Windows\s*([^\(]+)\(([^\)]+)\)/i + res[:os_name] = "Microsoft Windows" + res[:os_flavor] = $1.strip + build = $2.strip + + if build =~ /Service Pack (\d+)/ + res[:os_sp] = "SP" + $1 + else + res[:os_sp] = "SP0" + end + end + + if info["System Language"] + case info["System Language"] + when /^en_/ + res[:os_lang] = "English" + end + end + + + # Truncate the info field at the maximum field length + if res[:info] + res[:info] = res[:info][0,65535] + end + + # Truncate the name field at the maximum field length + if res[:name] + res[:name] = res[:name][0,255] + end + + res.each { |k,v| + + if (host.attribute_names.include?(k.to_s)) + unless host.attribute_locked?(k.to_s) + host[k] = v.to_s.gsub(/[\x00-\x1f]/, '') + end + else + dlog("Unknown attribute for Host: #{k}") + end + } + + # Set default fields if needed + host.state = HostState::Alive if not host.state + host.comm = '' if not host.comm + host.workspace = wspace if not host.workspace + + if host.changed? + host.save! + end + + host + end # # Iterates over the hosts table calling the supplied block with the host # instance of each entry. @@ -908,7 +1023,10 @@ class DBManager raise DBImportError.new("Missing required option :addr") unless addr wspace = opts.delete(:wspace) raise DBImportError.new("Missing required option :wspace") unless wspace - + if wspace.kind_of? String + wspace = find_workspace(wspace) + end + host = nil report_host(:workspace => wspace, :address => addr) @@ -5248,15 +5366,9 @@ class DBManager end elsif host.kind_of? Session norm_host = host.host - elsif host.respond_to?(:target_host) - # Then it's an Msf::Session object with a target but target_host - # won't be set in some cases, so try tunnel_peer as well - thost = host.target_host - if host.tunnel_peer and (!thost or thost.empty?) - # tunnel_peer is of the form ip:port, so strip off the port to - # get the addr by itself - thost = host.tunnel_peer.split(":")[0] - end + elsif host.respond_to?(:session_host) + # Then it's an Msf::Session object + thost = host.session_host norm_host = thost end diff --git a/lib/msf/core/framework.rb b/lib/msf/core/framework.rb index 7b3519f438..ccef3d99cf 100644 --- a/lib/msf/core/framework.rb +++ b/lib/msf/core/framework.rb @@ -286,16 +286,10 @@ class FrameworkEventSubscriber # Generic handler for session events # def session_event(name, session, opts={}) - address = nil - - if session.respond_to? :peerhost and session.peerhost.to_s.length > 0 - address = session.peerhost - elsif session.respond_to? :tunnel_peer and session.tunnel_peer.to_s.length > 0 - address = session.tunnel_peer[0, session.tunnel_peer.rindex(":") || session.tunnel_peer.length ] - elsif session.respond_to? :target_host and session.target_host.to_s.length > 0 - address = session.target_host - else - elog("Session with no peerhost/tunnel_peer") + address = session.session_host + + if not (address and address.length > 0) + elog("Session with no session_host/target_host/tunnel_peer") dlog("#{session.inspect}", LEV_3) return end diff --git a/lib/msf/core/module.rb b/lib/msf/core/module.rb index d8c3396656..019fdd04f2 100644 --- a/lib/msf/core/module.rb +++ b/lib/msf/core/module.rb @@ -376,6 +376,21 @@ class Module nil end + # + # Returns the address of the last target port (rough estimate) + # + def target_port + if(self.respond_to?('rport')) + return rport() + end + + if(self.datastore['RPORT']) + return self.datastore['RPORT'] + end + + nil + end + # # Returns the current workspace # diff --git a/lib/msf/core/rpc/v10/rpc_session.rb b/lib/msf/core/rpc/v10/rpc_session.rb index 6ad8cfe5b3..8d108eeeea 100644 --- a/lib/msf/core/rpc/v10/rpc_session.rb +++ b/lib/msf/core/rpc/v10/rpc_session.rb @@ -10,17 +10,19 @@ class RPC_Session < RPC_Base self.framework.sessions.each do |sess| i,s = sess res[s.sid] = { - 'type' => s.type.to_s, - 'tunnel_local'=> s.tunnel_local.to_s, - 'tunnel_peer' => s.tunnel_peer.to_s, - 'via_exploit' => s.via_exploit.to_s, - 'via_payload' => s.via_payload.to_s, - 'desc' => s.desc.to_s, - 'info' => s.info.to_s, - 'workspace' => s.workspace.to_s, - 'target_host' => s.target_host.to_s, - 'username' => s.username.to_s, - 'uuid' => s.uuid.to_s, + 'type' => s.type.to_s, + 'tunnel_local' => s.tunnel_local.to_s, + 'tunnel_peer' => s.tunnel_peer.to_s, + 'via_exploit' => s.via_exploit.to_s, + 'via_payload' => s.via_payload.to_s, + 'desc' => s.desc.to_s, + 'info' => s.info.to_s, + 'workspace' => s.workspace.to_s, + 'session_host' => s.session_host.to_s, + 'session_port' => s.session_port.to_i, + 'target_host' => s.target_host.to_s, + 'username' => s.username.to_s, + 'uuid' => s.uuid.to_s, 'exploit_uuid' => s.exploit_uuid.to_s, 'routes' => s.routes.join(",") } diff --git a/lib/msf/core/session.rb b/lib/msf/core/session.rb index 8fdaae2359..71a90130a2 100644 --- a/lib/msf/core/session.rb +++ b/lib/msf/core/session.rb @@ -117,7 +117,7 @@ module Session # Brief and to the point # def inspect - "#" # " Fixes highlighting + "#" # " Fixes highlighting end # @@ -143,7 +143,55 @@ module Session # def tunnel_peer end + + # + # Returns the host associated with the session + # + def session_host + # Prefer the overridden session host or target_host + host = @session_host || self.target_host + return host if host + + # Fallback to the tunnel_peer (contains port) + peer = self.tunnel_peer + return if not peer + # Pop off the trailing port number + bits = peer.split(':') + bits.pop + bits.join(':') + end + + # + # Override the host associated with this session + # + def session_host=(v) + @session_host = v + end + + # + # Returns the port associated with the session + # + def session_port + port = @session_port || self.target_port + return port if port + # Fallback to the tunnel_peer (contains port) + peer = self.tunnel_peer + return if not peer + + # Pop off the trailing port number + bits = peer.split(':') + port = bits.pop + port.to_i + end + + # + # Override the host associated with this session + # + def session_port=(v) + @session_port = v + end + # # Returns a pretty representation of the tunnel. # @@ -164,7 +212,7 @@ module Session dt = Time.now dstr = sprintf("%.4d%.2d%.2d", dt.year, dt.mon, dt.mday) - rhost = (tunnel_peer || 'unknown').split(':')[0] + rhost = session_host.gsub(':', '_') "#{dstr}_#{rhost}_#{type}" end @@ -212,8 +260,8 @@ module Session def set_from_exploit(m) self.via = { 'Exploit' => m.fullname } self.via['Payload'] = ('payload/' + m.datastore['PAYLOAD'].to_s) if m.datastore['PAYLOAD'] - - self.target_host = m.target_host + self.target_host = m.target_host if (m.target_host.to_s.strip.length > 0) + self.target_port = m.target_port if (m.target_port.to_i != 0) self.workspace = m.workspace self.username = m.owner self.exploit_datastore = m.datastore @@ -307,6 +355,10 @@ module Session # attr_accessor :target_host # + # The original target port if applicable + # + attr_accessor :target_port + # # The datastore of the exploit that created this session # attr_accessor :exploit_datastore diff --git a/lib/msf/ui/console/command_dispatcher/core.rb b/lib/msf/ui/console/command_dispatcher/core.rb index 5d59e32ee4..3af937847d 100644 --- a/lib/msf/ui/console/command_dispatcher/core.rb +++ b/lib/msf/ui/console/command_dispatcher/core.rb @@ -1496,7 +1496,7 @@ class Core end sessions.each do |s| session = framework.sessions.get(s) - print_status("Running '#{cmd}' on #{session.type} session #{s} (#{session.tunnel_peer})") + print_status("Running '#{cmd}' on #{session.type} session #{s} (#{session.session_host})") if (session.type == "meterpreter") # If session.sys is nil, dont even try.. @@ -1598,7 +1598,7 @@ class Core sessions.each do |s| if ((session = framework.sessions.get(s))) if (script_paths[session.type]) - print_status("Session #{s} (#{session.tunnel_peer}):") + print_status("Session #{s} (#{session.session_host}):") begin session.execute_file(script_paths[session.type], extra) rescue ::Exception => e diff --git a/modules/payloads/stages/osx/x86/isight.rb b/modules/payloads/stages/osx/x86/isight.rb index b68a3fdd86..de72b7e43a 100644 --- a/modules/payloads/stages/osx/x86/isight.rb +++ b/modules/payloads/stages/osx/x86/isight.rb @@ -70,7 +70,7 @@ module Metasploit3 end # Extract the host and port - host,port = session.tunnel_peer.split(':') + host = session.session_host # Create a directory for the images base = File.join(Msf::Config.config_directory, 'logs', 'isight') diff --git a/modules/post/cisco/gather/enum_cisco.rb b/modules/post/cisco/gather/enum_cisco.rb index 96670a9513..c99aea134f 100644 --- a/modules/post/cisco/gather/enum_cisco.rb +++ b/modules/post/cisco/gather/enum_cisco.rb @@ -161,7 +161,7 @@ class Metasploit3 < Msf::Post # Run enumeration commands for when privilege level is 7 or 15 def enum_priv(prompt) - host,port = session.tunnel_peer.split(':') + host,port = session.session_host, session.session_port priv_commands = [ { "cmd" => "show run", diff --git a/modules/post/osx/gather/enum_osx.rb b/modules/post/osx/gather/enum_osx.rb index f6c0fa0aa3..c9e63d296b 100644 --- a/modules/post/osx/gather/enum_osx.rb +++ b/modules/post/osx/gather/enum_osx.rb @@ -474,7 +474,7 @@ class Metasploit3 < Msf::Post print_status("Dumping Hashes") users = [] nt_hash = nil - host,port = session.tunnel_peer.split(':') + host,port = session.session_host, session.session_port # Path to files with hashes nt_file = ::File.join(log_folder,"nt_hash.txt") diff --git a/modules/post/osx/gather/hashdump.rb b/modules/post/osx/gather/hashdump.rb index ea20036b40..660e2c0b7d 100644 --- a/modules/post/osx/gather/hashdump.rb +++ b/modules/post/osx/gather/hashdump.rb @@ -140,7 +140,7 @@ class Metasploit3 < Msf::Post print_status("Dumping Hashes") users = [] nt_hash = nil - host,port = session.tunnel_peer.split(':') + host,port = session.session_host, session.session_port # Path to files with hashes nt_file = ::File.join(log_folder,"nt_hash.txt") diff --git a/modules/post/windows/capture/lockout_keylogger.rb b/modules/post/windows/capture/lockout_keylogger.rb index 953c7a8dfc..b9157b7034 100644 --- a/modules/post/windows/capture/lockout_keylogger.rb +++ b/modules/post/windows/capture/lockout_keylogger.rb @@ -153,7 +153,7 @@ class Metasploit3 < Msf::Post def run # Log file variables - host,port = session.tunnel_peer.split(':') # Get hostname + host,port = session.session_host, session.session_port filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") # Create Filename info to be appended to downloaded files logs = ::File.join(Msf::Config.log_directory, 'scripts', 'smartlocker') # Create a directory for the logs ::FileUtils.mkdir_p(logs) # Create the log directory diff --git a/modules/post/windows/gather/credentials/dyndns.rb b/modules/post/windows/gather/credentials/dyndns.rb index bdc454b803..547670d978 100644 --- a/modules/post/windows/gather/credentials/dyndns.rb +++ b/modules/post/windows/gather/credentials/dyndns.rb @@ -74,7 +74,7 @@ class Metasploit3 < Msf::Post until f.eof? content << f.read end - p = store_loot("dyndns.raw", "text/plain", session.tunnel_peer, "dyndns_raw_config.dyndns") + p = store_loot("dyndns.raw", "text/plain", session, "dyndns_raw_config.dyndns") vprint_status("Raw config file saved: #{p.to_s}") return content end diff --git a/modules/post/windows/gather/enum_chrome.rb b/modules/post/windows/gather/enum_chrome.rb index fc51c677a7..65e1bfebe8 100644 --- a/modules/post/windows/gather/enum_chrome.rb +++ b/modules/post/windows/gather/enum_chrome.rb @@ -131,7 +131,7 @@ class Metasploit3 < Msf::Post end # Store raw data - local_path = store_loot("chrome.raw.#{f}", "text/plain", session.tunnel_peer, "chrome_raw_#{f}") + local_path = store_loot("chrome.raw.#{f}", "text/plain", session, "chrome_raw_#{f}") raw_files[f] = local_path session.fs.file.download_file(local_path, remote_path) print_status("Downloaded #{f} to '#{local_path}'") @@ -200,7 +200,7 @@ class Metasploit3 < Msf::Post # Automatically migrate to explorer.exe migrate_success = migrate if datastore["MIGRATE"] - host = session.tunnel_peer.split(':')[0] + host = session.session_host #Get Google Chrome user data path sysdrive = session.fs.file.expand_path("%SYSTEMDRIVE%") diff --git a/modules/post/windows/gather/enum_computers.rb b/modules/post/windows/gather/enum_computers.rb index 4cc0fec6e3..c24ffed4ee 100644 --- a/modules/post/windows/gather/enum_computers.rb +++ b/modules/post/windows/gather/enum_computers.rb @@ -123,7 +123,7 @@ class Metasploit3 < Msf::Post print_line("\n" + results + "\n") report_note( - :host => session.tunnel_peer, + :host => session, :type => 'domain.hosts', :data => tbl.to_csv ) diff --git a/modules/post/windows/gather/enum_tokens.rb b/modules/post/windows/gather/enum_tokens.rb index 53eff3f740..75e7c1b691 100644 --- a/modules/post/windows/gather/enum_tokens.rb +++ b/modules/post/windows/gather/enum_tokens.rb @@ -123,7 +123,7 @@ class Metasploit3 < Msf::Post return end - print_status("Scanning session #{session.sid} / #{session.tunnel_peer}") + print_status("Scanning session #{session.sid} / #{session.session_host}") # get system, if requested. get_system if (session.sys.config.getuid() !~ /SYSTEM/ and datastore['GETSYSTEM']) @@ -145,7 +145,7 @@ class Metasploit3 < Msf::Post session.core.use("incognito") if(! session.incognito) if(! session.incognito) - print_error("Failed to load incognito on #{session.sid} / #{session.tunnel_peer}") + print_error("Failed to load incognito on #{session.sid} / #{session.session_host}") return end @@ -173,7 +173,7 @@ class Metasploit3 < Msf::Post if ndom == domain and da_user == nusr sid = session.sid - peer = session.tunnel_peer + peer = session.session_host print_good("Found token for session #{sid}: #{peer} - #{nusr} (Delegation Token)") end end @@ -184,7 +184,7 @@ class Metasploit3 < Msf::Post session.sys.process.get_processes().each do |proc| if (proc['user'] == "#{domain}\\#{da_user}") sid = session.sid - peer = session.tunnel_peer + peer = session.session_host target_pid = proc['pid'] tbl_pids << [sid, peer, da_user, target_pid] print_good("Found PID on session #{sid}: #{peer} - #{da_user} (PID: #{target_pid})") @@ -194,7 +194,7 @@ class Metasploit3 < Msf::Post #At the end of the loop, store and print results for this da_user if not tbl_pids.rows.empty? and session.framework.db.active report_note( - :host => session.tunnel_peer, + :host => session.session_host, :type => "pid", :data => tbl_pids.to_csv ) diff --git a/modules/post/windows/gather/screen_spy.rb b/modules/post/windows/gather/screen_spy.rb index dea1c57746..fe95a21b50 100644 --- a/modules/post/windows/gather/screen_spy.rb +++ b/modules/post/windows/gather/screen_spy.rb @@ -44,7 +44,7 @@ class Metasploit3 < Msf::Post end def run - host = session.tunnel_peer.split(':')[0] + host = session.session_host screenshot = Msf::Config.install_root + "/data/" + host + ".jpg" migrate_explorer diff --git a/modules/post/windows/gather/smart_hashdump.rb b/modules/post/windows/gather/smart_hashdump.rb index 7a5abd9231..a170d28fda 100644 --- a/modules/post/windows/gather/smart_hashdump.rb +++ b/modules/post/windows/gather/smart_hashdump.rb @@ -266,7 +266,7 @@ class Metasploit3 < Msf::Post #------------------------------------------------------------------------------- def read_hashdump - host,port = session.tunnel_peer.split(":") + host,port = session.session_host, session.session_port collected_hashes = "" begin @@ -314,7 +314,7 @@ class Metasploit3 < Msf::Post def inject_hashdump collected_hashes = "" - host,port = session.tunnel_peer.split(":") + host,port = session.session_host, session.session_port # Load priv extension session.core.use("priv") # dump hashes diff --git a/modules/post/windows/manage/add_user_domain.rb b/modules/post/windows/manage/add_user_domain.rb index edecd1cba3..168e32388f 100644 --- a/modules/post/windows/manage/add_user_domain.rb +++ b/modules/post/windows/manage/add_user_domain.rb @@ -86,7 +86,7 @@ class Metasploit3 < Msf::Post end if(! session.incognito) - print_status("!! Failed to load incognito on #{session.sid} / #{session.tunnel_peer}") + print_status("!! Failed to load incognito on #{session.sid} / #{session.session_host}") return false end @@ -167,14 +167,14 @@ class Metasploit3 < Msf::Post end if(! session.incognito) - print_error("!! Failed to load incognito on #{session.sid} / #{session.tunnel_peer}") + print_error("!! Failed to load incognito on #{session.sid} / #{session.session_host}") return false end domain_admins.each do |da_user| ## current user if "#{domain}\\#{da_user}" == session.sys.config.getuid() - print_good "Found Domain Admin Token: #{session.sid} - #{session.tunnel_peer} - #{da_user} (Current User)" + print_good "Found Domain Admin Token: #{session.sid} - #{session.session_host} - #{da_user} (Current User)" return true,'',true end @@ -189,7 +189,7 @@ class Metasploit3 < Msf::Post end if ndom == domain and da_user == nusr sid = session.sid - peer = session.tunnel_peer + peer = session.session_host print_good("Found Domain Admin Token: #{sid} - #{peer} - #{nusr} (Delegation Token)") return true,nusr,false end @@ -201,7 +201,7 @@ class Metasploit3 < Msf::Post if ( x['user'] == "#{domain}\\#{da_user}") target_pid = x['pid'] sid = session.sid - peer = session.tunnel_peer + peer = session.session_host report_note( :host => session, :type => 'domain.token.pid', diff --git a/modules/post/windows/manage/persistence.rb b/modules/post/windows/manage/persistence.rb index 61000c4560..2822117d2b 100644 --- a/modules/post/windows/manage/persistence.rb +++ b/modules/post/windows/manage/persistence.rb @@ -87,7 +87,7 @@ class Metasploit3 < Msf::Post encoder = datastore['ENCODER'] iterations = datastore['ITERATIONS'] @clean_up_rc = "" - host,port = session.tunnel_peer.split(':') + host,port = session.session_host, session.session_port payload = "windows/meterpreter/reverse_tcp" if datastore['ACTION'] == 'TEMPLATE' diff --git a/plugins/session_tagger.rb b/plugins/session_tagger.rb index 9d22439bd5..66d93ec6fa 100644 --- a/plugins/session_tagger.rb +++ b/plugins/session_tagger.rb @@ -18,7 +18,7 @@ class Plugin::SessionTagger < Msf::Plugin include Msf::SessionEvent def on_session_open(session) - print_status("Hooked session #{session.sid} / #{session.tunnel_peer}") + print_status("Hooked session #{session.sid} / #{session.session_host}") # XXX: Determine what type of session this is before writing to it diff --git a/plugins/token_adduser.rb b/plugins/token_adduser.rb index f81516255b..b3cd13e046 100644 --- a/plugins/token_adduser.rb +++ b/plugins/token_adduser.rb @@ -68,14 +68,14 @@ class Plugin::TokenAdduser < Msf::Plugin session = framework.sessions[sid] next unless session.type == "meterpreter" - print_status(">> Opening session #{session.sid} / #{session.tunnel_peer}") + print_status(">> Opening session #{session.sid} / #{session.session_host}") unless session.incognito session.core.use("incognito") end unless session.incognito - print_status("!! Failed to load incognito on #{session.sid} / #{session.tunnel_peer}") + print_status("!! Failed to load incognito on #{session.sid} / #{session.session_host}") next end #print "DEBUG #{username} #{password}\n" diff --git a/plugins/token_hunter.rb b/plugins/token_hunter.rb index 96908dfb17..04dcff00c9 100644 --- a/plugins/token_hunter.rb +++ b/plugins/token_hunter.rb @@ -63,14 +63,14 @@ class Plugin::TokenHunter < Msf::Plugin session = framework.sessions[sid] next if session.type != "meterpreter" - print_status(">> Scanning session #{session.sid} / #{session.tunnel_peer}") + print_status(">> Scanning session #{session.sid} / #{session.session_host}") if(! session.incognito) session.core.use("incognito") end if(! session.incognito) - print_status("!! Failed to load incognito on #{session.sid} / #{session.tunnel_peer}") + print_status("!! Failed to load incognito on #{session.sid} / #{session.session_host}") next end @@ -87,14 +87,14 @@ class Plugin::TokenHunter < Msf::Plugin end if(not user.nil? and ndom and user.strip.downcase == needle.strip.downcase) - print_status("FOUND: #{session.sid} - #{session.tunnel_peer} - #{user} (delegation)") + print_status("FOUND: #{session.sid} - #{session.session_host} - #{user} (delegation)") next end fdom,fusr = user.split("\\") if (not fusr.nil? and ! ndom and fusr.strip.downcase == nusr.strip.downcase) - print_status("FOUND: #{session.sid} - #{session.tunnel_peer} - #{user} (delegation)") + print_status("FOUND: #{session.sid} - #{session.session_host} - #{user} (delegation)") end end @@ -113,13 +113,13 @@ class Plugin::TokenHunter < Msf::Plugin end if(not user.nil? and ndom and user.strip.downcase == needle.strip.downcase) - print_status(">> Found #{session.sid} - #{session.tunnel_peer} - #{user} (impersonation)") + print_status(">> Found #{session.sid} - #{session.session_host} - #{user} (impersonation)") next end fdom,fusr = user.split("\\") if (not fusr.nil? and ! ndom and fusr.strip.downcase == nusr.strip.downcase) - print_status(">> Found #{session.sid} - #{session.tunnel_peer} - #{user} (impersonation)") + print_status(">> Found #{session.sid} - #{session.session_host} - #{user} (impersonation)") end end diff --git a/scripts/meterpreter/enum_chrome.rb b/scripts/meterpreter/enum_chrome.rb index 7891bc6225..7c61d98db0 100644 --- a/scripts/meterpreter/enum_chrome.rb +++ b/scripts/meterpreter/enum_chrome.rb @@ -193,7 +193,7 @@ if @migrate end end -host = session.tunnel_peer.split(':')[0] +host = session.session_host @log_dir = File.join(Msf::Config.log_directory, "scripts", "enum_chrome", Rex::FileUtils.clean_path(@host_info['Computer']), Time.now.strftime("%Y%m%d.%H%M")) ::FileUtils.mkdir_p(@log_dir) diff --git a/scripts/meterpreter/enum_firefox.rb b/scripts/meterpreter/enum_firefox.rb index 70b3611da2..b38e44ce33 100644 --- a/scripts/meterpreter/enum_firefox.rb +++ b/scripts/meterpreter/enum_firefox.rb @@ -7,7 +7,7 @@ require 'sqlite3' @client = client kill_frfx = false -host,port = session.tunnel_peer.split(':') +host,port = session.session_host, session.session_port # Create Filename info to be appended to downloaded files filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") @@ -283,4 +283,4 @@ if client.platform =~ /win32|win64/ else print_error("This version of Meterpreter is not supported with this Script!") raise Rex::Script::Completed -end \ No newline at end of file +end diff --git a/scripts/meterpreter/keylogrecorder.rb b/scripts/meterpreter/keylogrecorder.rb index 62965a9d27..e620d4cd83 100644 --- a/scripts/meterpreter/keylogrecorder.rb +++ b/scripts/meterpreter/keylogrecorder.rb @@ -20,7 +20,7 @@ end #Get Hostname -host,port = session.tunnel_peer.split(':') +host,port = session.session_host, session.session_port # Create Filename info to be appended to downloaded files filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") @@ -178,4 +178,4 @@ if client.platform =~ /win32|win64/ else print_error("This version of Meterpreter is not supported with this Script!") raise Rex::Script::Completed -end \ No newline at end of file +end diff --git a/scripts/meterpreter/metsvc.rb b/scripts/meterpreter/metsvc.rb index f1087e53ac..46baa8eac4 100644 --- a/scripts/meterpreter/metsvc.rb +++ b/scripts/meterpreter/metsvc.rb @@ -104,12 +104,12 @@ if client.platform =~ /win32|win64/ # Setup the multi/handler if requested # if(autoconn) - print_status("Trying to connect to the Meterpreter service at #{client.tunnel_peer.split(':')[0]}:#{rport}...") + print_status("Trying to connect to the Meterpreter service at #{client.session_host}:#{rport}...") mul = client.framework.exploits.create("multi/handler") mul.datastore['WORKSPACE'] = client.workspace mul.datastore['PAYLOAD'] = "windows/metsvc_bind_tcp" mul.datastore['LPORT'] = rport - mul.datastore['RHOST'] = client.tunnel_peer.split(':')[0] + mul.datastore['RHOST'] = client.session_host mul.datastore['ExitOnSession'] = false mul.exploit_simple( 'Payload' => mul.datastore['PAYLOAD'], @@ -120,4 +120,4 @@ if client.platform =~ /win32|win64/ else print_error("This version of Meterpreter is not supported with this Script!") raise Rex::Script::Completed -end \ No newline at end of file +end diff --git a/scripts/meterpreter/netenum.rb b/scripts/meterpreter/netenum.rb index fd07509429..a8b5fbde26 100644 --- a/scripts/meterpreter/netenum.rb +++ b/scripts/meterpreter/netenum.rb @@ -19,7 +19,7 @@ "-sr" => [ false, "To Perform Service Record DNS lookup for a domain"] ) session = client -host,port = session.tunnel_peer.split(':') +host,port = session.session_host, session.session_port # Create Filename info to be appended to downloaded files filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") @@ -333,4 +333,4 @@ if client.platform =~ /win32|win64/ else print_error("This version of Meterpreter is not supported with this Script!") raise Rex::Script::Completed -end \ No newline at end of file +end diff --git a/scripts/meterpreter/prefetchtool.rb b/scripts/meterpreter/prefetchtool.rb index 0623cc20f8..8dc99dfffe 100644 --- a/scripts/meterpreter/prefetchtool.rb +++ b/scripts/meterpreter/prefetchtool.rb @@ -9,7 +9,7 @@ require 'net/http' require 'digest/sha1' @session = client -@host,@port = @session.tunnel_peer.split(':') +@host,@port = @session.session_host, session.session_port # Script Options @@exec_opts = Rex::Parser::Arguments.new( diff --git a/scripts/meterpreter/process_memdump.rb b/scripts/meterpreter/process_memdump.rb index 2b3c18560a..3f225f685c 100644 --- a/scripts/meterpreter/process_memdump.rb +++ b/scripts/meterpreter/process_memdump.rb @@ -77,7 +77,7 @@ end # Dumps the memory for a given PID def dump_mem(pid,name, toggle) - host,port = @client.tunnel_peer.split(':') + host,port = @client.session_host, session.session_port # Create Filename info to be appended to created files filenameinfo = "_#{name}_#{pid}_" + ::Time.now.strftime("%Y%m%d.%M%S") # Create a directory for the logs @@ -186,4 +186,4 @@ if client.platform =~ /win32|win64/ else print_error("This version of Meterpreter is not supported with this Script!") raise Rex::Script::Completed -end \ No newline at end of file +end diff --git a/scripts/meterpreter/scraper.rb b/scripts/meterpreter/scraper.rb index 99b264a8c3..b7d017490b 100644 --- a/scripts/meterpreter/scraper.rb +++ b/scripts/meterpreter/scraper.rb @@ -62,7 +62,7 @@ end # Extract the host and port -host,port = client.tunnel_peer.split(':') +host,port = client.session_host, client.session_port print_status("New session on #{host}:#{port}...") diff --git a/scripts/meterpreter/screenspy.rb b/scripts/meterpreter/screenspy.rb index e10eb2892e..86e841203c 100644 --- a/scripts/meterpreter/screenspy.rb +++ b/scripts/meterpreter/screenspy.rb @@ -59,7 +59,7 @@ session = client -host,port = session.tunnel_peer.split(':') +host,port = session.session_host, session.session_port print_status("New session on #{host}:#{port}...") diff --git a/scripts/meterpreter/winenum.rb b/scripts/meterpreter/winenum.rb index e56bf62e40..047f04cc33 100644 --- a/scripts/meterpreter/winenum.rb +++ b/scripts/meterpreter/winenum.rb @@ -36,7 +36,7 @@ opts.parse(args) { |opt, idx, val| #------------------------------------------------------------------------------- -host,port = @client.tunnel_peer.split(':') +host,port = @client.session_host, @client.session_port info = @client.sys.config.sysinfo # Create Filename info to be appended to downloaded files filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S") @@ -428,7 +428,7 @@ end #------------------------------------------------------------------------------- #Dumping and Downloading the Registry of the target machine def regdump(pathoflogs,filename) - host,port = @client.tunnel_peer.split(':') + host,port = @client.session_host, @client.session_port #This variable will only contain garbage, it is to make sure that the channel is not closed while the reg is being dumped and compress garbage = '' hives = %w{HKCU HKLM HKCC HKCR HKU} diff --git a/scripts/resource/multi_post.rc b/scripts/resource/multi_post.rc index 68138249d2..6f5aefe08d 100644 --- a/scripts/resource/multi_post.rc +++ b/scripts/resource/multi_post.rc @@ -104,8 +104,8 @@ if (framework.sessions.length > 0) # lets start with post exploitation modules framework.sessions.each_key do |sid| session = framework.sessions[sid] - ips = session.tunnel_peer.split(":") - print_status("Session ID: #{sid.to_i} - IP: #{ips[0]}") + ips = session.session_host + print_status("Session ID: #{sid.to_i} - IP: #{ips}") # multi -> all sessions modules_multi.each { |modul|