• Deutsch
  • English
  • Deutsch
  • English
  • Home
  • Blog
  • UFADE

    • Was ist UFADE?
    • Installation
    • Geräte verbinden
    • Navigation
    • Reporting
    • Extraktion
    • Logging
    • Entwickleroptionen
    • Erweiterte Optionen
    • Datenoperationen
  • Testpoints
  • Rechtliches

Ich könnte es dir beschreiben ... ALEAPP Live Data Aufbereitung

Andro-las


In den Zeiten der dateibasierten Verschlüsselungen sind vollständige Dateisystemextraktionen der Goldstandard einer Datenbasis für die Analyse von mobilen Endgeräten.

App- und System-Daten, Logs, Medien und idealerweise noch die Keychain erlauben eine vollumfängliche Analyse eines Android-Smartphones (Multi-User Szenarien klammern wir bei dieser Betrachtung einmal aus).

Was aber, wenn für ein aktuelles Gerät trotz bekannter Zugangsdaten derzeit keine Dateisystemsicherung verfügbar ist? Seit jeher liefern sich die Android/iOS-Entwickler und Anbieter von Forensik-Software ein Katz-und-Maus-Spiel. Häufig vergeht eine gewisse Zeit, bis für ein neues Modell ein "FFS" angeboten wird.

Viele kommerzielle Tools bieten für diese Fälle eine "erweiterte logische Sicherung" an. Also eine Sammlung der Daten, die das Gerät freiwillig preisgibt. Diese Sicherung ist meist weit weniger umfangreich und beinhaltet z.B. nur einen Bruchteil der verfügbaren App-Daten. Dennoch kann je nach Zielsetzung der Untersuchung auch diese Art der Extraktion ihre Berechtigung haben. Meine eigene Abwandlung einer erweiterten logischen Sicherung für UFADE und ALEX habe ich übrigens PRFS ("Partially Restored File System") getauft.

Über den Umfang tatsächlich verfügbarer Dateien (als Kopie aus dem Gerätedateisystem) hinaus, bietet Android einige Boardmittel, über die sich relevante Informationen vom System abfragen lassen, ohne dass die Quelldateien direkt abrufbar sind. Das Bash-Tool Android Triage von Mattia Epifani automatisiert einige dieser Abfragen und bietet dabei eine Dialog-basierte Oberfläche für die Kommandozeile. Dieses Script stand auch Pate für einige der Funktionen, die ich in ALEX integriert habe.

So beinhaltet ein PRFS Backup eines Android-Geräts (in der Default Einstellung) neben dem Nutzer zugänglichen Dateien (Ordner "Dump") auch live abgefragte Inhalte (Ordner "Extra"), die so nicht im Dateisystem zu finden sind. Aktuell werden dabei die folgenden ADB Befehle genutzt:

BefehlDatei in der Sicherung
adb shell logcat -d -b all -v epochextra\logcat.txt
adb shell dumpsysextra\dumpsys_{unix_timestamp}.txt
adb shell appops get {app}extra\app_ops.json
adb shell content query --uri content://{key}extra\content_provider\*

Beabsichtigt ist natürlich, dass diese Befehle als Debugging-Hilfen zur Laufzeit genutzt werden. Im Rahmen der PRFS-Sicherung ist aber eine spätere Analyse vorgesehen. Eine Hürde dabei: relative Zeitstempel.

Zeit ist relativ

Über ALEX werden bei der Abfrage der App Ops (später mehr) bereits absolute Zeitstempel erfasst. Dies geschieht unter Abfrage der Gerätezeit (adb shell date +%s) und liefert entsprechend "nur" eine sekundengenaue Darstellung. Über den Zusatz "-v epoch" beinhalten die Logcat-Einträge ebenfalls bereits UNIX-Timestamps. Anders sieht es bei den Dumpsys Einträgen aus. Hier unterscheidet sich die Darstellung zudem bei verschiedenen Android-Versionen. Um auch hier eine Zeitbasis für eine spätere Analyse zu schaffen, wird der (Geräte-)Zeitstempel der Abfrage mit im Dateinamen des Dumpsys-Outputs festgehalten.

Aufbereitung

Da kommerzielle Analysetools aktuell nur wenig mit den Live-Daten einer ALEX-Extraktion anfangen können, habe ich einen Parser für das wahrscheinlich umfangreichste Open Source Android-Analyseframework ALEAPP erstellt und plane diesen regelmäßig zu aktualisieren.

ALEAPP ALEX Options

Zum Teil sind die Live-Informationen bereits gut lesbar strukturiert und werden über ALEAPP nur noch durchsuchbar dargestellt. Andere Inhalte benötigten jedoch ein wenig Recherchearbeit. Die bisher verfügbaren Aufbereitungen sollen folgend kurz vorgestellt werden:

App Ops

Hier wird festgehalten, welche App oder Systemkomponente welche Berechtigung wann erhalten hat oder wann ihr diese verweigert wurde. In einer Dateisystemsicherung wären diese Informationen unter /system/appops.xml zu finden.

ALEAPP App Ops

Logcat

Die Log-Einträge, die mit Logcat ausgegeben werden reichen maximal bis zum letzten Neustart des Geräts zurück und sollten entsprechend unmittelbar extrahiert werden, wenn hier relevante Informationen vermutet werden. Hier sind z.T. Benachrichtigungen zu finen, die dem Nutzer angezeigt werden oder allgemein Hinweise über die Dauer der Nutzung von Anwendungen.

ALEAPP Logcat

Dumpsys

Über Dumpsys lassen sich zahlreiche relevante Informationen abrufen, für die sonst eine Dateisystemsicherung erforderlich wäre. Die bisher erstellten Parser-Funktionen erheben keinen Anspruch auf Vollständigkeit. Dies könnte ein ausgezeichnetes Thema für eine wissenschaftliche Ausarbeitung sein, falls hier noch jemand auf der Suche ist.

Usagestats (Events)

Usagestats Events

Ob eine App in den Vordergrund geholt oder beendet wurde, wird unter dem Service Usagestats erfasst.

Usagestats (Yearly)

Usagestats Yearly

Die Jahreswerte der Nutzungszeiten von Apps lassen Rückschlüsse auf besonders relevante Anwendungen zu.

Role (default apps)

default apps

Unter "Role" werden Standardanwendungen z.B. für Mail, Telefonie oder Browsing erfasst.

Configured Networks

Configured Networks

"Configured Networks" werden wenigstens mit der SSID angegeben. Welche Informationen darüe hinaus verfügbar sind, hängt stark von der Android-Version ab.

Accounts

Accounts

Teilweise finden sich hier neben dem Google-Konto auch User-IDs zu Chat und Social-Media Accounts.

BTM Bonded Devices

Bluetooth

Diese Informationen sind nur verfügbar, wenn bei der Abfrage des Service Bluetooth am Gerät aktiv war. Ob MAC-Adressen vollständig ausgegeben werden ist wieder Versions-/Hersteller-abhängig.

Companiondevice

Watch

Der Companiondevice Service scheint nur bei aktuelleren Android-Versionen verfügbar zu sein. Hier findet sich z.B. eine gekoppelte Smartwatch und die dazugehörige App.

Dumpsys - Batterystats

Die Batterystats sind zuletzt hinzugekommen und erforderten ein wenig mehr an Einarbeitung. Daher möchte ich hierauf ein wenig genauer eingehen.

Batterystats

Zunächst konnten zwei verschiedene Zeitdarstellungen beobachtet werden. Ältere Android Versionen (4-14) zeigten ein relatives Zeitformat:

DUMP OF SERVICE batterystats:
Battery History (98% used, 4039KB used of 4096KB, 320 strings using 32KB):
                    0 (14) TIME: 2025-12-16-15-26-57
                    0 (2) 070 c0200040 status=discharging health=good ...
               +212ms (1) 070 80200040 -wake_lock
...
    +3d01h15m11s323ms (2) 043 80000020 +running wake_reason=0:"179 SPM"
...

Mit TIME: wird ein Referenzpunkt angegeben, von dem aus dann relativ weitergezählt wird (Angabe in Tagen, Stunden, Minuten, Sekunden und Millisekunden)

Daneben wurde auf einem Android 16 Gerät ein neues Zeitformat mit absoluten Angaben (jedoch ohne Jahreszahl) verwendet:

DUMP OF SERVICE batterystats:
Battery History [Format: 2] (101% used, 4156KB used of 4096KB, 11476 strings using 689KB):
  03-17 09:59:37.666 076 80001a18 status=discharging health=good ...
  03-17 09:59:37.711 076 02001a18 -running +mobile_radio -cellular_high_tx_power
  03-17 09:59:38.536 076 82001a18 +running wake_reason=0:"335 cp2ap_wakeup"
...

Da die Erfassungszeit im Dateinamen festgehalten wurde und Einträge nicht älter als ein Jahr sind (je nach Nutzung wenige Tage bis Wochen, in Ausnahmen Monate). Konnte schlicht festgehalten werden, dass Einträge, die vor dem Erfassungszeitpunkt liegen dem aktuellen Jahr zuzuordnen sind und Einträge, die schinbar in der Zukunft liegen aus dem vorangegangenen Jahr stammen müssen.

Darüber hinaus fanden sich Untimmigkeiten im alten Format. Bei einigen Geräten lagen die letzten Einträge scheinbar Monate zurück, obwohl die Sicherung erst wenige Minuten zuvor erfolgt war. Es stellte sich heraus, dass nach jedem Neustart des Gerätes ein neuer TIME: Referenzzeitpunkt erstellt wurde, die relative Zeitangabe aber unbeirrt weiterzählte, als sei zwischen Herunterfahren und Neustart des Geräts keine Zeit vergangen. Nach der Ergänzung eines Offsets für solche Neustart-Events ließen sich die Zeiten bis zur Sicherung lückenlos nachvollziehen.

Der Zeitangabe folgt der Ladezustand des Akkus. So steht 076 für eine Akkuladung von 76%.

Die folgende Hexadezimal-Angabe ist das eigentliche Kernstück der Batterystats, da sich hieraus diverse Gerätezustände ableiten lassen. Hierbei handelt es sich um die Hexadezimaldarstellung einer Bitmaske.

80001a18
binär1 0 0 0 0 0 0 00 0 0 0 0 0 0 00 0 0 1 1 0 1 00 0 0 1 1 0 0 0

Für die Bestimmung der STATE Einträge sind die vorderen 16 Bit der Maske entscheidend:

31302928272625242322212019181716
binär1000000000000000

Die folgenden 16 Bit betreffen Statusänderungen.

Die Zuordnung der STATE-Einträge zu den einzelnen Statusbits kann direkt aus dem Android-Sourcecode (BatteryStats.java) abgeleitet werden:

		public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
        public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
        public static final int STATE_GPS_ON_FLAG = 1<<29;
        public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
        public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
        public static final int STATE_WIFI_RADIO_ACTIVE_FLAG = 1<<26;
        public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
        private static final int STATE_RESERVED_0 = 1<<24;
        public static final int STATE_SENSOR_ON_FLAG = 1<<23;
        public static final int STATE_AUDIO_ON_FLAG = 1<<22;
        public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
        public static final int STATE_SCREEN_ON_FLAG = 1<<20;       // consider moving to states2
        public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19; // consider moving to states2
        public static final int STATE_SCREEN_DOZE_FLAG = 1 << 18;
        // empty slot
        public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<16;

Das Beispiel 80001a18 kurz nach dem Gerätestart zeigt demnach nur auf, dass die CPU aktuell aktiv ist.

Natürlich hat sich diese Zuordnung im Laufe der Zeit entwickelt und verschiedene Android-Versionen nutzen eine leicht abgewandelte Zuordnung der Batterystats. Daher habe ich im Rahmen der Recherche über ein Skript die STATE-Flags der verschiedenen Android-Haptversionen extrahiert, gegenübergestellt und das folgende Dictionary angelegt, über das ein Mapping erfolgen kann:

BitAndroid 4Android 5Android 6 - 8Android 9 und darüber
31CPU_RUNNINGCPU_RUNNINGCPU_RUNNING
30WAKE_LOCKWAKE_LOCKWAKE_LOCKWAKE_LOCK
29SENSOR_ONGPS_ONGPS_ONGPS_ON
28GPS_ONWIFI_FULL_LOCKWIFI_FULL_LOCKWIFI_FULL_LOCK
27PHONE_SCANNINGWIFI_SCANWIFI_SCANWIFI_SCAN
26WIFI_RUNNINGWIFI_MULTICAST_ONWIFI_RADIO_ACTIVEWIFI_RADIO_ACTIVE
25WIFI_FULL_LOCKMOBILE_RADIO_ACTIVEMOBILE_RADIO_ACTIVEMOBILE_RADIO_ACTIVE
24WIFI_SCAN_LOCK
23WIFI_MULTICAST_ONSENSOR_ONSENSOR_ONSENSOR_ON
22AUDIO_ONAUDIO_ONAUDIO_ONAUDIO_ON
21VIDEO_ONVIDEO_ONVIDEO_ONVIDEO_ON
20SCREEN_ONSCREEN_ONSCREEN_ONSCREEN_ON
19BATTERY_PLUGGEDBATTERY_PLUGGEDBATTERY_PLUGGEDBATTERY_PLUGGED
18PHONE_IN_CALLPHONE_IN_CALLSCREEN_DOZE
17WIFI_ON
16BLUETOOTH_ONBLUETOOTH_ONWIFI_MULTICAST_ONWIFI_MULTICAST_ON

Zusammengefasst: Bis Android 3 konnten die Batterystats STATE Einträge in dieser Form nicht vorgefunden werden. Von Version 4 über 5 und 6 fanden Änderungen an der Zuordnung statt, die bis Android 9 Bestand hatten. Aktuell findet noch immer das Schema Anwendung, welches mit Android 9 eingeführt wurde. In den Batterystats selbst findet sich der Hinweis auf die verwendete Android-Version übrigens nicht. Passenderweise wird diese Information aber ebenfalls von ALEX in einem PRFS Backup vorgehalten.

Für die batterystats-daily.xml einer Full Filesystem Sicherung hat kürzlich Marco Neumann einen ALEAPP-Parser gebaut. In seinem Code fand ich den Hinweis auf die Definitionen im Android Sourcecode.

Ich werde wohl noch eine ganze Weile beschäftigt sein, ALEAPP den Output von ALEX schmackhaft zu machen. Mit den Contentprovider-Daten habe ich noch gar nicht angefangen und auch Dumpsys beinhaltet noch Informationen, die bisher keine Berücksichtigung fanden.

Über Hinweise oder Anregungen zu den Parsern freue ich mich auf den einschlägigen Kanälen.