Autopsy  4.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
FileExtMismatchIngestModule.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2016 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.modules.fileextmismatch;
20 
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.Set;
24 import java.util.logging.Level;
25 import org.openide.util.NbBundle;
26 import org.openide.util.NbBundle.Messages;
38 import org.sleuthkit.datamodel.AbstractFile;
39 import org.sleuthkit.datamodel.BlackboardArtifact;
40 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
41 import org.sleuthkit.datamodel.TskCoreException;
42 import org.sleuthkit.datamodel.TskData;
43 import org.sleuthkit.datamodel.TskData.FileKnown;
44 import org.sleuthkit.datamodel.TskException;
45 
49 @NbBundle.Messages({
50  "CannotRunFileTypeDetection=Unable to run file type detection.",
51  "FileExtMismatchIngestModule.readError.message=Could not read settings."
52 })
54 
55  private static final Logger logger = Logger.getLogger(FileExtMismatchIngestModule.class.getName());
56  private final IngestServices services = IngestServices.getInstance();
57  private final FileExtMismatchDetectorModuleSettings settings;
58  private HashMap<String, Set<String>> mimeTypeToExtsMap = new HashMap<>();
59  private long jobId;
60  private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
61  private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
62  private static Blackboard blackboard;
64 
65  private static class IngestJobTotals {
66 
67  private long processTime = 0;
68  private long numFiles = 0;
69  }
70 
77  private static synchronized void addToTotals(long ingestJobId, long processTimeInc) {
78  IngestJobTotals ingestJobTotals = totalsForIngestJobs.get(ingestJobId);
79  if (ingestJobTotals == null) {
80  ingestJobTotals = new IngestJobTotals();
81  totalsForIngestJobs.put(ingestJobId, ingestJobTotals);
82  }
83 
84  ingestJobTotals.processTime += processTimeInc;
85  ingestJobTotals.numFiles++;
86  totalsForIngestJobs.put(ingestJobId, ingestJobTotals);
87  }
88 
89  FileExtMismatchIngestModule(FileExtMismatchDetectorModuleSettings settings) {
90  this.settings = settings;
91  }
92 
93  @Override
94  public void startUp(IngestJobContext context) throws IngestModuleException {
95  jobId = context.getJobId();
96  refCounter.incrementAndGet(jobId);
97 
98  try {
99  mimeTypeToExtsMap = FileExtMismatchSettings.readSettings().getMimeTypeToExtsMap();
100  this.detector = new FileTypeDetector();
101  } catch (FileExtMismatchSettings.FileExtMismatchSettingsException ex) {
102  throw new IngestModuleException(Bundle.FileExtMismatchIngestModule_readError_message(), ex);
104  throw new IngestModuleException(Bundle.CannotRunFileTypeDetection(), ex);
105  }
106  }
107 
108  @Override
109  @Messages({"FileExtMismatchIngestModule.indexError.message=Failed to index file extension mismatch artifact for keyword search."})
110  public ProcessResult process(AbstractFile abstractFile) {
111  blackboard = Case.getCurrentCase().getServices().getBlackboard();
112  if (this.settings.skipKnownFiles() && (abstractFile.getKnown() == FileKnown.KNOWN)) {
113  return ProcessResult.OK;
114  }
115 
116  // skip non-files
117  if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
118  || (abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
119  || (abstractFile.isFile() == false)) {
120  return ProcessResult.OK;
121  }
122 
123  // deleted files often have content that was not theirs and therefor causes mismatch
124  if ((abstractFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC))
125  || (abstractFile.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC))) {
126  return ProcessResult.OK;
127  }
128 
129  try {
130  long startTime = System.currentTimeMillis();
131 
132  boolean mismatchDetected = compareSigTypeToExt(abstractFile);
133 
134  addToTotals(jobId, System.currentTimeMillis() - startTime);
135 
136  if (mismatchDetected) {
137  // add artifact
138  BlackboardArtifact bart = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED);
139 
140  try {
141  // index the artifact for keyword search
142  blackboard.indexArtifact(bart);
143  } catch (Blackboard.BlackboardException ex) {
144  logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bart.getArtifactID(), ex); //NON-NLS
146  Bundle.FileExtMismatchIngestModule_indexError_message(), bart.getDisplayName());
147  }
148 
149  services.fireModuleDataEvent(new ModuleDataEvent(FileExtMismatchDetectorModuleFactory.getModuleName(), ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED, Collections.singletonList(bart)));
150  }
151  return ProcessResult.OK;
152  } catch (TskException ex) {
153  logger.log(Level.WARNING, "Error matching file signature", ex); //NON-NLS
154  return ProcessResult.ERROR;
155  }
156  }
157 
165  private boolean compareSigTypeToExt(AbstractFile abstractFile) throws TskCoreException {
166  String currActualExt = abstractFile.getNameExtension();
167 
168  // If we are skipping names with no extension
169  if (settings.skipFilesWithNoExtension() && currActualExt.isEmpty()) {
170  return false;
171  }
172  String currActualSigType = detector.getFileType(abstractFile);
173  if (currActualSigType == null) {
174  return false;
175  }
176  if (settings.skipFilesWithTextPlainMimeType()) {
177  if (!currActualExt.isEmpty() && currActualSigType.equals("text/plain")) { //NON-NLS
178  return false;
179  }
180  }
181 
182  //get known allowed values from the map for this type
183  Set<String> allowedExtSet = mimeTypeToExtsMap.get(currActualSigType);
184  if (allowedExtSet != null) {
185  // see if the filename ext is in the allowed list
186  for (String e : allowedExtSet) {
187  if (e.equals(currActualExt)) {
188  return false;
189  }
190  }
191  return true; //potential mismatch
192  }
193 
194  return false;
195  }
196 
197  @Override
198  public void shutDown() {
199  // We only need to post the summary msg from the last module per job
200  if (refCounter.decrementAndGet(jobId) == 0) {
201  IngestJobTotals jobTotals;
202  synchronized (this) {
203  jobTotals = totalsForIngestJobs.remove(jobId);
204  }
205  if (jobTotals != null) {
206  StringBuilder detailsSb = new StringBuilder();
207  detailsSb.append("<table border='0' cellpadding='4' width='280'>"); //NON-NLS
208  detailsSb.append("<tr><td>").append(FileExtMismatchDetectorModuleFactory.getModuleName()).append("</td></tr>"); //NON-NLS
209  detailsSb.append("<tr><td>").append( //NON-NLS
210  NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.totalProcTime"))
211  .append("</td><td>").append(jobTotals.processTime).append("</td></tr>\n"); //NON-NLS
212  detailsSb.append("<tr><td>").append( //NON-NLS
213  NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.totalFiles"))
214  .append("</td><td>").append(jobTotals.numFiles).append("</td></tr>\n"); //NON-NLS
215  detailsSb.append("</table>"); //NON-NLS
216 
218  NbBundle.getMessage(this.getClass(),
219  "FileExtMismatchIngestModule.complete.svcMsg.text"),
220  detailsSb.toString()));
221  }
222  }
223  }
224 }
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
void postMessage(final IngestMessage message)
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
static void error(String title, String message)
synchronized void indexArtifact(BlackboardArtifact artifact)
Definition: Blackboard.java:59
synchronized static Logger getLogger(String name)
Definition: Logger.java:161
static synchronized void addToTotals(long ingestJobId, long processTimeInc)
static synchronized IngestServices getInstance()

Copyright © 2012-2016 Basis Technology. Generated on: Tue Oct 25 2016
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.