Merge pull request #4691 from APriestman/encryptionDetectionCancellation

Added cancellation checks to EncryptionDetection
This commit is contained in:
Richard Cordovano 2019-04-09 14:06:51 -04:00 committed by GitHub
commit 1639e83af7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 5 deletions

View File

@ -52,6 +52,7 @@ final class EncryptionDetectionDataSourceIngestModule implements DataSourceInges
private Blackboard blackboard; private Blackboard blackboard;
private double calculatedEntropy; private double calculatedEntropy;
private final double minimumEntropy; private final double minimumEntropy;
private IngestJobContext context;
/** /**
* Create an EncryptionDetectionDataSourceIngestModule object that will * Create an EncryptionDetectionDataSourceIngestModule object that will
@ -67,6 +68,7 @@ final class EncryptionDetectionDataSourceIngestModule implements DataSourceInges
public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException { public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException {
validateSettings(); validateSettings();
blackboard = Case.getCurrentCase().getServices().getBlackboard(); blackboard = Case.getCurrentCase().getServices().getBlackboard();
this.context = context;
} }
@Messages({ @Messages({
@ -77,8 +79,6 @@ final class EncryptionDetectionDataSourceIngestModule implements DataSourceInges
@Override @Override
public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) { public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
try { try {
if (dataSource instanceof Image) { if (dataSource instanceof Image) {
@ -92,10 +92,23 @@ final class EncryptionDetectionDataSourceIngestModule implements DataSourceInges
int numVolSystemsChecked = 0; int numVolSystemsChecked = 0;
progressBar.progress(Bundle.EncryptionDetectionDataSourceIngestModule_processing_message(), 0); progressBar.progress(Bundle.EncryptionDetectionDataSourceIngestModule_processing_message(), 0);
for (VolumeSystem volumeSystem : volumeSystems) { for (VolumeSystem volumeSystem : volumeSystems) {
if (context.dataSourceIngestIsCancelled()) {
return ProcessResult.OK;
}
for (Volume volume : volumeSystem.getVolumes()) { for (Volume volume : volumeSystem.getVolumes()) {
if (context.dataSourceIngestIsCancelled()) {
return ProcessResult.OK;
}
if (BitlockerDetection.isBitlockerVolume(volume)) { if (BitlockerDetection.isBitlockerVolume(volume)) {
return flagVolume(volume, BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED, Bundle.EncryptionDetectionDataSourceIngestModule_artifactComment_bitlocker()); return flagVolume(volume, BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED, Bundle.EncryptionDetectionDataSourceIngestModule_artifactComment_bitlocker());
} }
if (context.dataSourceIngestIsCancelled()) {
return ProcessResult.OK;
}
if (isVolumeEncrypted(volume)) { if (isVolumeEncrypted(volume)) {
return flagVolume(volume, BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED, String.format(Bundle.EncryptionDetectionDataSourceIngestModule_artifactComment_suspected(), calculatedEntropy)); return flagVolume(volume, BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED, String.format(Bundle.EncryptionDetectionDataSourceIngestModule_artifactComment_suspected(), calculatedEntropy));
} }
@ -139,6 +152,11 @@ final class EncryptionDetectionDataSourceIngestModule implements DataSourceInges
* there was a problem. * there was a problem.
*/ */
private IngestModule.ProcessResult flagVolume(Volume volume, BlackboardArtifact.ARTIFACT_TYPE artifactType, String comment) { private IngestModule.ProcessResult flagVolume(Volume volume, BlackboardArtifact.ARTIFACT_TYPE artifactType, String comment) {
if (context.dataSourceIngestIsCancelled()) {
return ProcessResult.OK;
}
try { try {
BlackboardArtifact artifact = volume.newArtifact(artifactType); BlackboardArtifact artifact = volume.newArtifact(artifactType);
artifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, EncryptionDetectionModuleFactory.getModuleName(), comment)); artifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, EncryptionDetectionModuleFactory.getModuleName(), comment));
@ -198,7 +216,7 @@ final class EncryptionDetectionDataSourceIngestModule implements DataSourceInges
* http://www.forensicswiki.org/wiki/TrueCrypt#Detection * http://www.forensicswiki.org/wiki/TrueCrypt#Detection
*/ */
if (volume.getFileSystems().isEmpty()) { if (volume.getFileSystems().isEmpty()) {
calculatedEntropy = EncryptionDetectionTools.calculateEntropy(volume); calculatedEntropy = EncryptionDetectionTools.calculateEntropy(volume, context);
if (calculatedEntropy >= minimumEntropy) { if (calculatedEntropy >= minimumEntropy) {
return true; return true;
} }

View File

@ -82,6 +82,7 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
private final Logger logger = services.getLogger(EncryptionDetectionModuleFactory.getModuleName()); private final Logger logger = services.getLogger(EncryptionDetectionModuleFactory.getModuleName());
private FileTypeDetector fileTypeDetector; private FileTypeDetector fileTypeDetector;
private Blackboard blackboard; private Blackboard blackboard;
private IngestJobContext context;
private double calculatedEntropy; private double calculatedEntropy;
private final double minimumEntropy; private final double minimumEntropy;
@ -107,6 +108,7 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException { public void startUp(IngestJobContext context) throws IngestModule.IngestModuleException {
try { try {
validateSettings(); validateSettings();
this.context = context;
blackboard = Case.getCurrentCaseThrows().getServices().getBlackboard(); blackboard = Case.getCurrentCaseThrows().getServices().getBlackboard();
fileTypeDetector = new FileTypeDetector(); fileTypeDetector = new FileTypeDetector();
} catch (FileTypeDetector.FileTypeDetectorInitException ex) { } catch (FileTypeDetector.FileTypeDetectorInitException ex) {
@ -194,6 +196,10 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
*/ */
private IngestModule.ProcessResult flagFile(AbstractFile file, BlackboardArtifact.ARTIFACT_TYPE artifactType, String comment) { private IngestModule.ProcessResult flagFile(AbstractFile file, BlackboardArtifact.ARTIFACT_TYPE artifactType, String comment) {
try { try {
if (context.fileIngestIsCancelled()) {
return IngestModule.ProcessResult.OK;
}
BlackboardArtifact artifact = file.newArtifact(artifactType); BlackboardArtifact artifact = file.newArtifact(artifactType);
artifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, artifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT,
EncryptionDetectionModuleFactory.getModuleName(), comment)); EncryptionDetectionModuleFactory.getModuleName(), comment));
@ -397,7 +403,7 @@ final class EncryptionDetectionFileIngestModule extends FileIngestModuleAdapter
/* /*
* Qualify the entropy. * Qualify the entropy.
*/ */
calculatedEntropy = EncryptionDetectionTools.calculateEntropy(file); calculatedEntropy = EncryptionDetectionTools.calculateEntropy(file, context);
if (calculatedEntropy >= minimumEntropy) { if (calculatedEntropy >= minimumEntropy) {
possiblyEncrypted = true; possiblyEncrypted = true;
} }

View File

@ -22,6 +22,7 @@ import java.io.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestModule; import org.sleuthkit.autopsy.ingest.IngestModule;
import org.sleuthkit.datamodel.ReadContentInputStream; import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
@ -69,6 +70,7 @@ final class EncryptionDetectionTools {
* content as possibly encrypted. * content as possibly encrypted.
* *
* @param content The content to be calculated against. * @param content The content to be calculated against.
* @param context The ingest job context for cancellation checks
* *
* @return The entropy of the content. * @return The entropy of the content.
* *
@ -77,7 +79,7 @@ final class EncryptionDetectionTools {
* @throws IOException If there is a failure closing or * @throws IOException If there is a failure closing or
* reading from the InputStream. * reading from the InputStream.
*/ */
static double calculateEntropy(Content content) throws ReadContentInputStream.ReadContentInputStreamException, IOException { static double calculateEntropy(Content content, IngestJobContext context) throws ReadContentInputStream.ReadContentInputStreamException, IOException {
/* /*
* Logic in this method is based on * Logic in this method is based on
* https://github.com/willjasen/entropy/blob/master/entropy.java * https://github.com/willjasen/entropy/blob/master/entropy.java
@ -95,8 +97,17 @@ final class EncryptionDetectionTools {
*/ */
int[] byteOccurences = new int[BYTE_OCCURENCES_BUFFER_SIZE]; int[] byteOccurences = new int[BYTE_OCCURENCES_BUFFER_SIZE];
int readByte; int readByte;
long bytesRead = 0;
while ((readByte = bin.read()) != -1) { while ((readByte = bin.read()) != -1) {
byteOccurences[readByte]++; byteOccurences[readByte]++;
// Do a cancellation check every 10,000 bytes
bytesRead++;
if (bytesRead % 10000 == 0) {
if (context.dataSourceIngestIsCancelled() || context.fileIngestIsCancelled()) {
return 0;
}
}
} }
/* /*