mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
First cut
This commit is contained in:
parent
56e7958ba6
commit
b8b608930a
@ -72,6 +72,9 @@ public class Artifacts {
|
||||
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST
|
||||
= EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED);
|
||||
|
||||
private static BlackboardArtifact.Type MALWARE_ARTIFACT_TYPE = null;
|
||||
private static final String MALWARE_HITS = "TSK_MALWARE";
|
||||
|
||||
/**
|
||||
* Base class for a parent node of artifacts.
|
||||
@ -242,6 +245,16 @@ public class Artifacts {
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private static TypeNodeKey getTypeKey(BlackboardArtifact.Type type, SleuthkitCase skCase, long dsObjId) {
|
||||
|
||||
// ELTODO
|
||||
if (MALWARE_ARTIFACT_TYPE == null) {
|
||||
try {
|
||||
MALWARE_ARTIFACT_TYPE = skCase.getArtifactType(MALWARE_HITS);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get TSK_MALWARE artifact type from database : ", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
int typeId = type.getTypeID();
|
||||
if (TSK_EMAIL_MSG.getTypeID() == typeId) {
|
||||
EmailExtracted.RootNode emailNode = new EmailExtracted(skCase, dsObjId).new RootNode();
|
||||
@ -267,7 +280,9 @@ public class Artifacts {
|
||||
} else if (TSK_HASHSET_HIT.getTypeID() == typeId) {
|
||||
HashsetHits.RootNode hashsetHits = new HashsetHits(skCase, dsObjId).new RootNode();
|
||||
return new TypeNodeKey(hashsetHits, TSK_HASHSET_HIT);
|
||||
|
||||
} else if (MALWARE_ARTIFACT_TYPE != null && MALWARE_ARTIFACT_TYPE.getTypeID() == typeId) {
|
||||
MalwareHits.RootNode malwareHits = new MalwareHits(skCase, dsObjId).new RootNode();
|
||||
return new TypeNodeKey(malwareHits, MALWARE_ARTIFACT_TYPE);
|
||||
} else {
|
||||
return new TypeNodeKey(type, dsObjId);
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ public interface AutopsyItemVisitor<T> {
|
||||
T visit(KeywordHits kh);
|
||||
|
||||
T visit(HashsetHits hh);
|
||||
|
||||
T visit(MalwareHits mh);
|
||||
|
||||
T visit(EmailExtracted ee);
|
||||
|
||||
@ -169,6 +171,11 @@ public interface AutopsyItemVisitor<T> {
|
||||
return defaultVisit(hh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(MalwareHits mh) {
|
||||
return defaultVisit(mh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(InterestingHits ih) {
|
||||
return defaultVisit(ih);
|
||||
|
@ -111,6 +111,8 @@ public interface DisplayableItemNodeVisitor<T> {
|
||||
T visit(HashsetHits.RootNode hhrn);
|
||||
|
||||
T visit(HashsetHits.HashsetNameNode hhsn);
|
||||
|
||||
T visit(MalwareHits.RootNode mhrn);
|
||||
|
||||
T visit(EmailExtracted.RootNode eern);
|
||||
|
||||
@ -431,6 +433,11 @@ public interface DisplayableItemNodeVisitor<T> {
|
||||
return defaultVisit(hhsn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(MalwareHits.RootNode mhrn) {
|
||||
return defaultVisit(mhrn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T visit(InterestingHits.RootNode ihrn) {
|
||||
return defaultVisit(ihrn);
|
||||
|
331
Core/src/org/sleuthkit/autopsy/datamodel/MalwareHits.java
Executable file
331
Core/src/org/sleuthkit/autopsy/datamodel/MalwareHits.java
Executable file
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2023 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.datamodel;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.nodes.ChildFactory;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.WeakListeners;
|
||||
import org.openide.util.lookup.Lookups;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbQuery;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.autopsy.datamodel.Artifacts.UpdatableCountTypeNode;
|
||||
import org.sleuthkit.datamodel.AnalysisResult;
|
||||
import org.sleuthkit.datamodel.Score;
|
||||
|
||||
/**
|
||||
* Malware hits node support. Inner classes have all of the nodes in the tree.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"MalwareHits_malwareTypeDisplayName=Malware",})
|
||||
public class MalwareHits implements AutopsyVisitableItem {
|
||||
|
||||
private static final String MALWARE_HITS = "TSK_MALWARE";
|
||||
private static BlackboardArtifact.Type MALWARE_ARTIFACT_TYPE = null;
|
||||
private static final String DISPLAY_NAME = Bundle.MalwareHits_malwareTypeDisplayName(); // ELTODO get from database
|
||||
private static final Logger logger = Logger.getLogger(MalwareHits.class.getName());
|
||||
private static final Set<IngestManager.IngestJobEvent> INGEST_JOB_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestJobEvent.COMPLETED, IngestManager.IngestJobEvent.CANCELLED);
|
||||
private static final Set<IngestManager.IngestModuleEvent> INGEST_MODULE_EVENTS_OF_INTEREST = EnumSet.of(IngestManager.IngestModuleEvent.DATA_ADDED);
|
||||
private SleuthkitCase skCase;
|
||||
private final MalwareResults malwareResults;
|
||||
private final long filteringDSObjId; // 0 if not filtering/grouping by data source
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param skCase Case DB
|
||||
*
|
||||
*/
|
||||
public MalwareHits(SleuthkitCase skCase) {
|
||||
this(skCase, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param skCase Case DB
|
||||
* @param objId Object id of the data source
|
||||
*
|
||||
*/
|
||||
public MalwareHits(SleuthkitCase skCase, long objId) {
|
||||
this.skCase = skCase;
|
||||
this.filteringDSObjId = objId;
|
||||
malwareResults = new MalwareResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(AutopsyItemVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores all of the malware results in a single class that is observable
|
||||
* for the child nodes
|
||||
*/
|
||||
private class MalwareResults extends Observable {
|
||||
|
||||
// list of artifacts
|
||||
// NOTE: the list can be accessed by multiple worker threads and needs to be synchronized
|
||||
private final Set<Long> malwareHits = new HashSet<>();
|
||||
|
||||
MalwareResults() {
|
||||
update();
|
||||
}
|
||||
|
||||
Set<Long> getArtifactIds() {
|
||||
synchronized (malwareHits) {
|
||||
return Collections.unmodifiableSet(malwareHits);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
final void update() {
|
||||
synchronized (malwareHits) {
|
||||
malwareHits.clear();
|
||||
}
|
||||
|
||||
if (skCase == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (MALWARE_ARTIFACT_TYPE == null) {
|
||||
try {
|
||||
MALWARE_ARTIFACT_TYPE = skCase.getArtifactType(MALWARE_HITS);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to get TSK_MALWARE artifact type from database : ", ex); //NON-NLS
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String query = "SELECT blackboard_artifacts.artifact_obj_id " //NON-NLS
|
||||
+ "FROM blackboard_artifacts,tsk_analysis_results WHERE " //NON-NLS
|
||||
+ "blackboard_artifacts.artifact_type_id=" + MALWARE_ARTIFACT_TYPE.getTypeID()
|
||||
+ " AND tsk_analysis_results.artifact_obj_id=blackboard_artifacts.artifact_obj_id" //NON-NLS
|
||||
+ " AND (tsk_analysis_results.significance=" + Score.Significance.NOTABLE.getId()
|
||||
+ " OR tsk_analysis_results.significance=" + Score.Significance.LIKELY_NONE.getId() + " )"; // ELTODO LIKELY_NOTABLE
|
||||
if (filteringDSObjId > 0) {
|
||||
query += " AND blackboard_artifacts.data_source_obj_id = " + filteringDSObjId;
|
||||
}
|
||||
|
||||
try (CaseDbQuery dbQuery = skCase.executeQuery(query)) {
|
||||
ResultSet resultSet = dbQuery.getResultSet();
|
||||
synchronized (malwareHits) {
|
||||
while (resultSet.next()) {
|
||||
long artifactObjId = resultSet.getLong("artifact_obj_id"); //NON-NLS
|
||||
malwareHits.add(artifactObjId);
|
||||
}
|
||||
}
|
||||
} catch (TskCoreException | SQLException ex) {
|
||||
logger.log(Level.WARNING, "SQL Exception occurred: ", ex); //NON-NLS
|
||||
}
|
||||
|
||||
setChanged();
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Top-level node for all malware hits
|
||||
*/
|
||||
public class RootNode extends UpdatableCountTypeNode {
|
||||
|
||||
public RootNode() {
|
||||
super(Children.create(new HitFactory(DISPLAY_NAME), true),
|
||||
Lookups.singleton(DISPLAY_NAME),
|
||||
DISPLAY_NAME,
|
||||
filteringDSObjId,
|
||||
MALWARE_ARTIFACT_TYPE);
|
||||
|
||||
super.setName(MALWARE_HITS);
|
||||
//this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/hashset_hits.png"); // ELTODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeafTypeNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sheet createSheet() {
|
||||
Sheet sheet = super.createSheet();
|
||||
Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
|
||||
if (sheetSet == null) {
|
||||
sheetSet = Sheet.createPropertiesSet();
|
||||
sheet.put(sheetSet);
|
||||
}
|
||||
|
||||
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "MalwareHits.createSheet.name.name"),
|
||||
NbBundle.getMessage(this.getClass(), "MalwareHits.createSheet.name.displayName"),
|
||||
NbBundle.getMessage(this.getClass(), "MalwareHits.createSheet.name.desc"),
|
||||
getName()));
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemType() {
|
||||
return getClass().getName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Node for a hash set name
|
||||
|
||||
public class HashsetNameNode extends DisplayableItemNode implements Observer {
|
||||
|
||||
private final String hashSetName;
|
||||
|
||||
public HashsetNameNode(String hashSetName) {
|
||||
super(Children.create(new HitFactory(hashSetName), true), Lookups.singleton(hashSetName));
|
||||
super.setName(hashSetName);
|
||||
this.hashSetName = hashSetName;
|
||||
updateDisplayName();
|
||||
this.setIconBaseWithExtension("org/sleuthkit/autopsy/images/hashset_hits.png"); // ELTODO
|
||||
malwareResults.addObserver(this);
|
||||
}
|
||||
|
||||
// Update the count in the display name
|
||||
private void updateDisplayName() {
|
||||
super.setDisplayName(hashSetName + " (" + malwareResults.getArtifactIds(hashSetName).size() + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeafTypeNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sheet createSheet() {
|
||||
Sheet sheet = super.createSheet();
|
||||
Sheet.Set sheetSet = sheet.get(Sheet.PROPERTIES);
|
||||
if (sheetSet == null) {
|
||||
sheetSet = Sheet.createPropertiesSet();
|
||||
sheet.put(sheetSet);
|
||||
}
|
||||
|
||||
sheetSet.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "MalwareHits.createSheet.name.name"),
|
||||
NbBundle.getMessage(this.getClass(), "MalwareHits.createSheet.name.displayName"),
|
||||
NbBundle.getMessage(this.getClass(), "MalwareHits.createSheet.name.desc"),
|
||||
getName()));
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T accept(DisplayableItemNodeVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
updateDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemType() {
|
||||
// For custom settings for each hash set, return
|
||||
*getClass().getName() + hashSetName instead.
|
||||
return getClass().getName();
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Creates the nodes for the malware hits.
|
||||
*/
|
||||
private class HitFactory extends BaseChildFactory<AnalysisResult> implements Observer {
|
||||
|
||||
private final Map<Long, AnalysisResult> artifactHits = new HashMap<>();
|
||||
|
||||
private HitFactory(String nodeName) {
|
||||
super(nodeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAdd() {
|
||||
malwareResults.addObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRemove() {
|
||||
malwareResults.deleteObserver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node createNodeForKey(AnalysisResult key) {
|
||||
return new BlackboardArtifactNode(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
refresh(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AnalysisResult> makeKeys() {
|
||||
if (skCase != null) {
|
||||
|
||||
malwareResults.getArtifactIds().forEach((id) -> {
|
||||
try {
|
||||
if (!artifactHits.containsKey(id)) {
|
||||
AnalysisResult art = skCase.getBlackboard().getAnalysisResultById(id);
|
||||
//Cache attributes while we are off the EDT.
|
||||
//See JIRA-5969
|
||||
art.getAttributes();
|
||||
artifactHits.put(id, art);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "TSK Exception occurred", ex); //NON-NLS
|
||||
}
|
||||
});
|
||||
return new ArrayList<>(artifactHits.values());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user