Logo del progetto fl3xbl0w

Backup dei contenuti della tua Console - fl3xbl0w

Pubblicato il 28 mag 2022

Progetto di ingegneria inversa. È iniziato con il tapis roulant Bowflex Treadmill 22 ma si è poi generalizzato per qualsiasi macchina con Android venduta da Nautilus Inc. (Nautilus, Bowflex, Schwinn).

Dopo essere stato liberato da AppMonitorService (o dopo aver ricevuto qualsiasi aggiornamento OTA), la prima cosa da fare è eseguire il backup del maggior numero possibile di dati.

Assicurati di essere già connesso alla console:

> adb connect <Indirizzo IP della Console>

Backup dei contenuti di /sdcard

Potrebbe contenere alcuni file necessari affinché la macchina funzioni correttamente dopo un ripristino alle impostazioni di fabbrica (principalmente nelle cartelle /sdcard/Android e /sdcard/Nautilus). Faremo il backup di tutto con:

> adb pull /sdcard/ .

Backup degli APK

Prima, ottieni l’elenco di tutti i pacchetti installati sulla Console (solo per avere un riferimento):

> adb shell pm list packages -f

Appariranno nel seguente formato: package:<posizione dell'APK>=<nome del pacchetto>

Dovrai trovare le applicazioni che vuoi eseguire il backup. NON TUTTE LE APPLICAZIONI SONO NECESSARIE, la maggior parte sono applicazioni standard di Android, quindi cercheremo solo “applicazioni non standard” usando alcuni filtri:

> adb shell pm list packages -f | grep -wviE 'com.android|com.google|framework-res|/vendor/overlay'

Potrai vedere registrazioni di applicazioni di com.nautilus, com.redbend, com.netflix, com.amazon, com.disney e forse alcune altre in futuro. Vorremo eseguire il backup di tutto ciò che vediamo in quella lista (ID unici nascosti, usa i tuoi risultati):

> adb shell pm list packages -f | grep -wviE 'com.android|com.google|framework-res|/vendor/overlay'
package:/data/app/com.nautilus.sbctest-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.sbctest
package:/data/app/com.redbend.client-XXXXXXXXXXXXXXXX/base.apk=com.redbend.client
package:/data/app/com.nautilus.nlssbcsystemsettings-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.nlssbcsystemsettings
package:/system/priv-app/RBDualPartService/RBDualPartService.apk=com.redbend.dualpart.service.app
package:/data/app/com.netflix.mediaclient-XXXXXXXXXXXXXXXX/base.apk=com.netflix.mediaclient
package:/data/app/com.nautilus.nautiluslauncher-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.nautiluslauncher
package:/data/app/com.amazon.avod.thirdpartyclient-XXXXXXXXXXXXXXXX/base.apk=com.amazon.avod.thirdpartyclient
package:/data/app/com.nautilus.sbc_demo_app-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.sbc_demo_app
package:/data/app/com.nautilus.UtilityApp-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.UtilityApp
package:/data/app/com.nautilus.g4assetmanager-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.g4assetmanager
package:/data/app/com.nautilus.platform_hardwaretest-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.platform_hardwaretest
package:/data/app/com.nautilus.webviewer-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.webviewer
package:/data/app/com.nautilus.bowflex.usb-XXXXXXXXXXXXXXXX/base.apk=com.nautilus.bowflex.usb
package:/data/app/com.disney.disneyplus-XXXXXXXXXXXXXXXX/base.apk=com.disney.disneyplus

NOTA: com.redbend.dualpart.service.app proviene da /system/priv-app/, il che significa che rimarrà installato anche dopo un ripristino alle impostazioni di fabbrica. Possiamo comunque eseguire il backup se sei interessato al reverse engineering delle applicazioni.

Prendiamo come esempio Disney Plus (ID unico nascosto)

package:/data/app/com.disney.disneyplus-XXXXXXXXXXXXXXXX/base.apk=com.disney.disneyplus

Quella linea, basata sul formato che ho menzionato, sarebbe:

Posizione del pacchetto: /data/app/com.disney.disneyplus-XXXXXXXXXXXXXXXX/base.apk
Nome del pacchetto: com.disney.disneyplus

Cercheremo quale versione dell’applicazione abbiamo con queste informazioni. Usiamo il Nome del pacchetto che abbiamo appena identificato ed eseguiamo:

> adb shell dumpsys package com.disney.disneyplus | grep versionName

Nel mio caso, ho ricevuto:

> adb shell dumpsys package com.disney.disneyplus | grep versionName
    versionName=2.4.2-rc2

Ora, per creare un backup per il pacchetto di Disney Plus, la procedura sarebbe:

> adb pull /data/app/com.disney.disneyplus-XXXXXXXXXXXXXXXX/base.apk .

Subito dopo che finisce, vai al tuo File Explorer e rinomina il file base.apk appena eseguito il backup in com.disney.disneyplus-2.4.2-rc2.apk.

Il formato che suggerisco per gli APK, dato quell’esempio, è: <Nome del pacchetto>-<versione>.apk

Ora ripeti il processo per il resto delle applicazioni.

Backup dei Dati delle App

Sembra essere in grado di eseguire il backup di alcuni (non sono sicuro se tutti) i dati delle applicazioni.

Tieni presente che non tutte le applicazioni installate generano dati delle applicazioni, o noi, come utente shell, potremmo non avere i permessi per eseguire il backup di tutto.

Crea un backup completo di tutte le applicazioni installate dall’utente:

> adb backup -f appdata.adb -all -noapk -nosystem

In alternativa, puoi ottenere lo stesso risultato con un comando alternativo:

> adb shell 'bu backup -all -noapk -nosystem' > appdata.adb

Entrambi i comandi richiederanno una “conferma sullo schermo” che vuoi eseguire il backup. Tocca “BACK UP MY DATA”:

schermata di conferma del backup

Se vuoi estrarre i contenuti (su Linux, macOS), avrai bisogno di zlib-flate da qpdf ed eseguire:

> dd if=appdata.adb bs=24 skip=1 | zlib-flate -uncompress | tar xf -

Ci sono alcuni dati affascinanti per com.nautilus.bowflex.usb. Ci sono informazioni personali identificabili (PII) all’interno, quindi assicurati di controllare attentamente quali file condividi.

Questi metodi di backup ed estrazione provengono da questo Gist. Ho testato solo i metodi di backup elencati lì, che sono sicuri per giocare. Se giochi con il Ripristino del Gist, sei da solo. Facci sapere se funziona!

Script

Ho sviluppato uno script rapido e sporco in Python per eseguire il backup di alcuni contenuti (per ora non include AppData). Testato solo su macOS con android-platform-tools installato tramite brew. Leggi lo script e assicurati che abbia senso per te prima di eseguirlo.

import sys
import os
import subprocess
from datetime import datetime

# verifica se è stato fornito un argomento
if len(sys.argv) != 2:
    print("Uso: python3 dump.py <Indirizzo IP della Console>")
    sys.exit(1)

ipaddr = sys.argv[1]

# verifica se adb è disponibile per shell
adb_path = subprocess.check_output(["which", "adb"]).decode("utf-8").strip()
if not os.path.exists(adb_path):
    print("adb non trovato")
    exit()

# configurare cartella di backup con data e ora attuali
dump_folder = os.path.join(
    os.environ["HOME"],
    "Desktop",
    "nautilus_dump",
    "{}".format(datetime.now().strftime("%Y-%m-%d_%H-%M-%S")),
)
if not os.path.exists(dump_folder):
    os.makedirs(dump_folder)

# connettere adb
print("Connettendo a {}...".format(ipaddr))
subprocess.call(["adb connect {}".format(ipaddr)], shell=True)

# eseguire backup contenuto di /sdcard
print("Eseguendo backup contenuto di /sdcard...")
subprocess.call(["adb pull /sdcard/ {}".format(dump_folder)], shell=True)

# ottenere informazioni APK
print("Eseguendo backup degli APK...")
packages = (
    subprocess.check_output(["adb shell pm list packages -f"], shell=True)
    .decode("utf-8")
    .split("\n")
)

# filtrare righe vuote
packages = [x for x in packages if x.strip()]

# filtrare righe che contengono "com.android", "com.google", "framework-res"
packages = [package for package in packages if package.find("com.android") == -1]
packages = [package for package in packages if package.find("com.google") == -1]
packages = [package for package in packages if package.find("framework-res") == -1]

print("Trovati {} APK".format(len(packages)))

for package in packages:
    package_name = package.split("=")
    package_name = package_name[len(package_name) - 1].strip()
    package_version = (
        subprocess.check_output(
            ["adb shell dumpsys package {} | grep versionName".format(package_name)],
            shell=True,
        )
        .decode("utf-8")
        .split("=")[1]
        .strip()
    )

    package_path = package.split(":")[1].split(".apk=")[0].strip()
    package_path = "{}.apk".format(package_path)
    print("Eseguendo backup di {} v{}...".format(package_name, package_version))

    subprocess.call(["adb pull {} {}".format(package_path, dump_folder)], shell=True)

    os.rename(
        os.path.join(dump_folder, os.path.basename(package_path)),
        os.path.join(dump_folder, "{}-{}.apk".format(package_name, package_version)),
    )

# eseguire backup appdata
print("Eseguendo backup di appdata.adb ...")
print('TOCCA IL PULSANTE "BACK UP MY DATA" SULLO SCHERMO ORA!!!')
subprocess.call(
    ["adb backup -f {}/appdata.adb -all -noapk -nosystem".format(dump_folder)],
    shell=True,
)

# disconnettere adb
print("Disconnettendo...")
subprocess.check_output(["adb disconnect"], shell=True)
Contenuto tradotto da gpt-4-1106-preview

©2022-2024 Sebastián Barrenechea. Tutti i diritti riservati.

Costruito con Astro v4.15.9.