Openness of Android makes it very delicious target for the exploiters, reverse engineers. Android offers a very nice advantages for malicious actors which are not available in compare to its rival iOS. It is possible to peek into the source code when it comes to Android (Yes, I am talking about AOSP) and modify the OS and all the things come along according to your taste. Even in retail devices, It is possible to tamper with the system without much hassle and headache.

Overview

This article will address some of these most known and useful techniques against android apps.

All these techniques have different forms and execution style, but all of it boils down to some basics. If you have done red-teaming before, you can easily guess these steps. To dissect an android app, you need to have a target to attack. With that in mind, There are several generic ways to exploit; tampering with features, overriding protocols, de-compilation and probing to the byte code, inserting a payload, recompilation and repackage. A very popular tool to do all these with ease is apktool.

But hey, Why do you want to do all these just to hack a poorly coded game or a software? Just use a pirate software.

Poor man’s attack

This is the most common form of security risk: Automated tampering/patching. It can be used without a human intervention. It generally boils down to Automated string-matching and find-replace patch.

There are various pirate apps that allow one to target an app with this technique. Most notorious app is Lucky Patcher. Most of related apps like lucky patcher allows one to remove advertising from the app, modifying signature verification, toggle some intents/features, interfere with common security mechanisms or temper the in-app purchase protections. It is done by pattern matching and then replacing the byte code strings. Often times an app is rebuilt once the dirty work is done. If your app is unprepared to detect such attacks, you might lose some revenue with ads gone, and in-app purchase bypassed or even worse, It will be distributed on internet with all the premium features available without subscription fees.

An abstract way to prevent these attacks is performing checks over the package metadata and verification of signature. It is not always accurate, but it will give you hints of some parasitic code or modifications which would then be chained with other methods like safety-net checks or installer verification.

A glance of the source code

Not a very common type of attack, But if someone is determined enough; They will decompile the byte code of an app and figure out the ways to exploit it. There is a beautiful and nifty way to exploit web views, Take a look at how it is done. An attacker looks at the byte code to probe and find possible code that might look exploitable. Once probing is complete, payload can be added to exploit the functionality or bypass certain barriers. There can also, be modifications to logics of the app to make it misbehave in a way which favors the attacker.

Usually, This type of attacks boils down to one thing, Manual search and picking up hints. It requires a human brain to look at the decompiled code and figure out a way to exploit or modify the code in a way to achieve the end goal. That is why it is not widely used across the hacking community because it is too much work.

One thing to consider here is byte code is intermediate and raw language which JVM understands and executes. But with android, it is not JVM, it is ART (Android Runtime). However, It is all the same in a nutshell. And there are utilities to convert that byte-code to grab original source code. This is what an attacker might want to do instead of peaking around at raw byte code.

This type of attacks can be prevented by obfuscation. Computer does not give a damn about your code is obfuscated or not. It will work as is. You should always shrink and obfuscate your codebase used in production to make it difficult for such reverse engineering techniques. It will give a hard time for someone looking at obfuscated source code. But it is not impossible for someone determined enough to break it and exploit it.

The Mjollnir: Root access

Once the root access is available, it’s a different story. Root access unleashes too many scenarios and factors when it comes to hardening defenses. The operating system itself is now compromised with root access and user can escalate commands as system. There is not much to discuss in this area because one can hide root itself with various bypass techniques. Furthermore, Developers cannot do much about this case as well.

When you detect a presence of SU binary or a rooted system, all you can do is either kill the app with a notice or disable certain features. But if a root hide is active in the system, It is again a cat and mouse game. There is no easy solution to this since user now has full access to the system and that is bad for detection mechanisms to determine whether system is rooted or not.

There is a very straightforward way to crack an app which is not well protected, by just editing shared-preferences, SQLite database or just editing XML where data is being stored. There are so many poorly coded apps which store boolean in shared-preferences, which would allow some restricted/premium features to work by just modifying a few bytes of code. And attacker now has complete feature access even without a subscription. This can be prevented by SQLite cipher and using encrypted shared-preferences, And it is easy too. Please do not be lazy and use encryption.

Root access is the reason many financial apps, banking tools or games won’t work if they detect root access. Because a targeted attack can modify behavior application without needing to recompile the app. Lucky Patcher can do such exploits with root access. It can also hot-wire some exploits at runtime, which is dangerous on sophisticated and fabricated attacks.

The sophisticated attack vector

To be very honest, This is the worst type of attack vector. If someone knows what they are doing, They will try to break every bit of security protocols that you may have added in the first place. At this sophistication, It is very likely that they will implement payloads, modify the existing logical functionality and much worse.

But, The obfuscation helps in a way to slow these attacks, But there are tools available to convert the byte-code into readable java code. So, there is always a possibility that the attackers will find a way to achieve what they want. It is sad you can do absolutely nothing about it because once you ship the app, It’s very little you can do to prevent attacks. There is always a key for a lock. Often times, A good useful application will be custom patched to unlock premium features, and it is very unfortunate that perfect security solution does not exist.

The reason you can do nothing about these type of attack vectors is you lose control over the device once you ship your app. Bytes are transferred to a remote device and ends up being binary data which are open for modifications and hacks like these. Only a better solution to these attacks is having server-side access, data validations or integrity verification schemes deployed to the app. These techniques will put somewhat control back in your hand and prevent certain type of attacks.

My two cents

You can do very little about your app being modified. Root attacks or recompilation makes it very difficult to determine what has been done with the application. Because you can never know what exactly was done until it’s too late.

Writing your software with consistent conditional checks with all available detection methods and tamper protections applied can tip you off early in the process to determine whether software itself is modified or not. Because even a single bit of change in the codebase will change the hashes and when you recompile an app and sign it, Attackers can never have the original key (unless you have been breached, and they have the signing certs along with credentials to use it). Meanwhile, all these checks can be stripped away or even disabled by someone determined enough. This makes it very hard to detect tamper or intrusion to original code. Yes, All this is an overkill for apps, But these concepts and methods can be applied to at-least have an extra layer of protection and minimize the damage.

That’s it for this one, I will be writing more about security in android in upcoming posts. Until then, Bye.