Hunting for scams and malicious APKs using OSINT.
Scams have been a hot topic in Singapore for a fair bit and it is no wonder why. According to the Singapore Police Force Annual Scams and Cybercrime Brief 2022, victims of scams lost a total of S$660.7 million in 2022 alone, up from S$632 million in 2021. The number of reported scam cases have also increased, with a total of 31,728 scam cases reported in 2022, up from 23,933 in 2021.
More recently, news broke in June about a scam series publishing social media advertisements for cheap dim sum deals, where victims were instructed to download a malicious Android application which led to their phones being taken over and bank accounts being compromised. The news reports shared that the victims first saw the advertisements on Instagram and Facebook, and one victim even lost nearly S$24,000.
In this post, I will show how to use Open-Source Intelligence (OSINT) to hunt for malicious APKs used in scams.
OSINT: where to start?
Both news article mentioned that the victims first saw a social media advertisement, and after reaching out to the seller who posted the advertisement, were redirected to a WhatsApp chat. The victims were then provided an external link to download an application called “1stMall” or “1st Mall”. A few Google searches later, we find a possible match on Triage, a malware analysis sandbox service.
Looking around Triage, we find multiple submissions for APKs named “1st Mall” and tagged as Android banking trojans. These submissions were made in June, around the vicinity of the news reports. There seems to be a particular pattern for the naming convention of the APKs where the version of the APK is included in the filename itself, similar to what was shared in the news reports.
From Triage, we can get useful information about the samples that were uploaded, such as:
- sample submission time
- SHA256 hash
- permissions requested
- network packet capture and requests
- downloaded and dropped files etc.
From Triage, we also observe a common pattern across all the “1st Mall” samples where a process that spawns during the execution of the application attempts to run the command “ping -c 1 -W <IP address>”, where the IP address changed across different versions of the application. There is little context on when or how this was triggered, but one possible reason could be to test for internet connectivity or update a remote C2 server that the APK was “live”.
In the “Network” section of the Triage analysis, we see the amount of network data captured during the execution of the sample. In this tab, we see that 3 of the established communications were made over port 443 to Google APIs. We also observe that the IP address obtained from the ping command above is also sending and receiving data from the sample at an uncommon port, notably at more significant rates than the previous 3 connections (the amount of downloaded data is almost 10 times of the previous connection).
In the “Static” tab of the Triage analysis, we observe that the sample requests for a large number of Android permissions, some of which are commonly abused for malicious purposes. In total, this sample requests for 32 permissions, which is cause for concern considering this app is meant for users to purchase cheap dim sum.
More about the sample
By registering a free account on Triage, we can download submitted files for our own investigations. In this section, we do a quick run through of the “1st Mall v11.1.apk” sample to verify the findings from Triage.
After downloading the sample, use apktool to decompile the sample and obtain the AndroidManifest.xml file.
apktool d "1st Mall v11.1.apk"
In Line 1 of the AndroidManifest.xml file, we see the compileSdkVersion attribute set to “23“, which signifies that the APK was compiled targeting the Android API level 23 (Marshmallow).
However, in the apktool.yml generated by apktool, it states that the APK’s targetSdkVersion is “29“, while the minSdkVersion is “16“.
We can confirm the above findings by using aapt and the following command:
aapt dump badging "1st Mall v11.1.apk"
To avoid fretting too much about the exact target version, I spun up a virtual instance of an Android device running on Android version 7.1 (API level 25; Nougat) to test the “1st Mall v11.1.apk” sample. Once installed, we see that the launcher icon of the APK also matches the one showed in the news articles.
Once the sample is installed and run, it requests for permissions to become an Accessibility Service to access a wide range of functionalities, such as viewing the device’s screen and simulating touch. This Service can be seen in Line 139 of the AndroidManifest.xml file.
By interacting with the sample, we find that if the user grants the application Accessibility permissions, the sample requests for the other permissions shown in the screenshots previously and automatically accepts them on the user’s behalf by simulating touch actions. With virtually full control over the device, this is presumably how the sample compromised the victims’ bank accounts.
So far, things are not looking good for an application supposedly selling cheap dim sum. That said, our findings indicate that we are hunting in the correct direction.
Back to the hunt!
At this stage, we have a list of interesting “1st Mall” samples that we have collected from Triage. We know from the articles that the victims were provided an external link to download the application, which suggests that there could be websites/servers in the wild hosting these malicious APKs. In this section, we explore ways to look for places where the APK is hosted.
As with any OSINT investigation, we might not have all the necessary information to fully appreciate the scale of this scam, so it is important to note down our findings and collect information we deem relevant as we go about. At this stage, we have a list of interesting “1st Mall” samples that will help us in our investigation, noting down each sample’s filename, SHA256 hash, and the IP address each APK attempted to ping.
Since we know that these APKs are part of a scam series called “1st Mall”, we can start by looking for websites that are part of this scam series. One such way is by using URLScan, a service where users can submit URLs to scan and analyse websites.
URLScan also has a useful search feature that allows users to craft queries with regular expressions to sift through different fields in sites analysed by URLScan. Below are some queries that you can try:
The search query that ultimately got the ball rolling was the following:
page.url.keyword:https\:\/\/1st*mall*\/*
The search query returned a list of 9 sites whose domain contained the words “1st” then “Mall”.
The URLScan analysis of the 7th result “1stgetmall2-fappdoom5[.]top” managed to capture the index page of the site, which contains a download link to “1st Mall v3.2.apk”. This site is likely one of the external links that were given to the victims to download the malicious APKs.
We also see that the title of the index page is “1st MALL sell everything you need“.
With this information, we perform another search to look for more related sites analysed by URLScan.
page.title:"1st MALL sell everything you need"
The search query returned a list of more than 200 scans whose website title contained our search query!
After removing duplicates, we are left with 84 URLs whose index page contained our search query. Now that we have a list of interesting URLs, we can start extracting the filename of APKs found in each site and comparing them against our list from Triage. Using Python, I automated the search process to do the following:
- For each of the 84 URLs, get a list of all URLScan analyses performed on the URL
- Instead of relying on the just the first analysis for each URL, I checked all the analyses for each URL to ensure that I had a valid result because some scans might fail to get the HTML content of a site
- For each analysis, get the index page of the site
- Look for the “Primary Request” in the HTTP transactions section for each analysis
- Parse the HTML content of the index page to get a list of download links to APKs
- Use BeautifulSoup to look for HTML “a” tags containing links to APK files
- Create a list of URLs and the corresponding APK found in each analysis
With this method, we managed to find 290 analyses from the initial 84 URLs.
As we can see from the first few rows, there are duplicate results where a different analysis returned the same filename. After removing these duplicates, we are left with 130 unique site:filename pairs, which is more meaningful to our investigations. We also found 60 unique APK filenames, which could represent 60 unique files.
Interestingly, one of the URLScan results shows that the site “foezdalsp3-ezmarpdaoz2.top” actually contained a download link to “EZ Mart v1.3 (3).apk”.
This is confusing as the site layout and title was similar, if not identical, to the other URLScan results we have seen featuring our “1st Mall” APKs. This could suggest that the operators of the “1st Mall” scam series is linked to other scam series, something that we will explore in part 2 of this post!
Hunting for live sites
Because URLScan relies on user-submitted URLs, it is likely that some (if not most) of the URLs are already inaccessible. To improve our detection rates, we can use other search platforms that scan Internet-connected devices, such as Shodan and Censys. Similar to URLScan, all we have to do is search for devices hosting websites with a title matching our earlier search query. Both platforms require an account, but registration is free.
With Shodan, we use the following search query:
http.title:"1st MALL sell everything you need"
With Censys, we use the following search query:
services.http.response.html_title: "1st MALL sell everything you need"
As we can see from both searches, different platforms can provide us different results, so it is always a good practice to confirm our findings with multiple tools. In any case, the results provided by Shodan and Censys are useful for our investigations because we can find “live” sites with them.
Finally, by using our web browser to navigate to the IP addresses of the hosts directly on port 443, we can interact with the live sites hosting the APKs!
Even though the site content looks broken, we can still find the download links to the APKs by inspecting the HTML content of the site itself.
To confirm our findings, we download the APK and get it’s SHA256 hash, then compare the SHA256 hash with a sample from Triage with the same name.
Hunting for live sites – bonus!
Based on the list of interesting URLs from URLScan, we observe that there is clearly a trend in the naming convention of the domains registered for the scam series. By using the re library in Python, the following regular expression can obtain a list of domains fitting the naming convention:
^1s[a-z]{5,12}\d?-[a-z]{5,12}\d
When tested against our initial list of 84 URLs from URLScan, we are able to match 77 of the URLs – that’s a ~92% hit rate which is pretty reasonable for our purposes.
By running this regular expression against a list of newly registered domains in a 30-day period (27 May 2023 – 26 Jun 2023), we extracted a list of 53 newly registered domains that could be linked to our scam series, 26 of which were not in our initial list of 84!
Newly registered domains are usually used by cybercriminals to carry out their malicious activities, such as acting as domains for C2 servers, distributing malware, and for phishing attacks. As the news articles were published quite recently, it is not out of the norm to find newly registered domains that could be linked to the scam series.
Final Words
Et voilà! In this post, we managed to go full circle; from finding potentially malicious samples on Triage, to verifying the malicious functions of the samples, to identifying malicious websites hosting our malicious samples with URLScan, to finally finding live sites hosting the malicious samples themselves!
In the next part of this post, we will build on our findings and expand our search to look for other scam series associated with “1st Mall”. Until then, happy hunting!
Leave a Reply