PreEmptive logo

Tools Don’t Hack Apps, Hackers Do: Securing Android Apps Against Frida

Search for lockpicking, and you’ll see that there’s no shortage of suppliers ready to serve locksmiths and hobbyists. Each community has a legitimate need. Is there any reason to believe burglars don’t shop at the same sites? 

Hackers are developers, and they have a long history of enthusiastically embracing and adapting development (and DevOps) innovations to speed their work, extend their reach, and ship software – the only difference is that they’re more likely to use those development tools and platforms on YOUR software rather than on their own. Static code analysis tools, debuggers, and even public bug-tracking databases are all go-to hacker resources.

Any comprehensive app security strategy must include controls to prevent or significantly reduce the unauthorized use of development tools on (or against) applications. Suppose you want to tie this requirement back to regulations and compliance obligations. In that case, these topics typically fall squarely inside unauthorized privilege escalation or non-privileged user access to privileged utilities and tools.

Let’s examine Frida, an archetypal example, and examine the controls that have proven effective in limiting its unauthorized use.

The Frida website defines Frida as a “Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers.” A dynamic (binary) instrumentation toolkit (such as Frida) injects instrumentation code at runtime that can reveal and change the behavior and state of a targeted application throughout its execution.

The injected code executes as part of the normal instruction stream after being injected but is transparent to the application it’s been injected into, making it both a legitimate alternative to debuggers and a powerful hacker tool.

Further, to encourage adoption and maximize its legitimate value, Frida has published an open API itself and built a suite of productivity tools based largely on this core technology. These include:

  • Frida-ps: a command line tool for listing processes.
  • Frida-trace: a command line tool to dynamically trace function calls.
  • Fridump: a universal memory dumper tool. Aimed to dump accessible memory regions from any platform supported by Frida.
  • Frida-discover: a tool for discovering internal functions in a program. It dynamically instruments every thread in a given process and stalks every called function during process execution, trying to discover internal functions like statically linked functions.

This is so invasive! Why not just ban these tools? These are three legitimate use cases (offered on the Frida website) where Frida is especially effective versus alternative approaches (thus justifying their existence).

  1. You’re building a desktop app that has been deployed at a customer’s site. There’s a problem but the built-in logging code just isn’t enough. You must send your customer a custom build with lots of expensive logging code. Then, you realize you could use Frida and build an application-specific tool that will add all the necessary diagnostics in just a few lines of Python. There is no need to send the customer a new custom build. You send the tool, which will work on many app versions.
  2. You’d like to build a Wireshark on steroids with support for sniffing encrypted protocols. It could even manipulate function calls to fake network conditions that would otherwise require you to set up a test lab.
  3. Your in-house app could use some black-box tests without polluting your production code with logic only required for exotic testing.

Frida is free, useful, and, with the help of its extended development community, it’s getting easier and easier to use.

In-app Protection: What a development organization can do to secure their work against unauthorized monitoring and modification

Let’s begin by looking at a specific use case. Hail Frida!! The Universal SSL pinning bypass for Android applications offers a step-by-step guide (using Frida) to bypass an Android application’s SSL pinning (a technique used to ensure that an app is communicating securely with a verified service/server) for penetration testing. The use case is legitimate, but the identical steps can also be used to implement a “man in the middle” attack (an attack where the attacker secretly relays and possibly alters the communications between two parties who believe they are directly communicating with each other).

Effective risk management strategies combine preventative, detective, and responsive controls (also referred to as defensive or corrective controls) to present a layered approach to minimizing the likelihood of an actual loss event (successful exploit) without incurring excessive cost or complexity. In-app protection is no exception to this “golden rule.”

Prevention

The injection script must be run on a rooted mobile device (or an emulator).

One way to prevent the injection of instrumentation is to prevent your application from running on a rooted device or inside an emulator, but developers often need to run their apps in an emulator (or on a rooted device) during development and testing.

The requirement is that the app should not be run on an unauthorized rooted device or an emulator after deployment.

PreEmptive Protection DashO for Android & Java Root Check and Response & Emulator Check and Response

PreEmptive Protection products combine obfuscation transformations with “Checks.” A Check is a code injected into application methods post-code before signing and publication. At runtime, it ” checks” whether a particular condition is true and, if so, triggers various responses.

Unlike the dynamic form of code injection employed by Frida, this injection is entirely controlled by the original development organization and fully integrated into its build chain. The injected code consists of code included as part of PreEmptive Protection (the “check” component and the default “response” code) and, optionally, customized response code written by the development organization.

Each product component of the PreEmptive Protection suite includes a collection of relevant checks. PreEmptive Protection™ DashO™ for Android & Java (DashO) options include:

Configuring DashO to inject these two controls dramatically reduces the exposure stemming from Frida and similar dynamic instrumentation and hooking frameworks. However, no preventative control is perfect. New rooting and hooking kits are constantly being developed, and some will inevitably find a way to avoid detection. Because of this reality, the layered approach of prevention, detection, and response is essential.

Detection

Continuing with the Frida Android tutorial, the Frida server is moved to the device (or emulator), the script is run, and your application is now “hooked.” The SSL Pinning control you had painstakingly included in your app has been defeated.

Fortunately, PreEmptive Protection—DashO also includes a Hooking Check. The Hooking Check runs through a number of heuristics and attempts to determine if your app is somehow being run after being hooked (note: For a complete list of the Checks currently, See Runtime Checks inside PreEmptive Protection for Android).

Response

What is the appropriate response when your app detects it is being run on a rooted device or inside an emulator? Certainly, there are numerous scenarios other than a threat actor beginning the process of hooking your app with Frida. What if your app is a consumer banking app or an app helping to monitor a patient’s insulin level? It is reasonable to expect different responses to be required in these two scenarios. Neither is likely a default behavior conceived and implemented by a third-party software vendor. This is why the ability to include custom responses can be so valuable (having said that, default responses are ideal for simple responses, minimizing custom development effort).

Any Check can provide its custom response, so an application can defend itself based on many conditions and at many different stages in its lifecycle.

Final thoughts

The problem of preventing unauthorized use of development tools in the wild is complex and constantly evolving. While development teams are sometimes tempted to develop their runtime defenses, this is almost certainly a losing battle in the long run. Effective detection of debuggers, tampering, rooted devices, etc., requires constant evolution with the changing toolkits and frameworks. We can say this with some measure of confidence because this is our full-time job, and it is a full-time job. Learn more about mobile in-app protection.

In This Article:

Try a Free Trial of PreEmptive Today!