diff --git a/InternalPythonModules/android/module.py b/InternalPythonModules/android/module.py index 2df6d64e0e..3cf8921007 100644 --- a/InternalPythonModules/android/module.py +++ b/InternalPythonModules/android/module.py @@ -47,6 +47,9 @@ import tangomessage import textmessage import wwfmessage import imo +import xender +import zapya +import shareit import viber import skype import line @@ -96,7 +99,9 @@ class AndroidIngestModule(DataSourceIngestModule): analyzers = [contact.ContactAnalyzer(), calllog.CallLogAnalyzer(), textmessage.TextMessageAnalyzer(), tangomessage.TangoMessageAnalyzer(), wwfmessage.WWFMessageAnalyzer(), googlemaplocation.GoogleMapLocationAnalyzer(), browserlocation.BrowserLocationAnalyzer(), - cachelocation.CacheLocationAnalyzer(), imo.IMOAnalyzer(), line.LineAnalyzer(), whatsapp.WhatsAppAnalyzer(), + cachelocation.CacheLocationAnalyzer(), imo.IMOAnalyzer(), + xender.XenderAnalyzer(), zapya.ZapyaAnalyzer(), shareit.ShareItAnalyzer(), + line.LineAnalyzer(), whatsapp.WhatsAppAnalyzer(), textnow.TextNowAnalyzer(), skype.SkypeAnalyzer(), viber.ViberAnalyzer()] self.log(Level.INFO, "running " + str(len(analyzers)) + " analyzers") progressBar.switchToDeterminate(len(analyzers)) diff --git a/InternalPythonModules/android/shareit.py b/InternalPythonModules/android/shareit.py new file mode 100644 index 0000000000..937a663393 --- /dev/null +++ b/InternalPythonModules/android/shareit.py @@ -0,0 +1,123 @@ +""" +Autopsy Forensic Browser + +Copyright 2019 Basis Technology Corp. +Contact: carrier sleuthkit org + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +from java.io import File +from java.lang import Class +from java.lang import ClassNotFoundException +from java.lang import Long +from java.lang import String +from java.sql import ResultSet +from java.sql import SQLException +from java.sql import Statement +from java.util.logging import Level +from java.util import ArrayList +from org.apache.commons.codec.binary import Base64 +from org.sleuthkit.autopsy.casemodule import Case +from org.sleuthkit.autopsy.casemodule import NoCurrentCaseException +from org.sleuthkit.autopsy.coreutils import Logger +from org.sleuthkit.autopsy.coreutils import MessageNotifyUtil +from org.sleuthkit.autopsy.coreutils import AppSQLiteDB +from org.sleuthkit.autopsy.datamodel import ContentUtils +from org.sleuthkit.autopsy.ingest import IngestJobContext +from org.sleuthkit.datamodel import AbstractFile +from org.sleuthkit.datamodel import BlackboardArtifact +from org.sleuthkit.datamodel import BlackboardAttribute +from org.sleuthkit.datamodel import Content +from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel.Blackboard import BlackboardException +from org.sleuthkit.datamodel import Account +from org.sleuthkit.datamodel.blackboardutils import CommunicationArtifactsHelper +from org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper import MessageReadStatus +from org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper import CommunicationDirection + +import traceback +import general + +""" +Finds the SQLite DB for ShareIt, parses the DB for contacts & messages, +and adds artifacts to the case. +""" +class ShareItAnalyzer(general.AndroidComponentAnalyzer): + + def __init__(self): + self._logger = Logger.getLogger(self.__class__.__name__) + self._PACKAGE_NAME = "com.lenovo.anyshare.gps" + self._MODULE_NAME = "ShareIt Analyzer" + self._MESSAGE_TYPE = "ShareIt Message" + self._VERSION = "5.0.28_ww" + + 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, import_path FROM history" + historyResultSet = historyDb.runQuery(queryString) + if historyResultSet is not None: + while historyResultSet.next(): + direction = "" + fromAddress = None + toAdddress = None + + if (historyResultSet.getInt("history_type") == 1): + direction = CommunicationDirection.OUTGOING + toAddress = Account.Address(historyResultSet.getString("device_id"), historyResultSet.getString("device_name") ) + else: + direction = CommunicationDirection.INCOMING + fromAddress = Account.Address(historyResultSet.getString("device_id"), historyResultSet.getString("device_name") ) + + msgBody = "" # there is no body. + attachments = [historyResultSet.getString("import_path")] + msgBody = general.appendAttachmentList(msgBody, attachments) + + timeStamp = historyResultSet.getLong("timestamp") / 1000 + messageArtifact = transferDbHelper.addMessage( + self._MESSAGE_TYPE, + direction, + fromAddress, + toAddress, + 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() + + + diff --git a/InternalPythonModules/android/xender.py b/InternalPythonModules/android/xender.py new file mode 100644 index 0000000000..cdc520fb11 --- /dev/null +++ b/InternalPythonModules/android/xender.py @@ -0,0 +1,136 @@ +""" +Autopsy Forensic Browser + +Copyright 2019 Basis Technology Corp. +Contact: carrier sleuthkit org + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +from java.io import File +from java.lang import Class +from java.lang import ClassNotFoundException +from java.lang import Long +from java.lang import String +from java.sql import ResultSet +from java.sql import SQLException +from java.sql import Statement +from java.util.logging import Level +from java.util import ArrayList +from org.apache.commons.codec.binary import Base64 +from org.sleuthkit.autopsy.casemodule import Case +from org.sleuthkit.autopsy.casemodule import NoCurrentCaseException +from org.sleuthkit.autopsy.coreutils import Logger +from org.sleuthkit.autopsy.coreutils import MessageNotifyUtil +from org.sleuthkit.autopsy.coreutils import AppSQLiteDB +from org.sleuthkit.autopsy.datamodel import ContentUtils +from org.sleuthkit.autopsy.ingest import IngestJobContext +from org.sleuthkit.datamodel import AbstractFile +from org.sleuthkit.datamodel import BlackboardArtifact +from org.sleuthkit.datamodel import BlackboardAttribute +from org.sleuthkit.datamodel import Content +from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel.Blackboard import BlackboardException +from org.sleuthkit.datamodel import Account +from org.sleuthkit.datamodel.blackboardutils import CommunicationArtifactsHelper +from org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper import MessageReadStatus +from org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper import CommunicationDirection +import traceback +import general + +""" +Finds the SQLite DB for Xender, parses the DB for contacts & messages, +and adds artifacts to the case. +""" +class XenderAnalyzer(general.AndroidComponentAnalyzer): + + def __init__(self): + self._logger = Logger.getLogger(self.__class__.__name__) + self._PACKAGE_NAME = "cn.xender" + self._MODULE_NAME = "Xender Analyzer" + self._MESSAGE_TYPE = "Xender Message" + self._VERSION = "4.6.5" + + + def analyze(self, dataSource, fileManager, context): + selfAccountAddress = 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 selfAccountAddress: + selfAccountAddress = Account.Address(profilesResultSet.getString("device_id"), profilesResultSet.getString("nick_name")) + # create artifacts helper + if selfAccountAddress is not None: + transactionDbHelper = CommunicationArtifactsHelper(current_case.getSleuthkitCase(), + self._MODULE_NAME, transactionDb.getDBFile(), + Account.Type.XENDER, Account.Type.XENDER, selfAccountAddress ) + 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 + fromAddress = None + toAdddress = None + + if (messagesResultSet.getInt("c_direction") == 1): + direction = CommunicationDirection.OUTGOING + toAddress = Account.Address(messagesResultSet.getString("r_device_id"), messagesResultSet.getString("r_name")) + else: + direction = CommunicationDirection.INCOMING + fromAddress = Account.Address(messagesResultSet.getString("s_device_id"), messagesResultSet.getString("s_name")) + + 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, + fromAddress, + toAddress, + 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() + + + diff --git a/InternalPythonModules/android/zapya.py b/InternalPythonModules/android/zapya.py new file mode 100644 index 0000000000..230405075d --- /dev/null +++ b/InternalPythonModules/android/zapya.py @@ -0,0 +1,124 @@ +""" +Autopsy Forensic Browser + +Copyright 2019 Basis Technology Corp. +Contact: carrier sleuthkit org + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +from java.io import File +from java.lang import Class +from java.lang import ClassNotFoundException +from java.lang import Long +from java.lang import String +from java.sql import ResultSet +from java.sql import SQLException +from java.sql import Statement +from java.util.logging import Level +from java.util import ArrayList +from org.apache.commons.codec.binary import Base64 +from org.sleuthkit.autopsy.casemodule import Case +from org.sleuthkit.autopsy.casemodule import NoCurrentCaseException +from org.sleuthkit.autopsy.coreutils import Logger +from org.sleuthkit.autopsy.coreutils import MessageNotifyUtil +from org.sleuthkit.autopsy.coreutils import AppSQLiteDB +from org.sleuthkit.autopsy.datamodel import ContentUtils +from org.sleuthkit.autopsy.ingest import IngestJobContext +from org.sleuthkit.datamodel import AbstractFile +from org.sleuthkit.datamodel import BlackboardArtifact +from org.sleuthkit.datamodel import BlackboardAttribute +from org.sleuthkit.datamodel import Content +from org.sleuthkit.datamodel import TskCoreException +from org.sleuthkit.datamodel.Blackboard import BlackboardException +from org.sleuthkit.datamodel import Account +from org.sleuthkit.datamodel.blackboardutils import CommunicationArtifactsHelper +from org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper import MessageReadStatus +from org.sleuthkit.datamodel.blackboardutils.CommunicationArtifactsHelper import CommunicationDirection + +import traceback +import general + +""" +Finds the SQLite DB for Zapya, parses the DB for contacts & messages, +and adds artifacts to the case. +""" +class ZapyaAnalyzer(general.AndroidComponentAnalyzer): + + def __init__(self): + self._logger = Logger.getLogger(self.__class__.__name__) + self._PACKAGE_NAME = "com.dewmobile.kuaiya.play" + self._MODULE_NAME = "Zapya Analyzer" + self._MESSAGE_TYPE = "Zapya Message" + self._VERSION = "5.8.3" + + 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 + fromAddress = None + toAddress = None + + if (transfersResultSet.getInt("direction") == 1): + direction = CommunicationDirection.OUTGOING + toAddress = Account.Address(transfersResultSet.getString("device"), transfersResultSet.getString("name") ) + else: + direction = CommunicationDirection.INCOMING + fromAddress = Account.Address(transfersResultSet.getString("device"), transfersResultSet.getString("name") ) + + msgBody = "" # there is no body. + attachments = [transfersResultSet.getString("path")] + msgBody = general.appendAttachmentList(msgBody, attachments) + + timeStamp = transfersResultSet.getLong("createtime") / 1000 + messageArtifact = transferDbHelper.addMessage( + self._MESSAGE_TYPE, + direction, + fromAddress, + toAddress, + 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 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() + + +