mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge branch 'develop' of github.com:sleuthkit/autopsy into central_repo_fixes_3693
This commit is contained in:
commit
ec0583a69e
@ -31,7 +31,6 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.filechooser.FileFilter;
|
import javax.swing.filechooser.FileFilter;
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
import org.openide.modules.InstalledFileLocator;
|
import org.openide.modules.InstalledFileLocator;
|
||||||
import org.openide.util.Exceptions;
|
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.util.lookup.ServiceProvider;
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
@ -52,8 +51,8 @@ import org.sleuthkit.autopsy.datasourceprocessors.AutoIngestDataSourceProcessor;
|
|||||||
*/
|
*/
|
||||||
@ServiceProviders(value = {
|
@ServiceProviders(value = {
|
||||||
@ServiceProvider(service = DataSourceProcessor.class),
|
@ServiceProvider(service = DataSourceProcessor.class),
|
||||||
@ServiceProvider(service = AutoIngestDataSourceProcessor.class)}
|
@ServiceProvider(service = AutoIngestDataSourceProcessor.class)
|
||||||
)
|
})
|
||||||
@Messages({
|
@Messages({
|
||||||
"LocalFilesDSProcessor.logicalEvidenceFilter.desc=Logical Evidence Files (L01)"
|
"LocalFilesDSProcessor.logicalEvidenceFilter.desc=Logical Evidence Files (L01)"
|
||||||
})
|
})
|
||||||
@ -344,15 +343,15 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
|
|||||||
// It should return lowest possible non-zero confidence level and be treated
|
// It should return lowest possible non-zero confidence level and be treated
|
||||||
// as the "option of last resort" for auto ingest purposes
|
// as the "option of last resort" for auto ingest purposes
|
||||||
|
|
||||||
this.localFilePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
|
List<String> filePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
|
||||||
//If there is only 1 file check if it is an L01 file and if it is extract the
|
//If there is only 1 file check if it is an L01 file and if it is extract the
|
||||||
//contents and replace the paths, if the contents can't be extracted return 0
|
//contents and replace the paths, if the contents can't be extracted return 0
|
||||||
if (localFilePaths.size() == 1) {
|
if (filePaths.size() == 1) {
|
||||||
for (final String path : localFilePaths) {
|
for (final String path : filePaths) {
|
||||||
if (new File(path).isFile() && LOGICAL_EVIDENCE_FILTER.accept(new File(path))) {
|
if (new File(path).isFile() && LOGICAL_EVIDENCE_FILTER.accept(new File(path))) {
|
||||||
try {
|
try {
|
||||||
//if the L01 option was chosen
|
//if the L01 option was chosen
|
||||||
localFilePaths = extractLogicalEvidenceFileContents(localFilePaths);
|
filePaths = extractLogicalEvidenceFileContents(filePaths);
|
||||||
} catch (L01Exception ex) {
|
} catch (L01Exception ex) {
|
||||||
logger.log(Level.WARNING, "File extension was .l01 but contents of logical evidence file were unable to be extracted", ex);
|
logger.log(Level.WARNING, "File extension was .l01 but contents of logical evidence file were unable to be extracted", ex);
|
||||||
//contents of l01 could not be extracted don't add data source or run ingest
|
//contents of l01 could not be extracted don't add data source or run ingest
|
||||||
@ -369,7 +368,8 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
public void process(String deviceId, Path dataSourcePath, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callBack) {
|
||||||
run(deviceId, deviceId, this.localFilePaths, progressMonitor, callBack);
|
List<String> filePaths = Arrays.asList(new String[]{dataSourcePath.toString()});
|
||||||
|
run(deviceId, deviceId, filePaths, progressMonitor, callBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,9 +177,15 @@ public abstract class AbstractSqlEamDb implements EamDb {
|
|||||||
* @returns New Case class with populated database ID
|
* @returns New Case class with populated database ID
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException {
|
public synchronized CorrelationCase newCase(CorrelationCase eamCase) throws EamDbException {
|
||||||
Connection conn = connect();
|
|
||||||
|
// check if there is already an existing CorrelationCase for this Case
|
||||||
|
CorrelationCase cRCase = getCaseByUUID(eamCase.getCaseUUID());
|
||||||
|
if (cRCase != null) {
|
||||||
|
return cRCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection conn = connect();
|
||||||
PreparedStatement preparedStatement = null;
|
PreparedStatement preparedStatement = null;
|
||||||
|
|
||||||
String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
|
String sql = "INSERT INTO cases(case_uid, org_id, case_name, creation_date, case_number, "
|
||||||
|
@ -503,7 +503,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
rtfbodyTextPane.setText("");
|
rtfbodyTextPane.setText("");
|
||||||
htmlbodyTextPane.setText("");
|
htmlbodyTextPane.setText("");
|
||||||
textbodyTextArea.setText("");
|
textbodyTextArea.setText("");
|
||||||
drp.setNode(null);
|
|
||||||
showImagesToggleButton.setEnabled(false);
|
showImagesToggleButton.setEnabled(false);
|
||||||
msgbodyTabbedPane.setEnabled(false);
|
msgbodyTabbedPane.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ DataContentViewerString.pageLabel2.text=Page
|
|||||||
# Product Information panel
|
# Product Information panel
|
||||||
LBL_Description=<div style=\"font-size: 12pt; font-family: Verdana, 'Verdana CE', Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif;\">\n <b>Product Version:</b> {0} ({9}) <br><b>Sleuth Kit Version:</b> {7} <br><b>Netbeans RCP Build:</b> {8} <br> <b>Java:</b> {1}; {2}<br> <b>System:</b> {3}; {4}; {5}<br><b>Userdir:</b> {6}</div>
|
LBL_Description=<div style=\"font-size: 12pt; font-family: Verdana, 'Verdana CE', Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif;\">\n <b>Product Version:</b> {0} ({9}) <br><b>Sleuth Kit Version:</b> {7} <br><b>Netbeans RCP Build:</b> {8} <br> <b>Java:</b> {1}; {2}<br> <b>System:</b> {3}; {4}; {5}<br><b>Userdir:</b> {6}</div>
|
||||||
Format_OperatingSystem_Value={0} version {1} running on {2}
|
Format_OperatingSystem_Value={0} version {1} running on {2}
|
||||||
LBL_Copyright=<div style\="font-size\: 12pt; font-family\: Verdana, 'Verdana CE', Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif; ">Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools. <br><ul><li>General Information: <a style\="color\: \#1E2A60;" href\="http\://www.sleuthkit.org">http\://www.sleuthkit.org</a>.</li><li>Training: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/autopsy-training">http://www.basistech.com/autopsy-training</a></li><li>Commercial Support: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/digital-forensics/autopsy/support/">http://www.basistech.com/digital-forensics/autopsy/support/</a></li></ul>Copyright © 2003-2017. </div>
|
LBL_Copyright=<div style\="font-size\: 12pt; font-family\: Verdana, 'Verdana CE', Arial, 'Arial CE', 'Lucida Grande CE', lucida, 'Helvetica CE', sans-serif; ">Autopsy™ is a digital forensics platform based on The Sleuth Kit™ and other tools. <br><ul><li>General Information: <a style\="color\: \#1E2A60;" href\="http\://www.sleuthkit.org">http\://www.sleuthkit.org</a>.</li><li>Training: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/autopsy-training">http://www.basistech.com/autopsy-training</a></li><li>Commercial Support: <a style\="color\: \#1E2A60;" href\="http://www.basistech.com/digital-forensics/autopsy/support/">http://www.basistech.com/digital-forensics/autopsy/support/</a></li></ul>Copyright © 2003-2018. </div>
|
||||||
URL_ON_IMG=http://www.sleuthkit.org/
|
URL_ON_IMG=http://www.sleuthkit.org/
|
||||||
URL_ON_HELP=http://sleuthkit.org/autopsy/docs/user-docs/4.6.0/
|
URL_ON_HELP=http://sleuthkit.org/autopsy/docs/user-docs/4.6.0/
|
||||||
FILE_FOR_LOCAL_HELP=file:///
|
FILE_FOR_LOCAL_HELP=file:///
|
||||||
|
@ -72,8 +72,8 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
|||||||
private static final Logger logger = Logger.getLogger(IngestJobSettingsPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(IngestJobSettingsPanel.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a panel to allow a user to make ingest job settings.
|
* Construct a panel to allow a user to make ingest job settings. This
|
||||||
* This constructor assumes there is no ingest history.
|
* constructor assumes there is no ingest history.
|
||||||
*
|
*
|
||||||
* @param settings The initial settings for the ingest job.
|
* @param settings The initial settings for the ingest job.
|
||||||
*/
|
*/
|
||||||
@ -88,8 +88,8 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a panel to allow a user to make ingest job settings.
|
* Construct a panel to allow a user to make ingest job settings. This
|
||||||
* This constructor enables tracking of ingest job history.
|
* constructor enables tracking of ingest job history.
|
||||||
*
|
*
|
||||||
* @param settings The initial settings for the ingest job.
|
* @param settings The initial settings for the ingest job.
|
||||||
* @param dataSources The data sources ingest is being run on.
|
* @param dataSources The data sources ingest is being run on.
|
||||||
@ -423,16 +423,20 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
|||||||
} catch (FilesSetsManager.FilesSetsManagerException ex) {
|
} catch (FilesSetsManager.FilesSetsManagerException ex) {
|
||||||
logger.log(Level.SEVERE, "Failed to get user created file ingest filters, only default available for selection", ex); //NON-NLS
|
logger.log(Level.SEVERE, "Failed to get user created file ingest filters, only default available for selection", ex); //NON-NLS
|
||||||
}
|
}
|
||||||
|
String filterToSelect = settings.getFileFilter().getName();
|
||||||
for (FilesSet filter : newFilterList) { //getting one of the recently created filters
|
for (FilesSet filter : newFilterList) { //getting one of the recently created filters
|
||||||
if (!oldFilterList.contains(filter.getName())) {
|
if (!oldFilterList.contains(filter.getName())) {
|
||||||
//set newly created filter to selected filter
|
//set newly created filter to selected filter
|
||||||
settings.setFileFilter(filter);
|
filterToSelect = filter.getName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileIngestFilterComboBox.setModel(new DefaultComboBoxModel<>(getComboBoxContents()));
|
fileIngestFilterComboBox.setModel(new DefaultComboBoxModel<>(getComboBoxContents()));
|
||||||
//set the selected filter after the comboBox Contents were updated to include it
|
//set the selected filter after the comboBox Contents were updated to include it
|
||||||
fileIngestFilterComboBox.setSelectedItem(settings.getFileFilter().getName());
|
fileIngestFilterComboBox.setSelectedItem(filterToSelect);
|
||||||
|
//refresh the saved filter in use case where the selected modified filter
|
||||||
|
//has the same name as a previously existing filter
|
||||||
|
updateSelectedFilter(filterToSelect);
|
||||||
dialog.close();
|
dialog.close();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -440,21 +444,25 @@ public final class IngestJobSettingsPanel extends javax.swing.JPanel {
|
|||||||
//return to saved selection in case they cancel out of filter creation
|
//return to saved selection in case they cancel out of filter creation
|
||||||
fileIngestFilterComboBox.setSelectedItem(settings.getFileFilter().getName());
|
fileIngestFilterComboBox.setSelectedItem(settings.getFileFilter().getName());
|
||||||
} else if (evt.getActionCommand().equals("comboBoxChanged")) {
|
} else if (evt.getActionCommand().equals("comboBoxChanged")) {
|
||||||
try {
|
updateSelectedFilter(fileIngestFilterComboBox.getSelectedItem().toString());
|
||||||
Map<String, FilesSet> fileIngestFilters = FilesSetsManager.getInstance()
|
|
||||||
.getCustomFileIngestFilters();
|
|
||||||
for (FilesSet fSet : FilesSetsManager.getStandardFileIngestFilters()) {
|
|
||||||
fileIngestFilters.put(fSet.getName(), fSet);
|
|
||||||
}
|
|
||||||
settings.setFileFilter(fileIngestFilters
|
|
||||||
.get(fileIngestFilterComboBox.getSelectedItem().toString()));
|
|
||||||
} catch (FilesSetsManager.FilesSetsManagerException ex) {
|
|
||||||
settings.setFileFilter(FilesSetsManager.getDefaultFilter());
|
|
||||||
logger.log(Level.SEVERE, "Failed to get file ingest filter from combobox selection, default filter being used", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}//GEN-LAST:event_fileIngestFilterComboBoxActionPerformed
|
}//GEN-LAST:event_fileIngestFilterComboBoxActionPerformed
|
||||||
|
|
||||||
|
private void updateSelectedFilter(String filterName) {
|
||||||
|
try {
|
||||||
|
Map<String, FilesSet> fileIngestFilters = FilesSetsManager.getInstance()
|
||||||
|
.getCustomFileIngestFilters();
|
||||||
|
for (FilesSet fSet : FilesSetsManager.getStandardFileIngestFilters()) {
|
||||||
|
fileIngestFilters.put(fSet.getName(), fSet);
|
||||||
|
}
|
||||||
|
settings.setFileFilter(fileIngestFilters
|
||||||
|
.get(filterName));
|
||||||
|
} catch (FilesSetsManager.FilesSetsManagerException ex) {
|
||||||
|
settings.setFileFilter(FilesSetsManager.getDefaultFilter());
|
||||||
|
logger.log(Level.SEVERE, "Failed to get file ingest filter from combobox selection, default filter being used", ex); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array which will contain the names of all options which should
|
* Returns an array which will contain the names of all options which should
|
||||||
* exist in the "Run Ingest Modules On:" JCombobox
|
* exist in the "Run Ingest Modules On:" JCombobox
|
||||||
|
@ -44,6 +44,8 @@ import org.sleuthkit.autopsy.ingest.IngestJobSettings.IngestType;
|
|||||||
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory;
|
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeIdModuleFactory;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule;
|
||||||
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ExtensionCondition;
|
||||||
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.FullNameCondition;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MetaTypeCondition;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MetaTypeCondition;
|
||||||
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ParentPathCondition;
|
import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ParentPathCondition;
|
||||||
import org.sleuthkit.autopsy.testutils.DataSourceProcessorRunner;
|
import org.sleuthkit.autopsy.testutils.DataSourceProcessorRunner;
|
||||||
@ -147,8 +149,8 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
//All files in dir1 should have MIME type, except '.' '..' and slack files
|
//All files in dir1 should have MIME type, except '.' '..' and slack files
|
||||||
if (file.getParentPath().equalsIgnoreCase("/dir1/")) {
|
if (file.getParentPath().equalsIgnoreCase("/dir1/")) {
|
||||||
if (!(file.getName().equals(".") || file.getName().equals("..") || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)) {
|
if (!(file.getName().equals(".") || file.getName().equals("..") || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)) {
|
||||||
String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId());
|
String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId());
|
||||||
assertTrue(errMsg, !(file.getMIMEType() == null || file.getMIMEType().isEmpty()));
|
assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty());
|
||||||
}
|
}
|
||||||
} else { //All files not in dir1 shouldn't have MIME type
|
} else { //All files not in dir1 shouldn't have MIME type
|
||||||
String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId());
|
String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId());
|
||||||
@ -161,6 +163,98 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testExtAndDirWithOneRule() {
|
||||||
|
HashMap<String, Rule> rules = new HashMap<>();
|
||||||
|
rules.put("Rule", new Rule("testExtAndDirWithOneRule", new ExtensionCondition("jpg"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), new ParentPathCondition("dir1"), null, null, null));
|
||||||
|
//Build the filter that ignore unallocated space and with one rule
|
||||||
|
FilesSet filesExtDirsFilter = new FilesSet("Filter", "Filter to find all jpg files in dir1.", false, true, rules);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Case openCase = Case.getOpenCase();
|
||||||
|
runIngestJob(openCase.getDataSources(), filesExtDirsFilter);
|
||||||
|
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
||||||
|
List<AbstractFile> results = fileManager.findFiles("%%");
|
||||||
|
assertEquals(62, results.size());
|
||||||
|
for (AbstractFile file : results) {
|
||||||
|
//Files with jpg extension in dir1 should have MIME Type
|
||||||
|
if (file.getParentPath().equalsIgnoreCase("/dir1/") && file.getNameExtension().equalsIgnoreCase("jpg")) {
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty());
|
||||||
|
} else { //All others shouldn't have MIME Type
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() == null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExtAndDirWithTwoRules() {
|
||||||
|
HashMap<String, Rule> rules = new HashMap<>();
|
||||||
|
rules.put("rule1", new Rule("FindJpgExtention", new ExtensionCondition("jpg"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null));
|
||||||
|
rules.put("rule2", new Rule("FindDir1Directory", null, new MetaTypeCondition(MetaTypeCondition.Type.FILES), new ParentPathCondition("dir1"), null, null, null));
|
||||||
|
//Build the filter that ingnore unallocated space and with 2 rules
|
||||||
|
FilesSet filesExtDirsFilter = new FilesSet("Filter", "Filter to find all files in dir1 and all files with jpg extention.", false, true, rules);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Case openCase = Case.getOpenCase();
|
||||||
|
runIngestJob(openCase.getDataSources(), filesExtDirsFilter);
|
||||||
|
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
||||||
|
List<AbstractFile> results = fileManager.findFiles("%%");
|
||||||
|
assertEquals(62, results.size());
|
||||||
|
for (AbstractFile file : results) {
|
||||||
|
if (file.getNameExtension().equalsIgnoreCase("jpg")) { //All files with .jpg extension should have MIME type
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty());
|
||||||
|
} else if (file.getParentPath().equalsIgnoreCase("/dir1/")) {
|
||||||
|
//All files in dir1 should have MIME type except '.' '..' slack files
|
||||||
|
if (file.getName().equals(".") || file.getName().equals("..") || file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK) {
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() == null);
|
||||||
|
} else {
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty());
|
||||||
|
}
|
||||||
|
} else { //All files that are not in dir1 or not with .jpg extension should not have MIME type
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() == null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFullFileNameRule() {
|
||||||
|
HashMap<String, Rule> rules = new HashMap<>();
|
||||||
|
rules.put("rule", new Rule("FindFileWithFullName", new FullNameCondition("file.docx"), new MetaTypeCondition(MetaTypeCondition.Type.FILES), null, null, null, null));
|
||||||
|
//Build the filter to find file: file.docx
|
||||||
|
FilesSet fullNameFilter = new FilesSet("Filter", "Filter to find file.docx.", false, true, rules);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Case openCase = Case.getOpenCase();
|
||||||
|
runIngestJob(openCase.getDataSources(), fullNameFilter);
|
||||||
|
FileManager fileManager = Case.getOpenCase().getServices().getFileManager();
|
||||||
|
List<AbstractFile> results = fileManager.findFiles("%%");
|
||||||
|
assertEquals(62, results.size());
|
||||||
|
for (AbstractFile file : results) {
|
||||||
|
//Only file.docx has MIME Type
|
||||||
|
if (file.getName().equalsIgnoreCase("file.docx")) {
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly blocked by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() != null && !file.getMIMEType().isEmpty());
|
||||||
|
} else {
|
||||||
|
String errMsg = String.format("File %s (objId=%d) unexpectedly passed by the file filter.", file.getName(), file.getId());
|
||||||
|
assertTrue(errMsg, file.getMIMEType() == null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
Assert.fail(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
private void runIngestJob(List<Content> datasources, FilesSet filter) {
|
private void runIngestJob(List<Content> datasources, FilesSet filter) {
|
||||||
FileTypeIdModuleFactory factory = new FileTypeIdModuleFactory();
|
FileTypeIdModuleFactory factory = new FileTypeIdModuleFactory();
|
||||||
IngestModuleIngestJobSettings settings = factory.getDefaultIngestJobSettings();
|
IngestModuleIngestJobSettings settings = factory.getDefaultIngestJobSettings();
|
||||||
@ -171,6 +265,9 @@ public class IngestFileFiltersTest extends NbTestCase {
|
|||||||
IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestFileFiltersTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates, filter);
|
IngestJobSettings ingestJobSettings = new IngestJobSettings(IngestFileFiltersTest.class.getCanonicalName(), IngestType.FILES_ONLY, templates, filter);
|
||||||
try {
|
try {
|
||||||
List<IngestModuleError> errs = IngestJobRunner.runIngestJob(datasources, ingestJobSettings);
|
List<IngestModuleError> errs = IngestJobRunner.runIngestJob(datasources, ingestJobSettings);
|
||||||
|
for (IngestModuleError err : errs) {
|
||||||
|
System.out.println(String.format("Error: %s: %s.", err.getModuleDisplayName(), err.toString()));
|
||||||
|
}
|
||||||
assertEquals(0, errs.size());
|
assertEquals(0, errs.size());
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -23,80 +23,89 @@ import java.nio.file.Paths;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgressMonitor;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
|
||||||
import org.sleuthkit.datamodel.Image;
|
import org.sleuthkit.datamodel.Image;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A runnable that adds a raw data source to a case database.
|
* A runnable that adds a memory image data source to a case database.
|
||||||
*/
|
*/
|
||||||
final class AddMemoryImageTask implements Runnable {
|
final class AddMemoryImageTask implements Runnable {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(AddMemoryImageTask.class.getName());
|
private final static Logger logger = Logger.getLogger(AddMemoryImageTask.class.getName());
|
||||||
private final String deviceId;
|
private final String deviceId;
|
||||||
private final String imageFilePath;
|
private final String memoryImagePath;
|
||||||
private final String timeZone;
|
private final String timeZone;
|
||||||
private final List<String> pluginsToRun;
|
private final List<String> pluginsToRun;
|
||||||
private final DataSourceProcessorProgressMonitor progressMonitor;
|
private final DataSourceProcessorProgressMonitor progressMonitor;
|
||||||
private final DataSourceProcessorCallback callback;
|
private final DataSourceProcessorCallback callback;
|
||||||
private VolatilityProcessor volatilityProcessor = null;
|
private volatile VolatilityProcessor volatilityProcessor;
|
||||||
private boolean isCancelled = false;
|
private volatile boolean isCancelled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a runnable that adds a raw data source to a case database.
|
* Constructs a runnable that adds a memory image to a case database.
|
||||||
*
|
*
|
||||||
* @param deviceId An ASCII-printable identifier for the
|
* @param deviceId An ASCII-printable identifier for the device
|
||||||
* device associated with the data source
|
* associated with the data source that is intended
|
||||||
* that is intended to be unique across
|
* to be unique across multiple cases (e.g., a UUID).
|
||||||
* multiple cases (e.g., a UUID).
|
* @param memoryImagePath Path to the memory image file.
|
||||||
* @param imageFilePath Path to a Raw data source file.
|
* @param pluginsToRun The Volatility plugins to run.
|
||||||
* @param timeZone The time zone to use when processing dates
|
* @param timeZone The time zone to use when processing dates and
|
||||||
* and times for the image, obtained from
|
* times for the image, obtained from
|
||||||
* java.util.TimeZone.getID.
|
* java.util.TimeZone.getID.
|
||||||
* @param breakupChunks 2GB or not breakup.
|
* @param progressMonitor Progress monitor for reporting progressMonitor
|
||||||
* @param progressMonitor Progress monitor for reporting
|
* during processing.
|
||||||
* progressMonitor during processing.
|
* @param callback Callback to call when processing is done.
|
||||||
* @param callback Callback to call when processing is done.
|
|
||||||
*/
|
*/
|
||||||
AddMemoryImageTask(String deviceId, String imageFilePath, List<String> PluginsToRun, String timeZone, long chunkSize, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
AddMemoryImageTask(String deviceId, String memoryImagePath, List<String> pluginsToRun, String timeZone, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
this.deviceId = deviceId;
|
this.deviceId = deviceId;
|
||||||
this.imageFilePath = imageFilePath;
|
this.memoryImagePath = memoryImagePath;
|
||||||
this.pluginsToRun = PluginsToRun;
|
this.pluginsToRun = pluginsToRun;
|
||||||
this.timeZone = timeZone;
|
this.timeZone = timeZone;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.progressMonitor = progressMonitor;
|
this.progressMonitor = progressMonitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a raw data source to a case database.
|
* Adds a memory image data source to a case database.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Messages({
|
||||||
|
"# {0} - exception message",
|
||||||
|
"AddMemoryImageTask_errorMessage_criticalException= Critical error: {0}",
|
||||||
|
})
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if (isCancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
progressMonitor.setIndeterminate(true);
|
progressMonitor.setIndeterminate(true);
|
||||||
progressMonitor.setProgress(0);
|
progressMonitor.setProgress(0);
|
||||||
|
List<Content> dataSources = new ArrayList<>();
|
||||||
List<String> errorMessages = new ArrayList<>();
|
List<String> errorMessages = new ArrayList<>();
|
||||||
boolean criticalErrorOccurred = false;
|
boolean criticalErrorOccurred = false;
|
||||||
Image dataSource = addImageToCase(errorMessages);
|
try {
|
||||||
if (dataSource == null) {
|
Image dataSource = addImageToCase();
|
||||||
|
dataSources.add(dataSource);
|
||||||
|
volatilityProcessor = new VolatilityProcessor(memoryImagePath, dataSource, pluginsToRun, progressMonitor);
|
||||||
|
volatilityProcessor.run();
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException | VolatilityProcessor.VolatilityProcessorException ex) {
|
||||||
criticalErrorOccurred = true;
|
criticalErrorOccurred = true;
|
||||||
|
errorMessages.add(Bundle.AddMemoryImageTask_errorMessage_criticalException(ex.getLocalizedMessage()));
|
||||||
|
/*
|
||||||
|
* Log the exception as well as add it to the error messages, to
|
||||||
|
* ensure that the stack trace is not lost.
|
||||||
|
*/
|
||||||
|
logger.log(Level.SEVERE, String.format("Critical error processing memory image data source at %s for device %s", memoryImagePath, deviceId), ex);
|
||||||
}
|
}
|
||||||
/* call Volatility to process the image */
|
errorMessages.addAll(volatilityProcessor.getErrorMessages());
|
||||||
else {
|
|
||||||
if (isCancelled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
volatilityProcessor = new VolatilityProcessor(imageFilePath, dataSource, pluginsToRun, progressMonitor);
|
|
||||||
if (volatilityProcessor.run()) {
|
|
||||||
criticalErrorOccurred = true;
|
|
||||||
}
|
|
||||||
errorMessages.addAll(volatilityProcessor.getErrorMessages());
|
|
||||||
}
|
|
||||||
|
|
||||||
progressMonitor.setProgress(100);
|
progressMonitor.setProgress(100);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,55 +119,64 @@ final class AddMemoryImageTask implements Runnable {
|
|||||||
} else {
|
} else {
|
||||||
result = DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS;
|
result = DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS;
|
||||||
}
|
}
|
||||||
|
callback.done(result, errorMessages, dataSources);
|
||||||
callback.done(result, errorMessages, new ArrayList<>(Arrays.asList(dataSource)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to add the input image to the case.
|
* Attempts to add the input memory image to the case as a data source.
|
||||||
*
|
*
|
||||||
* @param errorMessages If there are any error messages, the error messages
|
* @return The Image object representation of the memeory image file data
|
||||||
* are added to this list for eventual return to the
|
* source.
|
||||||
* caller via the callback.
|
*
|
||||||
* @returns Image that was added to DB or null on error
|
* @throws NoCurrentCaseException If there is no current case.
|
||||||
|
* @throws TskCoreException If there is an error adding the data
|
||||||
|
* source to the case database.
|
||||||
*/
|
*/
|
||||||
@Messages({"AddMemoryImageTask.progress.add.text=Adding memory image: ",
|
@Messages({
|
||||||
"AddMemoryImageTask.image.critical.error.adding=Critical error adding ",
|
"# {0} - image file path",
|
||||||
"AddMemoryImageTask.for.device=for device ",
|
"AddMemoryImageTask_progressMessage_addingImageFile= Adding memory image {0}",
|
||||||
"AddMemoryImageTask.image.notExisting=is not existing.",
|
"# {0} - image file path",
|
||||||
"AddMemoryImageTask.image.noncritical.error.adding=Non-critical error adding "})
|
"# {1} - device id",
|
||||||
private Image addImageToCase(List<String> errorMessages) {
|
"AddMemoryImageTask_exceptionMessage_noImageFile= Memory image file {0} for device {1} does not exist"
|
||||||
progressMonitor.setProgressText(Bundle.AddMemoryImageTask_progress_add_text() + imageFilePath);
|
})
|
||||||
|
private Image addImageToCase() throws NoCurrentCaseException, TskCoreException {
|
||||||
SleuthkitCase caseDatabase = Case.getCurrentCase().getSleuthkitCase();
|
progressMonitor.setProgressText(Bundle.AddMemoryImageTask_progressMessage_addingImageFile( memoryImagePath));
|
||||||
caseDatabase.acquireExclusiveLock();
|
|
||||||
|
|
||||||
// verify it exists
|
SleuthkitCase caseDatabase = Case.getOpenCase().getSleuthkitCase();
|
||||||
File imageFile = Paths.get(imageFilePath).toFile();
|
caseDatabase.acquireSingleUserCaseWriteLock();
|
||||||
if (!imageFile.exists()) {
|
|
||||||
errorMessages.add(Bundle.AddMemoryImageTask_image_critical_error_adding() + imageFilePath + Bundle.AddMemoryImageTask_for_device()
|
|
||||||
+ deviceId + Bundle.AddMemoryImageTask_image_notExisting());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// add it to the DB
|
/*
|
||||||
List<String> imageFilePaths = new ArrayList<>();
|
* Verify the memory image file exists.
|
||||||
imageFilePaths.add(imageFilePath);
|
*/
|
||||||
Image dataSource = caseDatabase.addImageInfo(0, imageFilePaths, timeZone); //TODO: change hard coded deviceId.
|
File imageFile = Paths.get(memoryImagePath).toFile();
|
||||||
|
if (!imageFile.exists()) {
|
||||||
|
throw new TskCoreException(Bundle.AddMemoryImageTask_exceptionMessage_noImageFile(memoryImagePath, deviceId));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the data source.
|
||||||
|
*
|
||||||
|
* NOTE: The object id for device passed to
|
||||||
|
* SleuthkitCase.addImageInfo is hard-coded to zero for now. This
|
||||||
|
* will need to be changed when a Device abstraction is added to the
|
||||||
|
* SleuthKit data model.
|
||||||
|
*/
|
||||||
|
Image dataSource = caseDatabase.addImageInfo(0, new ArrayList<>(Arrays.asList(memoryImagePath)), timeZone);
|
||||||
return dataSource;
|
return dataSource;
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
errorMessages.add(Bundle.AddMemoryImageTask_image_critical_error_adding() + imageFilePath + Bundle.AddMemoryImageTask_for_device() + deviceId + ":" + ex.getLocalizedMessage());
|
|
||||||
return null;
|
|
||||||
} finally {
|
} finally {
|
||||||
caseDatabase.releaseExclusiveLock();
|
caseDatabase.releaseSingleUserCaseWriteLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests cancellation of this task by setting a cancelled flag.
|
||||||
|
*/
|
||||||
void cancelTask() {
|
void cancelTask() {
|
||||||
isCancelled = true;
|
isCancelled = true;
|
||||||
if (volatilityProcessor != null) {
|
if (volatilityProcessor != null) {
|
||||||
volatilityProcessor.cancel();
|
volatilityProcessor.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -37,11 +37,13 @@ import javax.swing.table.AbstractTableModel;
|
|||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
|
||||||
import org.sleuthkit.autopsy.coreutils.PathValidator;
|
import org.sleuthkit.autopsy.coreutils.PathValidator;
|
||||||
|
|
||||||
final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L; //default
|
private static final long serialVersionUID = 1L; //default
|
||||||
private final String PROP_LASTINPUT_PATH = "LBL_LastInputFile_PATH";
|
private final String PROP_LASTINPUT_PATH = "LBL_LastInputFile_PATH";
|
||||||
private final JFileChooser fc = new JFileChooser();
|
private final JFileChooser fc = new JFileChooser();
|
||||||
@ -52,14 +54,14 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
private final List<String> PluginListNames = new ArrayList<>();
|
private final List<String> PluginListNames = new ArrayList<>();
|
||||||
private final Map<String, Boolean> pluginListStates = new HashMap<>(); // is set by listeners when users select and deselect items
|
private final Map<String, Boolean> pluginListStates = new HashMap<>(); // is set by listeners when users select and deselect items
|
||||||
private final Boolean isEnabled = true;
|
private final Boolean isEnabled = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new MemoryDSInputPanel panel for user input
|
* Creates new MemoryDSInputPanel panel for user input
|
||||||
*/
|
*/
|
||||||
private MemoryDSInputPanel(String context) {
|
private MemoryDSInputPanel(String context) {
|
||||||
this.pluginList = new String[]{"amcache","cmdline","cmdscan","consoles","malfind","netscan","notepad","pslist","psxview","shellbags","shimcache","shutdown","userassist", "apihooks","connscan","devicetree","dlllist","envars","filescan","gahti","getservicesids","getsids","handles","hashdump","hivelist","hivescan","impscan","ldrmodules","lsadump","modules","mutantscan","privs","psscan","pstree","sockets","svcscan","shimcache","timeliner","unloadedmodules","userhandles","vadinfo","verinfo"};
|
this.pluginList = new String[]{"amcache", "cmdline", "cmdscan", "consoles", "malfind", "netscan", "notepad", "pslist", "psxview", "shellbags", "shimcache", "shutdown", "userassist", "apihooks", "connscan", "devicetree", "dlllist", "envars", "filescan", "gahti", "getservicesids", "getsids", "handles", "hashdump", "hivelist", "hivescan", "impscan", "ldrmodules", "lsadump", "modules", "mutantscan", "privs", "psscan", "pstree", "sockets", "svcscan", "shimcache", "timeliner", "unloadedmodules", "userhandles", "vadinfo", "verinfo"};
|
||||||
Arrays.sort(this.pluginList);
|
Arrays.sort(this.pluginList);
|
||||||
|
|
||||||
initComponents();
|
initComponents();
|
||||||
|
|
||||||
errorLabel.setVisible(false);
|
errorLabel.setVisible(false);
|
||||||
@ -91,7 +93,7 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
private void postInit() {
|
private void postInit() {
|
||||||
pathTextField.getDocument().addDocumentListener(this);
|
pathTextField.getDocument().addDocumentListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void customizePluginListTable() {
|
private void customizePluginListTable() {
|
||||||
PluginList.setModel(tableModel);
|
PluginList.setModel(tableModel);
|
||||||
PluginList.setTableHeader(null);
|
PluginList.setTableHeader(null);
|
||||||
@ -135,14 +137,14 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
// set the selected timezone
|
// set the selected timezone
|
||||||
timeZoneComboBox.setSelectedItem(formatted);
|
timeZoneComboBox.setSelectedItem(formatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createVolatilityVersionList() {
|
private void createVolatilityVersionList() {
|
||||||
|
|
||||||
volExecutableComboBox.addItem("2.6");
|
volExecutableComboBox.addItem("2.6");
|
||||||
volExecutableComboBox.addItem("2.5");
|
volExecutableComboBox.addItem("2.5");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createPluginList() {
|
private void createPluginList() {
|
||||||
PluginListNames.clear();
|
PluginListNames.clear();
|
||||||
pluginListStates.clear();
|
pluginListStates.clear();
|
||||||
@ -150,19 +152,19 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
// if the config file doesn't exist, then set them all to enabled
|
// if the config file doesn't exist, then set them all to enabled
|
||||||
boolean allEnabled = !ModuleSettings.configExists(this.contextName);
|
boolean allEnabled = !ModuleSettings.configExists(this.contextName);
|
||||||
Map<String, String> pluginMap = ModuleSettings.getConfigSettings(this.contextName);
|
Map<String, String> pluginMap = ModuleSettings.getConfigSettings(this.contextName);
|
||||||
|
|
||||||
for (String plugin : pluginList) {
|
for (String plugin : pluginList) {
|
||||||
PluginListNames.add(plugin);
|
PluginListNames.add(plugin);
|
||||||
if (allEnabled)
|
if (allEnabled) {
|
||||||
pluginListStates.put(plugin, true);
|
pluginListStates.put(plugin, true);
|
||||||
else
|
} else {
|
||||||
pluginListStates.put(plugin, pluginMap.containsKey(plugin));
|
pluginListStates.put(plugin, pluginMap.containsKey(plugin));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tableModel.fireTableDataChanged();
|
tableModel.fireTableDataChanged();
|
||||||
//this.tableModel = pluginsToRun.getModel();
|
//this.tableModel = pluginsToRun.getModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -282,18 +284,18 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
private void browseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseButtonActionPerformed
|
||||||
String oldText = pathTextField.getText();
|
String oldText = pathTextField.getText();
|
||||||
// set the current directory of the FileChooser if the ImagePath Field is valid
|
// set the current directory of the FileChooser if the ImagePath Field is valid
|
||||||
File currentDir = new File(oldText);
|
File currentDir = new File(oldText);
|
||||||
if (currentDir.exists()) {
|
if (currentDir.exists()) {
|
||||||
fc.setCurrentDirectory(currentDir);
|
fc.setCurrentDirectory(currentDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
int retval = fc.showOpenDialog(this);
|
int retval = fc.showOpenDialog(this);
|
||||||
if (retval == JFileChooser.APPROVE_OPTION) {
|
if (retval == JFileChooser.APPROVE_OPTION) {
|
||||||
String path = fc.getSelectedFile().getPath();
|
String path = fc.getSelectedFile().getPath();
|
||||||
pathTextField.setText(path);
|
pathTextField.setText(path);
|
||||||
}
|
}
|
||||||
}//GEN-LAST:event_browseButtonActionPerformed
|
}//GEN-LAST:event_browseButtonActionPerformed
|
||||||
|
|
||||||
private void volExecutableComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_volExecutableComboBoxActionPerformed
|
private void volExecutableComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_volExecutableComboBoxActionPerformed
|
||||||
@ -322,7 +324,7 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
String getImageFilePath() {
|
String getImageFilePath() {
|
||||||
return pathTextField.getText();
|
return pathTextField.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> getPluginsToRun() {
|
List<String> getPluginsToRun() {
|
||||||
List<String> enabledPlugins = new ArrayList<>();
|
List<String> enabledPlugins = new ArrayList<>();
|
||||||
Map<String, String> pluginMap = new HashMap<>();
|
Map<String, String> pluginMap = new HashMap<>();
|
||||||
@ -332,7 +334,7 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
pluginMap.put(plugin, "");
|
pluginMap.put(plugin, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleSettings.setConfigSettings(this.contextName, pluginMap);
|
ModuleSettings.setConfigSettings(this.contextName, pluginMap);
|
||||||
// @@ Could return keys of set
|
// @@ Could return keys of set
|
||||||
return enabledPlugins;
|
return enabledPlugins;
|
||||||
@ -374,11 +376,19 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
*
|
*
|
||||||
* @param path Absolute path to the selected data source
|
* @param path Absolute path to the selected data source
|
||||||
*/
|
*/
|
||||||
@Messages({"MemoryDSInputPanel.error.text=Path to multi-user data source is on \"C:\" drive"})
|
@Messages({
|
||||||
|
"MemoryDSInputPanel_errorMsg_noOpenCase=No open case",
|
||||||
|
"MemoryDSInputPanel_errorMsg_dataSourcePathOnCdrive=Path to multi-user data source is on \"C:\" drive"
|
||||||
|
})
|
||||||
private void warnIfPathIsInvalid(String path) {
|
private void warnIfPathIsInvalid(String path) {
|
||||||
if (!PathValidator.isValid(path, Case.getCurrentCase().getCaseType())) {
|
try {
|
||||||
|
if (!PathValidator.isValid(path, Case.getOpenCase().getCaseType())) {
|
||||||
|
errorLabel.setVisible(true);
|
||||||
|
errorLabel.setText(Bundle.MemoryDSInputPanel_errorMsg_dataSourcePathOnCdrive());
|
||||||
|
}
|
||||||
|
} catch (NoCurrentCaseException unused) {
|
||||||
errorLabel.setVisible(true);
|
errorLabel.setVisible(true);
|
||||||
errorLabel.setText(Bundle.MemoryDSInputPanel_error_text());
|
errorLabel.setText(Bundle.MemoryDSInputPanel_errorMsg_dataSourcePathOnCdrive());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,5 +480,4 @@ final class MemoryDSInputPanel extends JPanel implements DocumentListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2011-2016 Basis Technology Corp.
|
* Copyright 2018 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -28,21 +28,21 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback
|
|||||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A MEmory data source processor that implements the DataSourceProcessor service
|
* A memory image data source processor that implements the DataSourceProcessor
|
||||||
* provider interface to allow integration with the add data source wizard. It
|
* service provider interface to allow integration with the Add Data Source
|
||||||
* also provides a run method overload to allow it to be used independently of
|
* wizard. It also provides a run method overload to allow it to be used
|
||||||
* the wizard.
|
* independently of the wizard.
|
||||||
*/
|
*/
|
||||||
@ServiceProvider(service = DataSourceProcessor.class)
|
@ServiceProvider(service = DataSourceProcessor.class)
|
||||||
public class MemoryDSProcessor implements DataSourceProcessor {
|
public class MemoryDSProcessor implements DataSourceProcessor {
|
||||||
|
|
||||||
private final MemoryDSInputPanel configPanel;
|
private final MemoryDSInputPanel configPanel;
|
||||||
private AddMemoryImageTask addImageTask = null;
|
private AddMemoryImageTask addImageTask;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructs a Memory data source processor that implements the
|
* Constructs a memory data source processor that implements the
|
||||||
* DataSourceProcessor service provider interface to allow integration with
|
* DataSourceProcessor service provider interface to allow integration with
|
||||||
* the add data source wizard. It also provides a run method overload to
|
* the Add Data source wizard. It also provides a run method overload to
|
||||||
* allow it to be used independently of the wizard.
|
* allow it to be used independently of the wizard.
|
||||||
*/
|
*/
|
||||||
public MemoryDSProcessor() {
|
public MemoryDSProcessor() {
|
||||||
@ -117,37 +117,40 @@ public class MemoryDSProcessor implements DataSourceProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
configPanel.storeSettings();
|
configPanel.storeSettings();
|
||||||
run(UUID.randomUUID().toString(), configPanel.getImageFilePath(), configPanel.getPluginsToRun(), configPanel.getTimeZone(), 0, progressMonitor, callback);
|
run(UUID.randomUUID().toString(), configPanel.getImageFilePath(), configPanel.getPluginsToRun(), configPanel.getTimeZone(), progressMonitor, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a "memory" data source to the case database using a background task in
|
* Adds a memory image data source to the case database using a background
|
||||||
* a separate thread and the given settings instead of those provided by the
|
* task in a separate thread and the given settings instead of those
|
||||||
* selection and configuration panel. Returns as soon as the background task
|
* provided by the selection and configuration panel. Returns as soon as the
|
||||||
* is started and uses the callback object to signal task completion and
|
* background task is started and uses the callback object to signal task
|
||||||
* return results.
|
* completion and return results.
|
||||||
*
|
*
|
||||||
* @param deviceId An ASCII-printable identifier for the device
|
* @param deviceId An ASCII-printable identifier for the device
|
||||||
* associated with the data source that is
|
* associated with the data source that is intended
|
||||||
* intended to be unique across multiple cases
|
* to be unique across multiple cases (e.g., a UUID).
|
||||||
* (e.g., a UUID).
|
* @param memoryImagePath Path to the memory image file.
|
||||||
* @param imageFilePath Path to the image file.
|
* @param pluginsToRun The Volatility plugins to run.
|
||||||
* @param timeZone The time zone to use when processing dates
|
* @param timeZone The time zone to use when processing dates and
|
||||||
* and times for the image, obtained from
|
* times for the image, obtained from
|
||||||
* java.util.TimeZone.getID.
|
* java.util.TimeZone.getID.
|
||||||
* @param chunkSize The maximum size of each chunk of the raw
|
* @param progressMonitor Progress monitor for reporting progress during
|
||||||
* data source as it is divided up into virtual
|
* processing.
|
||||||
* unallocated space files.
|
* @param callback Callback to call when processing is done.
|
||||||
* @param progressMonitor Progress monitor for reporting progress
|
|
||||||
* during processing.
|
|
||||||
* @param callback Callback to call when processing is done.
|
|
||||||
*/
|
*/
|
||||||
private void run(String deviceId, String imageFilePath, List<String> pluginsToRun, String timeZone, long chunkSize, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
private void run(String deviceId, String memoryImagePath, List<String> pluginsToRun, String timeZone, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
|
||||||
addImageTask = new AddMemoryImageTask(deviceId, imageFilePath, pluginsToRun, timeZone, 0, progressMonitor, callback);
|
addImageTask = new AddMemoryImageTask(deviceId, memoryImagePath, pluginsToRun, timeZone, progressMonitor, callback);
|
||||||
new Thread(addImageTask).start();
|
new Thread(addImageTask).start();
|
||||||
//new Thread(new AddLocalFilesTask(deviceId, rootVirtualDirectoryName, localFilePaths, progressMonitor, callback)).start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests cancellation of the background task that adds a data source to
|
||||||
|
* the case database, after the task is started using the run method. This
|
||||||
|
* is a "best effort" cancellation, with no guarantees that the case
|
||||||
|
* database will be unchanged. If cancellation succeeded, the list of new
|
||||||
|
* data sources returned by the background task will be empty.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
if (addImageTask != null) {
|
if (addImageTask != null) {
|
||||||
@ -165,4 +168,3 @@ public class MemoryDSProcessor implements DataSourceProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -645,18 +645,18 @@ final class RegexQuery implements KeywordSearchQuery {
|
|||||||
*/
|
*/
|
||||||
static private void addAttributeIfNotAlreadyCaptured(Map<BlackboardAttribute.Type, BlackboardAttribute> attributeMap, ATTRIBUTE_TYPE attrType, String groupName, Matcher matcher) {
|
static private void addAttributeIfNotAlreadyCaptured(Map<BlackboardAttribute.Type, BlackboardAttribute> attributeMap, ATTRIBUTE_TYPE attrType, String groupName, Matcher matcher) {
|
||||||
BlackboardAttribute.Type type = new BlackboardAttribute.Type(attrType);
|
BlackboardAttribute.Type type = new BlackboardAttribute.Type(attrType);
|
||||||
attributeMap.computeIfAbsent(type, t -> {
|
|
||||||
|
if( ! attributeMap.containsKey(type)) {
|
||||||
String value = matcher.group(groupName);
|
String value = matcher.group(groupName);
|
||||||
if (attrType.equals(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)) {
|
if (attrType.equals(ATTRIBUTE_TYPE.TSK_CARD_NUMBER)) {
|
||||||
attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD),
|
attributeMap.put(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_KEYWORD),
|
||||||
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, value));
|
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD, MODULE_NAME, value));
|
||||||
value = CharMatcher.anyOf(" -").removeFrom(value);
|
value = CharMatcher.anyOf(" -").removeFrom(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(value)) {
|
if (StringUtils.isNotBlank(value)) {
|
||||||
return new BlackboardAttribute(attrType, MODULE_NAME, value);
|
attributeMap.put(type, new BlackboardAttribute(attrType, MODULE_NAME, value));
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user