McAfee’s Mobile Research team has found a new Android malware in 144 “Trojanized” applications on Google Play. We named this threat Grabos because we found this string in several elements of the code, including variable and method names. Grabos was initially found in the Android application “Aristotle Music audio player 2017,” which claimed to be a free audio player on Google Play:
Figure 1. Trojanized music app in Google Play.
At the time Aristotle Music was discovered, the application had a very good rating. According to Google Play, the application was installed between one and five million times and had a recent comment from a user saying that the application was detected as malware:
Figure 2. User reporting the application Aristotle Music being detected as malware.
Grabos on Google Play
McAfee Mobile Research notified Google about Grabos in September and confirmed that Google promptly removed the reported application. After further research, we found another 143 applications (see complete list at the end of this post); all have been removed from Google Play. Six were removed after we reported the first to Google:
Figure 3. Additional Grabos Trojanized apps formerly on Google Play.
At the time of writing this post, 34 applications still had their webpages available in cache, so we were able to obtain additional information such as the approximate number of installs, last updated date, and rating. Most of these apps were last updated in August and October. They had an average rating of 4.4, and between 4.2 million and 17.4 million users downloaded these apps from Google Play:
Figure 4. Malicious apps details from Google Play.
Grabos likely evaded Google Play security measures because the injected code is protected with a commercial obfuscator, making it very difficult to statically analyze without executing the application. Even dynamic analysis to stop its execution is difficult without knowing what the app is checking. However, once we unpacked the code, we proceeded with our analysis.
“Fake” vs. “real” apps
We found Grabos injected in file explorer and music player applications, some of them open source. Every time that the app is opened, it checks if any of the following settings is not true to decide whether to launch the “fake” (legitimate functionality) or “real” (injected packed code) app:
- isOnline: Checks if the device has Internet connectivity
- getIsBlacklisted: Checks if the Android debug bridge (adb) and development settings are enabled or if the device is in an emulator. If the latter is the case, the device is blacklisted and the “fake” app is launched.
- getIsForcedBlacklisted: Flag set by the control server.
The code also has a test mode that allows the execution of the “real” app in case it is running in an emulator or has adb and development settings enabled. These checks detect if the app is currently being dynamically analyzed and prevent the execution of the hidden code if necessary.
In case the app is not being analyzed or is in test mode, the “real” app launches. This hidden music downloader searches for a specific song on YouTube. Once the song is selected, it can be downloaded in MP3 or MP4 format to be played offline.
Figure 5. “Fake” vs “real” app flow. “BL” stands for “blacklisted.”
At this point, the application seems to be just a music downloader hidden in a Trojanized app that checks for dynamic analysis to avoid being removed from Google Play due to its downloading of copyrighted music. In the background, however, more is happening.
Communicating with the Control Server
In addition to the “fake” and “real” app functionality, Grabos is also present in the AndroidManifest as a receiver that executes every time there is a connectivity change or when the app is installed:
Figure 6. Grabos receiver in the AndroidManifest.
If the receiver is executed due to a connectivity change, the execution ends if the device is offline or if fewer than five seconds have passed since the last connection. If more than five seconds have already passed, the method “updateRemoteSettingsSynchronousTask” executes. This method collects and encrypts (Base64 plus Advanced Encryption Standard) the following data from the infected device:
- Device information:
- android_version
- build_model
- install_referrer
- network_country
- sim_country
- carrier_name
- language_code
- country_code
- time_timezone
- Device location: Grabos uses free IP geolocation API services to obtain IP address information such as city, country code, ISP, organization, region, and ZIP code.
- Device configuration:
- is_emulator
- is_rooted
- is_adb_enabled
- is_dev_settings_enabled
- allow_mock_location
- allow_non_market (unknown sources enabled/disabled)
- is_vpn_connected
- dp checks (additional root, debug, and emulator checks provided by the commercial obfuscator)
- Installed Grabos app information: version_code, package_name, and install_time
- Specific apps installed: Grabos reports if any app in a predefined list is currently installed on the infected device (more on this later).
All the information is encrypted and submitted to a control server. The remote server responds with encrypted data that contains parameters required to download music (URLs, API keys, user agents, client_id, etc.) to show advertainments (nativead_id, interstitial_id, banner_id, etc.) and display customized notifications such as asking the user to rate the app in Google Play:
Figure 7. “Rate this app” parameters provided by the control server.
The rating pop-up appears the first time the app is opened. If the button “Rate 5 Stars” is clicked, the app opens in Google Play so the user can rate the app there.
Figure 8. Rating pop-up.
In a similar way, the remote server also provides parameters to ask the user to share the app with friends and promising faster download speeds:
Figure 9. “Share the app” parameters provided by the control server.
The control server also sends the parameter “is_forced_blacklisted,” which manually blacklists the device if the value is “true”—to prevent the execution of the hidden app.
Mysterious functionality
In addition to reporting an infected device’s location and configuration, Grabos checks if specific social and Google apps are installed using the method isPackageInstalled and the app package name. Depending whether an app is currently installed, the corresponding value is set to true or false and that information is encrypted and reported to the control server:
Figure 10. Social and Google apps reported to the control server.
We reported this finding to Google, who are investigating. At this point we do not know the purpose of this app reporting. However, we believe this information could be very useful to malware authors because Grabos has implemented several mechanisms to trick users into installing applications provided by the remote server. Let’s look into those functions.
Custom Push Notifications and Additional Apps
After the initial settings are obtained from the remote server, the AsyncTask ShowNotificationIfNeeded is executed to check if the parameters n_title, n_description, and n_package were provided by the control server. If that is the case, Grabos checks if the app is available on Google Play (if “pack” is a name and not a URL) or on a remote server (if “pack” starts with HTTP).
If the application is not installed and is available, Grabos gathers additional parameters (for example, icon and bigicon) from the remote server response to create a custom notification and trick the user into installing the app:
Figure 11. Parameters provided by the control server to create a custom notification.
Grabos also checks if the remote server provided the following parameters:
- interstitial_letang_options: provides values to delay and repeat the display of an activity (initial_delay and min_interval)
- interstitial_letang: includes the following remote commands:
- admob: executes method “showAdmobInterstitial”
- nothing
- grabos_direct
If the command is grabos_direct, Grabos gets the title, package, and max_times_shown values in the parameter grabos_direct_interstitial to open the app in Google Play or trigger a download:
Figure 12. Downloading an APK from a URL or open app on Google Play.
Both the notification and the interstitial_letang methods, to trick the user into downloading or installing apps, are executed in the background every time there is a connectivity change. However, Grabos also implements another app delivery method when the music downloader executes. This method, ShowGrabosIfNeeded, is very similar to interstitial_letang in that it checks if the required parameters are present and the app is available as well as checking if the app should be opened without the user’s consent:
Figure 13. Grabos checking whether the installed app should be opened.
As soon as Grabos confirms that the device is online, the app is available either on Google Play or a remote server, and the package is not installed, the malware gets the following parameters from the remote server response to create an AlertDialog and trick the user into downloading another app:
Figure 14. Grabos parameters to create an AlertDialog.
Flying Under the Radar: Evading Analysis
In addition to the multiple efforts to detect if the app is being dynamically analyzed (emulator, adb, development settings) and the encryption of the injected code, Grabos updates its remote settings every 24 hours (unless it is in test mode). This restriction can be easily bypassed by changing the date and time of the device used to analyze the app. However, recent versions of Grabos include checks to detect if the automatic date and time and time zone are enabled:
Figure 15. Grabos checks if automatic date and time and time zone are enabled.
The status of this setting is reported to the control server in the fields time_is_auto and time_timezone_is_auto. Although this check is not used in the Grabos code, the information could be used to determine if the app is being dynamically analyzed and decide if an additional payload should be delivered.
The URLs used as control servers indicate that Grabos tries to masquerade its network traffic as legitimate. At first sight the URLs appear to belong to familiar adware companies; the names are identical. However, instead of finishing with .com, Grabos uses domains such as .link and .click, which are not registered by the company.
Finally, Grabos defines an additional mechanism, currently not implemented, to blacklist or whitelist a specific device. For example, the device could be blacklisted or whitelisted in a future version depending on the country code or configured language of the infected device:
Figure 16. Blacklist and whitelist functions based on language and country code.
Grabos also defines (but does not implement) methods to blacklist a device based on IP address:
Figure 17. Blacklist functions based on IP address information.
Conclusion
During our analysis of this threat, the control servers always provided empty parameters for the custom notifications to trick users into installing applications. Taking into account the functionality to display ads and the high number of downloads, we believe the main purpose of Grabos is to make money by promoting the installation of apps.
Grabos gained popularity on Google Play because it allowed users to download music for free while constantly asking them to rate the app. However, users were not aware of the hidden functionality that comes with those apps, exposing them to custom notifications to download and install additional apps and open them without their consent.
Considering that Grabos also reports the presence of specific social and Google apps on infected devices, cybercriminals could use that information to deliver additional apps by tricking users into installing them using any of the notification methods implemented in the code. Although during our analysis the remote servers did not deliver the required parameters to trigger custom notifications, the devices remain exposed to the download of additional Android apps.
McAfee Mobile Security detects this threat as Android/Grabos. To protect yourselves from threats like this on Google Play, employ security software on your mobile devices, check user reviews, and avoid installing suspicious apps with screenshots or functionality that do not correspond to the name of the app.
We would like to thank Sebastian Porst and Jason Woloz from Google’s Android Security for their helpful contributions on this research.
List of Grabos Package Names
- com.picklieapps.player
- com.musicaplayer.stonetemples
- com.mp3musicplayer.playmusicmp3
- com.densebutter.musicplayer
- com.airplaneapps.soundmeter
- com.dinosaursr.musicplayer
- com.tenuousllc.humneate
- com.astropie.musicplayer
- info.chargeshoes.videoplayer
- com.callsaver.doubtful
- com.unfestenedsail.freeapp
- com.extendmilk.freeplayer
- com.excellentlossapps.playermusic
- com.AliciaTech.free
- com.mp3player.musicplayer.freelocalmusicplayer
- com.freemusicplayer.freemusicplayer.free
- com.afromusicplayer.fremediaplayer
- com.info_astro.glider_player
- com.illfatednotice.humdrum
- com.headybowl.musicplayer
- com.musicgratisplayerfree.free
- com.naturityllc.mp3player
- info.anothertube.music.player
- com.startdancingapps.callrecorder
- com.social.video.saver.pro
- es.gratis.video.downloader.hd
- com.sportingapps.copyleft_music.player
- com.auto_call_recorder.freeapp
- com.freenewsreader.rssfeed
- ar.music.video.player
- com.curatorinc.ringtone.search
- com.mp3musicplayer.local_files_player
- com.copyleft.stream.musica.player
- info_de.mp3.music.player
- com.nobodybeats.musicplayer
- com.file.manager.pronessbest
- info.ark.music.mp3.player
- com.air.browser.free
- com.aneeoboapps.playlistmanager
- com.local_music_player.free_mp3_player
- com.greenlinellc.voicechanger
- com.free.playlist.creator.tube
- com.toporganizer.fileorganizer
- com.thumb.webbrowse
- com.aspirator.ringtones.player
- com.freevideoplayer.musicplayer
- com.vimfast.videodl
- com.whimsical.piano.free
- com.truckneat.freeapp
- com.crowdedarmy.volume.controller
- com.arnold_legal.mp3.musica
- com.descent.shutterfly
- com.thankyou.arrowplayer
- com.pocahantasapps.musicplayer
- com.astroplayer.freee
- com.couchpotato.musica.play_stream
- com.abstractly.musica.player
- com.matsumoto.mp3player
- com.musicequalizer.freeequalizer
- com.lifesbad.fileexplorer
- com.videolunch.free
- legal.copyleft.cc.mp3.music
- com.ark.music.mp3.player
- info.musik.mp3.music
- com.streamerplayer.stream_videos
- info.voicerecorder.recordvoice
- com.snip.browser
- com.checkrein.musicapp
- com.mp3musicplayer.freemusicplayer.playmusic
- com.jadedprogram.mp3player
- com.preoral.freeborn
- com.voice.changer.freeappsapp
- es.streamplay.stream.player
- com.localmp3music.freeplayer
- com.drummachine.machinedrums
- com.coloringbook.freetrynow
- com.videodownloader.social_video_download
- com.ElephantApps.FileManager
- com.scaricare.app.musica
- com.quicksearch.tube.player
- com.rooseveltisland.mp3player
- com.mindprogram.musicf
- com.freeborn.sdkintegration
- com.koseapps.tubemusica
- fr.baixar.videos.gratis
- info.adeptly.forgoneapp
- us.musicas.gratis.player
- com.miniaturef.swanky
- com.insta.mp3.music.streamer
- com.anchor.musicplayer
- com.repeate.mp3musicplayer
- com.FeisalLLC.MusicPlayer
- com.shelfshare.freeapp
- info.simple.streamer.player
- com.streamplayer.freearnold
- com.freeturkish.video.downloader
- com.cowherd.freeapp
- com.localmp3musicplayer.local_player
- com.scaricare.apps.musica
- com.silymove.freeapp
- com.pinkphone.funfreetube
- info.tissuepaper.freemusic
- com.chopsuey.musicplayer
- com.branchnotice.musicplayer
- com.fradcip.MasterApp
- sv.music.player.mp3.ares
- com.social.video.downloader.for_fb
- com.frobenius.time.tube
- com.spelldoom.comeup
- com.bailymusic.player
- com.sportifco.musicplayer
- com.topsaver.video.downloader
- com.coupleweeks.modcium
- com.unbecomingllc.videodownloader
- com.video.for_fb.downloader.saver
- com.macdrop.apptool
- com.callsaver.recorderfreeapp
- com.arnie_legal.mp3.musica
- com.kikiapps.freeplayer
- com.pintaapps.expensetracker
- com.marble.musicequalizer
- com.artproject.searcher
- com.UnitTest.FreeApp
- com.exudedplayer.freemusicplayer
- com.blackballed.player
- com.mp3player.decisiveapps
- com.rusticd.musicplayer
- com.byunhyeong.jungfree
- com.voicelessapps.mp3musicplayer
- com.localmp3player.freeplayer
- com.kinokunya.free
- com.socialvideo.downloader_vim
- com.viastore.video.saver_for_fb
- com.disarmbit.reache
- com.crackerbalancellc.mp3converter
- info.vaskollc.jpfree
- com.freemusicplayer.musicplayfreetoolpalyer
- com.combustionapps.musique
- com.arnold.mp3.musica
- com.purpleheadphones.audioplayer
- com.unscalableapps.free
- com.freefile.organizerfree
- com.free.mp3.stream_cc_music
- com.mp3uncle.musiccamera