def analyze(self, dataSource, fileManager, context): try: contact_and_message_dbs = AppSQLiteDB.findAppDatabases( dataSource, "naver_line", True, self._LINE_PACKAGE_NAME) calllog_dbs = AppSQLiteDB.findAppDatabases(dataSource, "call_history", True, self._LINE_PACKAGE_NAME) for contact_and_message_db in contact_and_message_dbs: current_case = Case.getCurrentCaseThrows() helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, contact_and_message_db.getDBFile(), Account.Type.LINE) self.parse_contacts(contact_and_message_db, helper) self.parse_messages(contact_and_message_db, helper) for calllog_db in calllog_dbs: current_case = Case.getCurrentCaseThrows() helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, calllog_db.getDBFile(), Account.Type.LINE) self.parse_calllogs(dataSource, calllog_db, helper) except NoCurrentCaseException as ex: # Error parsing Line databases. self._logger.log(Level.WARNING, "Error parsing the Line App Databases", ex) self._logger.log(Level.WARNING, traceback.format_exc()) for contact_and_message_db in contact_and_message_dbs: contact_and_message_db.close() for calllog_db in calllog_dbs: calllog_db.close()
def analyzeHistory(self, dataSource, fileManager, context): historyDbs = AppSQLiteDB.findAppDatabases(dataSource, "History", True, self._PACKAGE_NAME) for historyDb in historyDbs: try: historyDbHelper = WebBrowserArtifactsHelper( self.current_case.getSleuthkitCase(), self._MODULE_NAME, historyDb.getDBFile()) historyResultSet = historyDb.runQuery( "SELECT url, title, last_visit_time FROM urls") if historyResultSet is not None: while historyResultSet.next(): accessTime = historyResultSet.getLong( "last_visit_time") / 1000000 - 11644473600 historyDbHelper.addWebHistory( historyResultSet.getString("url"), accessTime, "", # referrer historyResultSet.getString("title"), self._PROGRAM_NAME) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query results for Opera history.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add Opera history artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: historyDb.close()
def analyze(self, dataSource, fileManager, context): try: contactsDbs = AppSQLiteDB.findAppDatabases(dataSource, "contacts.db", True, self._PACKAGE_NAME) contactsDbs.addAll(AppSQLiteDB.findAppDatabases(dataSource, "contacts2.db", True, self._PACKAGE_NAME)) if contactsDbs.isEmpty(): return for contactDb in contactsDbs: try: self.__findContactsInDB(contactDb, dataSource) except Exception as ex: self._logger.log(Level.SEVERE, "Error parsing Contacts", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except TskCoreException as ex: # Error finding Contacts. pass
def analyze(self, dataSource, fileManager, context): try: # Create new account type, if doesnt exist global wwfAccountType wwfAccountType = Case.getCurrentCase().getSleuthkitCase( ).getCommunicationsManager().addAccountType( "WWF", "Words with Friends") wwfDbFiles = AppSQLiteDB.findAppDatabases(dataSource, "WordsFramework", True, self._PACKAGE_NAME) for wwfDbFile in wwfDbFiles: try: self.__findWWFMessagesInDB(wwfDbFile, dataSource) except Exception as ex: self._logger.log(Level.SEVERE, "Error parsing WWF messages", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except TskCoreException as ex: # Error finding WWF messages. self._logger.log(Level.SEVERE, "Error finding WWF message files.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) pass
def analyze(self, dataSource, fileManager, context): historyDbs = AppSQLiteDB.findAppDatabases(dataSource, "history.db", True, self._PACKAGE_NAME) for historyDb in historyDbs: try: current_case = Case.getCurrentCaseThrows() historyDbHelper = CommunicationArtifactsHelper(current_case.getSleuthkitCase(), self._MODULE_NAME, historyDb.getDBFile(), Account.Type.SHAREIT) queryString = """ SELECT history_type, device_id, device_name, description, timestamp, file_path FROM history JOIN item where history.content_id = item.item_id """ historyResultSet = historyDb.runQuery(queryString) if historyResultSet is not None: while historyResultSet.next(): direction = "" fromId = None toId = None if (historyResultSet.getInt("history_type") == 1): direction = CommunicationDirection.INCOMING fromId = historyResultSet.getString("device_id") else: direction = CommunicationDirection.OUTGOING toId = historyResultSet.getString("device_id") msgBody = "" # there is no body. attachments = [historyResultSet.getString("file_path")] msgBody = general.appendAttachmentList(msgBody, attachments) timeStamp = historyResultSet.getLong("timestamp") / 1000 messageArtifact = historyDbHelper.addMessage( self._MESSAGE_TYPE, direction, fromId, toId, timeStamp, MessageReadStatus.UNKNOWN, None, # subject msgBody, None ) # thread id # TBD: add the file as attachment ?? except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for ShareIt history.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to create ShareIt message artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: historyDb.close()
def analyze(self, dataSource, fileManager, context): """ Extract, Transform and Load all messages, contacts and calllogs from the TextNow databases. """ textnow_dbs = AppSQLiteDB.findAppDatabases(dataSource, "textnow_data.db", True, self._TEXTNOW_PACKAGE_NAME) try: for textnow_db in textnow_dbs: current_case = Case.getCurrentCaseThrows() helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, textnow_db.getDBFile(), Account.Type.TEXTNOW ) self.parse_contacts(textnow_db, helper) self.parse_calllogs(textnow_db, helper) self.parse_messages(textnow_db, helper, current_case) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) for textnow_db in textnow_dbs: textnow_db.close()
def analyzeMessagesAndCallLogs(self, dataSource, fileManager, context): threadsDbs = AppSQLiteDB.findAppDatabases( dataSource, "threads_db2", True, self._FB_MESSENGER_PACKAGE_NAME) for threadsDb in threadsDbs: try: if self.selfAccountId is not None: threadsDBHelper = CommunicationArtifactsHelper( self.current_case.getSleuthkitCase(), self._MODULE_NAME, threadsDb.getDBFile(), Account.Type.FACEBOOK, Account.Type.FACEBOOK, self.selfAccountId) else: threadsDBHelper = CommunicationArtifactsHelper( self.current_case.getSleuthkitCase(), self._MODULE_NAME, threadsDb.getDBFile(), Account.Type.FACEBOOK) self.analyzeMessages(threadsDb, threadsDBHelper) self.analyzeCallLogs(threadsDb, threadsDBHelper) except TskCoreException as ex: self._logger.log( Level.SEVERE, "Failed to to create CommunicationArtifactsHelper for FB Messenger.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) finally: threadsDb.close()
def analyzeWebFormAddress(self, dataSource, fileManager, context): webFormAddressDbs = AppSQLiteDB.findAppDatabases( dataSource, "Web Data", True, self._PACKAGE_NAME) for webFormAddressDb in webFormAddressDbs: try: webFormAddressDbHelper = WebBrowserArtifactsHelper( self.current_case.getSleuthkitCase(), self._MODULE_NAME, webFormAddressDb.getDBFile()) queryString = """ SELECT street_address, city, state, zipcode, country_code, date_modified, first_name, last_name, number, email FROM autofill_profiles INNER JOIN autofill_profile_names ON autofill_profiles.guid = autofill_profile_names.guid INNER JOIN autofill_profile_phones ON autofill_profiles.guid = autofill_profile_phones.guid INNER JOIN autofill_profile_emails ON autofill_profiles.guid = autofill_profile_emails.guid """ webFormAddressResultSet = webFormAddressDb.runQuery( queryString) if webFormAddressResultSet is not None: while webFormAddressResultSet.next(): personName = webFormAddressResultSet.getString( "first_name" ) + " " + webFormAddressResultSet.getString( "last_name") address = '\n'.join([ webFormAddressResultSet.getString( "street_address"), webFormAddressResultSet.getString("city"), webFormAddressResultSet.getString("state") + " " + webFormAddressResultSet.getString("zipcode"), webFormAddressResultSet.getString("country_code") ]) creationTime = webFormAddressResultSet.getLong( "date_modified") / 1000000 - 11644473600 autofillDbHelper.addWebFormAddress( personName, webFormAddressResultSet.getString("email"), webFormAddressResultSet.getString("number"), address, creationTime, 0, 0) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query results for Opera web form addresses.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log( Level.SEVERE, "Failed to add Opera form address artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: webFormAddressDb.close()
def analyze(self, dataSource, fileManager, context): transferDbs = AppSQLiteDB.findAppDatabases(dataSource, "transfer20.db", True, self._PACKAGE_NAME) for transferDb in transferDbs: try: current_case = Case.getCurrentCaseThrows() # transferDbHelper = CommunicationArtifactsHelper(current_case.getSleuthkitCase(), self._MODULE_NAME, transferDb.getDBFile(), Account.Type.ZAPYA) queryString = "SELECT device, name, direction, createtime, path, title FROM transfer" transfersResultSet = transferDb.runQuery(queryString) if transfersResultSet is not None: while transfersResultSet.next(): direction = CommunicationDirection.UNKNOWN fromId = None toId = None fileAttachments = ArrayList() if (transfersResultSet.getInt("direction") == 1): direction = CommunicationDirection.OUTGOING toId = transfersResultSet.getString("device") else: direction = CommunicationDirection.INCOMING fromId = transfersResultSet.getString("device") timeStamp = transfersResultSet.getLong("createtime") / 1000 messageArtifact = transferDbHelper.addMessage( self._MESSAGE_TYPE, direction, fromId, toId, timeStamp, MessageReadStatus.UNKNOWN, None, # subject None, # message Text None ) # thread id # add the file as attachment fileAttachments.add(FileAttachment(current_case.getSleuthkitCase(), transferDb.getDBFile().getDataSource(), transfersResultSet.getString("path"))) messageAttachments = MessageAttachments(fileAttachments, []) transferDbHelper.addAttachments(messageArtifact, messageAttachments) except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for transfer.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to create Zapya message artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: transferDb.close()
def analyzeContacts(self, dataSource, fileManager, context): ## FB messenger and FB have same database structure for contacts. ## In our dataset, the FB Messenger database was empty. ## But the FB database had the data. contactsDbs = AppSQLiteDB.findAppDatabases(dataSource, "contacts_db2", True, self._FACEBOOK_PACKAGE_NAME) for contactsDb in contactsDbs: try: ## The device owner's FB account details can be found in the contacts table in a row with added_time_ms of 0. selfAccountResultSet = contactsDb.runQuery("SELECT fbid, display_name FROM contacts WHERE added_time_ms = 0") if selfAccountResultSet: if not self.selfAccountId: self.selfAccountId = selfAccountResultSet.getString("fbid") if self.selfAccountId is not None: contactsDBHelper = CommunicationArtifactsHelper(self.current_case.getSleuthkitCase(), self._MODULE_NAME, contactsDb.getDBFile(), Account.Type.FACEBOOK, Account.Type.FACEBOOK, self.selfAccountId ) else: contactsDBHelper = CommunicationArtifactsHelper(self.current_case.getSleuthkitCase(), self._MODULE_NAME, contactsDb.getDBFile(), Account.Type.FACEBOOK) ## get the other contacts/friends contactsResultSet = contactsDb.runQuery("SELECT fbid, display_name, added_time_ms FROM contacts WHERE added_time_ms <> 0") if contactsResultSet is not None: while contactsResultSet.next(): fbid = contactsResultSet.getString("fbid") contactName = contactsResultSet.getString("display_name") dateCreated = contactsResultSet.getLong("added_time_ms") / 1000 ## create additional attributes for contact. additionalAttributes = ArrayList(); additionalAttributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID, self._MODULE_NAME, fbid)) additionalAttributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, self._MODULE_NAME, dateCreated)) contactsDBHelper.addContact( contactName, ## contact name "", ## phone "", ## home phone "", ## mobile "", ## email additionalAttributes) except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for account", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add FB Messenger contact artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: contactsDb.close()
def analyze(self, dataSource, fileManager, context): oruxMapsTrackpointsDbs = AppSQLiteDB.findAppDatabases( dataSource, "oruxmapstracks.db", True, self._PACKAGE_NAME) for oruxMapsTrackpointsDb in oruxMapsTrackpointsDbs: try: current_case = Case.getCurrentCaseThrows() oruxDbHelper = ArtifactsHelper( current_case.getSleuthkitCase(), self._MODULE_NAME, oruxMapsTrackpointsDb.getDBFile()) poiQueryString = "SELECT poilat, poilon, poitime, poiname FROM pois" poisResultSet = oruxMapsTrackpointsDb.runQuery(poiQueryString) if poisResultSet is not None: while poisResultSet.next(): oruxDbHelper.addGPSLocation( poisResultSet.getDouble("poilat"), poisResultSet.getDouble("poilon"), poisResultSet.getLong("poitime") / 1000, # milliseconds since unix epoch poisResultSet.getString("poiname"), self._PROGRAM_NAME) trackpointsQueryString = "SELECT trkptlat, trkptlon, trkpttime FROM trackpoints" trackpointsResultSet = oruxMapsTrackpointsDb.runQuery( trackpointsQueryString) if trackpointsResultSet is not None: while trackpointsResultSet.next(): oruxDbHelper.addGPSLocation( trackpointsResultSet.getDouble("trkptlat"), trackpointsResultSet.getDouble("trkptlon"), trackpointsResultSet.getLong("trkpttime") / 1000, # milliseconds since unix epoch "", self._PROGRAM_NAME) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query result for Orux Map trackpoints.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log( Level.SEVERE, "Failed to add Orux Map trackpoint artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: oruxMapsTrackpointsDb.close()
def analyze(self, dataSource, fileManager, context): """ Extract, Transform and Load all TSK contact, message and calllog artifacts from the WhatsApp databases. """ try: contact_dbs = AppSQLiteDB.findAppDatabases( dataSource, "wa.db", True, self._WHATSAPP_PACKAGE_NAME) calllog_and_message_dbs = AppSQLiteDB.findAppDatabases( dataSource, "msgstore.db", True, self._WHATSAPP_PACKAGE_NAME) #Extract TSK_CONTACT information for contact_db in contact_dbs: current_case = Case.getCurrentCaseThrows() helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, contact_db.getDBFile(), Account.Type.WHATSAPP) self.parse_contacts(contact_db, helper) for calllog_and_message_db in calllog_and_message_dbs: current_case = Case.getCurrentCaseThrows() helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, calllog_and_message_db.getDBFile(), Account.Type.WHATSAPP) self.parse_calllogs(calllog_and_message_db, helper) self.parse_messages(dataSource, calllog_and_message_db, helper, current_case) except NoCurrentCaseException as ex: #If there is no current case, bail out immediately. self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exec()) #Clean up open file handles. for contact_db in contact_dbs: contact_db.close() for calllog_and_message_db in calllog_and_message_dbs: calllog_and_message_db.close()
def analyze(self, dataSource, fileManager, context): try: tangoDbFiles = AppSQLiteDB.findAppDatabases(dataSource, "tc.db", True, self._PACKAGE_NAME) for tangoDbFile in tangoDbFiles: try: self.__findTangoMessagesInDB(tangoDbFile, dataSource) except Exception as ex: self._logger.log(Level.SEVERE, "Error parsing Tango messages", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except TskCoreException as ex: # Error finding Tango messages. pass
def analyze(self, dataSource, fileManager, context): """ Extract, Transform and Load all messages, contacts and calllogs from the Viber databases. """ try: contact_and_calllog_dbs = AppSQLiteDB.findAppDatabases( dataSource, "viber_data", True, self._VIBER_PACKAGE_NAME) message_dbs = AppSQLiteDB.findAppDatabases( dataSource, "viber_messages", True, self._VIBER_PACKAGE_NAME) #Extract TSK_CONTACT and TSK_CALLLOG information for contact_and_calllog_db in contact_and_calllog_dbs: current_case = Case.getCurrentCaseThrows() helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, contact_and_calllog_db.getDBFile(), Account.Type.VIBER) self.parse_contacts(contact_and_calllog_db, helper) self.parse_calllogs(contact_and_calllog_db, helper) #Extract TSK_MESSAGE information for message_db in message_dbs: current_case = Case.getCurrentCaseThrows() helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, message_db.getDBFile(), Account.Type.VIBER) self.parse_messages(message_db, helper, current_case) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) for message_db in message_dbs: message_db.close() for contact_and_calllog_db in contact_and_calllog_dbs: contact_and_calllog_db.close()
def analyzeAutofill(self, dataSource, fileManager, context): autofillDbs = AppSQLiteDB.findAppDatabases(dataSource, "Web Data", True, self._PACKAGE_NAME) for autofillDb in autofillDbs: try: autofillDbHelper = WebBrowserArtifactsHelper( self.current_case.getSleuthkitCase(), self._MODULE_NAME, autofillDb.getDBFile()) queryString = """ SELECT name, value, count, date_created FROM autofill INNER JOIN autofill_dates ON autofill.pair_id = autofill_dates.pair_id """ autofillsResultSet = autofillDb.runQuery(queryString) if autofillsResultSet is not None: while autofillsResultSet.next(): creationTime = autofillsResultSet.getLong( "date_created" ) / 1000000 - 11644473600 # Webkit time autofillDbHelper.addWebFormAutofill( autofillsResultSet.getString("name"), autofillsResultSet.getString("value"), creationTime, 0, autofillsResultSet.getInt("count")) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query results for SBrowser autofill.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add SBrowser autofill artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: autofillDb.close()
def analyze(self, dataSource, fileManager, context): #Skype databases are of the form: live:XYZ.db, where #XYZ is the skype id of the user. The following search #does a generic substring match for 'live' in the skype #package. skype_dbs = AppSQLiteDB.findAppDatabases(dataSource, "live:", False, self._SKYPE_PACKAGE_NAME) try: for skype_db in skype_dbs: #Attempt to get the user account id from the database user_account_instance = None try: user_account_instance = self.get_user_account(skype_db) except SQLException as ex: self._logger.log( Level.WARNING, "Error querying for the user account in the Skype db.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) current_case = Case.getCurrentCaseThrows() if user_account_instance is None: helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, skype_db.getDBFile(), Account.Type.SKYPE) else: helper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, skype_db.getDBFile(), Account.Type.SKYPE, Account.Type.SKYPE, user_account_instance) self.parse_contacts(skype_db, helper) self.parse_calllogs(skype_db, helper) self.parse_messages(skype_db, helper) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) for skype_db in skype_dbs: skype_db.close()
def analyze(self, dataSource, fileManager, context): libraryDbs = AppSQLiteDB.findAppDatabases(dataSource, "library.db", True, self._PACKAGE_NAME) for libraryDb in libraryDbs: try: current_case = Case.getCurrentCaseThrows() libraryDbHelper = ArtifactsHelper( current_case.getSleuthkitCase(), self._MODULE_NAME, libraryDb.getDBFile()) queryString = "SELECT doc_id, purchase_time FROM ownership" ownershipResultSet = libraryDb.runQuery(queryString) if ownershipResultSet is not None: while ownershipResultSet.next(): purchase_time = ownershipResultSet.getLong( "purchase_time") / 1000 libraryDbHelper.addInstalledProgram( ownershipResultSet.getString("doc_id"), purchase_time) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query result for installed applications. ", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log( Level.SEVERE, "Failed to adding installed application artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: libraryDb.close()
def analyzeDownloads(self, dataSource, fileManager, context): downloadsDbs = AppSQLiteDB.findAppDatabases(dataSource, "History", True, self._PACKAGE_NAME) for downloadsDb in downloadsDbs: try: downloadsDbHelper = WebBrowserArtifactsHelper( self.current_case.getSleuthkitCase(), self._MODULE_NAME, downloadsDb.getDBFile()) queryString = "SELECT target_path, start_time, url FROM downloads"\ " INNER JOIN downloads_url_chains ON downloads.id = downloads_url_chains.id" downloadsResultSet = downloadsDb.runQuery(queryString) if downloadsResultSet is not None: while downloadsResultSet.next(): startTime = historyResultSet.getLong( "start_time") / 1000000 - 11644473600 # Webkit time downloadsDbHelper.addWebDownload( downloadsResultSet.getString("url"), startTime, downloadsResultSet.getString("target_path"), self._PROGRAM_NAME) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query results for SBrowser downloads.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add SBrowser download artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: downloadsDb.close()
def analyzeCookies(self, dataSource, fileManager, context): cookiesDbs = AppSQLiteDB.findAppDatabases(dataSource, "Cookies", True, self._PACKAGE_NAME) for cookiesDb in cookiesDbs: try: cookiesDbHelper = WebBrowserArtifactsHelper( self.current_case.getSleuthkitCase(), self._MODULE_NAME, cookiesDb.getDBFile()) cookiesResultSet = cookiesDb.runQuery( "SELECT host_key, name, value, creation_utc FROM cookies") if cookiesResultSet is not None: while cookiesResultSet.next(): createTime = cookiesResultSet.getLong( "creation_utc" ) / 1000000 - 11644473600 # Webkit time cookiesDbHelper.addWebCookie( cookiesResultSet.getString("host_key"), createTime, cookiesResultSet.getString("name"), cookiesResultSet.getString("value"), self._PROGRAM_NAME) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query results for SBrowser cookies.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add SBrowser cookie artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: cookiesDb.close()
def analyzeBookmarks(self, dataSource, fileManager, context): sbrowserDbs = AppSQLiteDB.findAppDatabases(dataSource, "sbrowser.db", True, self._PACKAGE_NAME) for sbrowserDb in sbrowserDbs: try: sbrowserDbHelper = WebBrowserArtifactsHelper( self.current_case.getSleuthkitCase(), self._MODULE_NAME, sbrowserDb.getDBFile()) bookmarkResultSet = sbrowserDb.runQuery( "SELECT url, title, created FROM bookmarks WHERE url IS NOT NULL" ) if bookmarkResultSet is not None: while bookmarkResultSet.next(): createTime = bookmarkResultSet.getLong( "created") / 1000 sbrowserDbHelper.addWebBookmark( bookmarkResultSet.getString("url"), bookmarkResultSet.getString("title"), createTime, self._PROGRAM_NAME) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query results for SBrowser bookmarks.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add SBrowser bookmark artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: sbrowserDb.close()
def analyzeMessages(self, dataSource, fileManager, context): threadsDbs = AppSQLiteDB.findAppDatabases(dataSource, "threads_db2", True, self._FB_MESSENGER_PACKAGE_NAME) for threadsDb in threadsDbs: try: if self.selfAccountId is not None: threadsDBHelper = CommunicationArtifactsHelper(self.current_case.getSleuthkitCase(), self._MODULE_NAME, threadsDb.getDBFile(), Account.Type.FACEBOOK, Account.Type.FACEBOOK, self.selfAccountId ) else: threadsDBHelper = CommunicationArtifactsHelper(self.current_case.getSleuthkitCase(), self._MODULE_NAME, threadsDb.getDBFile(), Account.Type.FACEBOOK) ## Messages are found in the messages table. ## This query filters messages by msg_type to only get actual user created conversation messages (msg_type 0). ## The participant ids can be found in the thread_participants table. ## Participant names are found in thread_users table. ## Joining these tables produces multiple rows per message, one row for each recipient. ## The result set is processed to collect the multiple recipients for a given message. sqlString = """ SELECT msg_id, text, sender, timestamp_ms, msg_type, messages.thread_key as thread_key, snippet, thread_participants.user_key as user_key, thread_users.name as name FROM messages JOIN thread_participants ON messages.thread_key = thread_participants.thread_key JOIN thread_users ON thread_participants.user_key = thread_users.user_key WHERE msg_type = 0 ORDER BY msg_id """ messagesResultSet = threadsDb.runQuery(sqlString) if messagesResultSet is not None: oldMsgId = None direction = CommunicationDirection.UNKNOWN fromId = None recipientIdsList = None timeStamp = -1 msgText = "" threadId = "" while messagesResultSet.next(): msgId = messagesResultSet.getString("msg_id") # new msg begins when msgId changes if msgId != oldMsgId: # Create message artifact with collected attributes if oldMsgId is not None: messageArtifact = threadsDBHelper.addMessage( self._MESSAGE_TYPE, direction, fromId, recipientIdsList, timeStamp, MessageReadStatus.UNKNOWN, "", # subject msgText, threadId) oldMsgId = msgId # New message - collect all attributes recipientIdsList = [] ## get sender id by parsing JSON in sender column senderJsonStr = messagesResultSet.getString("sender") if senderJsonStr is not None: sender_dict = json.loads(senderJsonStr) senderId = sender_dict['user_key'] senderId = senderId.replace('FACEBOOK:', '') senderName = sender_dict['name'] fromId = senderId if senderId == self.selfAccountId: direction = CommunicationDirection.OUTGOING else: direction = CommunicationDirection.INCOMING # Get recipient and add to list self.addRecipientToList(messagesResultSet.getString("user_key"), recipientIdsList) timeStamp = messagesResultSet.getLong("timestamp_ms") / 1000 # Get msg text # Sometimes there may not be an explict msg text, # but an app generated snippet instead msgText = messagesResultSet.getString("text") if not msgText: msgText = messagesResultSet.getString("snippet") # TBD: get attachment threadId = messagesResultSet.getString("thread_key") else: # same msgId as last, just collect recipient from current row self.addRecipientToList(messagesResultSet.getString("user_key"), recipientIdsList) # at the end of the loop, add last message messageArtifact = threadsDBHelper.addMessage( self._MESSAGE_TYPE, direction, fromId, recipientIdsList, timeStamp, MessageReadStatus.UNKNOWN, "", # subject msgText, threadId) except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for FB Messenger messages.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add FB Messenger message artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: threadsDb.close()
def analyze(self, dataSource, fileManager, context): oruxMapsTrackpointsDbs = AppSQLiteDB.findAppDatabases( dataSource, "oruxmapstracks.db", True, self._PACKAGE_NAME) for oruxMapsTrackpointsDb in oruxMapsTrackpointsDbs: try: current_case = Case.getCurrentCaseThrows() skCase = Case.getCurrentCase().getSleuthkitCase() geoArtifactHelper = GeoArtifactsHelper( skCase, self._MODULE_NAME, self._PROGRAM_NAME, oruxMapsTrackpointsDb.getDBFile()) poiQueryString = "SELECT poilat, poilon, poialt, poitime, poiname FROM pois" poisResultSet = oruxMapsTrackpointsDb.runQuery(poiQueryString) abstractFile = oruxMapsTrackpointsDb.getDBFile() if poisResultSet is not None: while poisResultSet.next(): latitude = poisResultSet.getDouble("poilat") longitude = poisResultSet.getDouble("poilon") time = poisResultSet.getLong( "poitime") / 1000 # milliseconds since unix epoch name = poisResultSet.getString("poiname") altitude = poisResultSet.getDouble("poialt") attributes = ArrayList() artifact = abstractFile.newArtifact( BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_DATETIME, self._MODULE_NAME, time)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_GEO_LATITUDE, self._MODULE_NAME, latitude)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_GEO_LONGITUDE, self._MODULE_NAME, longitude)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_GEO_ALTITUDE, self._MODULE_NAME, altitude)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, self._MODULE_NAME, name)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_PROG_NAME, self._MODULE_NAME, self._PROGRAM_NAME)) artifact.addAttributes(attributes) try: # index the artifact for keyword search blackboard = Case.getCurrentCase( ).getSleuthkitCase().getBlackboard() blackboard.postArtifact(artifact, self._MODULE_NAME) except Blackboard.BlackboardException as ex: self._logger.log( Level.SEVERE, "Unable to index blackboard artifact " + str(artifact.getArtifactID()), ex) self._logger.log(Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error( "Failed to index trackpoint artifact for keyword search.", artifact.getDisplayName()) # tracks -> segments -> trackpoints # # The reason that the track and the segment are put into arrays is that once the segment query is run an error occurs that it cannot find the # trackname column in the track query. This is avoided if all the tracks/segments are found and put into an array(s) that can then be processed all at once. trackQueryString = "SELECT _id, trackname, trackciudad FROM tracks" trackResultSet = oruxMapsTrackpointsDb.runQuery( trackQueryString) if trackResultSet is not None: trackResults = ArrayList() while trackResultSet.next(): tempTrack = ArrayList() trackName = trackResultSet.getString( "trackname") + " - " + trackResultSet.getString( "trackciudad") trackId = str(trackResultSet.getInt("_id")) tempTrack.append(trackId) tempTrack.append(trackName) trackResults.append(tempTrack) for trackResult in trackResults: trackId = trackResult[0] trackName = trackResult[1] segmentQueryString = "SELECT _id, segname FROM segments WHERE segtrack = " + trackId segmentResultSet = oruxMapsTrackpointsDb.runQuery( segmentQueryString) if segmentResultSet is not None: segmentResults = ArrayList() while segmentResultSet.next(): segmentName = trackName + " - " + segmentResultSet.getString( "segname") segmentId = str(segmentResultSet.getInt("_id")) tempSegment = ArrayList() tempSegment.append(segmentId) tempSegment.append(segmentName) segmentResults.append(tempSegment) for segmentResult in segmentResults: segmentId = segmentResult[0] segmentName = segmentResult[1] trackpointsQueryString = "SELECT trkptlat, trkptlon, trkptalt, trkpttime FROM trackpoints WHERE trkptseg = " + segmentId trackpointsResultSet = oruxMapsTrackpointsDb.runQuery( trackpointsQueryString) if trackpointsResultSet is not None: geoPointList = GeoTrackPoints() while trackpointsResultSet.next(): latitude = trackpointsResultSet.getDouble( "trkptlat") longitude = trackpointsResultSet.getDouble( "trkptlon") altitude = trackpointsResultSet.getDouble( "trkptalt") time = trackpointsResultSet.getLong( "trkpttime" ) / 1000 # milliseconds since unix epoch geoPointList.addPoint( TrackPoint(latitude, longitude, altitude, segmentName, 0, 0, 0, time)) try: geoartifact = geoArtifactHelper.addTrack( segmentName, geoPointList, None) except Blackboard.BlackboardException as ex: self._logger.log( Level.SEVERE, "Error using geo artifact helper with blackboard", ex) self._logger.log( Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error( "Failed to add track artifact.", "geoArtifactHelper") except TskCoreException as e: self._logger.log( Level.SEVERE, "Error using geo artifact helper with TskCoreException", ex) self._logger.log( Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error( "Failed to add track artifact with TskCoreException.", "geoArtifactHelper") except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query result for Orux Map trackpoints.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log( Level.SEVERE, "Failed to add Orux Map trackpoint artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: oruxMapsTrackpointsDb.close()
def analyze(self, dataSource, fileManager, context): selfAccountId = None messageDbs = AppSQLiteDB.findAppDatabases(dataSource, "mmssms.db", True, self._PACKAGE_NAME) for messageDb in messageDbs: try: current_case = Case.getCurrentCaseThrows() if selfAccountId is not None: messageDbHelper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, messageDb.getDBFile(), Account.Type.PHONE, Account.Type.IMO, selfAccountId) else: messageDbHelper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, messageDb.getDBFile(), Account.Type.PHONE) uuid = UUID.randomUUID().toString() messagesResultSet = messageDb.runQuery( "SELECT address, date, read, type, subject, body, thread_id FROM sms;" ) if messagesResultSet is not None: while messagesResultSet.next(): direction = "" address = None fromId = None toId = None address = messagesResultSet.getString( "address" ) # may be phone number, or other addresses timeStamp = Long.valueOf( messagesResultSet.getString("date")) / 1000 read = messagesResultSet.getInt( "read") # may be unread = 0, read = 1 subject = messagesResultSet.getString( "subject") # message subject msgBody = messagesResultSet.getString( "body") # message body thread_id = "{0}-{1}".format( uuid, messagesResultSet.getInt("thread_id")) if messagesResultSet.getString("type") == "1": direction = CommunicationDirection.INCOMING fromId = address else: direction = CommunicationDirection.OUTGOING toId = address message_read = messagesResultSet.getInt( "read") # may be unread = 0, read = 1 if (message_read == 1): msgReadStatus = MessageReadStatus.READ elif (message_read == 0): msgReadStatus = MessageReadStatus.UNREAD else: msgReadStatus = MessageReadStatus.UNKNOWN ## add a message if address is not None: messageArtifact = messageDbHelper.addMessage( self._MESSAGE_TYPE, direction, fromId, toId, timeStamp, msgReadStatus, subject, # subject msgBody, thread_id) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query result for Android messages.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add Android message artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: messageDb.close()
def analyze(self, dataSource, fileManager, context): oruxMapsTrackpointsDbs = AppSQLiteDB.findAppDatabases( dataSource, "oruxmapstracks.db", True, self._PACKAGE_NAME) for oruxMapsTrackpointsDb in oruxMapsTrackpointsDbs: try: current_case = Case.getCurrentCaseThrows() poiQueryString = "SELECT poilat, poilon, poitime, poiname FROM pois" poisResultSet = oruxMapsTrackpointsDb.runQuery(poiQueryString) abstractFile = oruxMapsTrackpointsDb.getDBFile() if poisResultSet is not None: while poisResultSet.next(): latitude = poisResultSet.getDouble("poilat") longitude = poisResultSet.getDouble("poilon") time = poisResultSet.getLong( "poitime") / 1000 # milliseconds since unix epoch name = poisResultSet.getString("poiname") attributes = ArrayList() artifact = abstractFile.newArtifact( BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT ) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_DATETIME, self._MODULE_NAME, time)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_GEO_LATITUDE, self._MODULE_NAME, latitude)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_GEO_LONGITUDE, self._MODULE_NAME, longitude)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, self._MODULE_NAME, name)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_PROG_NAME, self._MODULE_NAME, self._PROGRAM_NAME)) artifact.addAttributes(attributes) try: # index the artifact for keyword search blackboard = Case.getCurrentCase( ).getSleuthkitCase().getBlackboard() blackboard.postArtifact(artifact, self._MODULE_NAME) except Blackboard.BlackboardException as ex: self._logger.log( Level.SEVERE, "Unable to index blackboard artifact " + str(artifact.getArtifactID()), ex) self._logger.log(Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error( "Failed to index trackpoint artifact for keyword search.", artifact.getDisplayName()) trackpointsQueryString = "SELECT trkptlat, trkptlon, trkpttime FROM trackpoints" trackpointsResultSet = oruxMapsTrackpointsDb.runQuery( trackpointsQueryString) if trackpointsResultSet is not None: while trackpointsResultSet.next(): latitude = trackpointsResultSet.getDouble("trkptlat") longitude = trackpointsResultSet.getDouble("trkptlon") time = trackpointsResultSet.getLong( "trkpttime" ) / 1000 # milliseconds since unix epoch name = "" attributes = ArrayList() artifact = abstractFile.newArtifact( BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT ) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_DATETIME, self._MODULE_NAME, time)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_GEO_LATITUDE, self._MODULE_NAME, latitude)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_GEO_LONGITUDE, self._MODULE_NAME, longitude)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME, self._MODULE_NAME, name)) attributes.add( BlackboardAttribute( BlackboardAttribute.ATTRIBUTE_TYPE. TSK_PROG_NAME, self._MODULE_NAME, self._PROGRAM_NAME)) artifact.addAttributes(attributes) try: # index the artifact for keyword search blackboard = Case.getCurrentCase( ).getSleuthkitCase().getBlackboard() blackboard.postArtifact(artifact, self._MODULE_NAME) except Blackboard.BlackboardException as ex: self._logger.log( Level.SEVERE, "Unable to index blackboard artifact " + str(artifact.getArtifactID()), ex) self._logger.log(Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error( "Failed to index trackpoint artifact for keyword search.", artifact.getDisplayName()) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query result for Orux Map trackpoints.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log( Level.SEVERE, "Failed to add Orux Map trackpoint artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: oruxMapsTrackpointsDb.close()
def analyze(self, dataSource, fileManager, context): selfAccountId = None accountDbs = AppSQLiteDB.findAppDatabases(dataSource, "accountdb.db", True, self._PACKAGE_NAME) for accountDb in accountDbs: try: accountResultSet = accountDb.runQuery("SELECT uid, name FROM account") if accountResultSet: # We can determine the IMO user ID of the device owner. # Therefore we can create and use a app account and use that # as a 'self' account instead of a Device account if not selfAccountId: selfAccountId = accountResultSet.getString("uid") except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for account", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: accountDb.close() friendsDbs = AppSQLiteDB.findAppDatabases(dataSource, "imofriends.db", True, self._PACKAGE_NAME) for friendsDb in friendsDbs: try: current_case = Case.getCurrentCaseThrows() if selfAccountId is not None: friendsDBHelper = CommunicationArtifactsHelper(current_case.getSleuthkitCase(), self._PARSER_NAME, friendsDb.getDBFile(), Account.Type.IMO, Account.Type.IMO, selfAccountId ) else: friendsDBHelper = CommunicationArtifactsHelper(current_case.getSleuthkitCase(), self._PARSER_NAME, friendsDb.getDBFile(), Account.Type.IMO ) contactsResultSet = friendsDb.runQuery("SELECT buid, name FROM friends") if contactsResultSet is not None: while contactsResultSet.next(): contactId = contactsResultSet.getString("buid") ## add a TSK_ID attribute with contact's IMO Id additionalAttributes = ArrayList() additionalAttributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID, self._PARSER_NAME, contactId)) friendsDBHelper.addContact( contactsResultSet.getString("name"), ## contact name "", ## phone "", ## home phone "", ## mobile "", ## email additionalAttributes) queryString = """ SELECT messages.buid AS buid, imdata, last_message, timestamp, message_type, message_read, name FROM messages INNER JOIN friends ON friends.buid = messages.buid """ messagesResultSet = friendsDb.runQuery(queryString) if messagesResultSet is not None: while messagesResultSet.next(): direction = "" fromId = None toId = None name = messagesResultSet.getString("name") uniqueId = messagesResultSet.getString("buid") if (messagesResultSet.getInt("message_type") == 1): direction = CommunicationDirection.INCOMING fromId = uniqueId else: direction = CommunicationDirection.OUTGOING toId = uniqueId message_read = messagesResultSet.getInt("message_read") if (message_read == 1): msgReadStatus = MessageReadStatus.READ elif (message_read == 0): msgReadStatus = MessageReadStatus.UNREAD else: msgReadStatus = MessageReadStatus.UNKNOWN timeStamp = messagesResultSet.getLong("timestamp") / 1000000000 messageArtifact = friendsDBHelper.addMessage( self._MESSAGE_TYPE, direction, fromId, toId, timeStamp, msgReadStatus, "", # subject messagesResultSet.getString("last_message"), "") # thread id # TBD: parse the imdata JSON structure to figure out if there is an attachment. # If one exists, add the attachment as a derived file and a child of the message artifact. except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for IMO friends", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to add IMO message artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: friendsDb.close()
def analyze(self, dataSource, fileManager, context): selfAccountId = None transactionDbs = AppSQLiteDB.findAppDatabases(dataSource, "trans-history-db", True, self._PACKAGE_NAME) for transactionDb in transactionDbs: try: current_case = Case.getCurrentCaseThrows() # get the profile with connection_times 0, that's the self account. profilesResultSet = transactionDb.runQuery("SELECT device_id, nick_name FROM profile WHERE connect_times = 0") if profilesResultSet: while profilesResultSet.next(): if not selfAccountId: selfAccountId = profilesResultSet.getString("device_id") # create artifacts helper if selfAccountId is not None: transactionDbHelper = CommunicationArtifactsHelper(current_case.getSleuthkitCase(), self._MODULE_NAME, transactionDb.getDBFile(), Account.Type.XENDER, Account.Type.XENDER, selfAccountId ) else: transactionDbHelper = CommunicationArtifactsHelper(current_case.getSleuthkitCase(), self._MODULE_NAME, transactionDb.getDBFile(), Account.Type.XENDER) queryString = """ SELECT f_path, f_display_name, f_size_str, f_create_time, c_direction, c_session_id, s_name, s_device_id, r_name, r_device_id FROM new_history """ messagesResultSet = transactionDb.runQuery(queryString) if messagesResultSet is not None: while messagesResultSet.next(): direction = CommunicationDirection.UNKNOWN fromId = None toId = None if (messagesResultSet.getInt("c_direction") == 1): direction = CommunicationDirection.OUTGOING toId = messagesResultSet.getString("r_device_id") else: direction = CommunicationDirection.INCOMING fromId = messagesResultSet.getString("s_device_id") msgBody = "" # there is no body. attachments = [messagesResultSet.getString("f_path")] msgBody = general.appendAttachmentList(msgBody, attachments) timeStamp = messagesResultSet.getLong("f_create_time") / 1000 messageArtifact = transactionDbHelper.addMessage( self._MESSAGE_TYPE, direction, fromId, toId, timeStamp, MessageReadStatus.UNKNOWN, None, # subject msgBody, messagesResultSet.getString("c_session_id") ) # TBD: add the file as attachment ?? except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for profiles.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log(Level.SEVERE, "Failed to create Xender message artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: transactionDb.close()
def analyze(self, dataSource, fileManager, context): for _dbFileName in CallLogAnalyzer._dbFileNames: selfAccountId = None callLogDbs = AppSQLiteDB.findAppDatabases(dataSource, _dbFileName, True, self._PACKAGE_NAME) for callLogDb in callLogDbs: try: current_case = Case.getCurrentCaseThrows() if selfAccountId is not None: callLogDbHelper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, callLogDb.getDBFile(), Account.Type.PHONE, Account.Type.PHONE, selfAccountId) else: callLogDbHelper = CommunicationArtifactsHelper( current_case.getSleuthkitCase(), self._PARSER_NAME, callLogDb.getDBFile(), Account.Type.PHONE) for tableName in CallLogAnalyzer._tableNames: try: tableFound = callLogDb.tableExists(tableName) if tableFound: resultSet = callLogDb.runQuery( "SELECT number, date, duration, type, name FROM " + tableName + " ORDER BY date DESC;") self._logger.log( Level.INFO, "Reading call log from table {0} in db {1}", [ tableName, callLogDb.getDBFile().getName() ]) if resultSet is not None: while resultSet.next(): direction = "" callerId = None calleeId = None timeStamp = resultSet.getLong( "date") / 1000 number = resultSet.getString("number") duration = resultSet.getLong( "duration" ) # duration of call is in seconds name = resultSet.getString( "name" ) # name of person dialed or called. None if unregistered calltype = resultSet.getInt("type") if calltype == 1 or calltype == 3: direction = CommunicationDirection.INCOMING callerId = number elif calltype == 2 or calltype == 5: direction = CommunicationDirection.OUTGOING calleeId = number else: direction = CommunicationDirection.UNKNOWN ## add a call log if callerId is not None or calleeId is not None: callLogArtifact = callLogDbHelper.addCalllog( direction, callerId, calleeId, timeStamp, ## start time timeStamp + duration * 1000, ## end time CallMediaType.AUDIO) except SQLException as ex: self._logger.log( Level.WARNING, "Error processing query result for Android messages.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log( Level.SEVERE, "Failed to add Android call log artifacts.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except BlackboardException as ex: self._logger.log(Level.WARNING, "Failed to post artifacts.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) except TskCoreException as ex: self._logger.log( Level.SEVERE, "Failed to create CommunicationArtifactsHelper.", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) except NoCurrentCaseException as ex: self._logger.log(Level.WARNING, "No case currently open.", ex) self._logger.log(Level.WARNING, traceback.format_exc()) finally: callLogDb.close()