Zimperium discovered and reported a fake version of the popular Snapchat app in the official Google Play Store; At the time of our discovery, it was the second result when searching for “Snapchat”. The fake version of Snapchat app is using “Snap Inc .” as Company Name, with a ” .” appended to original name.
Fake Snapchat Metadata
Application Name: Ѕnарϲhаt
Company Name: Snap Inc .
Package Name: com.snacha.android
Play Store Link: https://play.google.com/store/apps/details?id=com.snacha.android
- Initial detection and analysis: August 5th, 2017
- Reported to Google – Aug 5th, 2017 at 11:34 PM
- Google removed the app from the playstore – Aug 7th, 2017 at 6:39 PM
As the Google Play Store page has now been removed, all the information can been seen at the following Archive links.
In the above archive history we can see that on August 6th 2017 the fake Snapchat on Google Play Store got 2,127 ratings with 1,000 – 5,000 installations, on August 7th 2017 we can see 4,244 ratings with 5,000 – 10,000 installations. The number of ratings and installation doubled in 24 hours. The campaign in fact was stopped very early, following exponential downloads growth and our report to Google.
After starting the application the user will be greeted by an Ad, after closing it and clicking on the “Next” button shown on the screen additional Ads will be loaded. Between an Ad and the other the application also shows to the user different messages like: “Attention App Requires Internet Connection Before Proceed Make Sure You are Connected.” or “Connection Error”. It’s clear that the attacker needs to make sure that the user is connected to be able to fetch and display the Ads. The user will enable connectivity, if not already available, and will continue through messages and Ads. As last step the application asks to be rated on the Google Play Store, after doing that nothing happens and the “Connection Error” message will be shown coupled with a “Try again” button; after clicking it the Ads cycle will start once again.
During execution the application establishes connections to different IPs, all owned by Google Ads (184.108.40.206, 220.127.116.11, 18.104.22.168, 22.214.171.124, 126.96.36.199, 188.8.131.52, 184.108.40.206, 220.127.116.11).
The following is a video showing the behavior of the application:
The samples were compared both structurally and according to its behaviour with the original Snapchat APK coming from the official Play Store.
The fake Snapchat application is completely different from the original one:
- different certificate: the fake version is using a certificate mimicking the Google one;
- different class: not a single class was borrowed from the original application, so we can’t even say the developer patched the classes to inject Ads, they simply wrote a different one;
- different activities: com.snacha.android.PTPlayer is used to initialise the BuildBox environment, register a connection with Google IAB and loading the native library libplayer.so; com.google.android.gms.ads.AdActivity is the Google Ads activity used to display the Ads.
- different services: the fake version doesn’t start any service;
- different receivers: the fake version doesn’t setup any receiver.
The behaviour of the fake application doesn’t match at all the one of the original Snapchat, confirming that the control flow is different.
The main idea behind the application seems to be Ad / traffic Monetization , or by visualisation or by actually clicking on them. The requested permissions confirm that the application is indeed fetching data from the network and trying to gather information about the connection.
The two main packages in the APK are com.snacha.android and com.secrethq. The former is initialising the Java counterpart of the game engine (based on Cocos2dx), connecting to Google IAB and loading libplayer.so. During initialisation an interface for various Ads subscriptions (e.g. AdMob, AppLovin, Chartboost, Facebook, Heyzap, Leadbolt, RevMob) is setup and the second package takes care of handling JNI communication with the native library. Of the listed Ads only AdMob is implemented.
The native library libplayer.so is loaded when the PTPlayer.java class in first instantiated, the JNI_OnLoad is saving a reference to the JavaVM pointer that will be later used for the JNI bridge.
The native code is loading the /assets/data/*.xml configuration files during initialisation; in particular the PTModelGeneralSettings.0.attributes.xml file contains all the configurations for AdMob banners and the link used to rate the application on the Play Store.
<key>Google Play Store</key>
All the AdMob related methods in the com.secrethq.ads.PTAdMobBridge class are called using JNI from the libplayer.so library (e.g. _ZN9PTAdAdMob10showBannerEv, _ZN9PTAdAdMob16showInterstitialEv, PTAdAdMobJni_hideBannerJNI, PTAdAdMobJni_initBannerJNI).
The “Rate Now” button is triggering a call to PTServices::openReviewUrl, which is reading the URL from the XML configurations and using JNI to connect to the URL.
- PTPScreenUi::init will initialise the buttons in the UI and in particular will register a listener to the “Rate Now” button calling PTPScreen::assignActionToButtons (the associated listener is PTPScreenUi::reviewButtonAction).
- When the button is clicked the function PTPScreenUi::reviewButtonAction is called and the control is passed to the PTServices::openReviewUrl function.
- The PTServices::openReviewUrl function is extracting the value associated to the key “reviewLink” from the PTModelGeneralSettings.0.attributes.xml configuration file.
- The PTServices::openUrl function is called and execution is passed to PTServicesJni_openUrlJNI.
- The PTServicesJni_openUrlJNI function calls the openUrl(String url) method of the com/secrethq/utils/PTServicesBridge.java class.
The “Next” button is loading the cropped image to be shown full screen and each time is triggering the PTPScreen::showAds function which loads and shows the AdMob Ad fullscreen or interstitial.
The images and fonts used to display the different application screens come from the following files: assets/data/atlases/atlas_ID2057.png and assets/data/fonts/PTModelFont_ID2.png. The assets/data/atlases/atlas_ID2057.plist configuration files contains coordinates and size specifiers to crop the sprites and extract the images/fonts that are then displayed using the Cocos2dx engine.
The usage of a full game engine to implement such application may seems overcomplicated, but an attacker may actually employ this as a technique to harden and slow the analysis because the actions are actually handled internally to the engine and may result difficult to find; as an example the message “Please Rate This App To get Snapchat” and the button “Rate Now” are not coming from a png image or a string but are assembled using the font sprite and a plist configuration file.
What worried us at first was the complex structure of the application; in fact that simple control flow is built using a game engine named BuildBox. The game engine also includes a built-in support for Ads and monetisation based on Google IAB.
Considering how the different buttons/Ads are displayed on the screen our first hypothesis was that the code tried to mimic an attack like Cloak&Dagger, displaying different layers of overlaying applications and tricking the user into triggering purchases or unwanted actions.
We’re still investigating the causes and circumstances associated with the application to trigger the behaviour and additional conditions that may be branched .
During our initial investigation we collected some examples of the usage of the BuildBox game engine:
- APK Gamer Side Shooter: it’s providing the same setup code present in the sample; the PTPlayer.java class and the com.secrethq package are indeed present, confirming those are part of the game engine.
- BuildBox Game Development: it’s proving different examples of the game engine usage for different platforms; in particular we can see the game engine native code initialisation.
Special thanks goes to @christypriory for the catch, @fvrmatteo, @shokoluv, @ihackbanme , @ryanza for the analysis and validation and the entire zLabs Group for the assistance and the writeup of this story.