Пример #1
0
def get_discreteNative(files_found, report_folder, seeker, wrap_text):
    data_list = []
    for file_found in files_found:
        file_found = str(file_found)
        
            
        #check if file is abx
        if (checkabx(file_found)):
            multi_root = False
            tree = abxread(file_found, multi_root)
        else:
            tree = ET.parse(file_found)
        root = tree.getroot()
    
        for elem in root:
            for subelem1 in elem:
                ptag = subelem1.tag
                ptagattrib = subelem1.attrib
                ptagattrib = ptagattrib["pn"]
                for subelem2 in subelem1:
                    otag = subelem2.tag
                    otagattrib = subelem2.attrib
                    otagattrib = otagattrib['op']
                    for subelem3 in subelem2:
                        atag = subelem3.tag
                        atagattrib = subelem3.attrib
                        atagattrib = atagattrib.get('at', '')
                        
                        for subelem4 in subelem3:
                            etag = subelem4.tag
                            etagattrib = subelem4.attrib
                            ntattrib = etagattrib.get('nt')
                            ndattrib = etagattrib.get('nd')
                            if ndattrib is None:
                                ndattrib = ''
                            else:
                                ndattrib = round(int(ndattrib) / 60, 1)
                    data_list.append((timestampcalc(ntattrib), ptagattrib, atagattrib, oplist(otagattrib), ndattrib))
                    
    if data_list:
        report = ArtifactHtmlReport('Privacy Dashboard')
        report.start_artifact_report(report_folder, 'Privacy Dashboard')
        report.add_script()
        data_headers = ('Timestamp', 'Bundle', 'Module', 'Operation', 'Usage in Seconds')
        report.write_artifact_data_table(data_headers, data_list, file_found)
        report.end_artifact_report()
        
        tsvname = f'Privacy Dashboard'
        tsv(report_folder, data_headers, data_list, tsvname)
        
        tlactivity = f'Privacy Dashboard'
        timeline(report_folder, tlactivity, data_list, data_headers)
    else:
        logfunc('No Privacy Dashboard data available')
Пример #2
0
def get_appopSetupWiz(files_found, report_folder, seeker, wrap_text):

    for file_found in files_found:
        file_found = str(file_found)
        if not file_found.endswith('appops.xml'):
            continue # Skip all other files
        
        data_list = []
        #check if file is abx
        if (checkabx(file_found)):
            multi_root = False
            tree = abxread(file_found, multi_root)
        else:
            tree = ET.parse(file_found)
        root = tree.getroot()
        
        for elem in root.iter('pkg'):
            if elem.attrib['n'] == 'com.google.android.setupwizard':
                pkg = elem.attrib['n']
                for subelem in elem:
                    #print(subelem.attrib)
                    for subelem2 in subelem:
                        #print(subelem2.attrib)
                        for subelem3 in subelem2:
                            test = subelem3.attrib.get('t', 0)
                            if int(test) > 0:
                                timestamp = (datetime.datetime.fromtimestamp(int(subelem3.attrib['t'])/1000).strftime('%Y-%m-%d %H:%M:%S'))
                            else:
                                timestamp = ''
                            data_list.append((timestamp, pkg))
        if data_list:
            report = ArtifactHtmlReport('Appops.xml Setup Wizard')
            report.start_artifact_report(report_folder, 'Appops.xml Setup Wizard')
            report.add_script()
            data_headers = ('Timestamp','Package')
            report.write_artifact_data_table(data_headers, data_list, file_found)
            report.end_artifact_report()
            
            tsvname = f'Appops Setup Wizard data'
            tsv(report_folder, data_headers, data_list, tsvname)
            
            tlactivity = f'Appops Setup Wizard data'
            timeline(report_folder, tlactivity, data_list, data_headers)
        else:
            logfunc('No Appops Setup Wizard data available')
Пример #3
0
def process_ssecure(file_path, uid, report_folder):

    if (checkabx(file_path)):
        multi_root = True
        tree = abxread(file_path, multi_root)
        root = tree.getroot()
    else:
        try:
            tree = ET.parse(file_path)
            root = tree.getroot()
        except ET.ParseError:  # Fix for android 11 invalid XML file (no root element present)
            with open(file_path) as f:
                xml = f.read()
                root = ET.fromstring(
                    re.sub(r"(<\?xml[^>]+\?>)", r"\1<root>", xml) + "</root>")

    data_list = []
    for setting in root.iter('setting'):
        nme = setting.get('name')
        val = setting.get('value')
        if nme == 'bluetooth_name':
            data_list.append((nme, val))
            logdevinfo(f"Bluetooth name: {val}")
        elif nme == 'mock_location':
            data_list.append((nme, val))
        elif nme == 'android_id':
            data_list.append((nme, val))
        elif nme == 'bluetooth_address':
            data_list.append((nme, val))
            logdevinfo(f"Bluetooth address: {val}")

    if len(data_list) > 0:
        report = ArtifactHtmlReport('Settings Secure')
        report.start_artifact_report(report_folder, f'Settings_Secure_{uid}')
        report.add_script()
        data_headers = ('Name', 'Value')
        report.write_artifact_data_table(data_headers, data_list, file_path)
        report.end_artifact_report()

        tsvname = f'settings secure'
        tsv(report_folder, data_headers, data_list, tsvname)
    else:
        logfunc('No Settings Secure data available')
Пример #4
0
def get_wifiConfigstore(files_found, report_folder, seeker, wrap_text):
    data_list = []
    for file_found in files_found:
        file_found = str(file_found)
        if file_found.endswith('WifiConfigStore.xml'):

            #check if file is abx
            if (checkabx(file_found)):
                multi_root = False
                tree = abxread(file_found, multi_root)
            else:
                tree = ET.parse(file_found)
            root = tree.getroot()

            for elem in root.iter():
                if elem.attrib.get('name') is not None:
                    if elem.text is not None:
                        data_list.append((elem.attrib.get('name'), elem.text))
                    elif elem.attrib.get('value') is not None:
                        data_list.append((elem.attrib.get('name'),
                                          elem.attrib.get('value')))

                    if (elem.attrib.get('name')) == 'RandomizedMacAddress':
                        logdevinfo(f'Randomized MAC Address: {elem.text}')

                    if (elem.attrib.get('name')
                        ) == 'wifi_sta_factory_mac_address':
                        logdevinfo(f'WIFI Factory MAC Address: {elem.text}')

                    if (elem.attrib.get('name')) == 'DefaultGwMacAddress':
                        logdevinfo(f'Default Gw MAC Address: {elem.text}')

                    if (elem.attrib.get('name')) == 'ConfigKey':
                        splitted = elem.text.split('"')
                        logdevinfo(f'Config Key: {splitted[1]}')
                        logdevinfo(f'Protocol: {splitted[2]}')

                    if (elem.attrib.get('name')) == 'SSID':
                        splitted = elem.text.split('"')
                        logdevinfo(f'SSID: {splitted[1]}')

                    if (elem.attrib.get('name')) == 'PreSharedKey':
                        splitted = elem.text.split('"')
                        logdevinfo(f'Pre-Shared Key: {splitted[1]}')

                    if (elem.attrib.get('name')) == 'LastConnectedTime':
                        timestamp = datetime.datetime.fromtimestamp(
                            int(elem.attrib.get("value")) /
                            1000).strftime('%Y-%m-%d %H:%M:%S.%f')
                        logdevinfo(f'WIFI Last Connected Time: {timestamp}')

        if data_list:
            report = ArtifactHtmlReport('Wifi Configuration Store.xml')
            report.start_artifact_report(report_folder,
                                         'Wifi Configuration Store')
            report.add_script()
            data_headers = ('Key', 'Value')
            report.write_artifact_data_table(data_headers, data_list,
                                             file_found)
            report.end_artifact_report()

            tsvname = f'Wifi Configuration Store data'
            tsv(report_folder, data_headers, data_list, tsvname)

            tlactivity = f'Wifi Configuration Store data'
            timeline(report_folder, tlactivity, data_list, data_headers)
        else:
            logfunc('No Wifi Configuration Store data available')
Пример #5
0
def get_permissions(files_found, report_folder, seeker, wrap_text):

    slash = '\\' if is_platform_windows() else '/'

    for file_found in files_found:
        file_found = str(file_found)

        data_list_permission_trees = []
        data_list_permissions = []
        data_list_packages_su = []
        err = 0
        user = ''

        parts = file_found.split(slash)
        if 'mirror' in parts:
            user = '******'

        if user == 'mirror':
            continue
        else:
            try:
                if (checkabx(file_found)):
                    multi_root = False
                    tree = abxread(file_found, multi_root)
                else:
                    tree = ET.parse(file_found)

            except ET.ParseError:
                logfunc('Parse error - Non XML file.')
                err = 1

            if err == 0:
                root = tree.getroot()

                for elem in root:
                    #print('TAG LVL 1 '+ elem.tag, elem.attrib)
                    #role = elem.attrib['name']
                    #print()
                    if elem.tag == 'permission-trees':
                        for subelem in elem:
                            #print(elem.tag +' '+ subelem.tag, subelem.attrib)
                            data_list_permission_trees.append(
                                (subelem.attrib.get('name', ''),
                                 subelem.attrib.get('package', '')))
                    elif elem.tag == 'permissions':
                        for subelem in elem:
                            data_list_permissions.append(
                                (subelem.attrib.get('name', ''),
                                 subelem.attrib.get('package', ''),
                                 subelem.attrib.get('protection', '')))
                            #print(elem.tag +' '+ subelem.tag, subelem.attrib)
                    else:
                        for subelem in elem:
                            if subelem.tag == 'perms':
                                for sub_subelem in subelem:
                                    #print(elem.tag, elem.attrib['name'], sub_subelem.attrib['name'], sub_subelem.attrib['granted'] )

                                    data_list_packages_su.append(
                                        (elem.tag, elem.attrib.get('name', ''),
                                         sub_subelem.attrib.get('name', ''),
                                         sub_subelem.attrib.get('granted',
                                                                '')))

                if len(data_list_permission_trees) > 0:
                    report = ArtifactHtmlReport('Permission Trees')
                    report.start_artifact_report(report_folder,
                                                 f'Permission Trees')
                    report.add_script()
                    data_headers = ('Name', 'Package')
                    report.write_artifact_data_table(
                        data_headers, data_list_permission_trees, file_found)
                    report.end_artifact_report()

                    tsvname = f'Permission Trees'
                    tsv(report_folder, data_headers,
                        data_list_permission_trees, tsvname)

                if len(data_list_permissions) > 0:
                    report = ArtifactHtmlReport('Permissions')
                    report.start_artifact_report(report_folder, f'Permissions')
                    report.add_script()
                    data_headers = ('Name', 'Package', 'Protection')
                    report.write_artifact_data_table(data_headers,
                                                     data_list_permissions,
                                                     file_found)
                    report.end_artifact_report()

                    tsvname = f'Permissions'
                    tsv(report_folder, data_headers, data_list_permissions,
                        tsvname)

                if len(data_list_packages_su) > 0:
                    report = ArtifactHtmlReport('Package and Shared User')
                    report.start_artifact_report(report_folder,
                                                 f'Package and Shared User')
                    report.add_script()
                    data_headers = ('Type', 'Package', 'Permission',
                                    'Granted?')
                    report.write_artifact_data_table(data_headers,
                                                     data_list_packages_su,
                                                     file_found)
                    report.end_artifact_report()

                    tsvname = f'Permissions - Packages and Shared User'
                    tsv(report_folder, data_headers, data_list_packages_su,
                        tsvname)
Пример #6
0
def process_recentactivity(folder, uid, report_folder):

    slash = '\\' if is_platform_windows() else '/'

    db = sqlite3.connect(
        os.path.join(report_folder, 'RecentAct_{}.db'.format(uid)))
    cursor = db.cursor()
    #Create table recent.
    cursor.execute('''
    CREATE TABLE 
    recent(task_id TEXT, effective_uid TEXT, affinity TEXT, real_activity TEXT, first_active_time TEXT, last_active_time TEXT,
    last_time_moved TEXT, calling_package TEXT, user_id TEXT, action TEXT, component TEXT, snap TEXT,recimg TXT, fullat1 TEXT, fullat2 TEXT)
    ''')
    db.commit()
    err = 0
    if report_folder[-1] == slash:
        folder_name = os.path.basename(report_folder[:-1])
    else:
        folder_name = os.path.basename(report_folder)

    for filename in glob.iglob(os.path.join(folder, 'recent_tasks', '**'),
                               recursive=True):
        if os.path.isfile(filename):  # filter dirs
            file_name = os.path.basename(filename)
            #logfunc(filename)
            #logfunc(file_name)
            #numid = file_name.split('_')[0]

            try:
                if (checkabx(filename)):
                    multi_root = False
                    tree = abxread(filename, multi_root)
                else:
                    tree = ET.parse(filename)
            except ET.ParseError:
                logfunc('Parse error - Non XML file? at: ' + filename)
                err = 1
                #print(filename)

            if err == 1:
                err = 0
                continue
            else:
                #tree = ET.parse(filename)
                root = tree.getroot()
                #print('Processed: '+filename)
                for child in root:
                    #All attributes. Get them in using json dump thing
                    fullat1 = json.dumps(root.attrib)
                    task_id = (root.attrib.get('task_id'))
                    effective_uid = (root.attrib.get('effective_uid'))
                    affinity = (root.attrib.get('affinity'))
                    real_activity = (root.attrib.get('real_activity'))
                    first_active_time = (root.attrib.get('first_active_time'))
                    last_active_time = (root.attrib.get('last_active_time'))
                    last_time_moved = (root.attrib.get('last_time_moved'))
                    calling_package = (root.attrib.get('calling_package'))
                    user_id = (root.attrib.get('user_id'))
                    #print(root.attrib.get('task_description_icon_filename'))

                    #All attributes. Get them in using json dump thing
                    fullat2 = json.dumps(child.attrib)
                    action = (child.attrib.get('action'))
                    component = (child.attrib.get('component'))
                    icon_image_path = (
                        root.attrib.get('task_description_icon_filename'))

                    #Snapshot section picture
                    snapshot = task_id + '.jpg'
                    #print(snapshot)

                    #check for image in directories
                    check1 = os.path.join(folder, 'snapshots', snapshot)
                    isit1 = os.path.isfile(check1)
                    if isit1:
                        #copy snaphot image to report folder
                        shutil.copy2(check1, report_folder)
                        #snap = r'./snapshots/' + snapshot
                        snap = snapshot
                    else:
                        snap = 'NO IMAGE'
                    #Recent_images section
                    if icon_image_path is not None:
                        recent_image = os.path.basename(icon_image_path)
                        check2 = os.path.join(folder, 'recent_images',
                                              recent_image)
                        isit2 = os.path.isfile(check2)
                        if isit2:
                            shutil.copy2(check2, report_folder)
                            #recimg = r'./recent_images/' + recent_image
                            recimg = recent_image
                        else:
                            recimg = 'NO IMAGE'
                    else:
                        #check for other files not in the XML - all types
                        check3 = glob.glob(
                            os.path.join(folder, 'recent_images', task_id,
                                         '*.*'))
                        if check3:
                            check3 = check3[0]
                            isit3 = os.path.isfile(check3)
                        else:
                            isit3 = 0

                        if isit3:
                            shutil.copy2(check3, report_folder)
                            recimg = os.path.basename(check3)
                        else:
                            recimg = 'NO IMAGE'
                    #else:
                    #    recimg = 'NO IMAGE'
                    #insert all items in database
                    cursor = db.cursor()
                    datainsert = (
                        task_id,
                        effective_uid,
                        affinity,
                        real_activity,
                        first_active_time,
                        last_active_time,
                        last_time_moved,
                        calling_package,
                        user_id,
                        action,
                        component,
                        snap,
                        recimg,
                        fullat1,
                        fullat2,
                    )
                    cursor.execute(
                        'INSERT INTO recent (task_id, effective_uid, affinity, real_activity, first_active_time, last_active_time, last_time_moved, calling_package, user_id, action, component, snap, recimg, fullat1, fullat2)  VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
                        datainsert)
                    db.commit()

    #Query to create report
    db = sqlite3.connect(
        os.path.join(report_folder, 'RecentAct_{}.db'.format(uid)))
    cursor = db.cursor()

    #Query to create report
    cursor.execute('''
    SELECT 
        task_id as Task_ID, 
        effective_uid as Effective_UID, 
        affinity as Affinity, 
        real_activity as Real_Activity, 
        datetime(first_active_time/1000, 'UNIXEPOCH') as First_Active_Time, 
        datetime(last_active_time/1000, 'UNIXEPOCH') as Last_Active_Time,
        datetime(last_time_moved/1000, 'UNIXEPOCH') as Last_Time_Moved,
        calling_package as Calling_Package, 
        user_id as User_ID, 
        action as Action, 
        component as Component, 
        snap as Snapshot_Image, 
        recimg as Recent_Image
    FROM recent
    ''')
    all_rows = cursor.fetchall()
    colnames = cursor.description

    if len(all_rows) > 0:
        report = ArtifactHtmlReport('Recent Tasks, Snapshots & Images')
        location = os.path.join(folder, 'recent_tasks')
        report.start_artifact_report(report_folder, f'Recent Activity_{uid}',
                                     f'Artifacts located at {location}')
        report.add_script()
        data_headers = ('Key', 'Value')
        image_data_headers = ('Snapshot_Image', 'Recent_Image')

        for row in all_rows:

            if row[2] is None:
                row2 = ''  #'NO DATA'
            else:
                row2 = row[2]

            report.write_minor_header(f'Application: {row2}')

            #do loop for headers
            data_list = []

            for x in range(0, 13):
                if row[x] is None:
                    pass
                else:
                    data_list.append((colnames[x][0], str(row[x])))

            report.write_artifact_data_table(data_headers,
                                             data_list,
                                             folder,
                                             table_id='',
                                             write_total=False,
                                             write_location=False,
                                             cols_repeated_at_bottom=False)

            image_data_row = []
            image_data_list = [image_data_row]

            if row[11] == 'NO IMAGE':
                image_data_row.append('No Image')
            else:
                image_data_row.append(
                    '<a href="{1}/{0}"><img src="{1}/{0}" class="img-fluid z-depth-2 zoom" style="max-height: 400px" title="{0}"></a>'
                    .format(str(row[11]), folder_name))
            if row[12] == 'NO IMAGE':
                image_data_row.append('No Image')
            else:
                image_data_row.append(
                    '<a href="{1}/{0}"><img src="{1}/{0}" class="img-fluid z-depth-2 zoom" style="max-height: 400px" title="{0}"></a>'
                    .format(str(row[12]), folder_name))
            report.write_artifact_data_table(image_data_headers,
                                             image_data_list,
                                             folder,
                                             table_id='',
                                             table_style="width: auto",
                                             write_total=False,
                                             write_location=False,
                                             html_escape=False,
                                             cols_repeated_at_bottom=False)
            report.write_raw_html('<br />')

        report.end_artifact_report()
Пример #7
0
def get_package_info(files_found, report_folder, seeker, wrap_text):
    packages = []
    for file_found in files_found:
        file_found = str(file_found)
        if file_found.find('{0}mirror{0}'.format(slash)) >= 0:
            # Skip sbin/.magisk/mirror/data/.. , it should be duplicate data
            continue
        elif os.path.isdir(
                file_found):  # skip folders (there shouldn't be any)
            continue

        file_name = os.path.basename(file_found)
        if (checkabx(file_found)):
            multi_root = False
            tree = abxread(file_found, multi_root)
            xlmstring = (etree.tostring(tree.getroot()).decode())
            doc = xmltodict.parse(xlmstring)
        else:
            with open(file_found) as fd:
                doc = xmltodict.parse(fd.read())

        package_dict = doc.get('packages', {}).get('package', {})
        for package in package_dict:
            name = package.get('@name', '')
            ft = ReadUnixTimeMs(package.get('@ft', None))
            it = ReadUnixTimeMs(package.get('@it', None))
            ut = ReadUnixTimeMs(package.get('@ut', None))
            install_originator = package.get('@installOriginator', '')
            installer = package.get('@installer', '')
            code_path = package.get('@codePath', '')
            public_flags = hex(
                int(package.get('@publicFlags', 0)) & (2**32 - 1))
            private_flags = hex(
                int(package.get('@privateFlags', 0)) & (2**32 - 1))
            package = Package(name, ft, it, ut, install_originator, installer,
                              code_path, public_flags, private_flags)
            packages.append(package)

        if len(packages):
            break

    if report_folder[-1] == slash:
        folder_name = os.path.basename(report_folder[:-1])
    else:
        folder_name = os.path.basename(report_folder)
    entries = len(packages)
    if entries > 0:
        description = "All packages (user installed, oem installed and system) appear here. Many of these are not user apps"
        report = ArtifactHtmlReport('Packages')
        report.start_artifact_report(report_folder, 'Packages', description)
        report.add_script()
        data_headers = ('ft', 'Name', 'Install Time', 'Update Time',
                        'Install Originator', 'Installer', 'Code Path',
                        'Public Flags', 'Private Flags')
        data_list = []
        for p in packages:
            data_list.append((p.ft, p.name, p.install_time, p.update_time,
                              p.install_originator, p.installer, p.code_path,
                              p.public_flags, p.private_flags))

        report.write_artifact_data_table(data_headers, data_list, file_found)
        report.end_artifact_report()

        tsvname = f'Packages'
        tsv(report_folder, data_headers, data_list, tsvname)

        tlactivity = f'Packages'
        timeline(report_folder, tlactivity, data_list, data_headers)
    else:
        logfunc('No package data available')
Пример #8
0
def get_appops(files_found, report_folder, seeker, wrap_text):

    for file_found in files_found:
        file_found = str(file_found)
        if not file_found.endswith('appops.xml'):
            continue # Skip all other files
        
        data_list = []
        #check if file is abx
        if (checkabx(file_found)):
            multi_root = False
            tree = abxread(file_found, multi_root)
        else:
            tree = ET.parse(file_found)
        root = tree.getroot()
        
        for elem in root.iter('pkg'):
            pkg = elem.attrib['n']
            for subelem in elem:
                #print(subelem.attrib)
                for subelem2 in subelem:
                    #print(subelem2.attrib)
                    for subelem3 in subelem2:
                        #print(subelem3.attrib)
                        timesr = subelem3.attrib.get('r')
                        timest = subelem3.attrib.get('t')
                        pp = subelem3.attrib.get('pp')
                        pu = subelem3.attrib.get('pu')
                        n = subelem3.attrib.get('n')
                        id = subelem3.attrib.get('id')
                        if timesr:
                            timestampr = (datetime.datetime.fromtimestamp(int(timesr)/1000).strftime('%Y-%m-%d %H:%M:%S'))
                        else:
                            timestampr = ''
                        if timest:	
                            timestampt = (datetime.datetime.fromtimestamp(int(timest)/1000).strftime('%Y-%m-%d %H:%M:%S'))
                        else:
                            timestampt = ''
                        if not pp:
                            pp = ''
                        if not pu:
                            pu = ''
                        if not n:
                            n = ''
                        if not id:
                            id = ''
                            
                        data_list.append((timestampt, timestampr, pkg, id, pp, pu, n))
                            
                        
        if data_list:
            report = ArtifactHtmlReport('Appops.xml')
            report.start_artifact_report(report_folder, 'Appops.xml')
            report.add_script()
            data_headers = ('Timestamp T', 'Timestamp R', 'PKG', 'ID', 'PP', 'PU', 'N')
            report.write_artifact_data_table(data_headers, data_list, file_found)
            report.end_artifact_report()
            
            tsvname = f'Appops.xml data'
            tsv(report_folder, data_headers, data_list, tsvname)
            
            tlactivity = f'Appops.xml data'
            timeline(report_folder, tlactivity, data_list, data_headers)
        else:
            logfunc('No Appops.xml data available')