19 package org.sleuthkit.autopsy.modules.hashdatabase;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.concurrent.atomic.AtomicLong;
27 import java.util.logging.Level;
28 import org.openide.util.NbBundle;
29 import org.openide.util.NbBundle.Messages;
53 "HashDbIngestModule.noKnownBadHashDbSetMsg=No known bad hash database set.",
54 "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn=Known bad file search will not be executed.",
55 "HashDbIngestModule.noKnownHashDbSetMsg=No known hash database set.",
56 "HashDbIngestModule.knownFileSearchWillNotExecuteWarn=Known file search will not be executed."
61 private static final int MAX_COMMENT_SIZE = 500;
65 private final HashLookupModuleSettings
settings;
66 private List<HashDb> knownBadHashSets =
new ArrayList<>();
67 private List<HashDb> knownHashSets =
new ArrayList<>();
69 private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs =
new HashMap<>();
75 private AtomicLong totalKnownBadCount =
new AtomicLong(0);
76 private AtomicLong totalCalctime =
new AtomicLong(0);
77 private AtomicLong totalLookuptime =
new AtomicLong(0);
84 totalsForIngestJobs.put(ingestJobId, totals);
90 this.settings = settings;
95 jobId = context.getJobId();
96 if (!hashDbManager.verifyAllDatabasesLoadedCorrectly()) {
97 throw new IngestModuleException(
"Could not load all hash databases");
104 getTotalsForIngestJobs(jobId);
107 if (knownBadHashSets.isEmpty()) {
110 Bundle.HashDbIngestModule_noKnownBadHashDbSetMsg(),
111 Bundle.HashDbIngestModule_knownBadFileSearchWillNotExecuteWarn()));
114 if (knownHashSets.isEmpty()) {
117 Bundle.HashDbIngestModule_noKnownHashDbSetMsg(),
118 Bundle.HashDbIngestModule_knownFileSearchWillNotExecuteWarn()));
130 enabledHashSets.clear();
131 for (
HashDb db : allHashSets) {
132 if (settings.isHashSetEnabled(db.getHashSetName())) {
135 enabledHashSets.add(db);
138 logger.log(Level.WARNING,
"Error getting index status for " + db.getHashSetName() +
" hash database", ex);
165 if ((knownHashSets.isEmpty()) && (knownBadHashSets.isEmpty()) && (!settings.shouldCalculateHashes())) {
175 if (md5Hash == null || md5Hash.isEmpty()) {
177 long calcstart = System.currentTimeMillis();
179 long delta = (System.currentTimeMillis() - calcstart);
182 }
catch (IOException ex) {
183 logger.log(Level.WARNING,
"Error calculating hash of file " + name, ex);
186 NbBundle.getMessage(this.getClass(),
187 "HashDbIngestModule.fileReadErrorMsg",
189 NbBundle.getMessage(this.getClass(),
190 "HashDbIngestModule.calcHashValueErr",
197 boolean foundBad =
false;
199 for (
HashDb db : knownBadHashSets) {
201 long lookupstart = System.currentTimeMillis();
203 if (null != hashInfo) {
210 logger.log(Level.WARNING,
"Couldn't set known bad state for file " + name +
" - see sleuthkit log for details", ex);
213 NbBundle.getMessage(this.getClass(),
214 "HashDbIngestModule.hashLookupErrorMsg",
216 NbBundle.getMessage(this.getClass(),
217 "HashDbIngestModule.settingKnownBadStateErr",
221 String hashSetName = db.getHashSetName();
224 ArrayList<String> comments = hashInfo.
getComments();
226 for (String c : comments) {
231 if (comment.length() > MAX_COMMENT_SIZE) {
232 comment = comment.substring(0, MAX_COMMENT_SIZE) +
"...";
237 postHashSetHitToBlackboard(file, md5Hash, hashSetName, comment, db.getSendIngestMessages());
239 long delta = (System.currentTimeMillis() - lookupstart);
243 logger.log(Level.WARNING,
"Couldn't lookup known bad hash for file " + name +
" - see sleuthkit log for details", ex);
246 NbBundle.getMessage(this.getClass(),
247 "HashDbIngestModule.hashLookupErrorMsg",
249 NbBundle.getMessage(this.getClass(),
250 "HashDbIngestModule.lookingUpKnownBadHashValueErr",
260 for (
HashDb db : knownHashSets) {
262 long lookupstart = System.currentTimeMillis();
263 if (db.lookupMD5Quick(file)) {
268 logger.log(Level.WARNING,
"Couldn't set known state for file " + name +
" - see sleuthkit log for details", ex);
272 long delta = (System.currentTimeMillis() - lookupstart);
276 logger.log(Level.WARNING,
"Couldn't lookup known hash for file " + name +
" - see sleuthkit log for details", ex);
279 NbBundle.getMessage(this.getClass(),
280 "HashDbIngestModule.hashLookupErrorMsg",
282 NbBundle.getMessage(this.getClass(),
283 "HashDbIngestModule.lookingUpKnownHashValueErr",
293 @Messages({
"HashDbIngestModule.indexError.message=Failed to index hashset hit artifact for keyword search."})
296 String MODULE_NAME = NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.moduleName");
312 logger.log(Level.SEVERE,
"Unable to index blackboard artifact " + badFile.
getArtifactID(), ex);
314 Bundle.HashDbIngestModule_indexError_message(), badFile.
getDisplayName());
317 if (showInboxMessage) {
318 StringBuilder detailsSb =
new StringBuilder();
320 detailsSb.append(
"<table border='0' cellpadding='4' width='280'>");
322 detailsSb.append(
"<tr>");
323 detailsSb.append(
"<th>")
324 .append(NbBundle.getMessage(
this.getClass(),
"HashDbIngestModule.postToBB.fileName"))
326 detailsSb.append(
"<td>")
327 .append(abstractFile.
getName())
329 detailsSb.append(
"</tr>");
331 detailsSb.append(
"<tr>");
332 detailsSb.append(
"<th>")
333 .append(NbBundle.getMessage(
this.getClass(),
"HashDbIngestModule.postToBB.md5Hash"))
335 detailsSb.append(
"<td>").append(md5Hash).append(
"</td>");
336 detailsSb.append(
"</tr>");
338 detailsSb.append(
"<tr>");
339 detailsSb.append(
"<th>")
340 .append(NbBundle.getMessage(
this.getClass(),
"HashDbIngestModule.postToBB.hashsetName"))
342 detailsSb.append(
"<td>").append(hashSetName).append(
"</td>");
343 detailsSb.append(
"</tr>");
345 detailsSb.append(
"</table>");
348 NbBundle.getMessage(this.getClass(),
349 "HashDbIngestModule.postToBB.knownBadMsg",
351 detailsSb.toString(),
352 abstractFile.
getName() + md5Hash,
357 logger.log(Level.WARNING,
"Error creating blackboard artifact", ex);
362 List<HashDb> knownBadHashSets, List<HashDb> knownHashSets) {
364 totalsForIngestJobs.remove(jobId);
366 if ((!knownBadHashSets.isEmpty()) || (!knownHashSets.isEmpty())) {
367 StringBuilder detailsSb =
new StringBuilder();
369 detailsSb.append(
"<table border='0' cellpadding='4' width='280'>");
371 detailsSb.append(
"<tr><td>")
372 .append(NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.complete.knownBadsFound"))
374 detailsSb.append(
"<td>").append(jobTotals.
totalKnownBadCount.get()).append(
"</td></tr>");
376 detailsSb.append(
"<tr><td>")
377 .append(NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.complete.totalCalcTime"))
378 .append(
"</td><td>").append(jobTotals.
totalCalctime.get()).append(
"</td></tr>\n");
379 detailsSb.append(
"<tr><td>")
380 .append(NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.complete.totalLookupTime"))
381 .append(
"</td><td>").append(jobTotals.
totalLookuptime.get()).append(
"</td></tr>\n");
382 detailsSb.append(
"</table>");
384 detailsSb.append(
"<p>")
385 .append(NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.complete.databasesUsed"))
386 .append(
"</p>\n<ul>");
387 for (
HashDb db : knownBadHashSets) {
388 detailsSb.append(
"<li>").append(db.getHashSetName()).append(
"</li>\n");
391 detailsSb.append(
"</ul>");
397 "HashDbIngestModule.complete.hashLookupResults"),
398 detailsSb.toString()));
405 postSummary(jobId, knownBadHashSets, knownHashSets);
static String calculateMd5(AbstractFile file)
synchronized long decrementAndGet(long jobId)
ProcessResult process(AbstractFile file)
static IngestMessage createDataMessage(String source, String subject, String detailsHtml, String uniqueKey, BlackboardArtifact data)
final HashLookupModuleSettings settings
static IngestMessage createErrorMessage(String source, String subject, String detailsHtml)
AtomicLong totalKnownBadCount
TskData.TSK_DB_FILES_TYPE_ENUM getType()
AtomicLong totalLookuptime
void startUp(org.sleuthkit.autopsy.ingest.IngestJobContext context)
synchronized long incrementAndGet(long jobId)
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
static synchronized IngestJobTotals getTotalsForIngestJobs(long ingestJobId)
void updateEnabledHashSets(List< HashDb > allHashSets, List< HashDb > enabledHashSets)
void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage)
synchronized List< HashDb > getKnownBadFileHashSets()
void addAttribute(BlackboardAttribute attr)
static synchronized HashDbManager getInstance()
void postMessage(final IngestMessage message)
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
ArrayList< String > getComments()
SleuthkitCase getSleuthkitCase()
Blackboard getBlackboard()
static synchronized void postSummary(long jobId, List< HashDb > knownBadHashSets, List< HashDb > knownHashSets)
BlackboardArtifact newArtifact(int artifactTypeID)
static void error(String title, String message)
synchronized void indexArtifact(BlackboardArtifact artifact)
boolean setKnown(AbstractFile file, FileKnown fileKnown)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
static IngestMessage createWarningMessage(String source, String subject, String detailsHtml)
synchronized List< HashDb > getKnownFileHashSets()
static synchronized IngestServices getInstance()