Home
Bio
Publications
Blog
Newsletter
Art
Contacts

Diving Deeper in Android System Diagnostics and Remote Forensics

February 4, 2022

Following up from last week’s Primer on Android Forensics, today we are going to dive a little deeper into Android system diagnostics, have a look at some new modules I have introduced to MVT in the last few days, and most importantly come up with a frictionless procedure to quickly triage suspected phones remotely.

For the purpose of this article, we’ll check a phone with an MSpy sample installed. We’ll also make use of a STIX2 indicators file provided by Tek.

Running a check-adb will show us something like this:

$ mvt-android check-adb -i /path/to/indicators.stix2 -o /path/to/results
...
INFO     [mvt.android.modules.adb.processes] Running module Processes...
INFO     [mvt.android.modules.adb.processes] Extracted records on a total of 729 processes
WARNING  [mvt.android.modules.adb.processes] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
...
INFO     [mvt.android.modules.adb.dumpsys_receivers] Running module DumpsysReceivers...
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
INFO     [mvt.android.modules.adb.dumpsys_receivers] Found a receiver to intercept incoming SMS messages: "system.framework/com.android.mob.display2.main.login_system.SmsWakeupReceiver"
INFO     [mvt.android.modules.adb.dumpsys_receivers] Found a receiver to intercept incoming SMS messages: "com.google.android.gms/.chimera.GmsIntentOperationService$GmsExternalReceiver"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
INFO     [mvt.android.modules.adb.dumpsys_receivers] Found a receiver monitoring outgoing calls: "system.framework/com.android.mob.display2.telephony.OutgoingCallReceiver"
INFO     [mvt.android.modules.adb.dumpsys_receivers] Found a receiver monitoring outgoing calls: "com.sec.android.app.safetyassurance/.emergencyreporthelper.EmergencyReportStartMonitorReceiver"
INFO     [mvt.android.modules.adb.dumpsys_receivers] Found a receiver monitoring outgoing calls: "com.google.android.gms/.chimera.GmsIntentOperationService$PersistentTrustedReceiver"
INFO     [mvt.android.modules.adb.dumpsys_activities] Running module DumpsysActivities...
WARNING  [mvt.android.modules.adb.dumpsys_activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
INFO     [mvt.android.modules.adb.dumpsys_accessibility] Running module DumpsysAccessibility...
INFO     [mvt.android.modules.adb.dumpsys_accessibility] Found installed accessibility service "com.samsung.accessibility/.universalswitch.UniversalSwitchService"
INFO     [mvt.android.modules.adb.dumpsys_accessibility] Found installed accessibility service "com.samsung.android.accessibility.talkback/com.samsung.android.marvin.talkback.TalkBackService"
INFO     [mvt.android.modules.adb.dumpsys_accessibility] Found installed accessibility service "system.framework/com.android.mob.display2.main.sensors.KeyLoggerAccessibilityService"
INFO     [mvt.android.modules.adb.dumpsys_accessibility] Identified a total of 3 accessibility services
WARNING  [mvt.android.modules.adb.dumpsys_accessibility] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
INFO     [mvt.android.modules.adb.dumpsys_dbinfo] Running module DumpsysDBInfo...
INFO     [mvt.android.modules.adb.dumpsys_dbinfo] Extracted a total of 3078 records from database information
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.adb.dumpsys_dbinfo] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
...
INFO     [mvt.android.modules.adb.packages] Running module Packages...
INFO     [mvt.android.modules.adb.packages] Third-party package "system.framework" requested 13 potentially dangerous permissions
INFO     [mvt.android.modules.adb.packages] Found non-system package with name "system.framework" installed by "None" on 2022-02-03 01:18:04
ERROR    [mvt.android.lookups.virustotal] Unfortunately VirusTotal lookup is disabled until further notice, due to unresolved issues with the API service.
INFO     [mvt.android.lookups.koodous] Looking up all extracted files on Koodous (www.koodous.com)
INFO     [mvt.android.lookups.koodous] This might take a while...
Looking up 1 packages... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
                                            Koodous Packages Detections
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━┓
┃ Package name     ┃ File name                                                                               ┃ Trusted ┃ Detected ┃ Rating ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━┩
│ system.framework │ /data/app/~~ouN9uPoDFrrXECbW3wT92g==/system.framework-A8rmOWm9ftjO9nDxRcdasg==/base.apk │ no      │ yes      │ -2     │
└──────────────────┴─────────────────────────────────────────────────────────────────────────────────────────┴─────────┴──────────┴────────┘
INFO     [mvt.android.modules.adb.packages] Extracted at total of 331 installed package names
WARNING  [mvt.android.modules.adb.packages] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
...

Right off the bat we can see a running process matching a known malicious package name system.framework attributed to MSpy:

WARNING  [mvt.android.modules.adb.processes] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"

If we check the file /path/to/results/processes_detected.json we see it running with pid 10595:

[
    {
        "user": "u0_a222",
        "pid": "10595",
        "parent_pid": "734",
        "vsize": "1327820",
        "rss": "78972",
        "wchan": "0",
        "pc": "0",
        "name": "system.framework",
        "matched_indicator": {
            "value": "system.framework",
            "type": "app_ids",
            "name": "mspy",
            "stix2_file_name": "indicators.stix2"
        }
    },
]

Then we see a number of receivers matching the same known bad package name. Some are highlighted in the console logs right away, but we can check the full list in the JSON results file:

$ cat /path/to/results/dumpsys_receivers_detected.json | grep receiver
            "receiver": "system.framework/com.android.mob.display2.MainController",
            "receiver": "system.framework/com.android.inputmethod.dictionarypack.EventHandler",
            "receiver": "system.framework/com.android.mob.display2.main.system.SystemHelper",
            "receiver": "system.framework/com.android.mob.display2.MainController",
            "receiver": "system.framework/com.android.mob.display2.main.commands.DeviceAdmin",
            "receiver": "system.framework/com.android.mob.display2.main.system.SystemHelper",
            "receiver": "system.framework/com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver",
            "receiver": "system.framework/com.android.mob.display2.MainController",
            "receiver": "system.framework/com.android.mob.display2.main.commands.DeviceAdmin",
            "receiver": "system.framework/com.android.mob.display2.MainController",
            "receiver": "system.framework/com.android.mob.display2.main.system.SystemHelper",
            "receiver": "system.framework/com.android.inputmethod.latin.DictionaryPackInstallBroadcastReceiver",
            "receiver": "system.framework/com.android.inputmethod.latin.personalization.DictionaryDecayBroadcastReciever",
            "receiver": "system.framework/com.android.mob.display2.telephony.OutgoingCallReceiver",

After a few detected Activities, we also see that MSpy creates an Accessibility service with a rather self-decriptive name indicating its keylogging purpose:

INFO     [mvt.android.modules.adb.dumpsys_accessibility] Found installed accessibility service "system.framework/com.android.mob.display2.main.sensors.KeyLoggerAccessibilityService"

Indeed, the decompiled code of the installed app seems to indicate this service listens to accessibility events in order to likely steal passwords:

public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
    if (!TextUtils.isEmpty(accessibilityEvent.getPackageName())) {
        a(accessibilityEvent);
        switch (accessibilityEvent.getEventType()) {
            ...
            case 8192:
                a(8192);
                if (accessibilityEvent.getItemCount() >= 0 && accessibilityEvent.getEventTime() > this.j) {
                    if (accessibilityEvent.getItemCount() <= 0 || (this.h && !accessibilityEvent.isPassword())) {
                        d();
                        return;
                    }
                    if (!this.h && accessibilityEvent.isPassword()) {
                        d();
                    }
                    String b2 = b(accessibilityEvent);
                    if (!b2.startsWith(this.e)) {
                        d();
                    }
                    this.e = b2;
                    this.j = accessibilityEvent.getEventTime();
                    this.g = accessibilityEvent.getPackageName().toString();
                    this.h = accessibilityEvent.isPassword();
                    this.i = g.b(System.currentTimeMillis());
                    return;
                }
                return;
            default:
                return;
        }
    }
}

Check Database Connection Pools

In the latest version of MVT I introduced a new module called DumpsysDBInfo. The purpose of this module is to parse records retrieved from a dump of the dbinfo service, which among other things displays a list of queries currently being performed by all database connection pools active on the Android system.

For example, when running the check-adb command at the beginning of this post, we can see a number of records matching the known bad package name system.framework. Because we launched the command shortly after installing the sample, we can in fact see the spyware creating some tables in it’s internal.db SQLite database, such as one called kik_messages, presumably used to log messages from the Kik messaging app:

{
    "isodate": "2022-02-03 01:18:13.442",
    "pid": "10595",
    "action": "executeForChangedRowCount",
    "sql": "CREATE TABLE `kik_messages` (`a` BIGINT NOT NULL , `b` VARCHAR NOT NULL , `c` VARCHAR , `d` VARCHAR NOT NULL , `e` VARCHAR NOT NULL , `f` SMALLINT NOT NULL , `g` VARCHAR , `h` BIGINT NOT NULL , `type` VARCHAR DEFAULT 'text' NOT NULL , `mediaFilePath` VARCHAR , `duration` INTEGER DEFAULT 0 , `id` INTEGER PRIMARY KEY AUTOINCREMENT , `contactRawId` VARCHAR , `sendGroupId` BIGINT NOT NULL )",
    "path": "/data/user/0/system.framework/databases/internal.db",
    "matched_indicator": {
        "value": "system.framework",
        "type": "app_ids",
        "name": "mspy",
        "stix2_file_name": "indicators.stix2"
    }
}

When run some moments later instead, this query is recorded as MSpy seems to have logged a different application that I have installed/uninstalled:

{
    "isodate": "2022-02-03 01:36:56.536",
    "pid": "10595",
    "action": "executeForLastInsertedRowId",
    "sql": "INSERT INTO `applications` (`appName` ,`deleted` ,`isSystem` ,`packageName` ,`sendGroupId` ,`versionName` ) VALUES (?,?,?,?,?,?)",
    "path": "/data/user/0/system.framework/databases/internal.db",
    "matched_indicator": {
        "value": "system.framework",
        "type": "app_ids",
        "name": "mspy",
        "stix2_file_name": "indicators.stix2"
    }
}

It’s worth noticing that the pid 10595 is indeed the same as that of the system.framework process identified earlier.

The caveat of this particular MVT module is that these records are extremely short-lived. Because the dump of the dbinfo service returns information on active database connection pools, this will mean that if the app is inactive and isn’t performing any read/write operations, we are unlikely to see any records. In my case, because my test phone is fresh of a factory reset and air-gapped, the spyware’s activity will inevitably be low. However, when inspecting a regularly used device instead, there’s a much higher chance of catching the spyware in the act of updating its internal records, such as logging an incoming message.

In any case, with a little bit of luck, this module can provide very useful information.

Check Requested Permissions

With a small update to the Packages module, MVT now highlights third-party apps which requested an unusual number of potentially dangerous Android permissions:

INFO     [mvt.android.modules.adb.packages] Third-party package "system.framework" requested 13 potentially dangerous permissions

If we inspect the file /path/to/results/packages_detected.json we can in fact see a long list of permissions which indicate a large set of capabilities the spyware implements in order to harvest information about the device’s activity:

"requested_permissions": [
    "android.permission.WRITE_CALL_LOG",
    "android.permission.READ_CALL_LOG",
    "android.permission.GET_TASKS",
    "android.permission.READ_PHONE_STATE",
    "android.permission.CALL_PHONE",
    "android.permission.GET_ACCOUNTS",
    "android.permission.PROCESS_OUTGOING_CALLS",
    "android.permission.RECEIVE_BOOT_COMPLETED",
    "android.permission.READ_SMS",
    "android.permission.WRITE_SMS",
    "android.permission.RECEIVE_SMS",
    "android.permission.SEND_SMS",
    "android.permission.INTERNET",
    "android.permission.ACCESS_FINE_LOCATION",
    "android.permission.READ_CONTACTS",
    "android.permission.WRITE_CONTACTS",
    "android.permission.WRITE_EXTERNAL_STORAGE",
    "android.permission.READ_CALENDAR",
    "android.permission.WRITE_CALENDAR",
    "android.permission.WAKE_LOCK",
    "com.android.browser.permission.READ_HISTORY_BOOKMARKS",
    "com.android.browser.permission.WRITE_HISTORY_BOOKMARKS",
    "android.permission.WRITE_SETTINGS",
    "android.permission.ACCESS_NETWORK_STATE",
    "android.permission.CHANGE_NETWORK_STATE",
    "android.permission.CHANGE_CONFIGURATION",
    "android.permission.ACCESS_WIFI_STATE",
    "android.permission.CHANGE_WIFI_STATE",
    "android.permission.SYSTEM_ALERT_WINDOW",
    "android.permission.VIBRATE",
    "android.permission.READ_USER_DICTIONARY",
    "android.permission.WRITE_USER_DICTIONARY",
    "android.permission.DOWNLOAD_WITHOUT_NOTIFICATION",
    "android.permission.READ_PROFILE",
    "android.permission.AUTHENTICATE_ACCOUNTS",
    "android.permission.READ_SYNC_SETTINGS",
    "android.permission.WRITE_SYNC_SETTINGS",
    "android.permission.READ_SYNC_STATS",
    "android.permission.PACKAGE_USAGE_STATS",
    "android.permission.READ_EXTERNAL_STORAGE",
    "android.permission.ACCESS_COARSE_LOCATION",
    "android.permission.ACCESS_BACKGROUND_LOCATION",
    "android.permission.ACCESS_MEDIA_LOCATION"
],

While access to any particular permission isn’t automatically indicative of malicious behavior, any app requesting a large amount of diverse ones should raise some suspicion. Android permissions total in the hundreds, so be on the lookout for a subset of requested ones which might be critical: for example, a combination of READ_SMS, CAMERA, ACCESS_COARSE_LOCATION and READ_PHONE_STATE already could be alarming. Some system apps will inevitably be granted a lot of these permissions for the correct functioning of Android, so prioritize looking at non-system and third-party apps especially.

Check Battery Stats

Two additional modules I have added recently are DumpsysBatteryHistory and DumpsysBatteryDaily, which respectively process the outputs of the commands dumpsys batterystats --history and dumpsys batterystats --daily.

DumpsysBatteryHistory will provide us some information about battery-consuming jobs running on the device since boot. More interestingly, DumpsysBatteryDaily provides a timeline of package installations and updates dating, unfortunately only, as far as a couple of weeks back (I think). Considering how seldomly Android provides historical data, this information could still be precious.

For example, one of my test phones displays records of the installation of malicious packages from weeks before:

[
    {
        "action": "update",
        "from": "2022-01-28",
        "to": "2022-01-29",
        "package": "com.mobiispy.system",
        "vers": "12",
        "matched_indicators": {
            "value": "com.mobiispy.system",
            "type": "app_ids",
            "name": "mobiispy"
        }
    },
    {
        "action": "update",
        "from": "2022-01-28",
        "to": "2022-01-29",
        "package": "com.wifiset.service",
        "vers": "4",
        "matched_indicators": {
            "value": "com.wifiset.service",
            "type": "app_ids",
            "name": "spyhide"
        }
    },
    {
        "action": "update",
        "from": "2022-01-11",
        "to": "2022-01-17",
        "package": "com.network.android",
        "vers": "292",
        "matched_indicators": {
            "value": "com.network.android",
            "type": "app_ids",
            "name": "Pegasus"
        }
    }
]

Checking an Android phone remotely

In the previous post we learned how to use MVT’s check-adb command to inspect an Android phone. The problem with that approach is that it requires us to have physical access to the device due to the need to connect it to our computer over USB in order to leverage the debugging bridge. Unfortunately this might not always be possible: due to logistical difficulties we might need to perform at least a quick remote triage of the device without the ability to have it handed or shipped to us. In this scenario our options are limited, but thankfully a bug report functionality of Android comes to the rescue.

After having enabled Developer Options, we should find a “Bug Report” option in the menu:

Screenshot of Settings app

By tapping it we should be offered the options of “interactive” or “full” report, the former should be fine:

Screenshot of bug report options

In the notification panel we should be able to see the progress, and be alerted once the generation completed:

Screenshot of notification

Once Android finished to aggregate system diagnostic information, the device should display a notification offering the user of the device to send or upload the newly generated bug report archive somewhere:

Screenshot of uploading prompt

At this point we can request the device user to send the bug report to us either via email, a messaging app, or a web file upload of our choice.

When the bug report is finally in our hands, we can inspect using a new MVT command called check-bugreport. This command will extract relevant information from files contained within the bug report archive, especially from a dumpstate file.

We can launch an analysis of the archive with the following command:

$ mvt-android check-bugreport -o /path/to/results /path/to/bugreport.zip

Similarly to check-adb, check-bugreport currently supports the following modules: Accessibility, Activities, BatteryDaily, BatteryHistory, DBInfo, Getprop, Packages and Receivers.

For example, the check-bugreport analysis of a bug report generated for my MSpy-infected device logs the following:

INFO     [mvt.android.modules.bugreport.accessibility] Running module Accessibility...
INFO     [mvt.android.modules.bugreport.accessibility] Found installed accessibility service "com.samsung.accessibility/.universalswitch.UniversalSwitchService"
INFO     [mvt.android.modules.bugreport.accessibility] Found installed accessibility service "com.samsung.android.accessibility.talkback/com.samsung.android.marvin.talkback.TalkBackService"
INFO     [mvt.android.modules.bugreport.accessibility] Found installed accessibility service "system.framework/com.android.mob.display2.main.sensors.KeyLoggerAccessibilityService"
INFO     [mvt.android.modules.bugreport.accessibility] Identified a total of 3 accessibility services
WARNING  [mvt.android.modules.bugreport.accessibility] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
INFO     [mvt.android.modules.bugreport.activities] Running module Activities...
WARNING  [mvt.android.modules.bugreport.activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.activities] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
...
INFO     [mvt.android.modules.bugreport.packages] Running module Packages...
WARNING  [mvt.android.modules.bugreport.packages] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
INFO     [mvt.android.modules.bugreport.receivers] Running module Receivers...
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
INFO     [mvt.android.modules.bugreport.receivers] Found a receiver to intercept incoming SMS messages: "system.framework/com.android.mob.display2.main.login_system.SmsWakeupReceiver"
INFO     [mvt.android.modules.bugreport.receivers] Found a receiver to intercept incoming SMS messages: "com.google.android.gms/.chimera.GmsIntentOperationService$GmsExternalReceiver"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
WARNING  [mvt.android.modules.bugreport.receivers] Found a known suspicious app with ID "system.framework" matching indicators from "mspy"
INFO     [mvt.android.modules.bugreport.receivers] Found a receiver monitoring outgoing calls: "system.framework/com.android.mob.display2.telephony.OutgoingCallReceiver"
INFO     [mvt.android.modules.bugreport.receivers] Found a receiver monitoring outgoing calls: "com.sec.android.app.safetyassurance/.emergencyreporthelper.EmergencyReportStartMonitorReceiver"
INFO     [mvt.android.modules.bugreport.receivers] Found a receiver monitoring outgoing calls: "com.google.android.gms/.chimera.GmsIntentOperationService$PersistentTrustedReceiver" 

As we can see, the output is fundamentally identical to the analysis performed with check-adb, obviously excluding modules which require to execute commands directly on the device.

Samsung devices provide an alternative to bug reports, as they support the generation of a dumpstate log only through a SysDump menu activated through a custom USSD message. We can do so by opening the Phone app, and dialing *#9900#. This will immediately spawn the SysDump screen. Scrolling to the bottom, we should find a “Run dumpstate & Copy to sdcard” option:

Screenshot of SysDump

Tapping it we are offered to provide a custom name to the log file. This step doesn’t really matter, as the resulting file will ultimately be a zip archive. We can leave the field empty and just tap “OK”:

After some moments, a confirmation should appear informing us the dumpstate log file is successfully generated and stored at /sdcard/log/:

Similarly to a bug report, we can then request the device user to send or upload to us the generated zip archive so we can further inspect it just in the same way using mvt-android check-bugreport /path/to/dumpState_XXXXXXXXX_YYYYMMDDHHmm.zip.

The advantage of this process is that we can avoid walking the device user through the steps of enabling and then disabling Developer Options. The downside is that the log file will be stored on the SD card, which is easily accessible in case the device is lost or seized. And although the log file should not contain very sensitive information, it might still contain sensory data related to networks or, for example, GPS. In this case, we should make sure the device user deletes the dumpstate file after sending it to us.

Because the dumpstate will primarily contain information on apps leveraging Android services, and because in this scenario we can’t perform any further manual inspection of the device, checking bug reports/dumpstates should be considered an triaging step. While it should be enough to spot the presence of off-the-shelf spyware, it will be harder to observe traces of sophisticated implants, for example running as native binaries rather than Android packages.

I should note that the parsing of dumpstate and dumpsys logs is a rather delicate process which will be sensitive to unexpected format differences. While I have tried to support as many Android devices I could test, undoubtedly there will be parsing errors and broken results from other devices and manufacturers. In that case, please report in GitHub Issues.

Further Digging using AndroidQF

Let’s assume our first triage of a remote Android device using check-bugreport turned up some suspicious results. What can we do now to collect even more data that a bug report simply won’t contain? For example, we might want to get a copy of all installed APKs, in order to decompile and analyse some dodgy ones. Or, at the very least, we’d like to get their SHA256 hashes.

Because MVT requires some preparation and some technical-savviness, we can’t expect all device users to install and familiarize themselves with MVT’s terminal interface in order to gather and send us data. Because of this, I have created a separate utility called AndroidQF (Android Quick Forensics) which replicates some of the modules of MVT, but packaged in portable binary executables available for Linux, Mac and Windows.

Using AndroidQF is rather straightforward: the user should launch it, and then pick an option when prompted with multiple choices. All results will be stored in a UUID-named folder at the same path as the binary executable. We can then request to have the folder sent to us in our preferred way. Keep in mind tho: downloading all APKs will inevitably result in a rather large upload.

Screenshot of AndroidQF

As a bonus feature, when the acquisition is completed we can have AndroidQF zip up and encrypt the newly-created results folder using age. All we need to do is place a “key.txt” file containing our age public key in the same folder of the executable. AndroidQF will recognise the presence of the key, attempt the encryption, and delete the original unencrypted folder.

For further instructions, check out the AndroidQF README. Please note: AndroidQF is still in a preliminary state, and hasn’t been extensively tested in the field. Bugs may occur and some features (such as proper packaging of a Mac app bundle) are still missing. So, contributions are welcome.