Information Security Stack Exchange is a question and answer site for information security professionals. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have android applications (Mobile banking) that connect to my server and do online transactions (via Internet/USSD/SMS), I want to make sure those clients are not tampered with and are the original ones distributed by me.

Keep in mind that not all of my customers download the application via google play, some of them use 3rd party markets or download the apk from elsewhere.

Is there a way I can validate the integrity of the application (using a checksum or a signature) on the server side to make sure its not tampered with. (e.g a trojan is not implanted in the application and then redistributed)

For suggested solutions:

  • Can they be implemented over all 3 communication channels (SMS/USSD/Internet) or are the solutions proprietary to one/some channels?

(I'm looking exactly for the technique that's been referred to in this page: https://samsclass.info/android/chase.htm) :

Chase's servers don't check the integrity of their Android app when it connects to their servers. It is therefore easy to modify the app, adding trojan code that does malicious things. An attacker who can trick people into using the trojaned app can exploit them.

This vulnerability does not affect people who are using the genuine app from the Google Play Store. It would only harm people who are tricked into installing a modified app from a Web site, email, etc.

share|improve this question
3  
Not readily, as your proof of integrity can itself be spoofed. For example, you could try some sort of challenge-and-response protocol, one where the response is not possible to generate without having access to the unmodified app. One approach would be to send a salt from the server to the app, which then has to generate a cryptographically-secure hash of the APK using that salt and send it back. However, this can be broken by having the hacked app pass the salt to its own server, which generates the hash on an unmodified APK, sends it to the app, which returns it to the server. – CommonsWare Jan 31 at 18:10
1  
It's called remote attestation and only works if the device contains treacherous hardware. There have been multiple attempts to introduce such features (TCPA, TPM, Intel SGX,...) but I don't know if typical android devices contain such a feature. – CodesInChaos Jan 31 at 21:30
    
@CodesInChaos "Treacherous hardware" is loaded language. If I were you I'd try to avoid using that in objective discussions. – immibis Jan 31 at 21:41
    
@CommonsWare Or just let the hacked app include a copy of the original app, and use that to calculate the checksum. – immibis Jan 31 at 21:42
1  
@immibis I consider acting in the interests of its owner the most important duty of a computer. Thus I consider it justified to call a piece of hardware that's willing to testify against its owner treacherous. But I'm open to other descriptions, if you have any good ideas. – CodesInChaos Jan 31 at 21:46

This is impossible. Anyone who has the integer APK file can decompile it and make a malicious clone that behaves in exactly the same way towards the server.

share|improve this answer
    
The thing is, under the link I mentioned above, it said that chase fixed this vulnerability somehow. So I assume there has to be a way. – Silverfox Jan 31 at 18:31
18  
No @Silverfox. They just say that they fixed it. It's hogwash. They can't even tell if they're talking to their app or some hand-written client running on a botnet or something. There's no security without physical security. – Neil Smithline Jan 31 at 19:58
    
If you read the entire thing, they fixed the apk no longer decodes using apktool, so they only obfuscated the code. Nothing about verifying the app server-side – AmazingDreams Feb 1 at 13:30

Use Android SafetyNet. This is how Android Pay validates itself.

The basic flow is:

  • Your server generates a nonce that it sends to the client app.
  • The app sends a verification request with the nonce via Google Play Services.
  • SafetyNet verifies that the local device is unmodified and passed the CTS.
  • A Google-signed response ("attestation") is returned to your app with a pass/fail result and information about your app's APK (hash and sigining certificate).
  • Your app sends the attestation to your server.
  • Your server validates the nonce and APK signature, and then submits the attestation to a Google server for verification. Google checks the attestation signature and tells you if it is genuine.

If this passes, you can be fairly confident that the user is running a genuine version of your app on an unmodified system. The app should get an attestation when it starts up and send it along to your sever with every transaction request.

Note, however, this means:

  • Users who have rooted their phone will not pass these checks
  • Users who have installed custom or third-party ROM/firmware/OS (eg Cyanogen) will not pass these checks
  • Users who do not have access to Google Play Services (eg Amazon devices, people in China) will not pass these checks

...and therefore will be unable to use your app. Your company needs to make a business decision as to whether or not these restrictions (and the accompanying upset users) are acceptable.

Finally, realize that this is not an entirely airtight solution. With root access and perhaps Xposed, it is possible to modify the SafetyNet library to lie to Google's servers, telling them the "right" answers to get a verification pass result that Google signs. In reality, SafetyNet just moves the goalposts and makes it harder for malicious actors. Since these checks ultimately have to run on a device out of your control, it is indeed impossible to design an entirely secure system.

Read an excellent analysis of how the internals of SafetyNet work here.

share|improve this answer
3  
+1 for "In reality, SafetyNet just moves the goalposts and makes it harder for malicious actors." – Bergi Feb 1 at 9:17

This problem is something that mobile games have to deal with for income reasons, and from what I can tell, they deal with this by constantly updating the app, requiring the user to download and install a fresh patch every time before they start the game. usually this is a small amount. These patches also add new content to the game. The patches also handle the updating themselves, so if an app is modified, the patch fails.

So in theory (not sure how accurate this is), you basically write an app within an app. The internal app is the app that does the heavy lifting. The external app, every time it's started, downloads a patch/integrity validator, which then first verifies that the apps haven't been tampered with (usually through a checksum), then patches the internal app if necessary. It's similar to a bootstrap.

As mentioned by marstato, this still isn't perfect. For example, an attacker can redirect the requests to their own server and install customized patches that way. A possible way around that is to do this integrity validation before each transaction, but that would be rather slow.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.