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;
38 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
40 import org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
58 private final HashLookupModuleSettings
settings;
77 totalsForIngestJobs.put(ingestJobId, totals);
88 jobId = context.getJobId();
98 if (knownBadHashSets.isEmpty()) {
101 NbBundle.getMessage(this.getClass(),
102 "HashDbIngestModule.noKnownBadHashDbSetMsg"),
103 NbBundle.getMessage(this.getClass(),
104 "HashDbIngestModule.knownBadFileSearchWillNotExecuteWarn")));
107 if (knownHashSets.isEmpty()) {
110 NbBundle.getMessage(this.getClass(),
111 "HashDbIngestModule.noKnownHashDbSetMsg"),
112 NbBundle.getMessage(this.getClass(),
113 "HashDbIngestModule.knownFileSearchWillNotExecuteWarn")));
125 enabledHashSets.clear();
126 for (
HashDb db : allHashSets) {
127 if (settings.isHashSetEnabled(db.getHashSetName())) {
130 enabledHashSets.add(db);
132 }
catch (TskCoreException ex) {
133 logger.log(Level.WARNING,
"Error getting index status for " + db.getHashSetName() +
" hash database", ex);
144 if (file.getType().equals(TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)) {
159 if ((knownHashSets.isEmpty()) && (knownBadHashSets.isEmpty()) && (!settings.shouldCalculateHashes())) {
167 String name = file.getName();
168 String md5Hash = file.getMd5Hash();
169 if (md5Hash == null || md5Hash.isEmpty()) {
171 long calcstart = System.currentTimeMillis();
172 md5Hash = HashUtility.calculateMd5(file);
173 long delta = (System.currentTimeMillis() - calcstart);
176 }
catch (IOException ex) {
177 logger.log(Level.WARNING,
"Error calculating hash of file " + name, ex);
180 NbBundle.getMessage(this.getClass(),
181 "HashDbIngestModule.fileReadErrorMsg",
183 NbBundle.getMessage(this.getClass(),
184 "HashDbIngestModule.calcHashValueErr",
191 boolean foundBad =
false;
193 for (
HashDb db : knownBadHashSets) {
195 long lookupstart = System.currentTimeMillis();
196 HashHitInfo hashInfo = db.lookupMD5(file);
197 if (null != hashInfo) {
202 skCase.setKnown(file, TskData.FileKnown.BAD);
203 }
catch (TskException ex) {
204 logger.log(Level.WARNING,
"Couldn't set known bad state for file " + name +
" - see sleuthkit log for details", ex);
207 NbBundle.getMessage(this.getClass(),
208 "HashDbIngestModule.hashLookupErrorMsg",
210 NbBundle.getMessage(this.getClass(),
211 "HashDbIngestModule.settingKnownBadStateErr",
215 String hashSetName = db.getHashSetName();
218 ArrayList<String> comments = hashInfo.getComments();
220 for (String c : comments) {
226 comment = comment.substring(0, MAX_COMMENT_SIZE) +
"...";
233 long delta = (System.currentTimeMillis() - lookupstart);
236 }
catch (TskException ex) {
237 logger.log(Level.WARNING,
"Couldn't lookup known bad hash for file " + name +
" - see sleuthkit log for details", ex);
240 NbBundle.getMessage(this.getClass(),
241 "HashDbIngestModule.hashLookupErrorMsg",
243 NbBundle.getMessage(this.getClass(),
244 "HashDbIngestModule.lookingUpKnownBadHashValueErr",
254 for (
HashDb db : knownHashSets) {
256 long lookupstart = System.currentTimeMillis();
257 if (db.lookupMD5Quick(file)) {
259 skCase.setKnown(file, TskData.FileKnown.KNOWN);
261 }
catch (TskException ex) {
262 logger.log(Level.WARNING,
"Couldn't set known state for file " + name +
" - see sleuthkit log for details", ex);
266 long delta = (System.currentTimeMillis() - lookupstart);
269 }
catch (TskException ex) {
270 logger.log(Level.WARNING,
"Couldn't lookup known hash for file " + name +
" - see sleuthkit log for details", ex);
273 NbBundle.getMessage(this.getClass(),
274 "HashDbIngestModule.hashLookupErrorMsg",
276 NbBundle.getMessage(this.getClass(),
277 "HashDbIngestModule.lookingUpKnownHashValueErr",
287 private void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment,
boolean showInboxMessage) {
289 String MODULE_NAME = NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.moduleName");
291 BlackboardArtifact badFile = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_HASHSET_HIT);
294 BlackboardAttribute att2 =
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, hashSetName);
295 badFile.addAttribute(att2);
296 BlackboardAttribute att3 =
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_HASH_MD5, MODULE_NAME, md5Hash);
297 badFile.addAttribute(att3);
298 BlackboardAttribute att4 =
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME, comment);
299 badFile.addAttribute(att4);
305 logger.log(Level.SEVERE, NbBundle.getMessage(
Blackboard.class,
"Blackboard.unableToIndexArtifact.error.msg", badFile.getDisplayName()), ex);
307 NbBundle.getMessage(
Blackboard.class,
"Blackboard.unableToIndexArtifact.exception.msg"), badFile.getDisplayName());
310 if (showInboxMessage) {
311 StringBuilder detailsSb =
new StringBuilder();
313 detailsSb.append(
"<table border='0' cellpadding='4' width='280'>");
315 detailsSb.append(
"<tr>");
316 detailsSb.append(
"<th>")
317 .append(NbBundle.getMessage(
this.getClass(),
"HashDbIngestModule.postToBB.fileName"))
319 detailsSb.append(
"<td>")
320 .append(abstractFile.getName())
322 detailsSb.append(
"</tr>");
324 detailsSb.append(
"<tr>");
325 detailsSb.append(
"<th>")
326 .append(NbBundle.getMessage(
this.getClass(),
"HashDbIngestModule.postToBB.md5Hash"))
328 detailsSb.append(
"<td>").append(md5Hash).append(
"</td>");
329 detailsSb.append(
"</tr>");
331 detailsSb.append(
"<tr>");
332 detailsSb.append(
"<th>")
333 .append(NbBundle.getMessage(
this.getClass(),
"HashDbIngestModule.postToBB.hashsetName"))
335 detailsSb.append(
"<td>").append(hashSetName).append(
"</td>");
336 detailsSb.append(
"</tr>");
338 detailsSb.append(
"</table>");
341 NbBundle.getMessage(this.getClass(),
342 "HashDbIngestModule.postToBB.knownBadMsg",
343 abstractFile.getName()),
344 detailsSb.toString(),
345 abstractFile.getName() + md5Hash,
349 }
catch (TskException ex) {
350 logger.log(Level.WARNING,
"Error creating blackboard artifact", ex);
355 List<HashDb> knownBadHashSets, List<HashDb> knownHashSets) {
357 totalsForIngestJobs.remove(jobId);
359 if ((!knownBadHashSets.isEmpty()) || (!knownHashSets.isEmpty())) {
360 StringBuilder detailsSb =
new StringBuilder();
362 detailsSb.append(
"<table border='0' cellpadding='4' width='280'>");
364 detailsSb.append(
"<tr><td>")
365 .append(NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.complete.knownBadsFound"))
367 detailsSb.append(
"<td>").append(jobTotals.
totalKnownBadCount.get()).append(
"</td></tr>");
369 detailsSb.append(
"<tr><td>")
370 .append(NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.complete.totalCalcTime"))
371 .append(
"</td><td>").append(jobTotals.
totalCalctime.get()).append(
"</td></tr>\n");
372 detailsSb.append(
"<tr><td>")
373 .append(NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.complete.totalLookupTime"))
374 .append(
"</td><td>").append(jobTotals.
totalLookuptime.get()).append(
"</td></tr>\n");
375 detailsSb.append(
"</table>");
377 detailsSb.append(
"<p>")
378 .append(NbBundle.getMessage(
HashDbIngestModule.class,
"HashDbIngestModule.complete.databasesUsed"))
379 .append(
"</p>\n<ul>");
380 for (
HashDb db : knownBadHashSets) {
381 detailsSb.append(
"<li>").append(db.getHashSetName()).append(
"</li>\n");
384 detailsSb.append(
"</ul>");
390 "HashDbIngestModule.complete.hashLookupResults"),
391 detailsSb.toString()));
398 postSummary(jobId, knownBadHashSets, knownHashSets);
synchronized long decrementAndGet(long jobId)
ProcessResult process(AbstractFile file)
List< HashDb > knownHashSets
static IngestMessage createDataMessage(String source, String subject, String detailsHtml, String uniqueKey, BlackboardArtifact data)
void indexArtifact(BlackboardArtifact artifact)
final HashLookupModuleSettings settings
static IngestMessage createErrorMessage(String source, String subject, String detailsHtml)
AtomicLong totalKnownBadCount
static final IngestModuleReferenceCounter refCounter
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)
static final int MAX_COMMENT_SIZE
void updateEnabledHashSets(List< HashDb > allHashSets, List< HashDb > enabledHashSets)
List< HashDb > knownBadHashSets
void postHashSetHitToBlackboard(AbstractFile abstractFile, String md5Hash, String hashSetName, String comment, boolean showInboxMessage)
final SleuthkitCase skCase
synchronized List< HashDb > getKnownBadFileHashSets()
static final HashMap< Long, IngestJobTotals > totalsForIngestJobs
static synchronized HashDbManager getInstance()
void postMessage(final IngestMessage message)
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
SleuthkitCase getSleuthkitCase()
Blackboard getBlackboard()
static synchronized void postSummary(long jobId, List< HashDb > knownBadHashSets, List< HashDb > knownHashSets)
static void error(String title, String message)
static Case getCurrentCase()
synchronized static Logger getLogger(String name)
static IngestMessage createWarningMessage(String source, String subject, String detailsHtml)
final IngestServices services
synchronized List< HashDb > getKnownFileHashSets()
static final Logger logger
final HashDbManager hashDbManager
static synchronized IngestServices getInstance()