mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 00:16:16 +00:00
Adding in plaso module, updating build.xml to use plaso
This commit is contained in:
parent
f1e3df73fe
commit
20a7799358
@ -39,7 +39,11 @@
|
|||||||
<copy todir="${basedir}/release/Tesseract-OCR" >
|
<copy todir="${basedir}/release/Tesseract-OCR" >
|
||||||
<fileset dir="${thirdparty.dir}/Tesseract-OCR"/>
|
<fileset dir="${thirdparty.dir}/Tesseract-OCR"/>
|
||||||
</copy>
|
</copy>
|
||||||
|
|
||||||
|
<!--Copy Plaso to release-->
|
||||||
|
<copy todir="${basedir}/release/plaso" >
|
||||||
|
<fileset dir="${thirdparty.dir}/plaso"/>
|
||||||
|
</copy>
|
||||||
<!--Copy GStreamer to release-->
|
<!--Copy GStreamer to release-->
|
||||||
<copy todir="${basedir}/release/gstreamer" >
|
<copy todir="${basedir}/release/gstreamer" >
|
||||||
<fileset dir="${thirdparty.dir}/gstreamer"/>
|
<fileset dir="${thirdparty.dir}/gstreamer"/>
|
||||||
|
@ -196,6 +196,53 @@ public final class ExecUtil {
|
|||||||
}
|
}
|
||||||
return process.exitValue();
|
return process.exitValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for the given process to finish, using the given ProcessTerminator.
|
||||||
|
*
|
||||||
|
* @param command The command that was used to start the process. Used
|
||||||
|
* only for logging purposes.
|
||||||
|
* @param process The process to wait for.
|
||||||
|
* @param terminator The ProcessTerminator used to determine if the process
|
||||||
|
* should be killed.
|
||||||
|
*
|
||||||
|
* @returnthe exit value of the process
|
||||||
|
*
|
||||||
|
* @throws SecurityException if a security manager exists and vetoes any
|
||||||
|
* aspect of running the process.
|
||||||
|
* @throws IOException if an I/o error occurs.
|
||||||
|
*/
|
||||||
|
public static int waitForTermination(String command, Process process, ProcessTerminator terminator) throws SecurityException, IOException {
|
||||||
|
return ExecUtil.waitForTermination(command, process, ExecUtil.DEFAULT_TIMEOUT, ExecUtil.DEFAULT_TIMEOUT_UNITS, terminator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int waitForTermination(String command, Process process, long timeOut, TimeUnit units, ProcessTerminator terminator) throws SecurityException, IOException {
|
||||||
|
try {
|
||||||
|
do {
|
||||||
|
process.waitFor(timeOut, units);
|
||||||
|
if (process.isAlive() && terminator.shouldTerminateProcess()) {
|
||||||
|
killProcess(process);
|
||||||
|
try {
|
||||||
|
process.waitFor(); //waiting to help ensure process is shutdown before calling interrupt() or returning
|
||||||
|
} catch (InterruptedException exx) {
|
||||||
|
Logger.getLogger(ExecUtil.class.getName()).log(Level.INFO, String.format("Wait for process termination following killProcess was interrupted for command %s", command));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (process.isAlive());
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
if (process.isAlive()) {
|
||||||
|
killProcess(process);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
process.waitFor(); //waiting to help ensure process is shutdown before calling interrupt() or returning
|
||||||
|
} catch (InterruptedException exx) {
|
||||||
|
Logger.getLogger(ExecUtil.class.getName()).log(Level.INFO, String.format("Wait for process termination following killProcess was interrupted for command %s", command));
|
||||||
|
}
|
||||||
|
Logger.getLogger(ExecUtil.class.getName()).log(Level.INFO, "Thread interrupted while running {0}", command); // NON-NLS
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
return process.exitValue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kills a process and its children
|
* Kills a process and its children
|
||||||
|
3
Core/src/org/sleuthkit/autopsy/modules/plaso/Bundle.properties
Executable file
3
Core/src/org/sleuthkit/autopsy/modules/plaso/Bundle.properties
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
PlasoModuleSettingsPanel.winRegCheckBox.text=winreg: Parser for Windows NT Registry (REGF) files.
|
||||||
|
PlasoModuleSettingsPanel.peCheckBox.text=pe: Parser for Portable Executable (PE) files.
|
||||||
|
PlasoModuleSettingsPanel.plasoParserInfoTextArea.text=All plaso parsers except chrome_cache and the ones listed below are run. chrome_cache duplicates data collected by the RecentActivity module. The parsers below add significantly to the processing time and should only be enabled if the events they produce are needed.
|
25
Core/src/org/sleuthkit/autopsy/modules/plaso/Bundle.properties-MERGED
Executable file
25
Core/src/org/sleuthkit/autopsy/modules/plaso/Bundle.properties-MERGED
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
# {0} - file that events are from
|
||||||
|
PlasoIngestModule.artifact.progress=Adding events to case: {0}
|
||||||
|
PlasoIngestModule.bad.imageFile=Cannot find image file name and path
|
||||||
|
PlasoIngestModule.completed=Plaso Processing Completed
|
||||||
|
PlasoIngestModule.create.artifacts.cancelled=Cancelled Plaso Artifact Creation
|
||||||
|
PlasoIngestModule.dataSource.not.an.image=Datasource is not an Image.
|
||||||
|
PlasoIngestModule.error.creating.output.dir=Error creating Plaso module output directory.
|
||||||
|
PlasoIngestModule.error.running.log2timeline=Error running log2timeline, see log file.
|
||||||
|
PlasoIngestModule.error.running.psort=Error running Psort, see log file.
|
||||||
|
PlasoIngestModule.event.datetime=Event Date Time
|
||||||
|
PlasoIngestModule.event.description=Event Description
|
||||||
|
PlasoIngestModule.exception.posting.artifact=Exception Posting artifact.
|
||||||
|
PlasoIngestModule.executable.not.found=Plaso Executable Not Found.
|
||||||
|
PlasoIngestModule.has.run=Plaso Plugin has been run.
|
||||||
|
PlasoIngestModule.log2timeline.cancelled=Log2timeline run was canceled
|
||||||
|
PlasoIngestModule.psort.cancelled=psort run was canceled
|
||||||
|
PlasoIngestModule.requires.windows=Plaso module requires windows.
|
||||||
|
PlasoIngestModule.running.psort=Running Psort
|
||||||
|
PlasoIngestModule.starting.log2timeline=Starting Log2timeline
|
||||||
|
PlasoModuleFactory.ingestJobSettings.exception.msg=Expected settings argument to be instanceof PlasoModuleSettings
|
||||||
|
PlasoModuleFactory_moduleDesc=Runs Plaso against a Data Source.
|
||||||
|
PlasoModuleFactory_moduleName=Plaso
|
||||||
|
PlasoModuleSettingsPanel.winRegCheckBox.text=winreg: Parser for Windows NT Registry (REGF) files.
|
||||||
|
PlasoModuleSettingsPanel.peCheckBox.text=pe: Parser for Portable Executable (PE) files.
|
||||||
|
PlasoModuleSettingsPanel.plasoParserInfoTextArea.text=All plaso parsers except chrome_cache and the ones listed below are run. chrome_cache duplicates data collected by the RecentActivity module. The parsers below add significantly to the processing time and should only be enabled if the events they produce are needed.
|
458
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoIngestModule.java
Executable file
458
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoIngestModule.java
Executable file
@ -0,0 +1,458 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018-2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.plaso;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import static java.util.Objects.nonNull;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import org.openide.modules.InstalledFileLocator;
|
||||||
|
import org.openide.util.Cancellable;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.services.FileManager;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.SQLiteDBConnect;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestMessage;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Blackboard;
|
||||||
|
import org.sleuthkit.datamodel.Blackboard.BlackboardException;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_TL_EVENT;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DESCRIPTION;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TL_EVENT_TYPE;
|
||||||
|
import org.sleuthkit.datamodel.Content;
|
||||||
|
import org.sleuthkit.datamodel.Image;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.timeline.EventType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data source ingest module that runs Plaso against the image.
|
||||||
|
*/
|
||||||
|
public class PlasoIngestModule implements DataSourceIngestModule {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(PlasoIngestModule.class.getName());
|
||||||
|
private static final String MODULE_NAME = PlasoModuleFactory.getModuleName();
|
||||||
|
|
||||||
|
private static final String PLASO = "plaso"; //NON-NLS
|
||||||
|
private static final String PLASO64 = "plaso-20180818-amd64";//NON-NLS
|
||||||
|
private static final String PLASO32 = "plaso-20180818-win32";//NON-NLS
|
||||||
|
private static final String LOG2TIMELINE_EXECUTABLE = "Log2timeline.exe";//NON-NLS
|
||||||
|
private static final String PSORT_EXECUTABLE = "psort.exe";//NON-NLS
|
||||||
|
private static final String COOKIE = "cookie";//NON-NLS
|
||||||
|
private static final int LOG2TIMELINE_WORKERS = 2;
|
||||||
|
|
||||||
|
private File log2TimeLineExecutable;
|
||||||
|
private File psortExecutable;
|
||||||
|
|
||||||
|
private final PlasoModuleSettings settings;
|
||||||
|
private IngestJobContext context;
|
||||||
|
private Case currentCase;
|
||||||
|
private FileManager fileManager;
|
||||||
|
|
||||||
|
private Image image;
|
||||||
|
private AbstractFile previousFile = null; // cache used when looking up files in Autopsy DB
|
||||||
|
|
||||||
|
PlasoIngestModule(PlasoModuleSettings settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"PlasoIngestModule.executable.not.found=Plaso Executable Not Found.",
|
||||||
|
"PlasoIngestModule.requires.windows=Plaso module requires windows.",
|
||||||
|
"PlasoIngestModule.dataSource.not.an.image=Datasource is not an Image."})
|
||||||
|
@Override
|
||||||
|
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
if (false == PlatformUtil.isWindowsOS()) {
|
||||||
|
throw new IngestModuleException(Bundle.PlasoIngestModule_requires_windows());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
log2TimeLineExecutable = locateExecutable(LOG2TIMELINE_EXECUTABLE);
|
||||||
|
psortExecutable = locateExecutable(PSORT_EXECUTABLE);
|
||||||
|
} catch (FileNotFoundException exception) {
|
||||||
|
logger.log(Level.WARNING, "Plaso executable not found.", exception); //NON-NLS
|
||||||
|
throw new IngestModuleException(Bundle.PlasoIngestModule_executable_not_found(), exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
Content dataSource = context.getDataSource();
|
||||||
|
if (!(dataSource instanceof Image)) {
|
||||||
|
throw new IngestModuleException(Bundle.PlasoIngestModule_dataSource_not_an_image());
|
||||||
|
}
|
||||||
|
image = (Image) dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"PlasoIngestModule.error.running.log2timeline=Error running log2timeline, see log file.",
|
||||||
|
"PlasoIngestModule.error.running.psort=Error running Psort, see log file.",
|
||||||
|
"PlasoIngestModule.error.creating.output.dir=Error creating Plaso module output directory.",
|
||||||
|
"PlasoIngestModule.starting.log2timeline=Starting Log2timeline",
|
||||||
|
"PlasoIngestModule.running.psort=Running Psort",
|
||||||
|
"PlasoIngestModule.log2timeline.cancelled=Log2timeline run was canceled",
|
||||||
|
"PlasoIngestModule.psort.cancelled=psort run was canceled",
|
||||||
|
"PlasoIngestModule.bad.imageFile=Cannot find image file name and path",
|
||||||
|
"PlasoIngestModule.completed=Plaso Processing Completed",
|
||||||
|
"PlasoIngestModule.has.run=Plaso Plugin has been run."})
|
||||||
|
@Override
|
||||||
|
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) {
|
||||||
|
assert dataSource.equals(image);
|
||||||
|
|
||||||
|
statusHelper.switchToDeterminate(100);
|
||||||
|
currentCase = Case.getCurrentCase();
|
||||||
|
fileManager = currentCase.getServices().getFileManager();
|
||||||
|
|
||||||
|
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS
|
||||||
|
Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), PLASO, currentTime);
|
||||||
|
try {
|
||||||
|
Files.createDirectories(moduleOutputPath);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error creating Plaso module output directory.", ex); //NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run log2timeline
|
||||||
|
logger.log(Level.INFO, "Starting Plaso Run.");//NON-NLS
|
||||||
|
statusHelper.progress(Bundle.PlasoIngestModule_starting_log2timeline(), 0);
|
||||||
|
ProcessBuilder log2TimeLineCommand = buildLog2TimeLineCommand(moduleOutputPath, image);
|
||||||
|
try {
|
||||||
|
Process log2TimeLineProcess = log2TimeLineCommand.start();
|
||||||
|
try (BufferedReader log2TimeLineOutpout = new BufferedReader(new InputStreamReader(log2TimeLineProcess.getInputStream()))) {
|
||||||
|
L2TStatusProcessor statusReader = new L2TStatusProcessor(log2TimeLineOutpout, statusHelper, moduleOutputPath);
|
||||||
|
new Thread(statusReader, "log2timeline status reader").start(); //NON-NLS
|
||||||
|
ExecUtil.waitForTermination(LOG2TIMELINE_EXECUTABLE, log2TimeLineProcess, new DataSourceIngestModuleProcessTerminator(context));
|
||||||
|
statusReader.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.dataSourceIngestIsCancelled()) {
|
||||||
|
logger.log(Level.INFO, "Log2timeline run was canceled"); //NON-NLS
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
if (Files.notExists(moduleOutputPath.resolve(PLASO))) {
|
||||||
|
logger.log(Level.WARNING, "Error running log2timeline: there was no storage file."); //NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the output
|
||||||
|
statusHelper.progress(Bundle.PlasoIngestModule_running_psort(), 33);
|
||||||
|
ProcessBuilder psortCommand = buildPsortCommand(moduleOutputPath);
|
||||||
|
ExecUtil.execute(psortCommand, new DataSourceIngestModuleProcessTerminator(context));
|
||||||
|
|
||||||
|
if (context.dataSourceIngestIsCancelled()) {
|
||||||
|
logger.log(Level.INFO, "psort run was canceled"); //NON-NLS
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
Path plasoFile = moduleOutputPath.resolve("plasodb.db3"); //NON-NLS
|
||||||
|
if (Files.notExists(plasoFile)) {
|
||||||
|
logger.log(Level.SEVERE, "Error running Psort: there was no sqlite db file."); //NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse the output and make artifacts
|
||||||
|
createPlasoArtifacts(plasoFile.toString(), statusHelper);
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error running Plaso.", ex);//NON-NLS
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.DATA,
|
||||||
|
Bundle.PlasoIngestModule_has_run(),
|
||||||
|
Bundle.PlasoIngestModule_completed());
|
||||||
|
IngestServices.getInstance().postMessage(message);
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProcessBuilder buildLog2TimeLineCommand(Path moduleOutputPath, Image image) {
|
||||||
|
//make a csv list of disabled parsers.
|
||||||
|
String parsersString = settings.getParsers().entrySet().stream()
|
||||||
|
.filter(entry -> entry.getValue() == false)
|
||||||
|
.map(entry -> "!" + entry.getKey()) // '!' prepended to parsername disables it. //NON-NLS
|
||||||
|
.collect(Collectors.joining(","));//NON-NLS
|
||||||
|
|
||||||
|
ProcessBuilder processBuilder = buildProcessWithRunAsInvoker(
|
||||||
|
"\"" + log2TimeLineExecutable + "\"", //NON-NLS
|
||||||
|
"--vss-stores", "all", //NON-NLS
|
||||||
|
"-z", image.getTimeZone(), //NON-NLS
|
||||||
|
"--partitions", "all", //NON-NLS
|
||||||
|
"--hasher_file_size_limit", "1", //NON-NLS
|
||||||
|
"--hashers", "none", //NON-NLS
|
||||||
|
"--parsers", "\"" + parsersString + "\"",//NON-NLS
|
||||||
|
"--no_dependencies_check", //NON-NLS
|
||||||
|
"--workers", String.valueOf(LOG2TIMELINE_WORKERS),//NON-NLS
|
||||||
|
moduleOutputPath.resolve(PLASO).toString(),
|
||||||
|
image.getPaths()[0]
|
||||||
|
);
|
||||||
|
processBuilder.redirectError(moduleOutputPath.resolve("log2timeline_err.txt").toFile()); //NON-NLS
|
||||||
|
return processBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) {
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
|
||||||
|
/* Add an environment variable to force log2timeline/psort to run with
|
||||||
|
* the same permissions Autopsy uses. */
|
||||||
|
processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS
|
||||||
|
return processBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProcessBuilder buildPsortCommand(Path moduleOutputPath) {
|
||||||
|
ProcessBuilder processBuilder = buildProcessWithRunAsInvoker(
|
||||||
|
"\"" + psortExecutable + "\"", //NON-NLS
|
||||||
|
"-o", "4n6time_sqlite", //NON-NLS
|
||||||
|
"-w", moduleOutputPath.resolve("plasodb.db3").toString(), //NON-NLS
|
||||||
|
moduleOutputPath.resolve(PLASO).toString()
|
||||||
|
);
|
||||||
|
|
||||||
|
processBuilder.redirectOutput(moduleOutputPath.resolve("psort_output.txt").toFile()); //NON-NLS
|
||||||
|
processBuilder.redirectError(moduleOutputPath.resolve("psort_err.txt").toFile()); //NON-NLS
|
||||||
|
return processBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File locateExecutable(String executableName) throws FileNotFoundException {
|
||||||
|
String architectureFolder = PlatformUtil.is64BitOS() ? PLASO64 : PLASO32;
|
||||||
|
String executableToFindName = Paths.get(PLASO, architectureFolder, executableName).toString();
|
||||||
|
|
||||||
|
File exeFile = InstalledFileLocator.getDefault().locate(executableToFindName, PlasoIngestModule.class.getPackage().getName(), false);
|
||||||
|
if (null == exeFile || exeFile.canExecute() == false) {
|
||||||
|
throw new FileNotFoundException(executableName + " executable not found.");
|
||||||
|
}
|
||||||
|
return exeFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"PlasoIngestModule.exception.posting.artifact=Exception Posting artifact.",
|
||||||
|
"PlasoIngestModule.event.datetime=Event Date Time",
|
||||||
|
"PlasoIngestModule.event.description=Event Description",
|
||||||
|
"PlasoIngestModule.create.artifacts.cancelled=Cancelled Plaso Artifact Creation ",
|
||||||
|
"# {0} - file that events are from",
|
||||||
|
"PlasoIngestModule.artifact.progress=Adding events to case: {0}"})
|
||||||
|
private void createPlasoArtifacts(String plasoDb, DataSourceIngestModuleProgress statusHelper) {
|
||||||
|
Blackboard blackboard = currentCase.getSleuthkitCase().getBlackboard();
|
||||||
|
|
||||||
|
String sqlStatement = "SELECT substr(filename,1) AS filename, "
|
||||||
|
+ " strftime('%s', datetime) AS epoch_date, "
|
||||||
|
+ " description, "
|
||||||
|
+ " source, "
|
||||||
|
+ " type, "
|
||||||
|
+ " sourcetype "
|
||||||
|
+ " FROM log2timeline "
|
||||||
|
+ " WHERE source NOT IN ('FILE', "
|
||||||
|
+ " 'WEBHIST') " // bad dates and duplicates with what we have.
|
||||||
|
+ " AND sourcetype NOT IN ('UNKNOWN', "
|
||||||
|
+ " 'PE Import Time');"; // lots of bad dates //NON-NLS
|
||||||
|
SQLiteDBConnect tempdbconnect = null;
|
||||||
|
ResultSet resultSet = null;
|
||||||
|
try {
|
||||||
|
tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + plasoDb); //NON-NLS
|
||||||
|
resultSet = tempdbconnect.executeQry(sqlStatement);
|
||||||
|
while (resultSet.next()) {
|
||||||
|
if (context.dataSourceIngestIsCancelled()) {
|
||||||
|
logger.log(Level.INFO, "Cancelled Plaso Artifact Creation."); //NON-NLS
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String currentFileName = resultSet.getString("filename"); //NON-NLS
|
||||||
|
statusHelper.progress(Bundle.PlasoIngestModule_artifact_progress(currentFileName), 66);
|
||||||
|
Content resolvedFile = getAbstractFile(currentFileName);
|
||||||
|
if (resolvedFile == null) {
|
||||||
|
logger.log(Level.INFO, "File {0} from Plaso output not found in case. Associating it with the data source instead.", currentFileName);//NON-NLS
|
||||||
|
resolvedFile = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<BlackboardAttribute> bbattributes = Arrays.asList(
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_DATETIME, MODULE_NAME,
|
||||||
|
resultSet.getLong("epoch_date")), //NON-NLS
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_DESCRIPTION, MODULE_NAME,
|
||||||
|
resultSet.getString("description")),//NON-NLS
|
||||||
|
new BlackboardAttribute(
|
||||||
|
TSK_TL_EVENT_TYPE, MODULE_NAME,
|
||||||
|
findEventSubtype(currentFileName, resultSet)));
|
||||||
|
|
||||||
|
try {
|
||||||
|
BlackboardArtifact bbart = resolvedFile.newArtifact(TSK_TL_EVENT);
|
||||||
|
bbart.addAttributes(bbattributes);
|
||||||
|
try {
|
||||||
|
/* Post the artifact which will index the artifact for
|
||||||
|
* keyword search, and fire an event to notify UI of
|
||||||
|
* this new artifact */
|
||||||
|
blackboard.postArtifact(bbart, MODULE_NAME);
|
||||||
|
} catch (BlackboardException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error Posting Artifact.", ex);//NON-NLS
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception Adding Artifact.", ex);//NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Error while trying to read into a sqlite db.", ex);//NON-NLS
|
||||||
|
} finally {
|
||||||
|
if(resultSet != null) {
|
||||||
|
try {
|
||||||
|
resultSet.close();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to close ResultSet", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tempdbconnect != null) {
|
||||||
|
tempdbconnect.closeConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AbstractFile getAbstractFile(String file) {
|
||||||
|
|
||||||
|
Path path = Paths.get(file);
|
||||||
|
String fileName = path.getFileName().toString();
|
||||||
|
String filePath = path.getParent().toString().replaceAll("\\\\", "/");//NON-NLS
|
||||||
|
if (filePath.endsWith("/") == false) {//NON-NLS
|
||||||
|
filePath += "/";//NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the cached file
|
||||||
|
//TODO: would we reduce 'cache misses' if we retrieved the events sorted by file? Is that overhead worth it?
|
||||||
|
if (previousFile != null
|
||||||
|
&& previousFile.getName().equalsIgnoreCase(fileName)
|
||||||
|
&& previousFile.getParentPath().equalsIgnoreCase(filePath)) {
|
||||||
|
return previousFile;
|
||||||
|
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<AbstractFile> abstractFiles = fileManager.findFiles(fileName, filePath);
|
||||||
|
if (abstractFiles.size() == 1) {// TODO: why do we bother with this check. also we don't cache the file...
|
||||||
|
return abstractFiles.get(0);
|
||||||
|
}
|
||||||
|
for (AbstractFile resolvedFile : abstractFiles) {
|
||||||
|
// double check its an exact match
|
||||||
|
if (filePath.equalsIgnoreCase(resolvedFile.getParentPath())) {
|
||||||
|
// cache it for next time
|
||||||
|
previousFile = resolvedFile;
|
||||||
|
return resolvedFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception finding file.", ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the event_type_id of the event from the plaso information.
|
||||||
|
*
|
||||||
|
* @param fileName The name of the file this event is from.
|
||||||
|
* @param row The row returned from the log2timeline table of th eplaso
|
||||||
|
* output.
|
||||||
|
*
|
||||||
|
* @return the event_type_id of the EventType of the given event.
|
||||||
|
*
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
private long findEventSubtype(String fileName, ResultSet row) throws SQLException {
|
||||||
|
switch (row.getString("source")) {
|
||||||
|
case "WEBHIST": //These shouldn't actually be present, but keeping the logic just in case...
|
||||||
|
if (fileName.toLowerCase().contains(COOKIE)
|
||||||
|
|| row.getString("type").toLowerCase().contains(COOKIE)) {//NON-NLS
|
||||||
|
return EventType.WEB_COOKIE.getTypeID();
|
||||||
|
} else {
|
||||||
|
return EventType.WEB_HISTORY.getTypeID();
|
||||||
|
}
|
||||||
|
case "EVT":
|
||||||
|
case "LOG":
|
||||||
|
return EventType.LOG_ENTRY.getTypeID();
|
||||||
|
case "REG":
|
||||||
|
switch (row.getString("sourcetype").toLowerCase()) {//NON-NLS
|
||||||
|
case "unknown : usb entries":
|
||||||
|
case "unknown : usbstor entries":
|
||||||
|
return EventType.DEVICES_ATTACHED.getTypeID();
|
||||||
|
default:
|
||||||
|
return EventType.REGISTRY.getTypeID();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return EventType.OTHER.getTypeID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs in a thread and reads the output of log2timeline. It redirectes the
|
||||||
|
* output both to a log file, and to the status message of the Plaso ingest
|
||||||
|
* module progress bar.
|
||||||
|
*/
|
||||||
|
private static class L2TStatusProcessor implements Runnable, Cancellable {
|
||||||
|
|
||||||
|
private final BufferedReader log2TimeLineOutpout;
|
||||||
|
private final DataSourceIngestModuleProgress statusHelper;
|
||||||
|
volatile private boolean cancelled = false;
|
||||||
|
private final Path outputPath;
|
||||||
|
|
||||||
|
private L2TStatusProcessor(BufferedReader log2TimeLineOutpout, DataSourceIngestModuleProgress statusHelper, Path outputPath) throws IOException {
|
||||||
|
this.log2TimeLineOutpout = log2TimeLineOutpout;
|
||||||
|
this.statusHelper = statusHelper;
|
||||||
|
this.outputPath = outputPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try (BufferedWriter writer = Files.newBufferedWriter(outputPath.resolve("log2timeline_output.txt"));) {//NON-NLS
|
||||||
|
String line = log2TimeLineOutpout.readLine();
|
||||||
|
while (cancelled == false && nonNull(line)) {
|
||||||
|
statusHelper.progress(line);
|
||||||
|
writer.write(line);
|
||||||
|
writer.newLine();
|
||||||
|
line = log2TimeLineOutpout.readLine();
|
||||||
|
}
|
||||||
|
writer.flush();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Error reading log2timeline output stream.", ex);//NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean cancel() {
|
||||||
|
cancelled = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
112
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoModuleFactory.java
Executable file
112
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoModuleFactory.java
Executable file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2018-2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.plaso;
|
||||||
|
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
|
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory that creates data source ingest modules that run Plaso against an
|
||||||
|
* image and saves the storage file to module output.
|
||||||
|
*/
|
||||||
|
@ServiceProvider(service = IngestModuleFactory.class)
|
||||||
|
@NbBundle.Messages({"PlasoModuleFactory.ingestJobSettings.exception.msg=Expected settings argument to be instanceof PlasoModuleSettings"})
|
||||||
|
public class PlasoModuleFactory implements IngestModuleFactory {
|
||||||
|
|
||||||
|
@NbBundle.Messages({"PlasoModuleFactory_moduleName=Plaso"})
|
||||||
|
static String getModuleName() {
|
||||||
|
return Bundle.PlasoModuleFactory_moduleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleDisplayName() {
|
||||||
|
return getModuleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({"PlasoModuleFactory_moduleDesc=Runs Plaso against a Data Source."})
|
||||||
|
@Override
|
||||||
|
public String getModuleDescription() {
|
||||||
|
return Bundle.PlasoModuleFactory_moduleDesc();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleVersionNumber() {
|
||||||
|
return Version.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDataSourceIngestModuleFactory() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSourceIngestModule createDataSourceIngestModule(IngestModuleIngestJobSettings settings) {
|
||||||
|
assert settings instanceof PlasoModuleSettings;
|
||||||
|
if (settings instanceof PlasoModuleSettings) {
|
||||||
|
return new PlasoIngestModule((PlasoModuleSettings) settings);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(Bundle.PlasoModuleFactory_ingestJobSettings_exception_msg());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasGlobalSettingsPanel() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestModuleGlobalSettingsPanel getGlobalSettingsPanel() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettings getDefaultIngestJobSettings() {
|
||||||
|
return new PlasoModuleSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasIngestJobSettingsPanel() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) {
|
||||||
|
assert settings instanceof PlasoModuleSettings;
|
||||||
|
if (settings instanceof PlasoModuleSettings) {
|
||||||
|
return new PlasoModuleSettingsPanel((PlasoModuleSettings) settings);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(Bundle.PlasoModuleFactory_ingestJobSettings_exception_msg());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFileIngestModuleFactory() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
92
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoModuleSettings.java
Executable file
92
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoModuleSettings.java
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.plaso;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings for the Plaso Ingest Module.
|
||||||
|
*/
|
||||||
|
public class PlasoModuleSettings implements IngestModuleIngestJobSettings {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** Map from parser name (or match pattern) to its enabled state. */
|
||||||
|
final Map<String, Boolean> parsers = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an immutable map from parser name to its enabled state. Parsers
|
||||||
|
* mapped to true or with no entry will be enabled. Parsers mapped to false,
|
||||||
|
* will be disabled.
|
||||||
|
*/
|
||||||
|
Map<String, Boolean> getParsers() {
|
||||||
|
return ImmutableMap.copyOf(parsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. The PlasoModuleSettings will have the default parsers
|
||||||
|
* (winreg, pe, chrome, firefox, internet explorer) disabled.
|
||||||
|
*/
|
||||||
|
public PlasoModuleSettings() {
|
||||||
|
parsers.put("winreg", false);
|
||||||
|
parsers.put("pe", false);
|
||||||
|
|
||||||
|
//chrome
|
||||||
|
parsers.put("chrome_preferences", false);
|
||||||
|
parsers.put("chrome_cache", false);
|
||||||
|
parsers.put("chrome_27_history", false);
|
||||||
|
parsers.put("chrome_8_history", false);
|
||||||
|
parsers.put("chrome_cookies", false);
|
||||||
|
parsers.put("chrome_extension_activity", false);
|
||||||
|
|
||||||
|
//firefox
|
||||||
|
parsers.put("firefox_cache", false);
|
||||||
|
parsers.put("firefox_cache2", false);
|
||||||
|
parsers.put("firefox_cookies", false);
|
||||||
|
parsers.put("firefox_downloads", false);
|
||||||
|
parsers.put("firefox_history", false);
|
||||||
|
|
||||||
|
//Internet Explorer
|
||||||
|
parsers.put("msiecf", false);
|
||||||
|
parsers.put("msie_webcache", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the serialization version number.
|
||||||
|
*
|
||||||
|
* @return A serialization version number.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getVersionNumber() {
|
||||||
|
return serialVersionUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the given parser enabled/disabled
|
||||||
|
*
|
||||||
|
* @param parserName The name of the parser to enable/disable
|
||||||
|
* @param selected The new state (enabled/disabled) for the given parser.
|
||||||
|
*/
|
||||||
|
void setParserEnabled(String parserName, boolean selected) {
|
||||||
|
parsers.put(parserName, selected);
|
||||||
|
}
|
||||||
|
}
|
84
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoModuleSettingsPanel.form
Executable file
84
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoModuleSettingsPanel.form
Executable file
@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="plasoParserInfoTextArea" max="32767" attributes="0"/>
|
||||||
|
<Component id="peCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="winRegCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="plasoParserInfoTextArea" pref="188" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||||
|
<Component id="winRegCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="peCheckBox" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="winRegCheckBox">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/plaso/Bundle.properties" key="PlasoModuleSettingsPanel.winRegCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="winRegCheckBoxActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JCheckBox" name="peCheckBox">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/plaso/Bundle.properties" key="PlasoModuleSettingsPanel.peCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="peCheckBoxActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JTextArea" name="plasoParserInfoTextArea">
|
||||||
|
<Properties>
|
||||||
|
<Property name="editable" type="boolean" value="false"/>
|
||||||
|
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
|
||||||
|
<Color blue="f0" green="f0" id="Panel.background" palette="3" red="f0" type="palette"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="columns" type="int" value="20"/>
|
||||||
|
<Property name="lineWrap" type="boolean" value="true"/>
|
||||||
|
<Property name="rows" type="int" value="5"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/plaso/Bundle.properties" key="PlasoModuleSettingsPanel.plasoParserInfoTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="wrapStyleWord" type="boolean" value="true"/>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="null"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
115
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoModuleSettingsPanel.java
Executable file
115
Core/src/org/sleuthkit/autopsy/modules/plaso/PlasoModuleSettingsPanel.java
Executable file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> 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.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.plaso;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings panel for the PlasoIngestModule.
|
||||||
|
*/
|
||||||
|
public class PlasoModuleSettingsPanel extends IngestModuleIngestJobSettingsPanel {
|
||||||
|
|
||||||
|
private final PlasoModuleSettings settings;
|
||||||
|
|
||||||
|
public PlasoModuleSettingsPanel(PlasoModuleSettings settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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 regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
winRegCheckBox = new javax.swing.JCheckBox();
|
||||||
|
peCheckBox = new javax.swing.JCheckBox();
|
||||||
|
plasoParserInfoTextArea = new javax.swing.JTextArea();
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(winRegCheckBox, org.openide.util.NbBundle.getMessage(PlasoModuleSettingsPanel.class, "PlasoModuleSettingsPanel.winRegCheckBox.text")); // NOI18N
|
||||||
|
winRegCheckBox.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
winRegCheckBoxActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(peCheckBox, org.openide.util.NbBundle.getMessage(PlasoModuleSettingsPanel.class, "PlasoModuleSettingsPanel.peCheckBox.text")); // NOI18N
|
||||||
|
peCheckBox.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
peCheckBoxActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
plasoParserInfoTextArea.setEditable(false);
|
||||||
|
plasoParserInfoTextArea.setBackground(javax.swing.UIManager.getDefaults().getColor("Panel.background"));
|
||||||
|
plasoParserInfoTextArea.setColumns(20);
|
||||||
|
plasoParserInfoTextArea.setLineWrap(true);
|
||||||
|
plasoParserInfoTextArea.setRows(5);
|
||||||
|
plasoParserInfoTextArea.setText(org.openide.util.NbBundle.getMessage(PlasoModuleSettingsPanel.class, "PlasoModuleSettingsPanel.plasoParserInfoTextArea.text")); // NOI18N
|
||||||
|
plasoParserInfoTextArea.setWrapStyleWord(true);
|
||||||
|
plasoParserInfoTextArea.setBorder(null);
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(plasoParserInfoTextArea)
|
||||||
|
.addComponent(peCheckBox)
|
||||||
|
.addComponent(winRegCheckBox))
|
||||||
|
.addContainerGap())
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(plasoParserInfoTextArea, javax.swing.GroupLayout.DEFAULT_SIZE, 188, Short.MAX_VALUE)
|
||||||
|
.addGap(18, 18, 18)
|
||||||
|
.addComponent(winRegCheckBox)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
|
.addComponent(peCheckBox)
|
||||||
|
.addContainerGap())
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void winRegCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_winRegCheckBoxActionPerformed
|
||||||
|
settings.setParserEnabled("winreg", winRegCheckBox.isSelected());
|
||||||
|
}//GEN-LAST:event_winRegCheckBoxActionPerformed
|
||||||
|
|
||||||
|
private void peCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_peCheckBoxActionPerformed
|
||||||
|
settings.setParserEnabled("pe", peCheckBox.isSelected());
|
||||||
|
}//GEN-LAST:event_peCheckBoxActionPerformed
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettings getSettings() {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JCheckBox peCheckBox;
|
||||||
|
private javax.swing.JTextArea plasoParserInfoTextArea;
|
||||||
|
private javax.swing.JCheckBox winRegCheckBox;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user