Skip to main content

Create your own Android security tool, because you are a Hacker: Intercepting Android application network (day 98)


Sooner or later, it will come the time when you start thinking about developing your own tools.

Because the tools you usually used are not enough and you think you can do it better 

Thus, in this post, I will show you some of the thought processes that you can apply when designing your own hacking tools.  We will take a look at how to automate the process of intercepting an Android application.
If you want to see the source code directly you can check the following Github link

 

Some Background Knowledge:

Let's start with a simple question?

"why do we want to automate the process of intercepting an Android application?"


we can do this pretty easy right? You just have to alter the device network to your proxy device(Burp Suite or MITMProxy) by changing the wifi setting.


 Note:
  • 192.168.56.1 is the proxy device
  • 8080 is the port that the proxy device listening into
Make sure the proxy is listening to all interface:





If you want to analyze a secure network(https) you can install the proxy certificate in the device. You can follow these steps:

First, you need to download the proxy certificate. In Burpsuite, all you need to do is go to http://localhost:8080 and you need to change the cert extension into .crt. Copy the cert to the device folder, make sure you put this to a directory that you can easy to find, in this context I put the cert at "Downloads" folder. 

To copy the file, you can do this by ADB tools:

~# adb push cacert.crt /storage/emulated/0/Download/


Go to settings and search for "Install certificates from SD card" this will take you to encryption & credential settings in the device.



Click "Install from SD card" and choose the proxy certification that you have installed earlier.






"Easy peasy lemon squeezy"

But! in Android Nougat, this approach will not work anymore.

"why?"
According to Android-developer official website, Google has changed how the Android device will handle trusted Certificate Authorities(CA) to provide more security. These changes include:
  1. Safe and easy APIs to trust custom CA's. 
  2. Apps that target API Level 24 and above no longer trust user or admin-added CA's for secure connections, by default. 
  3. All devices running Android Nougat offer the same standardized set of system CA's—no device-specific customizations.

We are interested in the second and third points. It shows that if we want to intercept application traffic, we need to make the app explicitly state it by customizing it.

You can follow these steps to customize the application:
  • Decompile the application using Apktool. Apktool helps us to get the original file of the apk file.   
    • ~# apktool d <apk file> -d <directory result>
  • Edit the configuration in the AndroidManifest.xml file. In layman's term, The Manifest file is a file containing a summary of permission, components, and configuration that the application needs to have to run in the device. Put the following string to "application tag" in the XML file:
    <application android:networkSecurityConfig="@xml/network_security_config"...>

    the added string will told the application to use network security configuration inside "network_security_config.xml" file located in the XML directory.
  • Create a new file named "network_security_config.xml" inside the res/xml directory with the following content that instructs the application to trust any preinstalled system and user-added CAs. 
    <network-security-config>  
          <base-config>  
                <trust-anchors>  
                    <!-- Trust preinstalled CAs -->  
                    <certificates src="system" />  
                    <!-- Additionally trust user added CAs -->  
                    <certificates src="user" />  
               </trust-anchors>  
          </base-config>  
     </network-security-config> 
    The "res" directory contains all the pretty things that we see in the android app such as image, font, color, style, and dimension.
  • Rebuild the application, after customizing the application configuration it's time to rebuild the directory into the apk file again.
    •  ~# apktool b <app folder> -o <new apk>
  • Sign the application, we got our new application but it's not ready yet to be installed. We need to sign the application, you can use "uber-sign" tools to do this task.
    • ~# java -jar uber-apk-signer.jar --apks /path/to/apks (make sure java is installed in your host)
Finally, you can install the new customized app and start sniffing the application's traffic.

But as you probably realized there are a lot of steps that we need to take before doing any analysis of a single application. Thus, it is a good idea to automate the following steps using the programming language of our choice.

The Good Stuff:

Now we are ready to create our own tools, from this point I will use python version 3 as the programming language of choice. It's up to you if you want to use Ruby, Golang or Java, etc whatever that makes you comfortable

Setting up global variables:

First, we want to make global variables that hold the path to Apktool, Uber signer, and Java so we don't have to repeatedly type the path in every function.

The logging function will act as debugging information to check if there is an error in our coding.

Checking the file:

We want to make sure that the file that is submitted to our scripts is an apk file, we can utilize the python-magic library to identify the file type. First, you need to install the library using the python-pip utility

~# pip3 install python3-magic

 

Next, create a function named "check_file_apk" to hold the logic of our file check. To detect the file type you can use the "from_file" function from the magic library that we have installed earlier, the result of the function will be check if it's "application/zip" or not.

you should already know that android apk file is a zip file this is why we compared it with the string "application/zip"

Decompiling the apk file:

As we were sure that the user submits the correct file, we will straight to decompile the apk file using the Apktool.

Unfortunately, I haven't found any python library that integrated with the Apktool, so we will use os python library to execute OS command on the machine that invokes Apktool command for us.




  • First, we referenced the path of the Apktool from the global variable that we have initialized earlier.
  • Put some logging message so we know that it reaches the function(optional).
  • We construct the output directory name and make sure the result is in the same directory of our tools. I'm using "os.path.basename" to retrieve the name of the file from the path(if user submit "/home/user/test.apk", it will result "test.apk") and append it with "_smali"
  • We construct the OS command using a python format string.
  • Show the constructed os command using logging function so we know that the tool correctly places the string together(optional).
  • Execute the OS command using os.system() function and we compare the return value. If it returns 0 it means that our command successfully executed and finally we return the output directory for further reference.

Edit the manifest file:

We have decompiled the apk file, the next logical step is to edit the manifest file.




  • To edit an XML file we can use the ElementTree library. However, before we move any further I should warn you when the python ElementTree read the AndroidManifest.xml file you will soon notice that the prefix "android:" is replaced with "{http://schemas.android.com/apk/res/android}" and it will screw the entire file if we try to update it. 
  •  Thus, we told the library so that it knows to treat "http://schemas.android.com/apk/res/android" as "android" using ET.register_namespace() function.
  • We show the directory that is passed into the function(optional).
  • We join the path of output directory with the AndroidManifext.xml string to get the real path using os.path.join() function.
  • We need to make sure that the path we produce is correct so we check if the produced path leads to a file or not using os.path.isfile() function.
  • We show the path of the AndroidManifest.xml file(optional).
  • We load the XML file using parse() function and get the root of the XML using getroot(), we need to obtain the root first so we can navigate around the XML content. More details about python and XML files can be read in this link.
  • Inside the XML file, our main interest is the "application" tag we can get this tag directly by using find() function and we want to retrieve the content or attribute by appending the find() function with attrib.
  • Next, we want to append the new configuration in this tag which is "android:networkSecurityConfig" with the content "@xml/network_security_config" this means that the app will look for the configuration file named "network_security_config" in XML folder. Doing this is pretty easy, we can just add a new entry by creating a new key along with the content like a dictionary in python.
  • Finally, We update XML file so the new entry is saved using write() function

Copied the configuration file:


Now that we have customized the AndroidManifest.xml to use the new network configuration, we need to create a "network_security_config.xml"  in /res/xml folder of the application directory.
  • We joined the output directory with "res/xml" string to get the destination path.
  • I just create a new file named "network_security_config.xml" located in the tool directory and fill it with this configuration:
    <network-security-config>  
          <base-config>  
                <trust-anchors>  
                    <!-- Trust preinstalled CAs -->  
                    <certificates src="system" />  
                    <!-- Additionally trust user added CAs -->  
                    <certificates src="user" />  
               </trust-anchors>  
          </base-config>  
     </network-security-config> 
  • Next, we check if the source file and destination folder are present using isfile() and isdir() function respectively.
  • Put some logging message so we know that it reaches the function(optional).
  • Finally, copy the source file into the destination folder using shutil.copy() function. More details on how to use python to automate copy can be check in this link.

 

Rebuild the application directory into a new apk file:



Creating a function to rebuild the application is not much of a difference when doing the decompilation process, the only thing that is different is the OS command that we need to pass to the os.system() function. Using "b" as the parameter dictates the Apktool to build the application directory to an APK file.

Finally, at the end of the function, we return the file path inside the variable file_output as a reference.

Signing the application:


Once we are done with all of the heavy liftings we will create one last function to sign a newly build apk file.  This is a crucial step because the Android device will not accept unsigned applications. 

The process is pretty similar to decompiling and rebuilds APK function, however, in this function, we joined two tools into one command strings(Uber-signer and Java)

Put it together into the main function:

We have created several functions with each own programming task, we use this approach to make it easy to trace a bug and easier to read rather than bulked all of the functionality into one main function that could be a whole lot of mess. Now, it is time to put it into one main function, like this:



Printing the banner is optional, it is up to you whether you want to print a cool logo every time you want to run the program.

The sequence of the logic follows the order of function that we make earlier. First, we check if the file that submits to the program is APK file or not, if its yes it will decompile the program using Apktool then we saved the output directory so it can be referenced for edit_manifest_xml and copied_configuration_file function that will set up all the necessary configuration to prepare the application for proxy.

Finally, the program will rebuild the application directory into an APK file and saved the path of the file to be a reference for signing_new_apk function that will sign the new apk file.

The final result will be like this:





Once the script finishes the execution it will generate two folders consist of the smali folder which is the result of the Apktool and apk signed folder that contain the newly signed APK file that you will install in your Android device, whereas, one new apk file that is not yet signed.

For a test drive, I download the reddit(v.2.25.0) link application and turns out it works well enough for me :).


That's all for this blog I hope you enjoy creating your own tools, it is difficult but feels so rewarding at the end. I will try to run the tools into more testing cases to see if there is anything that I could improve in future development.


Comments

Popular posts from this blog

Having fun analyzing nginx log to find malicious attacker in the net (ง'̀-'́)ง (day 37)

  What makes you sleepless at night? is it because of a ghost or scary stories? is it because you have an important meeting tomorrow? or is it because you have an exam? For me, what keeps me up all night is that I keep thinking about what happens to a website that I just created, is it safe from an attacker (certainly not) or did I missing some security adjustments that lead to vulnerability? well I'm not the best secure programmer in the world, I'm still learning and there is a big possibility that I can make a mistake but for me, a mistake can be a valuable investment to myself or yourself to be better so from this idea, I want to know more about what attackers casually do when attacking a website. Here in this post, I'm going to show you how I analyzed attack to the website that I have permission to design and also some interesting findings that I could get from the analysis Background: All of this analysis comes from the traffic that is targeted to th

Utilize Pwntools for crafting ROP chain :') (day 69)

who doesn't like pwntools? it is a very versatile tool and can be customized according to our need using the python script but did you need to know that pwntools itself can help us to automatically craft a rop chain for us? so in this post, I will show you how to make rop chain less painful and make pwntools do all the heavy lifting. To demonstrate this I will use the binary challenge callme 64 bit from ropemporium link: https://ropemporium.com/challenge/callme.html Crashing the app: Like any other exploitation process, we need to crash the program by generating a long string pattern to determine the offset. based on the information from the above figure we can see that we required to provide 40 bytes of offset Fun stuff: now this where the fun stuff began write the following python script: as in the guideline of the challenged said we need to chain the function call by first to call the callme_one function, callme_two function and then callme_three funct

WriteUp PWN tarzan ROP UNICTF ಠ_ಠ (day 61)

So in this post, I'm going to talk about how to solve the Tarzan pwn challenge from UNICTF 2019. Back in the day when the competition is still going I couldn't finish it and don't have any clue to solve this but this time I was able to finish it :) Also in this post, we will be going to be heavily focused on how to utilize pwntools to construct a ROP chain. If you kinda confused about my explanation in this post you can refer to this following youtube video, link: https://www.youtube.com/watch?v=gWU2yOu0COk I build the python script based on this video Ok, let's get started! In this challenge, you will get two binary first go with tarzan and libc-2.29.so by providing .so file it tell us what version library that the target machine is using this could help us to do ROP chain. first, we run the Tarzan binary to get the basic idea of the program work and as you can see it just show you some text, newline and when you try to input something it doesn't gi