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:
                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()

    report = ArtifactHtmlReport('Recent Tasks, Snapshots & Images')
    report.start_artifact_report(report_folder, f'Recent Activity_{uid}')
    report.add_script()
    data_headers = ('Key', 'Value')
    image_data_headers = ('Snapshot_Image', 'Recent_Image')

    #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

    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" alt="{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" alt="{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()
Esempio n. 2
0
def generate_location_map(reportfolderbase, legend_title):
    KML_path = os.path.join(reportfolderbase, iLEAPP_KMLs)
    if not os.path.isdir(KML_path) or not os.listdir(KML_path):
        return

    location_path = os.path.join(reportfolderbase, 'LOCATIONS')
    os.makedirs(location_path, exist_ok=True)
    db = sqlite3.connect(os.path.join(KML_path, "_latlong.db"))
    df = pd.read_sql_query(
        "SELECT key as Name, Activity as Description, latitude, longitude FROM data ;",
        db)
    df["Point"] = df.apply(
        lambda row: Point(float(row['longitude']), float(row['latitude']), .0),
        axis=1)

    #sorting is needed for correct display
    df.sort_values(by=['Name'], inplace=True)

    #Parse geo data and add to Folium Map
    data_names = df[~df.Description.str.contains('Photos')].Description.unique(
    )
    featuresProp = {}

    for c, d in zip(colors, data_names):
        descFilter = d
        if 'ZRT' in d:
            fType = 'LineString'
            icon = 'marker'
            iconUrl = defaultIconUrl.format(c)
            shadowUrl = defaultShadowUrl
        else:
            fType = 'MultiPoint'
            icon = 'circle'
            iconUrl = ''
            shadowUrl = ''

        color = c

        featuresProp[d] = {
            'fType': fType,
            'color': c,
            'icon': icon,
            'iconUrl': iconUrl,
            'shadowUrl': defaultShadowUrl,
        }

    location_map = folium.Map([df.iloc[0].Point.y, df.iloc[0].Point.x],
                              prefer_canvas=True,
                              zoom_start=6)
    bounds = (
        df[~df.Description.str.contains('Photos')]['longitude'].min(),
        df[~df.Description.str.contains('Photos')]['latitude'].min(),
        df[~df.Description.str.contains('Photos')]['longitude'].max(),
        df[~df.Description.str.contains('Photos')]['latitude'].max(),
    )
    location_map.fit_bounds([
        (bounds[1], bounds[0]),
        (bounds[3], bounds[2]),
    ])

    tsGeo = TimestampedGeoJson(
        {
            'type': 'FeatureCollection',
            'features':
            [geodfToFeatures(df, f, featuresProp) for f in data_names]
        },
        period="PT1M",
        duration="PT1H",
        loop=False,
        transition_time=50,
        time_slider_drag_update=True,
        add_last_point=True,
        max_speed=200).add_to(location_map)

    #legend
    legend = '\n'.join([
        legend_tag.format(featuresProp[f]['color'], htmlencode(f))
        for f in data_names
    ])
    template = '\n'.join([
        template_part1,
        legend_title_tag.format(htmlencode(legend_title)),
        legend_div.format(legend), template_part2
    ])

    macro = MacroElement()
    macro._template = Template(template)

    location_map.get_root().add_child(macro)

    location_map.save(os.path.join(location_path, "Locations_Map.html"))

    report = ArtifactHtmlReport('Locations Map')
    report.start_artifact_report(location_path, 'Locations Map',
                                 'Map plotting all locations')
    report.write_raw_html(
        open(os.path.join(location_path, "Locations_Map.html")).read())
    report.end_artifact_report()
Esempio n. 3
0
def get_sms(files_found, report_folder, seeker):
    file_found = str(files_found[0])
    db = open_sqlite_db_readonly(file_found)
    sms_df = pd.read_sql_query(
        '''
    SELECT
    CASE
        WHEN LENGTH(MESSAGE.DATE)=18 THEN DATETIME(MESSAGE.DATE/1000000000+978307200,'UNIXEPOCH')
        WHEN LENGTH(MESSAGE.DATE)=9 THEN DATETIME(MESSAGE.DATE + 978307200,'UNIXEPOCH')
        ELSE "N/A"
    END "MESSAGE DATE",
    MESSAGE.ROWID as "MESSAGE ID",
    CASE 
        WHEN LENGTH(MESSAGE.DATE_DELIVERED)=18 THEN DATETIME(MESSAGE.DATE_DELIVERED/1000000000+978307200,"UNIXEPOCH")
        WHEN LENGTH(MESSAGE.DATE_DELIVERED)=9 THEN DATETIME(MESSAGE.DATE_DELIVERED+978307200,"UNIXEPOCH")
        ELSE "N/A"
    END "DATE DELIVERED",
    CASE 
        WHEN LENGTH(MESSAGE.DATE_READ)=18 THEN DATETIME(MESSAGE.DATE_READ/1000000000+978307200,"UNIXEPOCH")
        WHEN LENGTH(MESSAGE.DATE_READ)=9 THEN DATETIME(MESSAGE.DATE_READ+978307200,"UNIXEPOCH")
        ELSE "N/A"
    END "DATE READ",
    MESSAGE.TEXT as "MESSAGE",
    HANDLE.ID AS "CONTACT ID",
    MESSAGE.SERVICE AS "SERVICE",
    MESSAGE.ACCOUNT AS "ACCOUNT",
    MESSAGE.IS_DELIVERED AS "IS DELIVERED",
    MESSAGE.IS_FROM_ME AS "IS FROM ME",
    ATTACHMENT.FILENAME AS "FILENAME",
    ATTACHMENT.MIME_TYPE AS "MIME TYPE",
    ATTACHMENT.TRANSFER_NAME AS "TRANSFER TYPE",
    ATTACHMENT.TOTAL_BYTES AS "TOTAL BYTES"
    FROM MESSAGE
    LEFT OUTER JOIN MESSAGE_ATTACHMENT_JOIN ON MESSAGE.ROWID = MESSAGE_ATTACHMENT_JOIN.MESSAGE_ID
    LEFT OUTER JOIN ATTACHMENT ON MESSAGE_ATTACHMENT_JOIN.ATTACHMENT_ID = ATTACHMENT.ROWID
    LEFT OUTER JOIN HANDLE ON MESSAGE.HANDLE_ID = HANDLE.ROWID 
    ''', db)

    usageentries = sms_df.shape[0]
    if usageentries > 0:
        data_list = sms_df.to_records(index=False)

        report = ArtifactHtmlReport('SMS - iMessage')
        report.start_artifact_report(report_folder, 'SMS - iMessage')
        report.add_script()

        sms_df = sms_df.rename(
            columns={
                "MESSAGE DATE": "data-time",
                'MESSAGE ID': "message-id",
                "MESSAGE": "message",
                "CONTACT ID": "data-name",
                "IS FROM ME": "from_me",
                "MIME TYPE": "content-type"
            })
        sms_df["data-time"] = pd.to_datetime(sms_df["data-time"])

        def copyAttachments(rec):
            pathToAttachment = None
            if rec["FILENAME"]:
                attachment = seeker.search('**' +
                                           rec["FILENAME"].replace('~', '', 1),
                                           return_on_first_hit=True)
                if not attachment:
                    logfunc(
                        ' [!] Unable to extract attachment file: "{}"'.format(
                            rec['FILENAME']))
                    return
                if is_platform_windows():
                    destFileName = sanitize_file_name(
                        os.path.basename(rec["FILENAME"]))
                else:
                    destFileName = os.path.basename(rec["FILENAME"])
                pathToAttachment = os.path.join(
                    (os.path.basename(os.path.abspath(report_folder))),
                    destFileName)
                shutil.copy(attachment[0],
                            os.path.join(report_folder, destFileName))
            return pathToAttachment

        sms_df["file-path"] = sms_df.apply(lambda rec: copyAttachments(rec),
                                           axis=1)

        num_entries = sms_df.shape[0]
        report.write_minor_header(f'Total number of entries: {num_entries}',
                                  'h6')

        if file_found.startswith('\\\\?\\'):
            file_found = file_found[4:]
        report.write_lead_text(f'SMS - iMessage located at: {file_found}')
        report.write_raw_html(chat_HTML)
        report.add_script(render_chat(sms_df))

        data_headers = ('Message Date', 'Message ID', 'Date Delivered',
                        'Date Read', 'Message', 'Contact ID', 'Service',
                        'Account', 'Is Delivered', 'Is from Me', 'Filename',
                        'MIME Type', 'Transfer Type', 'Total Bytes')
        report.write_artifact_data_table(data_headers,
                                         data_list,
                                         file_found,
                                         write_total=False,
                                         write_location=False)
        report.end_artifact_report()

        tsvname = 'SMS - iMessage'
        tsv(report_folder, data_headers, data_list, tsvname)

        tlactivity = 'SMS - iMessage'
        timeline(report_folder, tlactivity, data_list, data_headers)
    else:
        logfunc('No SMS & iMessage data available')

    db.close()
    return