This post provides an in-depth analysis of the inner workings of Gooligan, the infamous Android OAuth stealing botnet.
This is the second post of a series dedicated to the hunt and takedown of Gooligan that we did at Google, in collaboration with Check Point, in November 2016. The first post recounts Gooligan’s origin story and provides an overview of how it works. The final post discusses Gooligan’s various monetization schemas and its take down. As this post builds on the previous one, I encourage you to read it, if you haven’t done so already.
This series of posts is modeled after the talk I gave at Botconf in December 2017. Here is a re-recording of the talk:
You can also get the slides here but they are pretty bare.
Infection
Initially, users are tricked into installing Gooligan’s staging app on their device under one false pretense or another. Once this app is executed, it will fully compromise the device by performing the five steps outlined in the diagram below:
As emphasized in the chart above, the first four stages are mostly borrowed from Ghost Push. Gooligan authors main addition is the code needed to instrument the Play Store app using a complex injection process. This heavy code reuse initially made it difficult for us to separate Ghost Push samples from Gooligan ones. However, as soon as we had the full kill chain analyzed, we were able to write accurate detection signatures.
Payload decoding
Most Gooligan samples hide their malicious payload in a fake image located in assets/close.png. This file is encrypted with a hardcoded XOR encryption] function. This encryption is used to escape the signatures that detect the code that Gooligan borrows from previous malware. Encrypting malicious payload is a very old malware trick that has been used by [Android malware since at least 2011.
Besides its encryption function, one of the most prominent Gooligan quirks is its weird (and poor) integrity verification algorithm. Basically, the integrity of the close.png file is checked by ensuring that the first ten bytes match the last ten. As illustrated in the diagram above, the oddest part of this schema is that the first five bytes (val 1) are compared with the last five, while bytes six through ten (val 2) are compared with the first five.
Phone rooting
As alluded to earlier, Gooligan, like Snappea and Ghostpush, weaponizes the Kingroot exploit kit to gain root access. Kingroot operates in three stages: First, the malware gathers information about the phone that are sent to the exploit server. Next, the server looks up its database of exploits (which only affect Android 3.x and 4.x) and builds a payload tailored for the device. Finally, upon payload reception, the malware runs the payload to gain root access.
The weaponization of known exploits by cyber-criminals who lack exploit development capacity (or don’t want to invest into it) is as old as crimeware itself. For example, DroidDream exploited Exploid and RageAgainstTheCage back in 2011. This pattern is common across every platform. For example, recently NSA-leaked exploit Eternal Blue was weaponized by the fake ransomware NoPetya. If you are interested in ransomware actors, check my posts on the subject.
Persistence setup
Upon rooting the device, Gooligan patches the install-recovery.sh script to ensure that it will survive a factory reset. This resilience mechanism was the most problematic aspect of Gooligan, from a remediation perspective, because for the oldest devices, it only left us with OTA (over the air) update and device re-flashing as a way to remove it. This situation was due to the fact that very old devices don’t have verified boot, as it was introduced in Android 4.4.
This difficult context, combined with the urgent need to help our users, led us to resort to a strategy that we rarely use: a coordinated takedown. The goal of this takedown was to disable key elements of the Gooligan infrastructure in a way that would ensure that the malware would be unable to work or update. As discussed in depth at the end of the post, we were able to isolate and take down Gooligan’s core server in less than a week thanks to a wide cross-industry effort. In particular, Kjell from the NorCert worked around the clock with us during the Thanksgiving holidays (thanks for all the help, Kjell!).
Play store app manipulation
The final step of the infection is the injection of a shared library into the Play store app. This shared library allows Gooligan to manipulate the Play store app to download apps and inject review.
We traced the injection code back to publicly shared code. The library itself is very bare: the authors added only the code needed to call Play store functions. All the fraud logic is in the main app, probably because the authors are more familiar with Java than C.
Impacted devices
Geo-distribution
Looking at the set of devices infected during the takedown revealed that most of the affected devices were from India, Latin America, and Asia, as visible in the map above. 19% of the infections were from India, and the top eight countries affected by Gooligan accounted for more than 50% of the infections.
Make
In term of devices, as shown in the barchart above, the infections are spread across all the big brands, with Samsung and Micromax being unsurprisingly the most affected given their market share. Micromax is the leading Indian phone maker, which is not very well known in the U.S. and Europe because it has no presence there. It started manufacturing Android One devices in 2014 and is selling in quite a few countries besides India, most notably Russia.
Attribution
Initial clue
Buried deep inside Gooligan patient zero code, Check Point researchers Andrey Polkovnichenko, Yoav Flint Rosenfeld, and Feixiang He, who worked with us during the escalation, found the very unusual text string oversea_adjust_read_redis. This string led to the discovery of a Chinese blog post discussing load balancer configuration, which in turn led to the full configuration file of Gooligan backend services.
#Ads API
acl is_ads path_beg /overseaads/
use_backend overseaads if is_ads
…
#Payment API
acl is_paystatis path_beg /overseapay/admin/
use_backend overseapaystatis if is_paystatis
...
# Play install
acl is_appstore path_beg /appstore/
use_backend overseapaystatis if is_appstore
...
Analyzing the exposed HAproxy configuration allowed us to pinpoint where the infrastructure was located and how the backend services were structured. As shown in the annotated configuration snippet above, the backend had API for click fraud, receiving payment from clients, and Play store abuse. While not visible above, there was also a complex admin and statistic-related API.
Infrastructure
Combining the API endpoints and IPs exposed in the HAproxy configuration with our knowledge of Gooligan binary allowed us to reconstruct the infrastructure charted above. Overall, Gooligan was split into two main data centers: one in China and one overseas in the US, which was using Amazon AWS IPs. After the takedown, all the infrastructure ended up moving back to China.
Note: in the above diagram, the Fraud end-point appears twice. This is not a mistake: at Gooligan peak, its authors splited it out to sustain the load and better distribute the requests.
Actor
So, who is behind Gooligan? Based on this infrastructure analysis and other data, we strongly believe that it is a group operating from mainland China. Publicly, the group claims to be a marketing company, while under the hood it is mostly focused on running various fraudulent schema. The apparent authenticity of its front explains why some reputable companies ended up being scammed by this group. Bottom line: be careful who you buy ads or install from: If it is too good to be true…
In the final post of the serie, I discusses Gooligan various monetization schemas and its takedown. See you there!
Thank you for reading this post till the end! If you enjoyed it, don’t forget to share it on your favorite social network so that your friends and colleagues can enjoy it too and learn about Gooligan.
To get notified when my next post is online, follow me on Twitter, Facebook, Google+, or LinkedIn. You can also get the full posts directly in your inbox by subscribing to the mailing list or via RSS.
A bientôt!