Google 2FA vulnerable code

Nowadays many applications support two factor authentication with SMS messages to increase the level of security of your account.
You login with a username/password and a secret code is sent to your phone to double check it’s really you.

It is hilarious how sometimes software vulnerabilities are introduced while trying to increase the level of the security…

At this address you can find the suggested way to handle a code received in a text message on Android. It is the official Android documentation from Google, available in many Stackoverflow answers too and currently implemented in many mobile applications.

Malware could abuse such badly written code provided by Google and crash your Android apps or execute malicious payloads within a vulnerable app sandbox!

Let’s have a look at the code from Google:

As you can see the first step is about receiving an intent in a broadcast receiver informing the app that a SMS has been retrieved (step 1); after that a nested intent is extracted (step 2) and finally that nested intent is passed to startActivityForResult() (step 3). The idea is that the nested intent will show the user a consent dialog to allow the app to read the SMS message.

Do you see the problem?

In this code the received nested intent is never validated. The application expects an ACTION_USER_CONSENT intent in order to work properly to show the consent dialog. The code blindly trusts the input and executes a startActivityForResult() on it. Now the problem is clear, right? :)
As an attacker all you have to do is to send to the victim application a SMS_RETRIEVED intent with a malicious nested intent (the payload) that will be executed blindly by the victim app.

The are hundreds of applications using this code in order to read the 2FA code from an SMS message. A malicious app can abuse it by just sending continuously a properly forged intent to the victim app. As soon as the user requests and waits for his 2FA code, the victim application will execute the vulnerable code and the malicious intent.

You can try it from adb with something like: adb shell am broadcast -a com.google.android.gms.auth.api.phone.SMS_RETRIEVED — es com.google.android.gms.auth.api.phone.EXTRA_CONSENT_INTENT — es com.companyname.vulnerableappname “payload” -es com.google.android.gms.auth.api.phone.EXTRA_STATUS “Status{statusCode=SUCCESS, resolution=null}”

If the malicious intent is sent by some malware while the app is waiting for anSMS message, and the application crashes…you found a vulnerable app :)
Now it is just a matter of deciding which private, unexposed activity or service you want to execute, and the payload to use. An attacker may launch an available WebViewActivity and pass as parameter the url of a malicious .so file and use it to overwrite a local one taking control of the victim application..it all depends on the target app and what is possible with it :)

Developers will keep using the same vulnerable code available in the Android documentation and everywhere on StackOverflow for a while. In the meanwhile many applications are vulnerable (just scan for apps containing the string EXTRA_CONSENT_INTENT and check with adb if they crash).

Never trust your input, always validate the data you get from untrusted sources and remember that even senior developers in big trustworthy companies sometimes make mistakes in their code :)

Software developer, passionate about reverse engineering, mobile development, 3d realtime rendering and game development