The Curious Case of Coulus Coelib
The technique we invented to uncover the active exploitation of side and covert channels continues to work. One such side channel comes from an obscure, purportedly-Panamanian company. A look at their code makes for an interesting case study in obfuscation (and provides a few examples of an app feeling far too much at home when collecting user data). Let’s begin with the app WiFi Mouse(remote control PC), which we see transmitting our router’s MAC address to the domain
An array called
ARPSurvey includes MAC addresses of not only the router, but also other devices on the home network. Importantly, this app did not have permission to access device location—a required permission to access router information—and so there must be some technique they are using to circumvent the permission system when it is run on a vulnerable version of Android. The name “ARP survey” suggests the answer: apps read a local cache of MAC addresses and IP addresses (e.g., the ARP cache) that was not correctly secured. (We had actually found this issue years ago and it appears to be first fixed in Android 11, but older versions of the operating system, such as the Android 9 version we used in our testing, remain vulnerable.)
While the issue that brought this SDK to our attention was resolved, our investigation into it had just begun. Another thing that we saw was the MAC address of the router being sent to the app—from the router itself!
In screenshot above, the router is sending what appears to be a plug-and-play configuration message to the app that includes its MAC address. The last row, which has the key “USN” (unique service name), is a non-standard UUID-like string whose node ID component is the 48 bit router MAC address. What motivates the router to share this information? There wasn’t a complementary connection from the app to the router, but there was a local network broadcast message, where the app (or in this case, a third-party monetization library) does some home network reconnaissance:
An M-SEARCH plug-and-play discovery message goes out to the entire home network: every laptop, router, and IoT device. Routers tend to happily share their configuration details to help make them easy for users to setup. In this case, the app asks nicely, and then receives the router’s MAC address in kind, despite the fact that the app should not have access to user location data without the requisite Android permissions. This also highlights an important thing: all of these apps, and all of the third-party code that they contain, are running on the “trusted” side of the home network. Firewalls are designed to keep malicious traffic out, but apps running on people’s phones while they’re connected to home networks can run scans without a firewall in their way. We recommend that Android use a separate permission for local network connections, that is, reserve the INTERNET permission for actual Internet connections, and have a LOCAL_NETWORK permissions to access devices that reside within a user’s home. (Apple already does this in iOS 14.) This would allow for such apps to be more easily audited and scrutinized, to protect against third parties piggy-backing off the permissions. (Of course, this doesn’t solve the problem of apps circumventing the permission system altogether.)
Additional Data Collected: Clipboard, GPS, Email, and Phone Numbers
We later observed more unusual transmissions, and observed that different apps running the same version of the SDK (version 2.78 in our examples) will collect different information. For instance, the Simple weather & clock widget app running this SDK includes the contents of the clipboard: whenever a user copy/pastes something, it goes to a shared clipboard, which this SDK was scouring and uploading to its servers. What gets put there is arbitrary data, and can include passwords, for example, if a user uses a password manager.
Other troubling transmissions we observed were the phone number of the device sent with the JSON key “PhoneNumber”, and the email address associated with the phone sent base64-encoded under the JSON key “Name”. It is worth noting that in apps that have access to the location permission, this SDK also collects precise GPS location in addition to coarser router-based location data. The thought that this data collector could have built a database mapping someone’s actual email and phone number to their precise GPS location history is particularly frightening, as such a database could be used to run a service to look up a person’s location history just by knowing their phone number or email, and could be used to target journalists, dissidents, or political rivals.
We are not sure exactly what causes the SDK to behave differently in different apps, aside from the particular subset of permissions that are available. Nevertheless, we did observe an interesting incoming transmission from
mobile.measurelib.com that may control how individual devices collect and report different information in the field, with intriguing fields such as
Who Receives the Data?
At this point, we wanted to figure out who owns
mobile.measurelib.com, which turned out to be rather difficult. We searched for strings that we saw in the network traffic to
measurelib.com, such as
measurelib.com: while listing other location and router data collectors like Huq, they somehow omitted
To find out more, we looked for other apps that talked to
mobile.measurelib.com. We found a few, including Audio Quran, Qibla Compass, and a QR code scanner, all of which have location permissions. This means that if the user grants the app access to location data, then this SDK does not need a side channel to get the router’s MAC address. In such apps, when we performed our test, we found that they also shared precise GPS location information with
measurelib.com, as well.
Again, the true identity of this SDK sending data to
measurelib.com was not clear after considering all these apps’ privacy policies, as well. That is, none seemed to acknowledge a relationship with this company. Moreover, none of the strings we saw in network transmissions were present in the app. But by looking to see what chunks of third-party code happened to be shared across all of these apps, we found a clue. A rare library, appearing as coelib.c.couluslibrary, was present in all of the apps that communicated with
measurelib.com. When we looked for strings inside it, we made a surprising discovery:
All the strings look like they are base64 encoded, which is why we couldn’t search for them. But worse, they decoded to random high-entropy binary values, indicating that they are likely encrypted, too—a technique that we’ve seen before. Digging deeper, we looked at the code that processes the strings:
After a string is declared, it is processed by a function “
b.c()” which takes a string and returns one, and that returned value is what is then used. Now the implementation of
b.c() is rather complicated and involved, so we summarize it using our own pseudocode below. Note that the variable name are our own interpretation based on how they are later used as parameters to public API calls, not the sample of code that we analyzed. The piecemeal manner in which strings are assembled, however, faithfully maps the implementation.
It works as follows:
- The string “Measure” is constructed from two pieces.
- Then “MeasureMoveMeasure” is made out of five.
- These are used as the password and salt respectively for ten rounds of password-based key derivation.
- The resulting key is then used to decrypt the base64-decoded string into the actual value.
There are many security best practices that are violated here:
- Don’t use fixed IVs.
- Don’t store passwords.
- 10 rounds is not enough for password-based key derivation.
- Deriving a key when you are already storing the password makes no sense.
And what is the threat model that requires encrypting your strings anyway?! At least, it’s a relief that they only do 10 rounds of key derivation, because this outrageous block of code executes every single time that a string is used by this library (delaying the app and wasting battery life). There is no caching—even for the resulting AES key. Whenever such an encrypted string is used, your phone is powering this deobfuscation process, which has the effect of hiding some of the string constants that they use. And some of those strings really jumped out as concerning. For example, we found the following:
We did not test to see what happens when WhatsApp is installed on a phone, but looking at the relevant code where these string constants are used, we see that that it is appended to the external storage directory (e.g., the SD card) and starts listing files present.
So now that we have the strings, we can see all our JSON keys and the network hostnames, and so we can also confirm that
coelib is the entity doing that M-SEARCH home network scan. But who are they? It turns out that they are also rather hard to find. Searching for coelib.c.couluslibrary gives only a handful of results that do not reflect well on the brand.
In a developer help forum, however, we found a link to the following page belonging to Panama-based Measurement Systems (according to their homepage, “The Internet measurement Authority”) that indicates how to integrate their SDK into apps, showing exactly the SDK name
coelib.c.couluslibrary that we observed. This page does not seem to be indexed by the main website for the company, but it finally gives us the link between this strange, heavily-obfuscated code doing home network scans and the company that appears to have created it.
Other webpages by Measurement Systems show how they position their SDK to developers. They offer to monetize apps and pay the developers the “highest CPMs for your data”. They boast doing so without ads, as they are an “alternative monetization strategy” that does not “sacrifice your users privacy or battery life (sic)“. They claim to have paid out more than 2 million dollars to partners and offer a calculator to tell you how much you could make with their SDK.
whois on the domain name revealed that
measurementsys.com was registered by VOSTROM Holdings, Inc., a Virginia-based company that has also registered Packet Forensics. Other domains registered by VOSTROM Holdings include the following:
The following table are the apps that we confirmed communicating with
mobile.measurelib.com. We reported this issue to Google on October 20th, 2021 along with this list of apps. They investigated it and removed these and other apps containing the SDK from the Play Store. The DNS records for
mobile.measurelib.com have also been recently updated to point to the non-routable value of
127.0.0.1, and the public
whois data for
measurementsys.com has been updated so that it no longer includes VOSTROM Holdings, Inc.
|Speed Camera Radar||link||10 million+||yes||no||yes||no||yes||yes|
|Al-Moazin Lite (Prayer Times)||link||10 million+||yes||no||yes||no||yes||yes|
|WiFi Mouse(remote control PC)||link||10 million+||no||no||no||no||no||yes|
|QR & Barcode Scanner||link||5 million+||yes||yes||yes||yes||yes||yes|
|Qibla Compass – Ramadan 2022||link||5 million+||no||no||no||yes||yes||yes|
|Simple weather & clock widget||link||1 million+||yes||no||yes||no||yes||yes|
|Handcent Next SMS-Text w/ MMS||link||1 million+||no||yes||yes||no||yes||yes|
|Smart Kit 360||link||1 million+||no||yes||yes||no||yes||yes|
|Al Quran Mp3 – 50 Reciters & Translation Audio||link||1 million+||no||no||no||yes||yes||yes|
|Full Quran MP3 – 50+ Languages & Translation Audio||link||1 million+||no||no||no||yes||yes||yes|
|Audiosdroid Audio Studio DAW – Apps on Google Play||link||1 million+||yes||no||yes||yes||yes||yes|