Add support for SHA-256

This commit is contained in:
apriestman 2020-10-26 13:38:11 -04:00
parent 3ee1713772
commit 0015a6d7bb
6 changed files with 57 additions and 42 deletions

View File

@ -96,7 +96,7 @@ Metadata.tableRowTitle.mimeType=MIME Type
Metadata.tableRowTitle.name=Name Metadata.tableRowTitle.name=Name
Metadata.tableRowTitle.sectorSize=Sector Size Metadata.tableRowTitle.sectorSize=Sector Size
Metadata.tableRowTitle.sha1=SHA1 Metadata.tableRowTitle.sha1=SHA1
Metadata.tableRowTitle.sha256=SHA256 Metadata.tableRowTitle.sha256=SHA-256
Metadata.tableRowTitle.size=Size Metadata.tableRowTitle.size=Size
Metadata.tableRowTitle.fileNameAlloc=File Name Allocation Metadata.tableRowTitle.fileNameAlloc=File Name Allocation
Metadata.tableRowTitle.metadataAlloc=Metadata Allocation Metadata.tableRowTitle.metadataAlloc=Metadata Allocation

View File

@ -137,7 +137,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
"Metadata.tableRowTitle.mimeType=MIME Type", "Metadata.tableRowTitle.mimeType=MIME Type",
"Metadata.nodeText.truncated=(results truncated)", "Metadata.nodeText.truncated=(results truncated)",
"Metadata.tableRowTitle.sha1=SHA1", "Metadata.tableRowTitle.sha1=SHA1",
"Metadata.tableRowTitle.sha256=SHA256", "Metadata.tableRowTitle.sha256=SHA-256",
"Metadata.tableRowTitle.imageType=Type", "Metadata.tableRowTitle.imageType=Type",
"Metadata.tableRowTitle.sectorSize=Sector Size", "Metadata.tableRowTitle.sectorSize=Sector Size",
"Metadata.tableRowTitle.timezone=Time Zone", "Metadata.tableRowTitle.timezone=Time Zone",
@ -182,6 +182,11 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
md5 = NbBundle.getMessage(this.getClass(), "Metadata.tableRowContent.md5notCalc"); md5 = NbBundle.getMessage(this.getClass(), "Metadata.tableRowContent.md5notCalc");
} }
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.md5"), md5); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.md5"), md5);
String sha256 = file.getSha256Hash();
if (sha256 == null) {
sha256 = NbBundle.getMessage(this.getClass(), "Metadata.tableRowContent.md5notCalc");
}
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.sha256"), sha256);
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.hashLookupResults"), file.getKnown().toString()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.hashLookupResults"), file.getKnown().toString());
addAcquisitionDetails(sb, dataSource); addAcquisitionDetails(sb, dataSource);

View File

@ -278,6 +278,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
"AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)", "AbstractAbstractFileNode.typeMetaColLbl=Type(Meta)",
"AbstractAbstractFileNode.knownColLbl=Known", "AbstractAbstractFileNode.knownColLbl=Known",
"AbstractAbstractFileNode.md5HashColLbl=MD5 Hash", "AbstractAbstractFileNode.md5HashColLbl=MD5 Hash",
"AbstractAbstractFileNode.sha256HashColLbl=SHA-256 Hash",
"AbstractAbstractFileNode.objectId=Object ID", "AbstractAbstractFileNode.objectId=Object ID",
"AbstractAbstractFileNode.mimeType=MIME Type", "AbstractAbstractFileNode.mimeType=MIME Type",
"AbstractAbstractFileNode.extensionColLbl=Extension"}) "AbstractAbstractFileNode.extensionColLbl=Extension"})
@ -305,6 +306,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
TYPE_META(AbstractAbstractFileNode_typeMetaColLbl()), TYPE_META(AbstractAbstractFileNode_typeMetaColLbl()),
KNOWN(AbstractAbstractFileNode_knownColLbl()), KNOWN(AbstractAbstractFileNode_knownColLbl()),
MD5HASH(AbstractAbstractFileNode_md5HashColLbl()), MD5HASH(AbstractAbstractFileNode_md5HashColLbl()),
SHA256HASH(AbstractAbstractFileNode_sha256HashColLbl()),
ObjectID(AbstractAbstractFileNode_objectId()), ObjectID(AbstractAbstractFileNode_objectId()),
MIMETYPE(AbstractAbstractFileNode_mimeType()), MIMETYPE(AbstractAbstractFileNode_mimeType()),
EXTENSION(AbstractAbstractFileNode_extensionColLbl()); EXTENSION(AbstractAbstractFileNode_extensionColLbl());
@ -358,6 +360,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
properties.add(new NodeProperty<>(KNOWN.toString(), KNOWN.toString(), NO_DESCR, content.getKnown().getName())); properties.add(new NodeProperty<>(KNOWN.toString(), KNOWN.toString(), NO_DESCR, content.getKnown().getName()));
properties.add(new NodeProperty<>(LOCATION.toString(), LOCATION.toString(), NO_DESCR, getContentPath(content))); properties.add(new NodeProperty<>(LOCATION.toString(), LOCATION.toString(), NO_DESCR, getContentPath(content)));
properties.add(new NodeProperty<>(MD5HASH.toString(), MD5HASH.toString(), NO_DESCR, StringUtils.defaultString(content.getMd5Hash()))); properties.add(new NodeProperty<>(MD5HASH.toString(), MD5HASH.toString(), NO_DESCR, StringUtils.defaultString(content.getMd5Hash())));
properties.add(new NodeProperty<>(SHA256HASH.toString(), SHA256HASH.toString(), NO_DESCR, StringUtils.defaultString(content.getSha256Hash())));
properties.add(new NodeProperty<>(MIMETYPE.toString(), MIMETYPE.toString(), NO_DESCR, StringUtils.defaultString(content.getMIMEType()))); properties.add(new NodeProperty<>(MIMETYPE.toString(), MIMETYPE.toString(), NO_DESCR, StringUtils.defaultString(content.getMIMEType())));
properties.add(new NodeProperty<>(EXTENSION.toString(), EXTENSION.toString(), NO_DESCR, content.getNameExtension())); properties.add(new NodeProperty<>(EXTENSION.toString(), EXTENSION.toString(), NO_DESCR, content.getNameExtension()));
@ -577,6 +580,7 @@ public abstract class AbstractAbstractFileNode<T extends AbstractFile> extends A
map.put(FLAGS_META.toString(), content.getMetaFlagsAsString()); map.put(FLAGS_META.toString(), content.getMetaFlagsAsString());
map.put(KNOWN.toString(), content.getKnown().getName()); map.put(KNOWN.toString(), content.getKnown().getName());
map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash())); map.put(MD5HASH.toString(), StringUtils.defaultString(content.getMd5Hash()));
map.put(SHA256HASH.toString(), StringUtils.defaultString(content.getSha256Hash()));
map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType())); map.put(MIMETYPE.toString(), StringUtils.defaultString(content.getMIMEType()));
map.put(EXTENSION.toString(), content.getNameExtension()); map.put(EXTENSION.toString(), content.getNameExtension());
} }

View File

@ -30,6 +30,7 @@ AbstractAbstractFileNode.modifiedTimeColLbl=Modified Time
AbstractAbstractFileNode.nameColLbl=Name AbstractAbstractFileNode.nameColLbl=Name
AbstractAbstractFileNode.objectId=Object ID AbstractAbstractFileNode.objectId=Object ID
AbstractAbstractFileNode.originalName=Original Name AbstractAbstractFileNode.originalName=Original Name
AbstractAbstractFileNode.sha256HashColLbl=SHA-256 Hash
AbstractAbstractFileNode.sizeColLbl=Size AbstractAbstractFileNode.sizeColLbl=Size
AbstractAbstractFileNode.tagsProperty.displayName=Tags AbstractAbstractFileNode.tagsProperty.displayName=Tags
AbstractAbstractFileNode.typeDirColLbl=Type(Dir) AbstractAbstractFileNode.typeDirColLbl=Type(Dir)

View File

@ -20,9 +20,11 @@ package org.sleuthkit.autopsy.modules.hashdatabase;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function; import java.util.function.Function;
import java.util.logging.Level; import java.util.logging.Level;
@ -208,10 +210,17 @@ public class HashDbIngestModule implements FileIngestModule {
// Safely get a reference to the totalsForIngestJobs object // Safely get a reference to the totalsForIngestJobs object
IngestJobTotals totals = getTotalsForIngestJobs(jobId); IngestJobTotals totals = getTotalsForIngestJobs(jobId);
// calc hash value // calc hash values
String md5Hash = getHash(file, totals); try {
if (md5Hash == null) { calculateHashes(file, totals);
return ProcessResult.ERROR; } catch (TskCoreException ex) {
logger.log(Level.WARNING, String.format("Error calculating hash of file '%s' (id=%d).", file.getName(), file.getId()), ex); //NON-NLS
services.postMessage(IngestMessage.createErrorMessage(
HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), "HashDbIngestModule.fileReadErrorMsg", file.getName()),
NbBundle.getMessage(this.getClass(), "HashDbIngestModule.calcHashValueErr",
file.getParentPath() + file.getName(),
file.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC) ? "Allocated File" : "Deleted File")));
} }
// the processing result of handling this file // the processing result of handling this file
@ -451,50 +460,46 @@ public class HashDbIngestModule implements FileIngestModule {
} }
/** /**
* Retrieves the md5 hash for a file or generates one if no one exists on * Generates hashes for the given file if they haven't already been set.
* the file. * Hashes are saved to the AbstractFile object.
* *
* @param file The file in order to determine the hash. * @param file The file in order to determine the hash.
* @param totals The timing metrics for this process. * @param totals The timing metrics for this process.
*
* @return The found or determined md5 hash or null if none could be
* determined.
*/ */
private String getHash(AbstractFile file, IngestJobTotals totals) { private void calculateHashes(AbstractFile file, IngestJobTotals totals) throws TskCoreException {
// First check if we've already calculated the hashes.
String md5Hash = file.getMd5Hash(); String md5Hash = file.getMd5Hash();
if (md5Hash != null && md5Hash.isEmpty()) { String sha256Hash = file.getSha256Hash();
return md5Hash; if ((md5Hash != null && md5Hash.isEmpty())
&& (sha256Hash != null && sha256Hash.isEmpty())) {
return;
} }
try { TimingMetric metric = HealthMonitor.getTimingMetric("Disk Reads: Hash calculation");
TimingMetric metric = HealthMonitor.getTimingMetric("Disk Reads: Hash calculation"); long calcstart = System.currentTimeMillis();
long calcstart = System.currentTimeMillis(); List<HashUtility.HashValue> newHashResults =
md5Hash = HashUtility.calculateMd5Hash(file); HashUtility.calculateHashes(file, Arrays.asList(HashUtility.HashType.MD5,HashUtility.HashType.SHA256 ));
if (file.getSize() > 0) { if (file.getSize() > 0) {
// Surprisingly, the hash calculation does not seem to be correlated that // Surprisingly, the hash calculation does not seem to be correlated that
// strongly with file size until the files get large. // strongly with file size until the files get large.
// Only normalize if the file size is greater than ~1MB. // Only normalize if the file size is greater than ~1MB.
if (file.getSize() < 1000000) { if (file.getSize() < 1000000) {
HealthMonitor.submitTimingMetric(metric); HealthMonitor.submitTimingMetric(metric);
} else { } else {
// In testing, this normalization gave reasonable resuls // In testing, this normalization gave reasonable resuls
HealthMonitor.submitNormalizedTimingMetric(metric, file.getSize() / 500000); HealthMonitor.submitNormalizedTimingMetric(metric, file.getSize() / 500000);
}
} }
file.setMd5Hash(md5Hash);
long delta = (System.currentTimeMillis() - calcstart);
totals.totalCalctime.addAndGet(delta);
return md5Hash;
} catch (IOException ex) {
logger.log(Level.WARNING, String.format("Error calculating hash of file '%s' (id=%d).", file.getName(), file.getId()), ex); //NON-NLS
services.postMessage(IngestMessage.createErrorMessage(
HashLookupModuleFactory.getModuleName(),
NbBundle.getMessage(this.getClass(), "HashDbIngestModule.fileReadErrorMsg", file.getName()),
NbBundle.getMessage(this.getClass(), "HashDbIngestModule.calcHashValueErr",
file.getParentPath() + file.getName(),
file.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.ALLOC) ? "Allocated File" : "Deleted File")));
return null;
} }
for (HashUtility.HashValue hash : newHashResults) {
if (hash.getType().equals(HashUtility.HashType.MD5)) {
file.setMd5Hash(hash.getValue());
} else if (hash.getType().equals(HashUtility.HashType.SHA256)) {
file.setSha256Hash(hash.getValue());
}
}
long delta = (System.currentTimeMillis() - calcstart);
totals.totalCalctime.addAndGet(delta);
} }
/** /**

View File

@ -1117,7 +1117,7 @@ public class PortableCaseReportModule implements ReportModule {
newContent = portableSkCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(), newContent = portableSkCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(),
abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(), abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(),
abstractFile.getMd5Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(), abstractFile.getMd5Hash(), abstractFile.getSha256Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(),
true, TskData.EncodingType.NONE, true, TskData.EncodingType.NONE,
newParent, trans); newParent, trans);
} catch (IOException ex) { } catch (IOException ex) {