Skip to content

Commit d8f59a9

Browse files
author
Brent Cook
committed
Land rapid7#7507, Fix payload uuid/arch/platform tracking
2 parents 6a35b36 + d7dce28 commit d8f59a9

File tree

279 files changed

+837
-895
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

279 files changed

+837
-895
lines changed

.ruby-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.3.1
1+
2.3.2

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ addons:
1010
- graphviz
1111
language: ruby
1212
rvm:
13-
- '2.3.1'
13+
- '2.3.2'
1414

1515
env:
1616
- RAKE_TASKS="cucumber cucumber:boot" CREATE_BINSTUBS=true

Gemfile.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ PATH
1414
metasploit-concern
1515
metasploit-credential
1616
metasploit-model
17-
metasploit-payloads (= 1.1.29)
17+
metasploit-payloads (= 1.2.1)
1818
metasploit_data_models
19-
metasploit_payloads-mettle (= 0.0.8)
19+
metasploit_payloads-mettle (= 0.1.2)
2020
msgpack
2121
nessus_rest
2222
net-ssh
@@ -33,7 +33,7 @@ PATH
3333
rb-readline-r7
3434
recog
3535
redcarpet
36-
rex-arch
36+
rex-arch (= 0.1.2)
3737
rex-bin_tools
3838
rex-core
3939
rex-encoder
@@ -169,7 +169,7 @@ GEM
169169
activemodel (~> 4.2.6)
170170
activesupport (~> 4.2.6)
171171
railties (~> 4.2.6)
172-
metasploit-payloads (1.1.29)
172+
metasploit-payloads (1.2.1)
173173
metasploit_data_models (2.0.8)
174174
activerecord (~> 4.2.6)
175175
activesupport (~> 4.2.6)
@@ -180,7 +180,7 @@ GEM
180180
postgres_ext
181181
railties (~> 4.2.6)
182182
recog (~> 2.0)
183-
metasploit_payloads-mettle (0.0.8)
183+
metasploit_payloads-mettle (0.1.2)
184184
method_source (0.8.2)
185185
mime-types (3.1)
186186
mime-types-data (~> 3.2015)

lib/msf/base/serializer/readable_text.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,11 @@ def self.dump_sessions(framework, opts={})
546546
row = []
547547
row << session.sid.to_s
548548
row << session.type.to_s
549-
row[-1] << (" " + session.platform) if session.respond_to?(:platform)
549+
if session.respond_to?(:session_type)
550+
row[-1] << (" " + session.session_type)
551+
elsif session.respond_to?(:platform)
552+
row[-1] << (" " + session.platform)
553+
end
550554

551555
if show_extended
552556
if session.respond_to?(:last_checkin) && session.last_checkin

lib/msf/base/sessions/command_shell_options.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,15 @@ def on_session(session)
3434
if self.platform and self.platform.kind_of? Msf::Module::Platform
3535
session.platform = self.platform.realname.downcase
3636
end
37-
session.arch = self.arch if self.arch
37+
38+
if self.arch
39+
if self.arch.kind_of?(Array)
40+
session.arch = self.arch.join('')
41+
else
42+
session.arch = self.arch
43+
end
44+
end
45+
3846
end
3947

4048
end

lib/msf/base/sessions/mainframe_shell.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ class MainframeShell < Msf::Sessions::CommandShell
3232
# initialize as mf shell session
3333
#
3434
def initialize(*args)
35-
self.platform = "mainframe"
36-
self.arch = "zarch"
35+
self.platform = 'mainframe'
36+
self.arch = ARCH_ZARCH
3737
self.translate_1047 = true
3838
super
3939
end

lib/msf/base/sessions/meterpreter.rb

Lines changed: 95 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def run_cmd(cmd)
284284
#
285285
# Load the stdapi extension.
286286
#
287-
def load_stdapi()
287+
def load_stdapi
288288
original = console.disable_output
289289
console.disable_output = true
290290
console.run_single('load stdapi')
@@ -294,9 +294,8 @@ def load_stdapi()
294294
#
295295
# Load the priv extension.
296296
#
297-
def load_priv()
297+
def load_priv
298298
original = console.disable_output
299-
300299
console.disable_output = true
301300
console.run_single('load priv')
302301
console.disable_output = original
@@ -310,7 +309,6 @@ def is_valid_session?(timeout=10)
310309

311310
begin
312311
self.machine_id = self.core.machine_id(timeout)
313-
self.payload_uuid ||= self.core.uuid(timeout)
314312

315313
return true
316314
rescue ::Rex::Post::Meterpreter::RequestError
@@ -325,41 +323,18 @@ def is_valid_session?(timeout=10)
325323
def update_session_info
326324
username = self.sys.config.getuid
327325
sysinfo = self.sys.config.sysinfo
328-
tuple = self.platform.split('/')
329326

330-
#
331-
# Windows meterpreter currently needs 'win32' or 'win64' to be in the
332-
# second half of the platform tuple, in order for various modules and
333-
# library code match on that specific string.
334-
#
335-
if self.platform !~ /win32|win64/
336-
337-
platform = case self.sys.config.sysinfo['OS']
338-
when /windows/i
339-
Msf::Module::Platform::Windows
340-
when /darwin/i
341-
Msf::Module::Platform::OSX
342-
when /freebsd/i
343-
Msf::Module::Platform::FreeBSD
344-
when /netbsd/i
345-
Msf::Module::Platform::NetBSD
346-
when /openbsd/i
347-
Msf::Module::Platform::OpenBSD
348-
when /sunos/i
349-
Msf::Module::Platform::Solaris
350-
when /android/i
351-
Msf::Module::Platform::Android
352-
else
353-
Msf::Module::Platform::Linux
354-
end.realname.downcase
355-
356-
#
357-
# This normalizes the platform from 'python/python' to 'python/linux'
358-
#
359-
self.platform = "#{tuple[0]}/#{platform}"
327+
# when updating session information, we need to make sure we update the platform
328+
# in the UUID to match what the target is actually running on, but only for a
329+
# subset of platforms.
330+
if ['java', 'python', 'php'].include?(self.platform)
331+
new_platform = guess_target_platform(sysinfo['OS'])
332+
if self.platform != new_platform
333+
self.payload_uuid.platform = new_platform
334+
self.core.set_uuid(self.payload_uuid)
335+
end
360336
end
361337

362-
363338
safe_info = "#{username} @ #{sysinfo['Computer']}"
364339
safe_info.force_encoding("ASCII-8BIT") if safe_info.respond_to?(:force_encoding)
365340
# Should probably be using Rex::Text.ascii_safe_hex but leave
@@ -369,6 +344,24 @@ def update_session_info
369344
self.info = safe_info
370345
end
371346

347+
def guess_target_platform(os)
348+
case os
349+
when /windows/i
350+
Msf::Module::Platform::Windows.realname.downcase
351+
when /darwin/i
352+
Msf::Module::Platform::OSX.realname.downcase
353+
when /mac os ?x/i
354+
# this happens with java on OSX (for real!)
355+
Msf::Module::Platform::OSX.realname.downcase
356+
when /freebsd/i
357+
Msf::Module::Platform::FreeBSD.realname.downcase
358+
when /openbsd/i, /netbsd/i
359+
Msf::Module::Platform::BSD.realname.downcase
360+
else
361+
Msf::Module::Platform::Linux.realname.downcase
362+
end
363+
end
364+
372365
#
373366
# Populate the session information.
374367
#
@@ -493,20 +486,79 @@ def create(param)
493486

494487
sock = net.socket.create(param)
495488

496-
# sf: unsure if we should raise an exception or just return nil. returning nil for now.
497-
#if( sock == nil )
498-
# raise Rex::UnsupportedProtocol.new(param.proto), caller
499-
#end
500-
501489
# Notify now that we've created the socket
502490
notify_socket_created(self, sock, param)
503491

504492
# Return the socket to the caller
505493
sock
506494
end
507495

508-
attr_accessor :platform
509-
attr_accessor :binary_suffix
496+
#
497+
# Get a string representation of the current session platform
498+
#
499+
def platform
500+
if self.payload_uuid
501+
# return the actual platform of the current session if it's there
502+
self.payload_uuid.platform
503+
else
504+
# otherwise just use the base for the session type tied to this handler.
505+
# If we don't do this, storage of sessions in the DB dies
506+
self.base_platform
507+
end
508+
end
509+
510+
#
511+
# Get a string representation of the current session architecture
512+
#
513+
def arch
514+
if self.payload_uuid
515+
# return the actual arch of the current session if it's there
516+
self.payload_uuid.arch
517+
else
518+
# otherwise just use the base for the session type tied to this handler.
519+
# If we don't do this, storage of sessions in the DB dies
520+
self.base_arch
521+
end
522+
end
523+
524+
#
525+
# Generate a binary suffix based on arch
526+
#
527+
def binary_suffix
528+
# generate a file/binary suffix based on the current arch and platform.
529+
# Platform-agnostic archs go first
530+
case self.arch
531+
when 'java'
532+
'jar'
533+
when 'php'
534+
'php'
535+
when 'python'
536+
'py'
537+
else
538+
# otherwise we fall back to the platform
539+
case self.platform
540+
when 'windows'
541+
"#{self.arch}.dll"
542+
when 'linux' , 'aix' , 'hpux' , 'irix' , 'unix'
543+
'lso'
544+
when 'android', 'java'
545+
'jar'
546+
when 'php'
547+
'php'
548+
when 'python'
549+
'py'
550+
else
551+
nil
552+
end
553+
end
554+
end
555+
556+
# These are the base arch/platform for the original payload, required for when the
557+
# session is first created thanks to the fact that the DB session recording
558+
# happens before the session is even established.
559+
attr_accessor :base_arch
560+
attr_accessor :base_platform
561+
510562
attr_accessor :console # :nodoc:
511563
attr_accessor :skip_ssl
512564
attr_accessor :skip_cleanup

lib/msf/base/sessions/meterpreter_android.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ class Meterpreter_Java_Android < Msf::Sessions::Meterpreter_Java_Java
1616

1717
def initialize(rstream, opts={})
1818
super
19-
self.platform = 'java/android'
19+
self.base_platform = 'android'
20+
self.base_arch = ARCH_JAVA
2021
end
2122

2223
def load_android

lib/msf/base/sessions/meterpreter_armle_linux.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ def supports_zlib?
1919
end
2020
def initialize(rstream, opts={})
2121
super
22-
self.platform = 'armle/linux'
23-
self.binary_suffix = 'lso'
22+
self.base_platform = 'linux'
23+
self.base_arch = ARCH_ARMLE
2424
end
2525
end
2626

lib/msf/base/sessions/meterpreter_java.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ def supports_zlib?
1919
end
2020
def initialize(rstream, opts={})
2121
super
22-
self.platform = 'java/java'
23-
self.binary_suffix = 'jar'
22+
self.base_platform = 'java'
23+
self.base_arch = ARCH_JAVA
2424
end
2525
end
2626

0 commit comments

Comments
 (0)