mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Merge branch 'develop' of github.com:sleuthkit/autopsy into archive_dsp_4658
This commit is contained in:
commit
bfa0aa8b06
@ -1,4 +1,5 @@
|
||||
OpenIDE-Module-Display-Category=Ingest Module
|
||||
|
||||
OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found.
|
||||
OpenIDE-Module-Name=KeywordSearch
|
||||
OptionsCategory_Name_KeywordSearchOptions=Keyword Search
|
||||
|
@ -47,8 +47,16 @@ ExtractSafari_Error_Getting_History=An error occurred while processing Safari hi
|
||||
ExtractSafari_Error_Parsing_Bookmark=An error occured while processing Safari Bookmark files
|
||||
ExtractSafari_Error_Parsing_Cookies=An error occured while processing Safari Cookies files
|
||||
ExtractSafari_Module_Name=Safari
|
||||
ExtractZone_Internet=Internet Zone
|
||||
ExtractZone_Local_Intranet=Local Intranet Zone
|
||||
ExtractZone_Local_Machine=Local Machine Zone
|
||||
ExtractZone_process_errMsg=An error occured processing ':Zone.Indentifier' files.
|
||||
ExtractZone_process_errMsg_find=A failure occured while searching for :Zone.Indentifier files.
|
||||
ExtractZone_progress_Msg=Extracting :Zone.Identifer files
|
||||
ExtractZone_Restricted=Restricted Sites Zone
|
||||
ExtractZone_Trusted=Trusted Sites Zone
|
||||
OpenIDE-Module-Display-Category=Ingest Module
|
||||
OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n\The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web acitivity (sites visited, stored cookies, bookmarked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\n\The module currently supports Windows only disk images.\n\The plugin is also fully functional when deployed on Windows version of Autopsy.
|
||||
OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\nThe module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web acitivity (sites visited, stored cookies, bookmarked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy.
|
||||
OpenIDE-Module-Name=RecentActivity
|
||||
OpenIDE-Module-Short-Description=Recent Activity finder ingest module
|
||||
Chrome.moduleName=Chrome
|
||||
@ -176,7 +184,7 @@ SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}.
|
||||
SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine
|
||||
SearchEngineURLQueryAnalyzer.engineName.none=NONE
|
||||
SearchEngineURLQueryAnalyzer.domainSubStr.none=NONE
|
||||
SearchEngineURLQueryAnalyzer.toString=Name: {0}\nDomain Substring: {1}\n\count: {2}\nSplit Tokens: \n{3}
|
||||
SearchEngineURLQueryAnalyzer.toString=Name: {0}\nDomain Substring: {1}\ncount: {2}\nSplit Tokens: \n{3}
|
||||
SearchEngineURLQueryAnalyzer.parentModuleName.noSpace=RecentActivity
|
||||
SearchEngineURLQueryAnalyzer.parentModuleName=Recent Activity
|
||||
UsbDeviceIdMapper.parseAndLookup.text=Product: {0}
|
||||
|
@ -0,0 +1,388 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2019 Basis Technology Corp.
|
||||
*
|
||||
* 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.recentactivity;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_LOCATION;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Extract the <i>:Zone.Indentifier<i> alternate data stream files. A file with
|
||||
* a <i>:Zone.Indentifier<i> extention contains information about the similarly
|
||||
* named (with out zone identifer extension) downloaded file.
|
||||
*/
|
||||
final class ExtractZoneIdentifier extends Extract {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ExtractEdge.class.getName());
|
||||
|
||||
private static final String ZONE_IDENTIFIER_FILE = "%:Zone.Identifier"; //NON-NLS
|
||||
private static final String ZONE_IDENTIFIER = ":Zone.Identifier"; //NON-NLS
|
||||
|
||||
@Messages({
|
||||
"ExtractZone_process_errMsg_find=A failure occured while searching for :Zone.Indentifier files.",
|
||||
"ExtractZone_process_errMsg=An error occured processing ':Zone.Indentifier' files.",
|
||||
"ExtractZone_progress_Msg=Extracting :Zone.Identifer files"
|
||||
})
|
||||
|
||||
@Override
|
||||
void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
|
||||
|
||||
progressBar.progress(Bundle.ExtractZone_progress_Msg());
|
||||
|
||||
List<AbstractFile> zoneFiles = null;
|
||||
try {
|
||||
zoneFiles = currentCase.getServices().getFileManager().findFiles(dataSource, ZONE_IDENTIFIER_FILE);
|
||||
} catch (TskCoreException ex) {
|
||||
addErrorMessage(Bundle.ExtractZone_process_errMsg_find());
|
||||
LOG.log(Level.SEVERE, "Unable to find zone identifier files, exception thrown. ", ex); // NON-NLS
|
||||
}
|
||||
|
||||
if (zoneFiles == null || zoneFiles.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Long> knownPathIDs = null;
|
||||
try {
|
||||
knownPathIDs = getPathIDsForType(TSK_WEB_DOWNLOAD);
|
||||
} catch (TskCoreException ex) {
|
||||
addErrorMessage(Bundle.ExtractZone_process_errMsg());
|
||||
LOG.log(Level.SEVERE, "Failed to build PathIDs List for TSK_WEB_DOWNLOAD", ex); // NON-NLS
|
||||
}
|
||||
|
||||
if (knownPathIDs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<BlackboardArtifact> sourceArtifacts = new ArrayList<>();
|
||||
Collection<BlackboardArtifact> downloadArtifacts = new ArrayList<>();
|
||||
|
||||
for (AbstractFile zoneFile : zoneFiles) {
|
||||
try {
|
||||
processZoneFile(context, dataSource, zoneFile, sourceArtifacts, downloadArtifacts, knownPathIDs);
|
||||
} catch (TskCoreException ex) {
|
||||
addErrorMessage(Bundle.ExtractZone_process_errMsg());
|
||||
String message = String.format("Failed to process zone identifier file %s", zoneFile.getName()); //NON-NLS
|
||||
LOG.log(Level.WARNING, message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
IngestServices services = IngestServices.getInstance();
|
||||
|
||||
if (!sourceArtifacts.isEmpty()) {
|
||||
services.fireModuleDataEvent(new ModuleDataEvent(
|
||||
RecentActivityExtracterModuleFactory.getModuleName(),
|
||||
TSK_DOWNLOAD_SOURCE, sourceArtifacts));
|
||||
}
|
||||
|
||||
if (!downloadArtifacts.isEmpty()) {
|
||||
services.fireModuleDataEvent(new ModuleDataEvent(
|
||||
RecentActivityExtracterModuleFactory.getModuleName(),
|
||||
TSK_WEB_DOWNLOAD, downloadArtifacts));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a single Zone Identifier file.
|
||||
*
|
||||
* @param context IngetJobContext
|
||||
* @param dataSource Content
|
||||
* @param zoneFile Zone Indentifier file
|
||||
* @param sourceArtifacts List for TSK_DOWNLOAD_SOURCE artifacts
|
||||
* @param downloadArtifacts List for TSK_WEB_DOWNLOAD aritfacts
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private void processZoneFile(IngestJobContext context, Content dataSource,
|
||||
AbstractFile zoneFile, Collection<BlackboardArtifact> sourceArtifacts,
|
||||
Collection<BlackboardArtifact> downloadArtifacts,
|
||||
Set<Long> knownPathIDs) throws TskCoreException {
|
||||
|
||||
ZoneIdentifierInfo zoneInfo = null;
|
||||
|
||||
try {
|
||||
zoneInfo = new ZoneIdentifierInfo(zoneFile);
|
||||
} catch (IOException ex) {
|
||||
String message = String.format("Unable to parse temporary File for %s", zoneFile.getName()); //NON-NLS
|
||||
LOG.log(Level.WARNING, message, ex);
|
||||
}
|
||||
|
||||
if (zoneInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractFile downloadFile = getDownloadFile(dataSource, zoneFile);
|
||||
|
||||
if (downloadFile != null) {
|
||||
// Only create a new TSK_WEB_DOWNLOAD artifact if one does not exist for downloadFile
|
||||
if (!knownPathIDs.contains(downloadFile.getDataSourceObjectId())) {
|
||||
// The zone identifier file is the parent of this artifact
|
||||
// because it is the file we parsed to get the data
|
||||
BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo);
|
||||
if (downloadBba != null) {
|
||||
downloadArtifacts.add(downloadBba);
|
||||
}
|
||||
}
|
||||
|
||||
// check if download has a child TSK_DOWNLOAD_SOURCE artifact, if not create one
|
||||
if (downloadFile.getArtifactsCount(TSK_DOWNLOAD_SOURCE) == 0) {
|
||||
BlackboardArtifact sourceBba = createDownloadSourceArtifact(downloadFile, zoneInfo);
|
||||
if (sourceBba != null) {
|
||||
sourceArtifacts.add(sourceBba);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the file that the Zone.Identifer file was created alongside.
|
||||
*
|
||||
* @param dataSource Content
|
||||
* @param zoneFile The zone identifier case file
|
||||
*
|
||||
* @return The downloaded file or null if a file was not found
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private AbstractFile getDownloadFile(Content dataSource, AbstractFile zoneFile) throws TskCoreException {
|
||||
AbstractFile downloadFile = null;
|
||||
|
||||
org.sleuthkit.autopsy.casemodule.services.FileManager fileManager
|
||||
= currentCase.getServices().getFileManager();
|
||||
|
||||
String downloadFileName = zoneFile.getName().replace(ZONE_IDENTIFIER, ""); //NON-NLS
|
||||
|
||||
List<AbstractFile> fileList = fileManager.findFiles(dataSource, downloadFileName, zoneFile.getParentPath());
|
||||
|
||||
if (fileList.size() == 1) {
|
||||
downloadFile = fileList.get(0);
|
||||
|
||||
// Check that the download file and the zone file came from the same dir
|
||||
if (!downloadFile.getParentPath().equals(zoneFile.getParentPath())) {
|
||||
downloadFile = null;
|
||||
} else if (zoneFile.getMetaAddr() != downloadFile.getMetaAddr()) {
|
||||
downloadFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
return downloadFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Download Source Artifact for the given ZoneIdentifierInfo
|
||||
* object.
|
||||
*
|
||||
* @param downloadFile AbstractFile representing the file downloaded, not
|
||||
* the zone indentifier file.
|
||||
* @param zoneInfo Zone Indentifer file wrapper object
|
||||
*
|
||||
* @return TSK_DOWNLOAD_SOURCE object for given parameters
|
||||
*/
|
||||
private BlackboardArtifact createDownloadSourceArtifact(AbstractFile downloadFile, ZoneIdentifierInfo zoneInfo) {
|
||||
|
||||
Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
|
||||
|
||||
bbattributes.addAll(Arrays.asList(
|
||||
new BlackboardAttribute(TSK_URL,
|
||||
RecentActivityExtracterModuleFactory.getModuleName(),
|
||||
StringUtils.defaultString(zoneInfo.getURL(), "")),
|
||||
|
||||
new BlackboardAttribute(TSK_DOMAIN,
|
||||
RecentActivityExtracterModuleFactory.getModuleName(),
|
||||
(zoneInfo.getURL() != null) ? NetworkUtils.extractDomain(zoneInfo.getURL()) : ""),
|
||||
|
||||
new BlackboardAttribute(TSK_LOCATION,
|
||||
RecentActivityExtracterModuleFactory.getModuleName(),
|
||||
StringUtils.defaultString(zoneInfo.getZoneIdAsString(), "")))); //NON-NLS
|
||||
|
||||
return addArtifact(TSK_DOWNLOAD_SOURCE, downloadFile, bbattributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TSK_WEB_DOWNLOAD Artifact for the given zone indentifier file.
|
||||
*
|
||||
* @param zoneFile Zone identifier file
|
||||
* @param zoneInfo ZoneIdentifierInfo file wrapper object
|
||||
*
|
||||
* @return BlackboardArifact for the given parameters
|
||||
*/
|
||||
private BlackboardArtifact createDownloadArtifact(AbstractFile zoneFile, ZoneIdentifierInfo zoneInfo) {
|
||||
|
||||
Collection<BlackboardAttribute> bbattributes = createDownloadAttributes(
|
||||
null, null,
|
||||
zoneInfo.getURL(), null,
|
||||
(zoneInfo.getURL() != null ? NetworkUtils.extractDomain(zoneInfo.getURL()) : ""),
|
||||
null);
|
||||
return addArtifact(TSK_WEB_DOWNLOAD, zoneFile, bbattributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a list of PathIDs for the given Artifact type.
|
||||
*
|
||||
* @param type BlackboardArtifact.ARTIFACT_TYPE
|
||||
*
|
||||
* @return A list of PathIDs
|
||||
*
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
private Set<Long> getPathIDsForType(BlackboardArtifact.ARTIFACT_TYPE type) throws TskCoreException {
|
||||
Set<Long> idList = new HashSet<>();
|
||||
for (BlackboardArtifact artifact : currentCase.getSleuthkitCase().getBlackboardArtifacts(type)) {
|
||||
BlackboardAttribute pathIDAttribute = artifact.getAttribute(new BlackboardAttribute.Type(TSK_PATH_ID));
|
||||
|
||||
if (pathIDAttribute != null) {
|
||||
long contentID = pathIDAttribute.getValueLong();
|
||||
if (contentID != -1) {
|
||||
idList.add(contentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
return idList;
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"ExtractZone_Local_Machine=Local Machine Zone",
|
||||
"ExtractZone_Local_Intranet=Local Intranet Zone",
|
||||
"ExtractZone_Trusted=Trusted Sites Zone",
|
||||
"ExtractZone_Internet=Internet Zone",
|
||||
"ExtractZone_Restricted=Restricted Sites Zone"
|
||||
})
|
||||
|
||||
/**
|
||||
* Wrapper class for information in the :ZoneIdentifier file. The
|
||||
* Zone.Identifier file has a simple format of <i>key<i>=<i>value<i>. There
|
||||
* are four known keys: ZoneId, ReferrerUrl, HostUrl, and
|
||||
* LastWriterPackageFamilyName. Not all browsers will put all values in the
|
||||
* file, in fact most will only supply the ZoneId. Only Edge supplies the
|
||||
* LastWriterPackageFamilyName.
|
||||
*/
|
||||
private final static class ZoneIdentifierInfo {
|
||||
|
||||
private static final String ZONE_ID = "ZoneId"; //NON-NLS
|
||||
private static final String REFERRER_URL = "ReferrerUrl"; //NON-NLS
|
||||
private static final String HOST_URL = "HostUrl"; //NON-NLS
|
||||
private static final String FAMILY_NAME = "LastWriterPackageFamilyName"; //NON-NLS
|
||||
|
||||
private final Properties properties = new Properties(null);
|
||||
|
||||
/**
|
||||
* Opens the zone file, reading for the key\value pairs and puts them
|
||||
* into a HashMap.
|
||||
*
|
||||
* @param zoneFile The ZoneIdentifier file
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
ZoneIdentifierInfo(AbstractFile zoneFile) throws IOException {
|
||||
properties.load(new ReadContentInputStream(zoneFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the integer zone id
|
||||
*
|
||||
* @return interger zone id or -1 if unknown
|
||||
*/
|
||||
private int getZoneId() {
|
||||
int zoneValue = -1;
|
||||
String value = properties.getProperty(ZONE_ID);
|
||||
if (value != null) {
|
||||
zoneValue = Integer.parseInt(value);
|
||||
}
|
||||
|
||||
return zoneValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string description of the zone id.
|
||||
*
|
||||
* @return String description or null if a zone id was not found
|
||||
*/
|
||||
private String getZoneIdAsString() {
|
||||
switch (getZoneId()) {
|
||||
case 0:
|
||||
return Bundle.ExtractZone_Local_Machine();
|
||||
case 1:
|
||||
return Bundle.ExtractZone_Local_Intranet();
|
||||
case 2:
|
||||
return Bundle.ExtractZone_Trusted();
|
||||
case 3:
|
||||
return Bundle.ExtractZone_Internet();
|
||||
case 4:
|
||||
return Bundle.ExtractZone_Restricted();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL from which the file was downloaded.
|
||||
*
|
||||
* @return String url or null if a host url was not found
|
||||
*/
|
||||
private String getURL() {
|
||||
return properties.getProperty(HOST_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the referrer url.
|
||||
*
|
||||
* @return String url or null if a host url was not found
|
||||
*/
|
||||
private String getReferrer() {
|
||||
return properties.getProperty(REFERRER_URL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string value for the key LastWriterPackageFamilyName.
|
||||
*
|
||||
* @return String value or null if the value was not found
|
||||
*/
|
||||
private String getFamilyName() {
|
||||
return properties.getProperty(FAMILY_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -76,6 +76,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
|
||||
Extract osExtract = new ExtractOs();
|
||||
Extract dataSourceAnalyzer = new DataSourceUsageAnalyzer();
|
||||
Extract safari = new ExtractSafari();
|
||||
Extract zoneInfo = new ExtractZoneIdentifier();
|
||||
|
||||
extractors.add(chrome);
|
||||
extractors.add(firefox);
|
||||
@ -87,6 +88,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
|
||||
extractors.add(registry); // this should run after quicker modules like the browser modules and needs to run before the DataSourceUsageAnalyzer
|
||||
extractors.add(osExtract); // this needs to run before the DataSourceUsageAnalyzer
|
||||
extractors.add(dataSourceAnalyzer); //this needs to run after ExtractRegistry and ExtractOs
|
||||
extractors.add(zoneInfo); // this needs to run after the web browser modules
|
||||
|
||||
browserExtractors.add(chrome);
|
||||
browserExtractors.add(firefox);
|
||||
|
Loading…
x
Reference in New Issue
Block a user