mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
5780: Context content viewer to show source of message attachments and web downloaded files.
- This includes replacing the TSK_DOWNLOAD_SOURCE artifact with TSK_ASSOCIATED_OBJECT artifact, in the RecentActivity module.
This commit is contained in:
parent
5452d2ba02
commit
8e48ac03e6
@ -0,0 +1,95 @@
|
|||||||
|
<?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" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||||
|
<Component id="jSourceNameLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="jSourceTextLabel" pref="192" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
|
<Component id="jSourceNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="jSourceTextLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
<EmptySpace type="separate" max="-2" attributes="0"/>
|
||||||
|
<Component id="jSourceGoToResultButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="203" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JButton" name="jSourceGoToResultButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContextViewer.jSourceGoToResultButton.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="jSourceGoToResultButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||||
|
<Properties>
|
||||||
|
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
|
||||||
|
<Font name="Dialog" size="14" style="1"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContextViewer.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="jSourceNameLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContextViewer.jSourceNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="jSourceTextLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContextViewer.jSourceTextLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
357
Core/src/org/sleuthkit/autopsy/contentviewers/ContextViewer.java
Normal file
357
Core/src/org/sleuthkit/autopsy/contentviewers/ContextViewer.java
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
/*
|
||||||
|
* 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.contentviewers;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.openide.nodes.Node;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays additional context for the selected file, such as its source, and
|
||||||
|
* usage, if known.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ServiceProvider(service = DataContentViewer.class, position = 7)
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"ContextViewer.title=Context Viewer",
|
||||||
|
"ContextViewer.toolTip=Displays context for selected file."
|
||||||
|
})
|
||||||
|
public final class ContextViewer extends javax.swing.JPanel implements DataContentViewer {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final Logger logger = Logger.getLogger(ContextViewer.class.getName());
|
||||||
|
|
||||||
|
// defines a list of artifacts that provide context for a file
|
||||||
|
private static final List<BlackboardArtifact.ARTIFACT_TYPE> SOURCE_CONTEXT_ARTIFACTS = new ArrayList<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
SOURCE_CONTEXT_ARTIFACTS.add(TSK_ASSOCIATED_OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlackboardArtifact sourceContextArtifact;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form ContextViewer
|
||||||
|
*/
|
||||||
|
public ContextViewer() {
|
||||||
|
|
||||||
|
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() {
|
||||||
|
|
||||||
|
jSourceGoToResultButton = new javax.swing.JButton();
|
||||||
|
jLabel1 = new javax.swing.JLabel();
|
||||||
|
jSourceNameLabel = new javax.swing.JLabel();
|
||||||
|
jSourceTextLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jSourceGoToResultButton, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceGoToResultButton.text")); // NOI18N
|
||||||
|
jSourceGoToResultButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
jSourceGoToResultButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
jLabel1.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jLabel1.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jSourceNameLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceNameLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(jSourceTextLabel, org.openide.util.NbBundle.getMessage(ContextViewer.class, "ContextViewer.jSourceTextLabel.text")); // NOI18N
|
||||||
|
|
||||||
|
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)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(jLabel1)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addGap(6, 6, 6)
|
||||||
|
.addComponent(jSourceNameLabel)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(jSourceTextLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)))
|
||||||
|
.addGap(36, 36, 36))
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(jSourceGoToResultButton)
|
||||||
|
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(jLabel1)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
|
.addComponent(jSourceNameLabel)
|
||||||
|
.addComponent(jSourceTextLabel))
|
||||||
|
.addGap(18, 18, 18)
|
||||||
|
.addComponent(jSourceGoToResultButton)
|
||||||
|
.addGap(0, 203, Short.MAX_VALUE))
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void jSourceGoToResultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jSourceGoToResultButtonActionPerformed
|
||||||
|
|
||||||
|
final DirectoryTreeTopComponent dtc = DirectoryTreeTopComponent.findInstance();
|
||||||
|
|
||||||
|
// Navigate to the source context artifact.
|
||||||
|
if (sourceContextArtifact != null) {
|
||||||
|
dtc.viewArtifact(sourceContextArtifact);
|
||||||
|
}
|
||||||
|
|
||||||
|
}//GEN-LAST:event_jSourceGoToResultButtonActionPerformed
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNode(Node selectedNode) {
|
||||||
|
if ((selectedNode == null) || (!isSupported(selectedNode))) {
|
||||||
|
resetComponent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
|
||||||
|
try {
|
||||||
|
populateSourceContextData(file);
|
||||||
|
} catch (NoCurrentCaseException | TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception displaying context for file {0}", file); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTitle() {
|
||||||
|
return Bundle.ContextViewer_title();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getToolTip() {
|
||||||
|
return Bundle.ContextViewer_toolTip();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataContentViewer createInstance() {
|
||||||
|
return new ContextViewer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getComponent() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetComponent() {
|
||||||
|
setSourceName("");
|
||||||
|
setSourceText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSupported(Node node) {
|
||||||
|
|
||||||
|
// check if the node has an abstract file and the file has any context defining artifacts.
|
||||||
|
if (node.getLookup().lookup(AbstractFile.class) != null) {
|
||||||
|
AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class);
|
||||||
|
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : SOURCE_CONTEXT_ARTIFACTS) {
|
||||||
|
List<BlackboardArtifact> artifactsList;
|
||||||
|
try {
|
||||||
|
artifactsList = abstractFile.getArtifacts(artifactType);
|
||||||
|
if (!artifactsList.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, "Exception while looking up context artifacts for file {0}", abstractFile); //NON-NLS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int isPreferred(Node node) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void populateSourceContextData(AbstractFile sourceFile) throws NoCurrentCaseException, TskCoreException {
|
||||||
|
|
||||||
|
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
|
||||||
|
|
||||||
|
// Check for all context artifacts
|
||||||
|
boolean foundASource = false;
|
||||||
|
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : SOURCE_CONTEXT_ARTIFACTS) {
|
||||||
|
List<BlackboardArtifact> artifactsList = tskCase.getBlackboardArtifacts(artifactType, sourceFile.getId());
|
||||||
|
if (!artifactsList.isEmpty()) {
|
||||||
|
foundASource = true;
|
||||||
|
}
|
||||||
|
for (BlackboardArtifact contextArtifact : artifactsList) {
|
||||||
|
addSourceEntry(contextArtifact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foundASource == false) {
|
||||||
|
setSourceName("Unknown");
|
||||||
|
showSourceText(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"ContextViewer.attachmentSource=Attached to: ",
|
||||||
|
"ContextViewer.downloadSource=Downloaded from: "
|
||||||
|
})
|
||||||
|
private void addSourceEntry(BlackboardArtifact artifact) throws TskCoreException {
|
||||||
|
|
||||||
|
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
|
||||||
|
BlackboardAttribute associatedArtifactAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
|
||||||
|
if (associatedArtifactAttribute != null) {
|
||||||
|
long artifactId = associatedArtifactAttribute.getValueLong();
|
||||||
|
BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(artifactId);
|
||||||
|
|
||||||
|
//save the artifact id for "Go to Result" button
|
||||||
|
sourceContextArtifact = associatedArtifact;
|
||||||
|
|
||||||
|
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == associatedArtifact.getArtifactTypeID()
|
||||||
|
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == associatedArtifact.getArtifactTypeID()) {
|
||||||
|
|
||||||
|
setSourceName(Bundle.ContextViewer_attachmentSource());
|
||||||
|
setSourceText(msgArtifactToAbbreiviatedString(associatedArtifact));
|
||||||
|
|
||||||
|
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == associatedArtifact.getArtifactTypeID()
|
||||||
|
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == associatedArtifact.getArtifactTypeID()) {
|
||||||
|
|
||||||
|
setSourceName(Bundle.ContextViewer_downloadSource());
|
||||||
|
setSourceText(webDownloadArtifactToString(associatedArtifact));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSourceName(String nameLabel) {
|
||||||
|
jSourceNameLabel.setText(nameLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSourceText(String text) {
|
||||||
|
jSourceTextLabel.setText(text);
|
||||||
|
showSourceText(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showSourceText(boolean isVisible) {
|
||||||
|
jSourceTextLabel.setVisible(isVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String webDownloadArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
|
||||||
|
StringBuilder sb = new StringBuilder(1024);
|
||||||
|
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
|
||||||
|
|
||||||
|
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
|
||||||
|
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
|
||||||
|
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL, attributesMap, "URL");
|
||||||
|
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED, attributesMap, "On");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String msgArtifactToAbbreiviatedString(BlackboardArtifact artifact) throws TskCoreException {
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder(1024);
|
||||||
|
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
|
||||||
|
|
||||||
|
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifact.getArtifactTypeID()) {
|
||||||
|
sb.append("Message ");
|
||||||
|
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM, attributesMap, "From");
|
||||||
|
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, attributesMap, "To");
|
||||||
|
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, "On");
|
||||||
|
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
|
||||||
|
sb.append("Email ");
|
||||||
|
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM, attributesMap, "From");
|
||||||
|
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO, attributesMap, "To");
|
||||||
|
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT, attributesMap, "On");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendAttributeString(StringBuilder sb, BlackboardAttribute.ATTRIBUTE_TYPE attribType,
|
||||||
|
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap, String prependStr) {
|
||||||
|
|
||||||
|
BlackboardAttribute attribute = attributesMap.get(attribType);
|
||||||
|
if (attribute != null) {
|
||||||
|
String attrVal = attribute.getDisplayString();
|
||||||
|
if (!StringUtils.isEmpty(attrVal)) {
|
||||||
|
if (!StringUtils.isEmpty(prependStr)) {
|
||||||
|
sb.append(prependStr).append(" ");
|
||||||
|
}
|
||||||
|
sb.append(StringUtils.abbreviate(attrVal, 200)).append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getAttribNameValue(BlackboardAttribute.ATTRIBUTE_TYPE attribType, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap) {
|
||||||
|
BlackboardAttribute attribute = attributesMap.get(attribType);
|
||||||
|
if (attribute != null) {
|
||||||
|
return String.format("%s : %s", attribType.getDisplayName(), attribute.getDisplayString());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> getAttributesMap(BlackboardArtifact artifact) throws TskCoreException {
|
||||||
|
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap = new HashMap<>();
|
||||||
|
|
||||||
|
List<BlackboardAttribute> attributeList = artifact.getAttributes();
|
||||||
|
for (BlackboardAttribute attribute : attributeList) {
|
||||||
|
BlackboardAttribute.ATTRIBUTE_TYPE type = BlackboardAttribute.ATTRIBUTE_TYPE.fromID(attribute.getAttributeType().getTypeID());
|
||||||
|
attributeMap.put(type, attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JLabel jLabel1;
|
||||||
|
private javax.swing.JButton jSourceGoToResultButton;
|
||||||
|
private javax.swing.JLabel jSourceNameLabel;
|
||||||
|
private javax.swing.JLabel jSourceTextLabel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -191,12 +191,21 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<BlackboardArtifact> sourceArtifacts = file.getArtifacts(ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
|
List<BlackboardArtifact> associatedObjectArtifacts = file.getArtifacts(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
|
||||||
if (!sourceArtifacts.isEmpty()) {
|
if (!associatedObjectArtifacts.isEmpty()) {
|
||||||
BlackboardArtifact artifact = sourceArtifacts.get(0);
|
BlackboardArtifact artifact = associatedObjectArtifacts.get(0);
|
||||||
BlackboardAttribute urlAttr = artifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_URL));
|
BlackboardAttribute associatedArtifactAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
|
||||||
if (urlAttr != null) {
|
if (associatedArtifactAttribute != null) {
|
||||||
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.downloadSource"), urlAttr.getValueString());
|
long artifactId = associatedArtifactAttribute.getValueLong();
|
||||||
|
BlackboardArtifact associatedArtifact = artifact.getSleuthkitCase().getBlackboardArtifact(artifactId);
|
||||||
|
if (associatedArtifact != null &&
|
||||||
|
((associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) ||
|
||||||
|
(associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())) ) {
|
||||||
|
BlackboardAttribute urlAttr = associatedArtifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_URL));
|
||||||
|
if (urlAttr != null) {
|
||||||
|
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.downloadSource"), urlAttr.getValueString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
|
@ -238,8 +238,8 @@ public class ExtractedContent implements AutopsyVisitableItem {
|
|||||||
doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT));
|
doNotShow.add(new BlackboardArtifact.Type(TSK_INTERESTING_ARTIFACT_HIT));
|
||||||
doNotShow.add(new BlackboardArtifact.Type(TSK_ACCOUNT));
|
doNotShow.add(new BlackboardArtifact.Type(TSK_ACCOUNT));
|
||||||
doNotShow.add(new BlackboardArtifact.Type(TSK_DATA_SOURCE_USAGE));
|
doNotShow.add(new BlackboardArtifact.Type(TSK_DATA_SOURCE_USAGE));
|
||||||
doNotShow.add(new BlackboardArtifact.Type(TSK_DOWNLOAD_SOURCE));
|
//doNotShow.add(new BlackboardArtifact.Type(TSK_DOWNLOAD_SOURCE));
|
||||||
doNotShow.add(new BlackboardArtifact.Type(TSK_ASSOCIATED_OBJECT));
|
//doNotShow.add(new BlackboardArtifact.Type(TSK_ASSOCIATED_OBJECT));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
private final PropertyChangeListener pcl = (PropertyChangeEvent evt) -> {
|
||||||
|
@ -554,22 +554,24 @@ class Chrome extends Extract {
|
|||||||
RecentActivityExtracterModuleFactory.getModuleName(),
|
RecentActivityExtracterModuleFactory.getModuleName(),
|
||||||
NbBundle.getMessage(this.getClass(), "Chrome.moduleName")));
|
NbBundle.getMessage(this.getClass(), "Chrome.moduleName")));
|
||||||
|
|
||||||
BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes);
|
BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadFile, bbattributes);
|
||||||
if (bbart != null) {
|
if (webDownloadArtifact != null) {
|
||||||
bbartifacts.add(bbart);
|
bbartifacts.add(webDownloadArtifact);
|
||||||
}
|
|
||||||
|
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
|
||||||
// find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it..
|
try {
|
||||||
try {
|
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(fullPath), FilenameUtils.getPath(fullPath))) {
|
||||||
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(fullPath), FilenameUtils.getPath(fullPath))) {
|
BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
|
||||||
BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
|
associatedObjectArtifact.addAttribute(
|
||||||
downloadSourceArt.addAttributes(createDownloadSourceAttributes(result.get("url").toString()));
|
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
|
||||||
|
RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
|
||||||
bbartifacts.add(downloadSourceArt);
|
|
||||||
break;
|
bbartifacts.add(associatedObjectArtifact);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'", fullPath), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'", fullPath), ex); //NON-NLS
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,12 +380,12 @@ final class ChromeCacheExtractor {
|
|||||||
* Extracts the files if needed and adds as derived files, creates artifacts
|
* Extracts the files if needed and adds as derived files, creates artifacts
|
||||||
*
|
*
|
||||||
* @param cacheEntryAddress cache entry address
|
* @param cacheEntryAddress cache entry address
|
||||||
* @param sourceArtifacts any source artifacts created are added to this collection
|
* @param associatedObjectArtifacts any associated object artifacts created are added to this collection
|
||||||
* @param webCacheArtifacts any web cache artifacts created are added to this collection
|
* @param webCacheArtifacts any web cache artifacts created are added to this collection
|
||||||
*
|
*
|
||||||
* @return Optional derived file, is a derived file is added for the given entry
|
* @return Optional derived file, is a derived file is added for the given entry
|
||||||
*/
|
*/
|
||||||
private List<DerivedFile> processCacheEntry(CacheAddress cacheEntryAddress, Collection<BlackboardArtifact> sourceArtifacts, Collection<BlackboardArtifact> webCacheArtifacts ) throws TskCoreException, IngestModuleException {
|
private List<DerivedFile> processCacheEntry(CacheAddress cacheEntryAddress, Collection<BlackboardArtifact> associatedObjectArtifacts, Collection<BlackboardArtifact> webCacheArtifacts ) throws TskCoreException, IngestModuleException {
|
||||||
|
|
||||||
List<DerivedFile> derivedFiles = new ArrayList<>();
|
List<DerivedFile> derivedFiles = new ArrayList<>();
|
||||||
|
|
||||||
@ -437,10 +437,6 @@ final class ChromeCacheExtractor {
|
|||||||
moduleName,
|
moduleName,
|
||||||
cacheEntry.getHTTPHeaders());
|
cacheEntry.getHTTPHeaders());
|
||||||
|
|
||||||
Collection<BlackboardAttribute> sourceArtifactAttributes = new ArrayList<>();
|
|
||||||
sourceArtifactAttributes.add(urlAttr);
|
|
||||||
sourceArtifactAttributes.add(createTimeAttr);
|
|
||||||
|
|
||||||
Collection<BlackboardAttribute> webCacheAttributes = new ArrayList<>();
|
Collection<BlackboardAttribute> webCacheAttributes = new ArrayList<>();
|
||||||
webCacheAttributes.add(urlAttr);
|
webCacheAttributes.add(urlAttr);
|
||||||
webCacheAttributes.add(createTimeAttr);
|
webCacheAttributes.add(createTimeAttr);
|
||||||
@ -450,12 +446,7 @@ final class ChromeCacheExtractor {
|
|||||||
// add artifacts to the f_XXX file
|
// add artifacts to the f_XXX file
|
||||||
if (dataSegment.isInExternalFile() ) {
|
if (dataSegment.isInExternalFile() ) {
|
||||||
try {
|
try {
|
||||||
BlackboardArtifact sourceArtifact = cachedFileAbstractFile.get().newArtifact(ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
|
|
||||||
if (sourceArtifact != null) {
|
|
||||||
sourceArtifact.addAttributes(sourceArtifactAttributes);
|
|
||||||
sourceArtifacts.add(sourceArtifact);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlackboardArtifact webCacheArtifact = cacheEntryFile.get().getAbstractFile().newArtifact(ARTIFACT_TYPE.TSK_WEB_CACHE);
|
BlackboardArtifact webCacheArtifact = cacheEntryFile.get().getAbstractFile().newArtifact(ARTIFACT_TYPE.TSK_WEB_CACHE);
|
||||||
if (webCacheArtifact != null) {
|
if (webCacheArtifact != null) {
|
||||||
webCacheArtifact.addAttributes(webCacheAttributes);
|
webCacheArtifact.addAttributes(webCacheAttributes);
|
||||||
@ -469,6 +460,14 @@ final class ChromeCacheExtractor {
|
|||||||
moduleName, cachedFileAbstractFile.get().getId()));
|
moduleName, cachedFileAbstractFile.get().getId()));
|
||||||
|
|
||||||
webCacheArtifacts.add(webCacheArtifact);
|
webCacheArtifacts.add(webCacheArtifact);
|
||||||
|
|
||||||
|
BlackboardArtifact associatedObjectArtifact = cachedFileAbstractFile.get().newArtifact(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
|
||||||
|
if (associatedObjectArtifact != null) {
|
||||||
|
associatedObjectArtifact.addAttribute(
|
||||||
|
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
|
||||||
|
moduleName, webCacheArtifact.getArtifactID()));
|
||||||
|
associatedObjectArtifacts.add(associatedObjectArtifact);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBrotliCompressed) {
|
if (isBrotliCompressed) {
|
||||||
@ -497,12 +496,7 @@ final class ChromeCacheExtractor {
|
|||||||
"",
|
"",
|
||||||
TskData.EncodingType.NONE);
|
TskData.EncodingType.NONE);
|
||||||
|
|
||||||
BlackboardArtifact sourceArtifact = derivedFile.newArtifact(ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
|
|
||||||
if (sourceArtifact != null) {
|
|
||||||
sourceArtifact.addAttributes(sourceArtifactAttributes);
|
|
||||||
sourceArtifacts.add(sourceArtifact);
|
|
||||||
}
|
|
||||||
|
|
||||||
BlackboardArtifact webCacheArtifact = cacheEntryFile.get().getAbstractFile().newArtifact(ARTIFACT_TYPE.TSK_WEB_CACHE);
|
BlackboardArtifact webCacheArtifact = cacheEntryFile.get().getAbstractFile().newArtifact(ARTIFACT_TYPE.TSK_WEB_CACHE);
|
||||||
if (webCacheArtifact != null) {
|
if (webCacheArtifact != null) {
|
||||||
webCacheArtifact.addAttributes(webCacheAttributes);
|
webCacheArtifact.addAttributes(webCacheAttributes);
|
||||||
@ -516,6 +510,14 @@ final class ChromeCacheExtractor {
|
|||||||
moduleName, derivedFile.getId()));
|
moduleName, derivedFile.getId()));
|
||||||
|
|
||||||
webCacheArtifacts.add(webCacheArtifact);
|
webCacheArtifacts.add(webCacheArtifact);
|
||||||
|
|
||||||
|
BlackboardArtifact associatedObjectArtifact = derivedFile.newArtifact(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
|
||||||
|
if (associatedObjectArtifact != null) {
|
||||||
|
associatedObjectArtifact.addAttribute(
|
||||||
|
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
|
||||||
|
moduleName, webCacheArtifact.getArtifactID()));
|
||||||
|
associatedObjectArtifacts.add(associatedObjectArtifact);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBrotliCompressed) {
|
if (isBrotliCompressed) {
|
||||||
|
@ -50,6 +50,7 @@ import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
|||||||
import org.sleuthkit.autopsy.recentactivity.BinaryCookieReader.Cookie;
|
import org.sleuthkit.autopsy.recentactivity.BinaryCookieReader.Cookie;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
@ -637,15 +638,17 @@ final class ExtractSafari extends Extract {
|
|||||||
time = date.getDate().getTime();
|
time = date.getDate().getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
BlackboardArtifact bbart = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD);
|
BlackboardArtifact webDownloadArtifact = origFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD);
|
||||||
bbart.addAttributes(this.createDownloadAttributes(path, pathID, url, time, NetworkUtils.extractDomain(url), getName()));
|
webDownloadArtifact.addAttributes(this.createDownloadAttributes(path, pathID, url, time, NetworkUtils.extractDomain(url), getName()));
|
||||||
bbartifacts.add(bbart);
|
bbartifacts.add(webDownloadArtifact);
|
||||||
|
|
||||||
// find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it.
|
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
|
||||||
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(path), FilenameUtils.getPath(path))) {
|
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(path), FilenameUtils.getPath(path))) {
|
||||||
BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
|
BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
|
||||||
downloadSourceArt.addAttributes(createDownloadSourceAttributes(url));
|
associatedObjectArtifact.addAttribute(
|
||||||
bbartifacts.add(downloadSourceArt);
|
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
|
||||||
|
RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
|
||||||
|
bbartifacts.add(associatedObjectArtifact);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +36,11 @@ import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
|
||||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE;
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE;
|
||||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD;
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD;
|
||||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
|
||||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN;
|
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_LOCATION;
|
||||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID;
|
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID;
|
||||||
@ -94,7 +96,7 @@ final class ExtractZoneIdentifier extends Extract {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<BlackboardArtifact> sourceArtifacts = new ArrayList<>();
|
Collection<BlackboardArtifact> associatedObjectArtifacts = new ArrayList<>();
|
||||||
Collection<BlackboardArtifact> downloadArtifacts = new ArrayList<>();
|
Collection<BlackboardArtifact> downloadArtifacts = new ArrayList<>();
|
||||||
|
|
||||||
for (AbstractFile zoneFile : zoneFiles) {
|
for (AbstractFile zoneFile : zoneFiles) {
|
||||||
@ -104,7 +106,7 @@ final class ExtractZoneIdentifier extends Extract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
processZoneFile(context, dataSource, zoneFile, sourceArtifacts, downloadArtifacts, knownPathIDs);
|
processZoneFile(context, dataSource, zoneFile, associatedObjectArtifacts, downloadArtifacts, knownPathIDs);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
addErrorMessage(Bundle.ExtractZone_process_errMsg());
|
addErrorMessage(Bundle.ExtractZone_process_errMsg());
|
||||||
String message = String.format("Failed to process zone identifier file %s", zoneFile.getName()); //NON-NLS
|
String message = String.format("Failed to process zone identifier file %s", zoneFile.getName()); //NON-NLS
|
||||||
@ -112,23 +114,23 @@ final class ExtractZoneIdentifier extends Extract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
postArtifacts(sourceArtifacts);
|
postArtifacts(associatedObjectArtifacts);
|
||||||
postArtifacts(downloadArtifacts);
|
postArtifacts(downloadArtifacts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a single Zone Identifier file.
|
* Process a single Zone Identifier file.
|
||||||
*
|
*
|
||||||
* @param context IngetJobContext
|
* @param context IngetJobContext
|
||||||
* @param dataSource Content
|
* @param dataSource Content
|
||||||
* @param zoneFile Zone Indentifier file
|
* @param zoneFile Zone Indentifier file
|
||||||
* @param sourceArtifacts List for TSK_DOWNLOAD_SOURCE artifacts
|
* @param associatedObjectArtifacts List for TSK_ASSOCIATED_OBJECT artifacts
|
||||||
* @param downloadArtifacts List for TSK_WEB_DOWNLOAD aritfacts
|
* @param downloadArtifacts List for TSK_WEB_DOWNLOAD artifacts
|
||||||
*
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
private void processZoneFile(IngestJobContext context, Content dataSource,
|
private void processZoneFile(IngestJobContext context, Content dataSource,
|
||||||
AbstractFile zoneFile, Collection<BlackboardArtifact> sourceArtifacts,
|
AbstractFile zoneFile, Collection<BlackboardArtifact> associatedObjectArtifacts,
|
||||||
Collection<BlackboardArtifact> downloadArtifacts,
|
Collection<BlackboardArtifact> downloadArtifacts,
|
||||||
Set<Long> knownPathIDs) throws TskCoreException {
|
Set<Long> knownPathIDs) throws TskCoreException {
|
||||||
|
|
||||||
@ -155,16 +157,16 @@ final class ExtractZoneIdentifier extends Extract {
|
|||||||
BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo);
|
BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo);
|
||||||
if (downloadBba != null) {
|
if (downloadBba != null) {
|
||||||
downloadArtifacts.add(downloadBba);
|
downloadArtifacts.add(downloadBba);
|
||||||
|
// create a TSK_ASSOCIATED_OBJECT for the downloaded file, associating it with the TSK_WEB_DOWNLOAD artifact.
|
||||||
|
if (downloadFile.getArtifactsCount(TSK_ASSOCIATED_OBJECT) == 0) {
|
||||||
|
BlackboardArtifact associatedObjectBba = createAssociatedObjectArtifact(downloadFile, downloadBba);
|
||||||
|
if (associatedObjectBba != null) {
|
||||||
|
associatedObjectArtifacts.add(associatedObjectBba);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,33 +205,26 @@ final class ExtractZoneIdentifier extends Extract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Download Source Artifact for the given ZoneIdentifierInfo
|
* Create a Associated Object Artifact for the given ZoneIdentifierInfo
|
||||||
* object.
|
* object.
|
||||||
*
|
*
|
||||||
* @param downloadFile AbstractFile representing the file downloaded, not
|
* @param downloadFile AbstractFile representing the file downloaded, not
|
||||||
* the zone identifier file.
|
* the zone identifier file.
|
||||||
* @param zoneInfo Zone identifier file wrapper object
|
* @param downloadBba TSK_WEB_DOWNLOAD artifact to associate with.
|
||||||
*
|
*
|
||||||
* @return TSK_DOWNLOAD_SOURCE object for given parameters
|
* @return TSK_ASSOCIATED_OBJECT artifact.
|
||||||
*/
|
*/
|
||||||
private BlackboardArtifact createDownloadSourceArtifact(AbstractFile downloadFile, ZoneIdentifierInfo zoneInfo) {
|
private BlackboardArtifact createAssociatedObjectArtifact(AbstractFile downloadFile, BlackboardArtifact downloadBba) {
|
||||||
|
|
||||||
Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
|
Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
|
||||||
|
|
||||||
bbattributes.addAll(Arrays.asList(
|
bbattributes.addAll(Arrays.asList(
|
||||||
new BlackboardAttribute(TSK_URL,
|
new BlackboardAttribute(TSK_ASSOCIATED_ARTIFACT,
|
||||||
RecentActivityExtracterModuleFactory.getModuleName(),
|
RecentActivityExtracterModuleFactory.getModuleName(),
|
||||||
StringUtils.defaultString(zoneInfo.getURL(), "")),
|
downloadBba.getArtifactID())
|
||||||
|
));
|
||||||
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 createArtifactWithAttributes(TSK_DOWNLOAD_SOURCE, downloadFile, bbattributes);
|
return createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, downloadFile, bbattributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -544,22 +544,25 @@ class Firefox extends Extract {
|
|||||||
domain)); //NON-NLS
|
domain)); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
|
BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
|
||||||
if (bbart != null) {
|
if (webDownloadArtifact != null) {
|
||||||
bbartifacts.add(bbart);
|
bbartifacts.add(webDownloadArtifact);
|
||||||
}
|
|
||||||
|
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
|
||||||
// find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it.
|
try {
|
||||||
try {
|
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
|
||||||
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
|
BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
|
||||||
BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
|
associatedObjectArtifact.addAttribute(
|
||||||
downloadSourceArt.addAttributes(createDownloadSourceAttributes(source));
|
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
|
||||||
bbartifacts.add(downloadSourceArt);
|
RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
|
||||||
break;
|
|
||||||
|
bbartifacts.add(associatedObjectArtifact);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'",
|
||||||
|
downloadedFilePath), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'",
|
|
||||||
downloadedFilePath), ex); //NON-NLS
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errors > 0) {
|
if (errors > 0) {
|
||||||
@ -681,22 +684,24 @@ class Firefox extends Extract {
|
|||||||
RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
|
RecentActivityExtracterModuleFactory.getModuleName(), domain)); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
BlackboardArtifact bbart = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
|
BlackboardArtifact webDownloadArtifact = createArtifactWithAttributes(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, downloadsFile, bbattributes);
|
||||||
if (bbart != null) {
|
if (webDownloadArtifact != null) {
|
||||||
bbartifacts.add(bbart);
|
bbartifacts.add(webDownloadArtifact);
|
||||||
}
|
|
||||||
|
|
||||||
// find the downloaded file and create a TSK_DOWNLOAD_SOURCE for it.
|
// find the downloaded file and create a TSK_ASSOCIATED_OBJECT for it, associating it with the TSK_WEB_DOWNLOAD artifact.
|
||||||
try {
|
try {
|
||||||
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
|
for (AbstractFile downloadedFile : fileManager.findFiles(dataSource, FilenameUtils.getName(downloadedFilePath), FilenameUtils.getPath(downloadedFilePath))) {
|
||||||
BlackboardArtifact downloadSourceArt = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_DOWNLOAD_SOURCE);
|
BlackboardArtifact associatedObjectArtifact = downloadedFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
|
||||||
downloadSourceArt.addAttributes(createDownloadSourceAttributes(url));
|
associatedObjectArtifact.addAttribute(
|
||||||
bbartifacts.add(downloadSourceArt);
|
new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
|
||||||
break;
|
RecentActivityExtracterModuleFactory.getModuleName(), webDownloadArtifact.getArtifactID()));
|
||||||
|
bbartifacts.add(associatedObjectArtifact);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Error creating associated object artifact for file '%s'",
|
||||||
|
downloadedFilePath), ex); //NON-NLS
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
logger.log(Level.SEVERE, String.format("Error creating download source artifact for file '%s'",
|
|
||||||
downloadedFilePath), ex); //NON-NLS
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errors > 0) {
|
if (errors > 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user