mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Cleaned up samples, added files associated with data source tutorial
This commit is contained in:
parent
568160d61e
commit
b6d911fa6b
@ -70,21 +70,16 @@ class SampleDataSourceIngestModule implements DataSourceIngestModule {
|
||||
|
||||
@Override
|
||||
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
return IngestModule.ProcessResult.OK;
|
||||
}
|
||||
|
||||
// There are two tasks to do.
|
||||
progressBar.switchToDeterminate(2);
|
||||
|
||||
Case autopsyCase = Case.getCurrentCase();
|
||||
SleuthkitCase sleuthkitCase = autopsyCase.getSleuthkitCase();
|
||||
Services services = new Services(sleuthkitCase);
|
||||
FileManager fileManager = services.getFileManager();
|
||||
try {
|
||||
// Get count of files with .doc extension.
|
||||
long fileCount = 0;
|
||||
FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
|
||||
List<AbstractFile> docFiles = fileManager.findFiles(dataSource, "%.doc");
|
||||
|
||||
long fileCount = 0;
|
||||
for (AbstractFile docFile : docFiles) {
|
||||
if (!skipKnownFiles || docFile.getKnown() != TskData.FileKnown.KNOWN) {
|
||||
++fileCount;
|
||||
@ -92,6 +87,7 @@ class SampleDataSourceIngestModule implements DataSourceIngestModule {
|
||||
}
|
||||
progressBar.progress(1);
|
||||
|
||||
// check if we were cancelled
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
return IngestModule.ProcessResult.OK;
|
||||
}
|
||||
|
176
pythonExamples/Aug2015DataSourceTutorial/FindContactsDb.py
Executable file
176
pythonExamples/Aug2015DataSourceTutorial/FindContactsDb.py
Executable file
@ -0,0 +1,176 @@
|
||||
# Sample module in the public domain. Feel free to use this as a template
|
||||
# for your modules (and you can remove this header and take complete credit
|
||||
# and liability)
|
||||
#
|
||||
# Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
#
|
||||
# In jurisdictions that recognize copyright laws, the author or authors
|
||||
# of this software dedicate any and all copyright interest in the
|
||||
# software to the public domain. We make this dedication for the benefit
|
||||
# of the public at large and to the detriment of our heirs and
|
||||
# successors. We intend this dedication to be an overt act of
|
||||
# relinquishment in perpetuity of all present and future rights to this
|
||||
# software under copyright law.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# Simple data source-level ingest module for Autopsy.
|
||||
# Used as part of Python tutorials from Basis Technology - August 2015
|
||||
#
|
||||
# Looks for files of a given name, opens then in SQLite, queries the DB,
|
||||
# and makes artifacts
|
||||
|
||||
import jarray
|
||||
import inspect
|
||||
import os
|
||||
from java.lang import Class
|
||||
from java.lang import System
|
||||
from java.sql import DriverManager, SQLException
|
||||
from java.util.logging import Level
|
||||
from java.io import File
|
||||
from org.sleuthkit.datamodel import SleuthkitCase
|
||||
from org.sleuthkit.datamodel import AbstractFile
|
||||
from org.sleuthkit.datamodel import ReadContentInputStream
|
||||
from org.sleuthkit.datamodel import BlackboardArtifact
|
||||
from org.sleuthkit.datamodel import BlackboardAttribute
|
||||
from org.sleuthkit.autopsy.ingest import IngestModule
|
||||
from org.sleuthkit.autopsy.ingest.IngestModule import IngestModuleException
|
||||
from org.sleuthkit.autopsy.ingest import DataSourceIngestModule
|
||||
from org.sleuthkit.autopsy.ingest import IngestModuleFactoryAdapter
|
||||
from org.sleuthkit.autopsy.ingest import IngestMessage
|
||||
from org.sleuthkit.autopsy.ingest import IngestServices
|
||||
from org.sleuthkit.autopsy.ingest import ModuleDataEvent
|
||||
from org.sleuthkit.autopsy.coreutils import Logger
|
||||
from org.sleuthkit.autopsy.casemodule import Case
|
||||
from org.sleuthkit.autopsy.casemodule.services import Services
|
||||
from org.sleuthkit.autopsy.casemodule.services import FileManager
|
||||
from org.sleuthkit.autopsy.datamodel import ContentUtils
|
||||
|
||||
|
||||
# Factory that defines the name and details of the module and allows Autopsy
|
||||
# to create instances of the modules that will do the analysis.
|
||||
class ContactsDbIngestModuleFactory(IngestModuleFactoryAdapter):
|
||||
|
||||
moduleName = "Contacts Db Analyzer"
|
||||
|
||||
def getModuleDisplayName(self):
|
||||
return self.moduleName
|
||||
|
||||
def getModuleDescription(self):
|
||||
return "Sample module that parses contacts.db"
|
||||
|
||||
def getModuleVersionNumber(self):
|
||||
return "1.0"
|
||||
|
||||
def isDataSourceIngestModuleFactory(self):
|
||||
return True
|
||||
|
||||
def createDataSourceIngestModule(self, ingestOptions):
|
||||
return ContactsDbIngestModule()
|
||||
|
||||
|
||||
# Data Source-level ingest module. One gets created per data source.
|
||||
class ContactsDbIngestModule(DataSourceIngestModule):
|
||||
|
||||
_logger = Logger.getLogger(ContactsDbIngestModuleFactory.moduleName)
|
||||
|
||||
def log(self, level, msg):
|
||||
self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)
|
||||
|
||||
def __init__(self):
|
||||
self.context = None
|
||||
|
||||
# Where any setup and configuration is done
|
||||
# 'context' is an instance of org.sleuthkit.autopsy.ingest.IngestJobContext.
|
||||
# See: http://sleuthkit.org/autopsy/docs/api-docs/3.1/classorg_1_1sleuthkit_1_1autopsy_1_1ingest_1_1_ingest_job_context.html
|
||||
def startUp(self, context):
|
||||
self.context = context
|
||||
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
|
||||
# raise IngestModuleException("Oh No!")
|
||||
|
||||
# Where the analysis is done.
|
||||
# The 'dataSource' object being passed in is of type org.sleuthkit.datamodel.Content.
|
||||
# See: http://www.sleuthkit.org/sleuthkit/docs/jni-docs/interfaceorg_1_1sleuthkit_1_1datamodel_1_1_content.html
|
||||
# 'progressBar' is of type org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress
|
||||
# See: http://sleuthkit.org/autopsy/docs/api-docs/3.1/classorg_1_1sleuthkit_1_1autopsy_1_1ingest_1_1_data_source_ingest_module_progress.html
|
||||
def process(self, dataSource, progressBar):
|
||||
|
||||
# we don't know how much work there is yet
|
||||
progressBar.switchToIndeterminate()
|
||||
|
||||
# Find files named contacts.db, regardless of parent path
|
||||
fileManager = Case.getCurrentCase().getServices().getFileManager()
|
||||
files = fileManager.findFiles(dataSource, "contacts.db")
|
||||
|
||||
numFiles = len(files)
|
||||
progressBar.switchToDeterminate(numFiles)
|
||||
fileCount = 0;
|
||||
for file in files:
|
||||
|
||||
# Check if the user pressed cancel while we were busy
|
||||
if self.context.isJobCancelled():
|
||||
return IngestModule.ProcessResult.OK
|
||||
|
||||
self.log(Level.INFO, "Processing file: " + file.getName())
|
||||
fileCount += 1
|
||||
|
||||
# Save the DB locally in the temp folder. use file id as name to reduce collisions
|
||||
lclDbPath = os.path.join(Case.getCurrentCase().getTempDirectory(), str(file.getId()) + ".db")
|
||||
ContentUtils.writeToFile(file, File(lclDbPath))
|
||||
|
||||
# Open the DB using JDBC
|
||||
Class.forName("org.sqlite.JDBC").newInstance()
|
||||
dbConn = DriverManager.getConnection("jdbc:sqlite:%s" % lclDbPath)
|
||||
|
||||
# Query the contacts table in the database and get all columns.
|
||||
stmt = dbConn.createStatement()
|
||||
resultSet = stmt.executeQuery("SELECT * FROM contacts")
|
||||
|
||||
# Cycle through each row and create artifacts
|
||||
while resultSet.next():
|
||||
|
||||
# Make an artifact on the blackboard, TSK_CONTACT and give it attributes for each of the fields
|
||||
art = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT)
|
||||
|
||||
name = resultSet.getString("name")
|
||||
art.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME_PERSON.getTypeID(),
|
||||
ContactsDbIngestModuleFactory.moduleName, name))
|
||||
|
||||
email = resultSet.getString("email")
|
||||
art.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL.getTypeID(),
|
||||
ContactsDbIngestModuleFactory.moduleName, email))
|
||||
|
||||
phone = resultSet.getString("phone")
|
||||
art.addAttribute(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER.getTypeID(),
|
||||
ContactsDbIngestModuleFactory.moduleName, phone))
|
||||
|
||||
# Fire an event to notify the UI and others that there are new artifacts
|
||||
IngestServices.getInstance().fireModuleDataEvent(
|
||||
ModuleDataEvent(ContactsDbIngestModuleFactory.moduleName,
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT, None))
|
||||
|
||||
# Clean up
|
||||
stmt.close()
|
||||
dbConn.close()
|
||||
os.remove(lclDbPath)
|
||||
|
||||
|
||||
# After all databases, post a message to the ingest messages in box.
|
||||
message = IngestMessage.createMessage(IngestMessage.MessageType.DATA,
|
||||
"ContactsDb Analyzer", "Found %d files" % fileCount)
|
||||
IngestServices.getInstance().postMessage(message)
|
||||
|
||||
return IngestModule.ProcessResult.OK
|
7
pythonExamples/Aug2015DataSourceTutorial/README.txt
Executable file
7
pythonExamples/Aug2015DataSourceTutorial/README.txt
Executable file
@ -0,0 +1,7 @@
|
||||
This folder contains files that were created for an August 2015 Tutorial from Basis Technology.
|
||||
|
||||
It contains the following:
|
||||
- FindContactsDb.py: Script to find databases and parse them.
|
||||
- Contacts.db: Sample database with the correct name and schema for the FindContactsDb.py script.
|
||||
- RunExe.py: Script that runs img_stat.exe on disk images.
|
||||
- img_stat.exe: 32-bit version of img_stat.exe from The Sleuth Kit that is needed by RunExe.py.
|
144
pythonExamples/Aug2015DataSourceTutorial/RunExe.py
Executable file
144
pythonExamples/Aug2015DataSourceTutorial/RunExe.py
Executable file
@ -0,0 +1,144 @@
|
||||
# Sample module in the public domain. Feel free to use this as a template
|
||||
# for your modules (and you can remove this header and take complete credit
|
||||
# and liability)
|
||||
#
|
||||
# Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
#
|
||||
# In jurisdictions that recognize copyright laws, the author or authors
|
||||
# of this software dedicate any and all copyright interest in the
|
||||
# software to the public domain. We make this dedication for the benefit
|
||||
# of the public at large and to the detriment of our heirs and
|
||||
# successors. We intend this dedication to be an overt act of
|
||||
# relinquishment in perpetuity of all present and future rights to this
|
||||
# software under copyright law.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# Simple data source-level ingest module for Autopsy.
|
||||
# Used as part of Python tutorials from Basis Technology - August 2015
|
||||
#
|
||||
# Runs img_stat tool from The Sleuth Kit on each data source, saves the
|
||||
# output, and adds a report to the Case for the output
|
||||
|
||||
import jarray
|
||||
import inspect
|
||||
import os
|
||||
import subprocess
|
||||
from java.lang import Class
|
||||
from java.lang import System
|
||||
from java.util.logging import Level
|
||||
from org.sleuthkit.datamodel import SleuthkitCase
|
||||
from org.sleuthkit.datamodel import AbstractFile
|
||||
from org.sleuthkit.datamodel import ReadContentInputStream
|
||||
from org.sleuthkit.datamodel import BlackboardArtifact
|
||||
from org.sleuthkit.datamodel import BlackboardAttribute
|
||||
from org.sleuthkit.datamodel import Image
|
||||
from org.sleuthkit.autopsy.ingest import IngestModule
|
||||
from org.sleuthkit.autopsy.ingest.IngestModule import IngestModuleException
|
||||
from org.sleuthkit.autopsy.ingest import DataSourceIngestModule
|
||||
from org.sleuthkit.autopsy.ingest import IngestModuleFactoryAdapter
|
||||
from org.sleuthkit.autopsy.ingest import IngestMessage
|
||||
from org.sleuthkit.autopsy.ingest import IngestServices
|
||||
from org.sleuthkit.autopsy.ingest import ModuleDataEvent
|
||||
from org.sleuthkit.autopsy.coreutils import Logger
|
||||
from org.sleuthkit.autopsy.coreutils import PlatformUtil
|
||||
from org.sleuthkit.autopsy.casemodule import Case
|
||||
from org.sleuthkit.autopsy.casemodule.services import Services
|
||||
from org.sleuthkit.autopsy.datamodel import ContentUtils
|
||||
|
||||
|
||||
# Factory that defines the name and details of the module and allows Autopsy
|
||||
# to create instances of the modules that will do the analysis.
|
||||
class RunExeIngestModuleFactory(IngestModuleFactoryAdapter):
|
||||
|
||||
moduleName = "Run EXE Module"
|
||||
|
||||
def getModuleDisplayName(self):
|
||||
return self.moduleName
|
||||
|
||||
def getModuleDescription(self):
|
||||
return "Sample module that runs img_stat on each disk image."
|
||||
|
||||
def getModuleVersionNumber(self):
|
||||
return "1.0"
|
||||
|
||||
def isDataSourceIngestModuleFactory(self):
|
||||
return True
|
||||
|
||||
def createDataSourceIngestModule(self, ingestOptions):
|
||||
return RunExeIngestModule()
|
||||
|
||||
|
||||
# Data Source-level ingest module. One gets created per data source.
|
||||
class RunExeIngestModule(DataSourceIngestModule):
|
||||
|
||||
_logger = Logger.getLogger(RunExeIngestModuleFactory.moduleName)
|
||||
|
||||
def log(self, level, msg):
|
||||
self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)
|
||||
|
||||
def __init__(self):
|
||||
self.context = None
|
||||
|
||||
# Where any setup and configuration is done
|
||||
# 'context' is an instance of org.sleuthkit.autopsy.ingest.IngestJobContext.
|
||||
# See: http://sleuthkit.org/autopsy/docs/api-docs/3.1/classorg_1_1sleuthkit_1_1autopsy_1_1ingest_1_1_ingest_job_context.html
|
||||
def startUp(self, context):
|
||||
self.context = context
|
||||
|
||||
# Get path to EXE based on where this script is run from.
|
||||
# Assumes EXE is in same folder as script
|
||||
# Verify it is there before any ingest starts
|
||||
self.path_to_exe = os.path.join(os.path.dirname(os.path.abspath(__file__)), "img_stat.exe")
|
||||
if not os.path.exists(self.path_to_exe):
|
||||
raise IngestModuleException("EXE was not found in module folder")
|
||||
|
||||
# Where the analysis is done.
|
||||
# The 'dataSource' object being passed in is of type org.sleuthkit.datamodel.Content.
|
||||
# See: http://www.sleuthkit.org/sleuthkit/docs/jni-docs/interfaceorg_1_1sleuthkit_1_1datamodel_1_1_content.html
|
||||
# 'progressBar' is of type org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress
|
||||
# See: http://sleuthkit.org/autopsy/docs/api-docs/3.1/classorg_1_1sleuthkit_1_1autopsy_1_1ingest_1_1_data_source_ingest_module_progress.html
|
||||
def process(self, dataSource, progressBar):
|
||||
|
||||
# we don't know how much work there will be
|
||||
progressBar.switchToIndeterminate()
|
||||
|
||||
# Example has only a Windows EXE, so bail if we aren't on Windows
|
||||
if not PlatformUtil.isWindowsOS():
|
||||
self.log(Level.INFO, "Ignoring data source. Not running on Windows")
|
||||
return IngestModule.ProcessResult.OK
|
||||
|
||||
# Verify we have a disk image and not a folder of files
|
||||
if not isinstance(dataSource, Image):
|
||||
self.log(Level.INFO, "Ignoring data source. Not an image")
|
||||
return IngestModule.ProcessResult.OK
|
||||
|
||||
# Get disk image paths
|
||||
imagePaths = dataSource.getPaths()
|
||||
|
||||
# We'll save our output to a file in the reports folder, named based on EXE and data source ID
|
||||
reportPath = os.path.join(Case.getCurrentCase().getCaseDirectory(), "Reports", "img_stat-" + str(dataSource.getId()) + ".txt")
|
||||
reportHandle = open(reportPath, 'w')
|
||||
|
||||
# Run the EXE, saving output to the report
|
||||
self.log(Level.INFO, "Running program on data source")
|
||||
subprocess.Popen([self.path_to_exe, imagePaths[0]], stdout=reportHandle).communicate()[0]
|
||||
reportHandle.close()
|
||||
|
||||
# Add the report to the case, so it shows up in the tree
|
||||
Case.getCurrentCase().addReport(reportPath, "Run EXE", "img_stat output")
|
||||
|
||||
return IngestModule.ProcessResult.OK
|
BIN
pythonExamples/Aug2015DataSourceTutorial/contacts.db
Executable file
BIN
pythonExamples/Aug2015DataSourceTutorial/contacts.db
Executable file
Binary file not shown.
BIN
pythonExamples/Aug2015DataSourceTutorial/img_stat.exe
Executable file
BIN
pythonExamples/Aug2015DataSourceTutorial/img_stat.exe
Executable file
Binary file not shown.
@ -98,7 +98,7 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
def startUp(self, context):
|
||||
self.context = context
|
||||
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
|
||||
# raise IngestModuleException(IngestModule(), "Oh No!")
|
||||
# raise IngestModuleException("Oh No!")
|
||||
|
||||
# Where the analysis is done.
|
||||
# The 'dataSource' object being passed in is of type org.sleuthkit.datamodel.Content.
|
||||
@ -107,20 +107,14 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
# See: http://sleuthkit.org/autopsy/docs/api-docs/3.1/classorg_1_1sleuthkit_1_1autopsy_1_1ingest_1_1_data_source_ingest_module_progress.html
|
||||
# TODO: Add your analysis code in here.
|
||||
def process(self, dataSource, progressBar):
|
||||
if self.context.isJobCancelled():
|
||||
return IngestModule.ProcessResult.OK
|
||||
|
||||
# we don't know how much work there is yet
|
||||
progressBar.switchToIndeterminate()
|
||||
|
||||
autopsyCase = Case.getCurrentCase()
|
||||
sleuthkitCase = autopsyCase.getSleuthkitCase()
|
||||
services = Services(sleuthkitCase)
|
||||
fileManager = services.getFileManager()
|
||||
|
||||
# For our example, we will use FileManager to get all
|
||||
# files with the word "test"
|
||||
# in the name and then count and read them
|
||||
fileManager = Case.getCurrentCase().getServices().getFileManager()
|
||||
files = fileManager.findFiles(dataSource, "%test%")
|
||||
|
||||
numFiles = len(files)
|
||||
|
@ -99,7 +99,7 @@ class SampleJythonFileIngestModule(FileIngestModule):
|
||||
self.filesFound = 0
|
||||
|
||||
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
|
||||
# raise IngestModuleException(IngestModule(), "Oh No!")
|
||||
# raise IngestModuleException("Oh No!")
|
||||
pass
|
||||
|
||||
# Where the analysis is done. Each file will be passed into here.
|
||||
|
@ -130,7 +130,7 @@ class SampleFileIngestModuleWithUI(FileIngestModule):
|
||||
self.log(Level.INFO, "flag is not set")
|
||||
|
||||
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
|
||||
# raise IngestModuleException(IngestModule(), "Oh No!")
|
||||
# raise IngestModuleException("Oh No!")
|
||||
pass
|
||||
|
||||
# Where the analysis is done. Each file will be passed into here.
|
||||
|
Loading…
x
Reference in New Issue
Block a user