Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate browsers from ra to own module #7710

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.recentactivity;
package org.sleuthkit.autopsy.modules.browseractivity;

import java.io.DataInputStream;
import java.io.File;
Expand All @@ -29,7 +29,7 @@
import java.util.NoSuchElementException;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.recentactivity.BinaryCookieReader.Cookie;
import org.sleuthkit.autopsy.modules.browseractivity.BinaryCookieReader.Cookie;

/**
* The binary cookie reader encapsulates all the knowledge of how to read the
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012-2021 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.browseractivity;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModule;
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.autopsy.ingest.IngestModule.ProcessResult;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.datamodel.SleuthkitCase;

/**
* Browser Activity image ingest module
*/
public final class BrowserActivityIngestModule implements DataSourceIngestModule {

private static final String BROWSER_ACTIVITY_FOLDER = "BrowserActivity";
private static final Logger logger = Logger.getLogger(BrowserActivityIngestModule.class.getName());
private final List<Extract> extractors = new ArrayList<>();
private final List<Extract> browserExtractors = new ArrayList<>();
private final IngestServices services = IngestServices.getInstance();
private IngestJobContext context;
protected SleuthkitCase tskCase;

BrowserActivityIngestModule() {
}

@Override
public void startUp(IngestJobContext context) throws IngestModuleException {
this.context = context;

tskCase = Case.getCurrentCase().getSleuthkitCase();

Extract iexplore = new ExtractIE(context);
Extract edge = new ExtractEdge(context);
Extract chrome = new Chromium(context);
Extract firefox = new Firefox(context);
Extract SEUQA = new SearchEngineURLQueryAnalyzer(context);
Extract osExtract = new ExtractOs(context);
Extract safari = new ExtractSafari(context);
Extract webAccountType = new ExtractWebAccountType(context);
Extract messageDomainType = new DomainCategoryRunner(context);

extractors.add(osExtract); // this needs to run before the DataSourceUsageAnalyzer
extractors.add(chrome);
extractors.add(firefox);
extractors.add(iexplore);
extractors.add(edge);
extractors.add(safari);
extractors.add(SEUQA); // this needs to run after the web browser modules
extractors.add(webAccountType); // this needs to run after the web browser modules
extractors.add(messageDomainType);

browserExtractors.add(chrome);
browserExtractors.add(firefox);
browserExtractors.add(iexplore);
browserExtractors.add(edge);
browserExtractors.add(safari);

for (Extract extractor : extractors) {
extractor.startUp();
}
}

@Override
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
services.postMessage(IngestMessage.createMessage(MessageType.INFO, BrowserActivityModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(),
"BrowserActivityIngestModule.process.started",
dataSource.getName())));

progressBar.switchToDeterminate(extractors.size());

ArrayList<String> errors = new ArrayList<>();

for (int i = 0; i < extractors.size(); i++) {
Extract extracter = extractors.get(i);
if (context.dataSourceIngestIsCancelled()) {
logger.log(Level.INFO, "Browser Activity has been canceled, quitting before {0}", extracter.getDisplayName()); //NON-NLS
break;
}

progressBar.progress(extracter.getDisplayName(), i);

try {
extracter.process(dataSource, progressBar);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Exception occurred in " + extracter.getDisplayName(), ex); //NON-NLS
errors.add(NbBundle.getMessage(this.getClass(), "BrowserActivityIngestModule.process.errModErrs", BrowserActivityModuleFactory.getModuleName()));
}
progressBar.progress(i + 1);
errors.addAll(extracter.getErrorMessages());
}

// create the final message for inbox
StringBuilder errorMessage = new StringBuilder();
String errorMsgSubject;
MessageType msgLevel = MessageType.INFO;
if (errors.isEmpty() == false) {
msgLevel = MessageType.ERROR;
errorMessage.append(
NbBundle.getMessage(this.getClass(), "BrowserActivityIngestModule.process.errMsg.errsEncountered"));
for (String msg : errors) {
errorMessage.append("<li>").append(msg).append("</li>\n"); //NON-NLS
}
errorMessage.append("</ul>\n"); //NON-NLS

if (errors.size() == 1) {
errorMsgSubject = NbBundle.getMessage(this.getClass(), "BrowserActivityIngestModule.process.errMsgSub.oneErr");
} else {
errorMsgSubject = NbBundle.getMessage(this.getClass(),
"BrowserActivityIngestModule.process.errMsgSub.nErrs", errors.size());
}
} else {
errorMessage.append(NbBundle.getMessage(this.getClass(), "BrowserActivityIngestModule.process.errMsg.noErrs"));
errorMsgSubject = NbBundle.getMessage(this.getClass(), "BrowserActivityIngestModule.process.errMsgSub.noErrs");
}
final IngestMessage msg = IngestMessage.createMessage(msgLevel, BrowserActivityModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(),
"BrowserActivityIngestModule.process.ingestMsg.finished",
dataSource.getName(), errorMsgSubject),
errorMessage.toString());
services.postMessage(msg);

StringBuilder historyMsg = new StringBuilder();
historyMsg.append(
NbBundle.getMessage(this.getClass(), "BrowserActivityIngestModule.process.histMsg.title", dataSource.getName()));
for (Extract module : browserExtractors) {
historyMsg.append("<li>").append(module.getDisplayName()); //NON-NLS
historyMsg.append(": ").append((module.foundData()) ? NbBundle
.getMessage(this.getClass(), "BrowserActivityIngestModule.process.histMsg.found") : NbBundle
.getMessage(this.getClass(), "BrowserActivityIngestModule.process.histMsg.notFnd"));
historyMsg.append("</li>"); //NON-NLS
}
historyMsg.append("</ul>"); //NON-NLS
final IngestMessage inboxMsg = IngestMessage.createMessage(MessageType.INFO, BrowserActivityModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(),
"BrowserActivityIngestModule.process.ingestMsg.results",
dataSource.getName()),
historyMsg.toString());
services.postMessage(inboxMsg);

return ProcessResult.OK;
}

@Override
public void shutDown() {
for (int i = 0; i < extractors.size(); i++) {
Extract extracter = extractors.get(i);
try {
extracter.shutDown();
} catch (Exception ex) {
logger.log(Level.SEVERE, "Exception occurred when completing " + extracter.getDisplayName(), ex); //NON-NLS
}
}
}

/**
* Makes a path of the format
* [basePath]/[RECENT_ACTIVITY_FOLDER]/[module]_[ingest job id] if it does
* not already exist and returns the created folder.
*
* @param basePath The base path (a case-related folder like temp or
* output).
* @param module The module name to include in the folder name.
* @param ingestJobId The id of the ingest job.
*
* @return The path to the folder.
*/
private static String getAndMakeBAPath(String basePath, String module, long ingestJobId) {
String moduleFolder = String.format("%s_%d", module, ingestJobId);
Path tmpPath = Paths.get(basePath, BROWSER_ACTIVITY_FOLDER, moduleFolder);
File dir = tmpPath.toFile();
if (dir.exists() == false) {
dir.mkdirs();
}
return tmpPath.toString();
}

/**
* Get the temp path for a specific sub-module in recent activity. Will
* create the dir if it doesn't exist.
*
* @param a_case Case that directory is for
* @param mod Module name that will be used for a sub folder in the temp
* folder to prevent name collisions
*
* @return Path to directory
*/
static String getBATempPath(Case a_case, String mod, long ingestJobId) {
return getAndMakeBAPath(a_case.getTempDirectory(), mod, ingestJobId);
}

/**
* Get the output path for a specific sub-module in recent activity. Will
* create the dir if it doesn't exist.
*
* @param a_case Case that directory is for
* @param mod Module name that will be used for a sub folder in the temp
* folder to prevent name collisions
*
* @return Path to directory
*/
static String getBAOutputPath(Case a_case, String mod, long ingestJobId) {
return getAndMakeBAPath(a_case.getModuleDirectory(), mod, ingestJobId);
}

/**
* Get relative path for module output folder.
*
* @throws NoCurrentCaseException if there is no open case.
* @return the relative path of the module output folder
*/
static String getRelModuleOutputPath(Case autCase, String mod, long ingestJobId) {
return Paths.get(getAndMakeBAPath(autCase.getModuleOutputDirectoryRelativePath(), mod, ingestJobId))
.normalize()
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 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.browseractivity;

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.IngestModuleFactory;
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;

/**
* A factory that creates data source ingest modules that extract browser
* activity artifacts from data sources.
*/
@ServiceProvider(service = IngestModuleFactory.class)
public class BrowserActivityModuleFactory extends IngestModuleFactoryAdapter {

static String getModuleName() {
return NbBundle.getMessage(BrowserActivityIngestModule.class, "BrowserActivityIngestModule.getName");
}

@Override
public String getModuleDisplayName() {
return getModuleName();
}

@Override
public String getModuleDescription() {
return NbBundle.getMessage(BrowserActivityIngestModule.class, "BrowserActivityIngestModule.getDesc");
}

@Override
public String getModuleVersionNumber() {
return Version.getVersion();
}

@Override
public boolean isDataSourceIngestModuleFactory() {
return true;
}

@Override
public DataSourceIngestModule createDataSourceIngestModule(IngestModuleIngestJobSettings ingestJobOptions) {
return new BrowserActivityIngestModule();
}
}
Loading