Autopsy  4.12.0
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-2018 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.HashMap;
22 import java.util.Set;
23 import java.util.logging.Level;
24 import org.openide.util.NbBundle;
25 import org.openide.util.NbBundle.Messages;
37 import org.sleuthkit.datamodel.AbstractFile;
38 import org.sleuthkit.datamodel.Blackboard;
39 import org.sleuthkit.datamodel.BlackboardArtifact;
40 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
41 import org.sleuthkit.datamodel.TskData;
42 import org.sleuthkit.datamodel.TskData.FileKnown;
43 import org.sleuthkit.datamodel.TskException;
44 
48 @NbBundle.Messages({
49  "CannotRunFileTypeDetection=Unable to run file type detection.",
50  "FileExtMismatchIngestModule.readError.message=Could not read settings."
51 })
53 
54  private static final Logger logger = Logger.getLogger(FileExtMismatchIngestModule.class.getName());
55  private final IngestServices services = IngestServices.getInstance();
56  private final FileExtMismatchDetectorModuleSettings settings;
57  private HashMap<String, Set<String>> mimeTypeToExtsMap = new HashMap<>();
58  private long jobId;
59  private static final HashMap<Long, IngestJobTotals> totalsForIngestJobs = new HashMap<>();
60  private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
61  private static Blackboard blackboard;
63 
64  private static class IngestJobTotals {
65 
66  private long processTime = 0;
67  private long numFiles = 0;
68  }
69 
76  private static synchronized void addToTotals(long ingestJobId, long processTimeInc) {
77  IngestJobTotals ingestJobTotals = totalsForIngestJobs.get(ingestJobId);
78  if (ingestJobTotals == null) {
79  ingestJobTotals = new IngestJobTotals();
80  totalsForIngestJobs.put(ingestJobId, ingestJobTotals);
81  }
82 
83  ingestJobTotals.processTime += processTimeInc;
84  ingestJobTotals.numFiles++;
85  totalsForIngestJobs.put(ingestJobId, ingestJobTotals);
86  }
87 
88  FileExtMismatchIngestModule(FileExtMismatchDetectorModuleSettings settings) {
89  this.settings = settings;
90  }
91 
92  @Override
93  public void startUp(IngestJobContext context) throws IngestModuleException {
94  jobId = context.getJobId();
95  refCounter.incrementAndGet(jobId);
96 
97  try {
98  mimeTypeToExtsMap = FileExtMismatchSettings.readSettings().getMimeTypeToExtsMap();
99  this.detector = new FileTypeDetector();
100  } catch (FileExtMismatchSettings.FileExtMismatchSettingsException ex) {
101  throw new IngestModuleException(Bundle.FileExtMismatchIngestModule_readError_message(), ex);
103  throw new IngestModuleException(Bundle.CannotRunFileTypeDetection(), ex);
104  }
105  }
106 
107  @Override
108  @Messages({"FileExtMismatchIngestModule.indexError.message=Failed to index file extension mismatch artifact for keyword search."})
109  public ProcessResult process(AbstractFile abstractFile) {
110  try {
111  blackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard();
112  } catch (NoCurrentCaseException ex) {
113  logger.log(Level.WARNING, "Exception while getting open case.", ex); //NON-NLS
114  return ProcessResult.ERROR;
115  }
116  if (this.settings.skipKnownFiles() && (abstractFile.getKnown() == FileKnown.KNOWN)) {
117  return ProcessResult.OK;
118  }
119 
120  // skip non-files
121  if ((abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
122  || (abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
123  || (abstractFile.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)
124  || (abstractFile.isFile() == false)) {
125  return ProcessResult.OK;
126  }
127 
128  // deleted files often have content that was not theirs and therefor causes mismatch
129  if ((abstractFile.isMetaFlagSet(TskData.TSK_FS_META_FLAG_ENUM.UNALLOC))
130  || (abstractFile.isDirNameFlagSet(TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC))) {
131  return ProcessResult.OK;
132  }
133 
134  try {
135  long startTime = System.currentTimeMillis();
136 
137  boolean mismatchDetected = compareSigTypeToExt(abstractFile);
138 
139  addToTotals(jobId, System.currentTimeMillis() - startTime);
140 
141  if (mismatchDetected) {
142  // add artifact
143  BlackboardArtifact bart = abstractFile.newArtifact(ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED);
144 
145  try {
146  /*
147  * post the artifact which will index the artifact for
148  * keyword search, and fire an event to notify UI of this
149  * new artifact
150  */
151  blackboard.postArtifact(bart, FileExtMismatchDetectorModuleFactory.getModuleName());
152  } catch (Blackboard.BlackboardException ex) {
153  logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bart.getArtifactID(), ex); //NON-NLS
154  MessageNotifyUtil.Notify.error(FileExtMismatchDetectorModuleFactory.getModuleName(), Bundle.FileExtMismatchIngestModule_indexError_message());
155  }
156 
157  }
158  return ProcessResult.OK;
159  } catch (TskException ex) {
160  logger.log(Level.WARNING, "Error matching file signature", ex); //NON-NLS
161  return ProcessResult.ERROR;
162  }
163  }
164 
172  private boolean compareSigTypeToExt(AbstractFile abstractFile) {
173  String currActualExt = abstractFile.getNameExtension();
174 
175  // If we are skipping names with no extension
176  if (settings.skipFilesWithNoExtension() && currActualExt.isEmpty()) {
177  return false;
178  }
179  String currActualSigType = detector.getMIMEType(abstractFile);
180  if (settings.getCheckType() != CHECK_TYPE.ALL) {
181  if (settings.getCheckType() == CHECK_TYPE.NO_TEXT_FILES) {
182  if (!currActualExt.isEmpty() && currActualSigType.equals("text/plain")) { //NON-NLS
183  return false;
184  }
185  }
186  if (settings.getCheckType() == CHECK_TYPE.ONLY_MEDIA_AND_EXE) {
187  if (!FileExtMismatchDetectorModuleSettings.MEDIA_AND_EXE_MIME_TYPES.contains(currActualSigType)) {
188  return false;
189  }
190  }
191  }
192 
193  //get known allowed values from the map for this type
194  Set<String> allowedExtSet = mimeTypeToExtsMap.get(currActualSigType);
195  if (allowedExtSet != null) {
196  // see if the filename ext is in the allowed list
197  for (String e : allowedExtSet) {
198  if (e.equals(currActualExt)) {
199  return false;
200  }
201  }
202  return true; //potential mismatch
203  }
204 
205  return false;
206  }
207 
208  @Override
209  public void shutDown() {
210  // We only need to post the summary msg from the last module per job
211  if (refCounter.decrementAndGet(jobId) == 0) {
212  IngestJobTotals jobTotals;
213  synchronized (this) {
214  jobTotals = totalsForIngestJobs.remove(jobId);
215  }
216  if (jobTotals != null) {
217  StringBuilder detailsSb = new StringBuilder();
218  detailsSb.append("<table border='0' cellpadding='4' width='280'>"); //NON-NLS
219  detailsSb.append("<tr><td>").append(FileExtMismatchDetectorModuleFactory.getModuleName()).append("</td></tr>"); //NON-NLS
220  detailsSb.append("<tr><td>").append( //NON-NLS
221  NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.totalProcTime"))
222  .append("</td><td>").append(jobTotals.processTime).append("</td></tr>\n"); //NON-NLS
223  detailsSb.append("<tr><td>").append( //NON-NLS
224  NbBundle.getMessage(this.getClass(), "FileExtMismatchIngestModule.complete.totalFiles"))
225  .append("</td><td>").append(jobTotals.numFiles).append("</td></tr>\n"); //NON-NLS
226  detailsSb.append("</table>"); //NON-NLS
227 
229  NbBundle.getMessage(this.getClass(),
230  "FileExtMismatchIngestModule.complete.svcMsg.text"),
231  detailsSb.toString()));
232  }
233  }
234  }
235 }
static IngestMessage createMessage(MessageType messageType, String source, String subject, String detailsHtml)
void postMessage(final IngestMessage message)
static void error(String title, String message)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static synchronized void addToTotals(long ingestJobId, long processTimeInc)
static synchronized IngestServices getInstance()

Copyright © 2012-2018 Basis Technology. Generated on: Wed Sep 18 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.