Android Mobile Pentest 101
© tsug0d, September 2018
Lecture 7 – Hooking With Frida
Goal: Known how to use Frida to hook into function
Description
- Dynamic instrumentation (tracing, profiling, and debugging the execution of an app during runtime) toolkit
for developers, reverse-engineers, and security researchers.
- Good things of Frida:
Installation -> Client (real pc)
- Install Frida CLI Tools:
pip3 install frida-tools
- Install Frida Python bindings (we mainly use it in this lecture)
pip3 install frida
- Test if frida successful installed
Installation -> Server (virtual phone)
- A frida-server binary from the release page, frida-server-12.1.2-android-x86.xz at this lecture
(if you don’t know your phone architecture, just try all binary arm/arm64/x86-64/x86)
- The frida-server version should match your Frida version.
Installation
- Our setup will look like this:
Frida-client
(use CLI or python binding to interact
with the android)
Frida-server
Frida-server
Listen on port 27042 by default
(listen on port 27042 by default)
Installation
- Check if our setup correctly, from real pc, type command:
frida-ps -U
success
Python bindings
- As I said above, we will mainly focus on “frida python bindings”, let learn about it.
- We will use original “InsecureBankv2” app as an example (so delete and reinstall the original apk first J )
Python bindings
- To use frida in python, we import it
import frida
- We use get_usb_device() function to get our device information
device = frida.get_usb_device()
- Then we spawn the app:
pid=device.spawn(“com.android.insecurebankv2”)
device.resume(pid)
- We now got a pid of spawned app, then attach it to begin our pentest journey:
session = device.attach(id)
- We almost done the python template, let inject the javascript code:
script = session.create_script(hook_script)
script.load()
Python bindings
- The python code that we’ve created so far:
Python bindings
- So you may wonder what the hook_script is, it’s the commands that we provide to Frida using its
Javascript API. With it, we can work with Java functions and objects directly.
- First notice here is, the code we entered is wrapped in a Java.perform(function(){ ... }) which is a
requirement of Frida Java API. So hook_script will look like this:
hook_script=“””
Java.perform(function ()
{
// do something
});
“””
- We are going to decide which we want to hook, back to our app, did you remember the weak crypto in
lecture 3 (Static analysis)?
- We have to understand the crypt, simulate it in python, blah...blah.... what if you can’t find the key, or
the crypt is more complex? Im not a crypto guys so i will give up...
- Luckily, Frida save the day J
Python bindings
- We found the decrypt code in com/android/insecurebankv2/CryptoClass.class
- We know that it will take crypt-text, decrypt then return plainText, we don’t even care what it does
inside. The task is very clear now, just call it function using our crypt-text as input J
Python bindings
- So, how to call the function using Frida? We are going to use Java.choose()
- From the official document:
- So, it will scan the heap, find instance of className we provide, on matching, the onMatch callback
will be triggered, and we call the function of this class in the instance.
Python bindings
- Talk is cheap, I show you the code J
className
Instance of
className
found on heap
Use instance
to Call function
Python bindings
- And here the result:
- As you see, Dinesh@123$ is the password of user dinesh J
Python bindings
- We move to another fun J
- Remember the root detection code? This time we will modify it, let’s Frida!
- We found the code in com/android/insecurebankv2/PostLogin.class
- As you see, if doesSuperuserApkExist(String paramString) return true, then root detected. By default, we
pass this check, but to see some fun, we make it detect us J => make it true!
Python bindings
- The return of this function is a bool val, so we hijack it, no need to care about the check code
- How? This time we use Java.use()
- From the official document:
Python bindings
- In short, Java.use() allow us to overwrite function in class.
- First, we use the class which got this function
Java.use(‘com.android.insecurebankv2.PostLogin’)
- Then we override the code using implementation:
class_PostLogin.doesSuperuserApkExist.implementation = function ()
{
//whatever, in this case, return true
}
- Done
Python bindings
- Here the code:
Use implementation to override
function doesSuperuserApkExist content
Python bindings
- Come to our virtual phone, login in, and we got root detected status (>_<!)
Normal start, by default Start and hooked by frida J
Python bindings
- Another example, when we pentest the app, we always meet some client-side check, with frida, bypass it’s easy!
- Look at this code in com/android/insecurebankv2/ChangePassword$RequestChangePasswordTask.class
Python bindings
- Notice the regex:
((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})
This regex is made to check the complexity of the password, so if we change our password to something simple, this
regex prevent us
- I’m simple man, I want to use “1234” as my new pass:
Failed because password require
length 6->20, “1234” is just 4
Python bindings
- Of course its failed because of the regex, we will use frida to change this regex. This time we don’t inject to app
class, because the check use method from java package, not our code.
from
- So we hook it:
regex_Pattern_hook = Java.use('java.util.regex.Pattern')
- We cannot simply use regex_Pattern_hook.compile.implementation because in Pattern package there are many
compile methods ( compile(String x); compile(String x,int y); etc…), so frida will be confused
- So we have to tell frida which method we are going to use, in this case: compile(String x)
- We use overload:
regex_Pattern_hook.compile.overload("java.lang.String").implementation
Python bindings
- Here the code:
Change compile method by calling the
original compile with “.*” regex provided
Python bindings
- Sometime frida hooking will make the app suspended or idle (maybe caused by old android mobile), we just
reload the script and it works like a charm
- Let test it:
Python bindings
- Login to confirm:
- There are some more useful frida api when dealing with python: send, recv and rpc
Read full docs here:
https://www.frida.re/docs/javascript-api/