Refactor SMS ADB code to use backup functions

This commit is contained in:
Donncha Ó Cearbhaill 2022-03-04 17:06:10 +01:00
parent b44c67e699
commit be511dcb51
3 changed files with 31 additions and 30 deletions

View File

@ -19,6 +19,7 @@ from adb_shell.exceptions import (AdbCommandFailureException, DeviceAuthError,
from usb1 import USBErrorAccess, USBErrorBusy
from mvt.common.module import InsufficientPrivileges, MVTModule
from mvt.android.parsers.backup import parse_ab_header, parse_backup_file
log = logging.getLogger(__name__)
@ -243,6 +244,33 @@ class AndroidExtraction(MVTModule):
# Disconnect from the device.
self._adb_disconnect()
def _generate_backup(package_name):
# Run ADB command to create a backup of SMS app
self.log.warning("Please check phone and accept Android backup prompt. You may need to set a backup password. \a")
# Run ADB command to create a backup of SMS app
# TODO: Base64 encoding as temporary fix to avoid byte-mangling over the shell transport...
backup_output_b64 = self._adb_command("/system/bin/bu backup -nocompress '{}' | base64".format(package_name))
backup_output = base64.b64decode(backup_output_b64)
header = parse_ab_header(backup_output)
if not header["backup"]:
self.log.error("Extracting SMS via Android backup failed. No valid backup data found.")
return
if header["encryption"] == "none":
return parse_backup_file(backup_output, password=None)
# Backup encrypted. Request password from user.
while password_retry in range(0, 3):
backup_password = getpass.getpass(prompt="Backup Password: ", stream=None)
try:
decrypted_backup_tar = parse_backup_file(backup_output, backup_password)
return decrypted_backup_tar
except InvalidBackupPassword:
self.log.info("Invalid backup password")
self.log.warn("All attempts to decrypt backup with password failed!")
def run(self):
"""Run the main procedure."""
raise NotImplementedError

View File

@ -10,7 +10,7 @@ import base64
import getpass
from mvt.common.utils import check_for_links, convert_timestamp_to_iso
from mvt.android.parsers.backup import parse_ab_header, parse_sms_backup, InvalidBackupPassword, AndroidBackupParsingError
from mvt.android.parsers.backup import parse_tar_for_sms, AndroidBackupParsingError
from mvt.common.module import InsufficientPrivileges
from .base import AndroidExtraction
@ -116,28 +116,9 @@ class SMS(AndroidExtraction):
It is crucial to use the under-documented "-nocompress" flag to disable the non-standard Java compression
algorithim. This module only supports an unencrypted ADB backup.
"""
# Run ADB command to create a backup of SMS app
self.log.warning("Please check phone and accept Android backup prompt. Do not set an encryption password. \a")
# Run ADB command to create a backup of SMS app
# TODO: Base64 encoding as temporary fix to avoid byte-mangling over the shell transport...
backup_output_b64 = self._adb_command("/system/bin/bu backup -nocompress com.android.providers.telephony | base64")
backup_output = base64.b64decode(backup_output_b64)
header = parse_ab_header(backup_output)
if not header["backup"]:
self.log.error("Extracting SMS via Android backup failed. No valid backup data found.")
return
pwd = None
if header["encryption"] != "none":
pwd = getpass.getpass(prompt="Backup Password: ", stream=None)
backup_tar = self._generate_backup("com.android.providers.telephony")
try:
self.results = parse_sms_backup(backup_output, password=pwd)
except InvalidBackupPassword:
self.log.info("Invalid backup password")
return
self.results = parse_tar_for_sms(backup_tar)
except AndroidBackupParsingError:
self.log.info("Impossible to read SMS from the Android Backup, please extract the SMS and try extracting it with Android Backup Extractor")
return

View File

@ -42,14 +42,6 @@ def to_utf8_bytes(input_bytes):
return bytes(output)
def parse_sms_backup(data, password=None):
"""
Parse a backup file and returns SMS in it
"""
tardata = parse_backup_file(data, password=password)
return parse_tar_for_sms(tardata)
def parse_ab_header(data):
"""
Parse the header of an Android Backup file