Jailmonkey Android Bypass
Studying and bypassing the SDK used by android applications designed to do RASP protections.
Last updated
Studying and bypassing the SDK used by android applications designed to do RASP protections.
Last updated
This Protection has proven to be effective against the generic hooks found at frida codeshare. But by searching the application a bit we can find this method
By returning an empty hashmap to this function we can bypass most of the protections of the SDK.
We can code a simple frida script to bypass this with ease.
Jailmonkey is a open source React js lib that is used to implement RASP (Runtime Application Self Protection), it is made to be an easy form of implementing security features to both IOS & Android.
The Protections I've found are :
Jailbreak/Root detection
Hooking detection (frida, xposed and others)
Mock location detection (it's basically if dev options are active with the option for mock location active)
Running on external storage detection
ADB enabled detections
I've came across this lib through a black box pentest and I needed to bypass those protections in order to test the api of the application. When the application closed with error, I knew that it was being blocked by some type of RASP.
After seeing that the application had the Rootbeer SDK I began to check if that was what were blocking me, so I proceeded to start the frida-trace to track if the application was using the "access" or "open" functions from libc.
Those functions are used in the RASP world to see if a file exists in the device, normally binaries or files that indicates that the device is rooted.
And if you've read the manual links from these two functions you will see that if the file exists it will return 0, otherwise it will return -1 (0xffffffffffffffff).
If you are familiarized with frida-trace, you know that it creates a __handler__ folder that contains the handler script of frida-trace for all the functions that you've decided to trace. And by modifying this script to print the return value of the functions you trace, make it a lot easier for us to know which protections are really stopping us.
So, with all that frida-trace gimmicks out of the way, let's return to the application. As I saw the "su" binary being accessed, I knew that it was doing a root detection check, and I Immediately crafted a frida script to bypass this protection
This frida snippet intercepts all the libc access functions and if the path that are being passed as argument of the function is /sbin/su, it returns -1.
After bypassing this check I saw that I was being blocked by another check, so I proceeded to check with objection which function was blocking me.
By using the "watch class" function of objection, after a little reverse engineering of the application, I saw that Jailmonkey was present at the application and was doing the root detection that I've spotted earlier, and rootbeer was there but it was not being used.
As the code was ofuscated, it was harder to know what was what, but after reading the code from Jailmonkey github I was able to know exactly what was blocking me.
https://github.com/GantMan/jail-monkey
As every check that was being done by Jailmonkey was done using booleans, it was easy for doing the frida hooks needed to bypass all protections of the application.
As you can see, all detections are straight forward to bypass, as it does not matter the checks that are being made, by hooking the function and returning a boolean value that is favorable to us, in this case, False, we can bypass all of those checks.
As I was hooking with frida, finally I saw what was blocking me after bypassing the root detection feature, the Hooking detection.
As we can see the code is searching for a lot of forms of hooking, but in this case, as we are using frida, the only method that needs to be bypassed is the "b". By returning false on that one, we are safe.
Another method of bypassing this protection with a more "intelligent" way, is to make a Java native function bypass. I will cover this one in another article but it's just like we've done before with Libc Access, but this one uses "android.app.ActivityManager" and android.content.Context" to search for this "fridaserver" string.
I was not running the application from external SD, but if I was, that would be simple to bypass too. (good to know that this protection can exist)
Well, this one is later used (i think) to know if the user can use a mock location, but, as I was not using it at the time, I completely ignored it.
After that I proceed to craft a giant frida script to bypass all of these protections and plus the SSL pinning (used a generic SSL pinning bypass script appended to this one).
After making a monster that returns False to everything it hooks I saw this code snippet:
If only I saw this code earlier... and to make it better, it was not ofuscated. This makes our job a lot easier, when all checks are called by a "master" function.
And, as you can guess, if you return a NULL hashmap, it bypasses all the protections immediately... so... yeah. Thats all.
Thanks for reading.