A Single Partner for Everything You Need Optiv works with more than 450 world-class security technology partners. By putting you at the center of our unmatched ecosystem of people, products, partners and programs, we accelerate business progress like no other company can.
We Are Optiv Greatness is every team working toward a common goal. Winning in spite of cyber threats and overcoming challenges in spite of them. It’s building for a future that only you can create or simply coming home in time for dinner. However you define greatness, Optiv is in your corner. We manage cyber risk so you can secure your full potential.
Mobile App Testing With Automation Trickery in Frida Breadcrumb Home Insights Blog Mobile App Testing With Automation Trickery in Frida March 30, 2018 Mobile App Testing With Automation Trickery in Frida When you spend a lot of time doing security testing on mobile apps like I do, you begin to worry that a large part of your life will be spent rebooting mobile apps that have stopped responding. Frida (https://www.frida.re/) is a powerful testing tool and I love using it, but something I have had to come to terms with is: Stomping your way through an application's runtime is occasionally going to provoke its ire. And programming defensively is one thing, but I can't exactly blame a developer for not thinking, "How do I handle it if every parameter in this function is passed a null reference, instead of the data I painstakingly parsed from the server?" Nonetheless, it's a big waste of time - if the app crashes, I frequently have to log back in to the app, which is time consuming. Recently I was looking for bug bounties in the ChatWork app (https://go.chatwork.com/), which is more or less analogous to Slack. While I was successfully bypassing the certificate pinning, it kept crashing, which was annoying to me. I was working with Frida, so a thought occurred to me - I can automate this, right? I just need to: Detect what page I'm on If I'm on the login page, enter my details and then hit the 'login' button Otherwise, do nothing So simple. What could possibly go wrong? My first draft looked a little like this: var login =setInterval(function(){ Java.perform(function(){ var BufferType= Java.use('android.widget.TextView$BufferType'); var SPANNABLE = BufferType.valueOf("SPANNABLE"); Java.choose("com.chatwork.android.shard.activity.LoginActivity",{ onMatch: function(activity){ if(activity.hasWindowFocus()){ activity._f.value.setText("john.labelle@optiv.com",SPANNABLE); activity._g.value.setText("[REDACTED]",SPANNABLE); activity.d(); clearInterval(login); } }, onComplete:doNothing }); }); },500); Because I don't have access to the original application source code, I see the ProGuarded member names for the 'username' and 'password' text boxes (f and g, which becomes _f and _g in Frida syntax). Similarly, the d() method is called by the 'login' button. By checking for the login screen every half second, I will eventually detect it and then login to the application, right? This code looks reasonably correct, but is also wrong for a very non-obvious reason. When you insert text into a text box in this way, the observing UI thread needs to redraw that text box... but the thread that Frida runs on is not an animator thread, and so enterprising UI automators are presented with the cryptic error: Error: android.util.AndroidRuntimeException: Animators may only be run on Looper threads My first instinct was, "Well, I know the main thread is an animator, so I'll simply call Java.scheduleOnMainThread(fn)..." Unfortunately, attempting to use this function in an asynchronous callback produced a Byzantine nightmare of errors and I didn't feel inclined to debug the Frida runtime. I needed something lazier. After many hours of digging in despair through the Android API, I did the unthinkable: I read the documentation for the Android Looper class. It provides the rather useful prepare() method (https://developer.android.com/reference/android/os/Looper.html#prepare()): prepare prepare() added in API level 1 void prepare () Initialize the current thread as a looper. This gives you a chance to create handlers that then reference this looper, before actually starting the loop. Be sure to call loop() after calling this method, and end it by calling quit(). Is the Frida thread an Android thread? Will there be performance penalties for making the main Frida thread an animation thread? Will I really reboot the application enough times to justify the enormous time sink of making this work automatically? I didn't think about any of these questions, I just gave it a try: var login =setInterval(function(){ Java.perform(function(){ var BufferType= Java.use('android.widget.TextView$BufferType'); var SPANNABLE = BufferType.valueOf("SPANNABLE"); Java.choose("com.chatwork.android.shard.activity.LoginActivity",{ onMatch: function(activity){ if(activity.hasWindowFocus()){ var looper=Java.use("android.os.Looper"); looper.prepare(); activity._f.value.setText("john.labelle@optiv.com",SPANNABLE); activity._g.value.setText("[REDACTED]",SPANNABLE); activity.d(); clearInterval(login); } }, onComplete:doNothing }); }); },500); Which indeed does the trick. Long story short, you can indeed make the Frida thread an animation thread on Android, and this will allow you to drive mobile application user interfaces and speed up your mobile app security testing. Give it a try and let me know how it works in the comments! By: John Labelle Senior Consultant John is a senior security consultant with Optiv’s application security team. In this role, he specializes in source code review. Share: SecOps
Would you like to speak to an advisor? How can we help you today? Image E-Book Cybersecurity Field Guide #13: A Practical Approach to Securing Your Cloud Transformation Download Now Image Events Register for an Upcoming OptivCon Learn More Ready to speak to an Optiv expert to discuss your security needs?