From bf383af0664ec94c3463c3dbee0a38bbf8189a43 Mon Sep 17 00:00:00 2001 From: Raman Date: Thu, 12 Sep 2019 07:45:19 -0400 Subject: [PATCH] 5446: Xender 5447: Zapya 5448: ShareIt --- InternalPythonModules/android/general.py | 15 +++ InternalPythonModules/android/module.py | 6 +- InternalPythonModules/android/shareit.py | 109 +++++++++++++++++++++ InternalPythonModules/android/xender.py | 117 +++++++++++++++++++++++ InternalPythonModules/android/zapya.py | 110 +++++++++++++++++++++ 5 files changed, 356 insertions(+), 1 deletion(-) create mode 100644 InternalPythonModules/android/shareit.py create mode 100644 InternalPythonModules/android/xender.py create mode 100644 InternalPythonModules/android/zapya.py diff --git a/InternalPythonModules/android/general.py b/InternalPythonModules/android/general.py index 28c96be9b9..1d0832362b 100644 --- a/InternalPythonModules/android/general.py +++ b/InternalPythonModules/android/general.py @@ -26,3 +26,18 @@ class AndroidComponentAnalyzer: # The Analyzer should implement this method def analyze(self, dataSource, fileManager, context): raise NotImplementedError + + + +""" +A utility method to append list of attachments to msg body +""" +def appendAttachmentList(msgBody, attachmentsList): + body = msgBody + if attachmentsList: + body = body + "\n\n------------Attachments------------\n" + body = body + "\n".join(attachmentsList) + + return body + + diff --git a/InternalPythonModules/android/module.py b/InternalPythonModules/android/module.py index 6430ec82be..996059adbc 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 class AndroidModuleFactory(IngestModuleFactoryAdapter): @@ -91,7 +94,8 @@ class AndroidIngestModule(DataSourceIngestModule): analyzers = [contact.ContactAnalyzer(), calllog.CallLogAnalyzer(), textmessage.TextMessageAnalyzer(), tangomessage.TangoMessageAnalyzer(), wwfmessage.WWFMessageAnalyzer(), googlemaplocation.GoogleMapLocationAnalyzer(), browserlocation.BrowserLocationAnalyzer(), - cachelocation.CacheLocationAnalyzer(), imo.IMOAnalyzer()] + cachelocation.CacheLocationAnalyzer(), imo.IMOAnalyzer(), + xender.XenderAnalyzer(), zapya.ZapyaAnalyzer(), shareit.ShareItAnalyzer()] 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..9d661fb9c0 --- /dev/null +++ b/InternalPythonModules/android/shareit.py @@ -0,0 +1,109 @@ +""" +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.coreutils import Logger +from org.sleuthkit.autopsy.coreutils import MessageNotifyUtil +from org.sleuthkit.autopsy.coreutils import AppSQLiteDB +from org.sleuthkit.autopsy.coreutils import AppDBParserHelper +from org.sleuthkit.autopsy.coreutils.AppDBParserHelper import CommunicationDirection +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 import Account + +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): + + moduleName = "ShareIT Analyzer" + progName = "ShareIt" + + def __init__(self): + self._logger = Logger.getLogger(self.__class__.__name__) + + def analyze(self, dataSource, fileManager, context): + historyDbs = AppSQLiteDB.findAppDatabases(dataSource, "history.db", True, "com.lenovo.anyshare.gps") + for historyDb in historyDbs: + try: + historyDbHelper = AppDBParserHelper(self.moduleName, 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( + "ShareIt Message", + direction, + fromAddress, + toAddress, + timeStamp, + AppDBParserHelper.MessageReadStatusEnum.UNKNOWN, + None, # subject + msgBody, + "" ) + + # TBD: add the file as attachment ?? + + except SQLException as ex: + self._logger.log(Level.SEVERE, "Error processing query result for ShareIt history.", ex) + except TskCoreException as ex: + self._logger.log(Level.SEVERE, "Failed to create AppDBParserHelper for adding artifacts.", ex) + finally: + historyDb.close() + + + diff --git a/InternalPythonModules/android/xender.py b/InternalPythonModules/android/xender.py new file mode 100644 index 0000000000..f3ea2ad2f3 --- /dev/null +++ b/InternalPythonModules/android/xender.py @@ -0,0 +1,117 @@ +""" +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.coreutils import Logger +from org.sleuthkit.autopsy.coreutils import MessageNotifyUtil +from org.sleuthkit.autopsy.coreutils import AppSQLiteDB +from org.sleuthkit.autopsy.coreutils import AppDBParserHelper +from org.sleuthkit.autopsy.coreutils.AppDBParserHelper import CommunicationDirection +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 import Account + +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): + + moduleName = "Xender Analyzer" + progName = "Xender" + + def __init__(self): + self._logger = Logger.getLogger(self.__class__.__name__) + + def analyze(self, dataSource, fileManager, context): + selfAccountAddress = None + transactionDbs = AppSQLiteDB.findAppDatabases(dataSource, "trans-history-db", True, "cn.xender") + for transactionDb in transactionDbs: + try: + # 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")) + + transactionDbHelper = AppDBParserHelper(self.moduleName, transactionDb.getDBFile(), + Account.Type.XENDER, Account.Type.XENDER, selfAccountAddress ) + + 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( + "Xender Message", + direction, + fromAddress, + toAddress, + timeStamp, + AppDBParserHelper.MessageReadStatusEnum.UNKNOWN, + None, + msgBody, + messagesResultSet.getString("c_session_id") ) + + # TBD: add the file as attachment ?? + + except SQLException as ex: + self._logger.log(Level.SEVERE, "Error processing query result for profiles", ex) + except TskCoreException as ex: + self._logger.log(Level.SEVERE, "Failed to create AppDBParserHelper for adding artifacts.", ex) + finally: + transactionDb.close() + + + diff --git a/InternalPythonModules/android/zapya.py b/InternalPythonModules/android/zapya.py new file mode 100644 index 0000000000..9338e47440 --- /dev/null +++ b/InternalPythonModules/android/zapya.py @@ -0,0 +1,110 @@ +""" +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.coreutils import Logger +from org.sleuthkit.autopsy.coreutils import MessageNotifyUtil +from org.sleuthkit.autopsy.coreutils import AppSQLiteDB +from org.sleuthkit.autopsy.coreutils import AppDBParserHelper +from org.sleuthkit.autopsy.coreutils.AppDBParserHelper import CommunicationDirection +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 import Account + +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): + + moduleName = "Zapya Analyzer" + progName = "Zapya" + + def __init__(self): + self._logger = Logger.getLogger(self.__class__.__name__) + + def analyze(self, dataSource, fileManager, context): + transferDbs = AppSQLiteDB.findAppDatabases(dataSource, "transfer20.db", True, "com.dewmobile.kuaiya.play") + for transferDb in transferDbs: + try: + transferDbHelper = AppDBParserHelper(self.moduleName, 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 + toAdddress = 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( + "Zapya Message", + direction, + fromAddress, + toAddress, + timeStamp, + AppDBParserHelper.MessageReadStatusEnum.UNKNOWN, + None, + msgBody, + "" ) + + # TBD: add the file as attachment ?? + + except SQLException as ex: + self._logger.log(Level.SEVERE, "Error processing query result for transfer", ex) + except TskCoreException as ex: + self._logger.log(Level.SEVERE, "Failed to create AppDBParserHelper for adding artifacts.", ex) + + finally: + transferDb.close() + + +