Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
SampleExecutableDataSourceIngestModule.java
Go to the documentation of this file.
1 /*
2  * Sample module in the public domain. Feel free to use this as a template
3  * for your modules.
4  *
5  * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
6  *
7  * This is free and unencumbered software released into the public domain.
8  *
9  * Anyone is free to copy, modify, publish, use, compile, sell, or
10  * distribute this software, either in source code form or as a compiled
11  * binary, for any purpose, commercial or non-commercial, and by any
12  * means.
13  *
14  * In jurisdictions that recognize copyright laws, the author or authors
15  * of this software dedicate any and all copyright interest in the
16  * software to the public domain. We make this dedication for the benefit
17  * of the public at large and to the detriment of our heirs and
18  * successors. We intend this dedication to be an overt act of
19  * relinquishment in perpetuity of all present and future rights to this
20  * software under copyright law.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  * OTHER DEALINGS IN THE SOFTWARE.
29  */
30 package org.sleuthkit.autopsy.examples;
31 
32 import java.io.File;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.logging.Level;
38 import javax.xml.parsers.DocumentBuilder;
39 import javax.xml.parsers.DocumentBuilderFactory;
40 import javax.xml.parsers.ParserConfigurationException;
41 import javax.xml.transform.Transformer;
42 import javax.xml.transform.TransformerConfigurationException;
43 import javax.xml.transform.TransformerException;
44 import javax.xml.transform.TransformerFactory;
45 import javax.xml.transform.dom.DOMSource;
46 import javax.xml.transform.stream.StreamResult;
65 import org.w3c.dom.Document;
66 import org.w3c.dom.Element;
67 
74 
76  private static final String moduleName = SampleExecutableIngestModuleFactory.getModuleName();
77  private final String fileInCaseDatabase = "/WINDOWS/system32/ntmsapi.dll"; // Probably
79  private String outputDirPath;
80  private String derivedFileInCaseDatabase;
81 
82  @Override
83  public void startUp(IngestJobContext context) throws IngestModuleException {
84  this.context = context;
85  if (refCounter.incrementAndGet(context.getJobId()) == 1) {
86  // Create an output directory for this job.
87  outputDirPath = Case.getCurrentCase().getModulesOutputDirAbsPath() + File.separator + moduleName; //NON-NLS
88  File outputDir = new File(outputDirPath);
89  if (outputDir.exists() == false) {
90  outputDir.mkdirs();
91  }
92  }
93  }
94 
95  @Override
96  public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar) {
97  if (refCounter.get(context.getJobId()) == 1) {
98  try {
99  // There will be two tasks: data source analysis and import of
100  // the results of the analysis.
101  progressBar.switchToDeterminate(2);
102 
103  // Do the analysis. The following sample code could be used to
104  // run an executable. In this case the executable would take
105  // two command line arguments, the path to the data source to be
106  // analyzed and the path to a results file to be generated. The
107  // results file would be an an XML file (see org.sleuthkit.autopsy.externalresults.autopsy_external_results.xsd)
108  // with instructions for the import of blackboard artifacts,
109  // derived files, and reports generated by the analysis. In this
110  // sample ingest module, the generation of the analysis results is
111  // simulated.
112  String resultsFilePath = outputDirPath + File.separator + String.format("job_%d_results.xml", context.getJobId());
113  boolean haveRealExecutable = false;
114  if (haveRealExecutable) {
115  if (dataSource instanceof Image) {
116  Image image = (Image)dataSource;
117  String dataSourcePath = image.getPaths()[0];
118  List<String> commandLine = new ArrayList<>();
119  commandLine.add("some.exe");
120  commandLine.add(dataSourcePath);
121  commandLine.add(resultsFilePath);
122  ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
123  ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
124  }
125  // not a disk image
126  else {
127  return ProcessResult.OK;
128  }
129  } else {
130  generateSimulatedResults(resultsFilePath);
131  }
132  progressBar.progress(1);
133 
134  // Import the results of the analysis.
135  ExternalResultsXMLParser resultsParser = new ExternalResultsXMLParser(dataSource, resultsFilePath);
136  ExternalResults results = resultsParser.parse();
137  List<ErrorInfo> errors = resultsParser.getErrorInfo();
139  errors.addAll(importer.importResults(results));
140  for (ErrorInfo errorInfo : errors) {
141  IngestServices.getInstance().postMessage(IngestMessage.createErrorMessage(moduleName, "External Results Import Error", errorInfo.getMessage()));
142  }
143  progressBar.progress(2);
144  } catch (ParserConfigurationException | TransformerException | IOException ex) {
145  Logger logger = IngestServices.getInstance().getLogger(moduleName);
146  logger.log(Level.SEVERE, "Failed to simulate analysis and results import", ex); //NON-NLS
147  return ProcessResult.ERROR;
148  }
149  }
150  return ProcessResult.OK;
151  }
152 
153  private void generateSimulatedResults(String resultsFilePath) throws ParserConfigurationException, IOException, TransformerConfigurationException, TransformerException {
154  List<String> derivedFilePaths = generateSimulatedDerivedFiles();
155  List<String> reportFilePaths = generateSimulatedReports();
156  generateSimulatedResultsFile(derivedFilePaths, reportFilePaths, resultsFilePath);
157  }
158 
159  private List<String> generateSimulatedDerivedFiles() throws IOException {
160  List<String> filePaths = new ArrayList<>();
161  String fileContents = "This is a simulated derived file.";
162  for (int i = 0; i < 2; ++i) {
163  String fileName = String.format("job_%d_derived_file_%d.txt", context.getJobId(), i);
164  filePaths.add(generateFile(fileName, fileContents.getBytes()));
165  if (i == 0) {
166  this.derivedFileInCaseDatabase = this.fileInCaseDatabase + "/" + fileName;
167  }
168  }
169  return filePaths;
170  }
171 
172  private List<String> generateSimulatedReports() throws IOException {
173  List<String> filePaths = new ArrayList<>();
174  String fileContents = "This is a simulated report.";
175  for (int i = 0; i < 2; ++i) {
176  String fileName = String.format("job_%d_report_%d.txt", context.getJobId(), i);
177  filePaths.add(generateFile(fileName, fileContents.getBytes()));
178  }
179  return filePaths;
180  }
181 
182  private String generateFile(String fileName, byte[] fileContents) throws IOException {
183  String filePath = outputDirPath + File.separator + fileName;
184  File file = new File(filePath);
185  if (!file.exists()) {
186  file.createNewFile();
187  }
188  try (FileOutputStream fileStream = new FileOutputStream(file)) {
189  fileStream.write(fileContents);
190  fileStream.flush();
191  }
192  return filePath;
193  }
194 
195  private void generateSimulatedResultsFile(List<String> derivedFilePaths, List<String> reportPaths, String resultsFilePath) throws ParserConfigurationException, TransformerConfigurationException, TransformerException {
196  // SAMPLE GENERATED BY THE CODE BELOW:
197  //
198  // <?xml version="1.0" encoding="UTF-8" standalone="no"?>
199  // <autopsy_results>
200  // <derived_files>
201  // <derived_file>
202  // <local_path>C:\cases\Small\ModuleOutput\Sample Executable Ingest Module\job_1_derived_file_0.txt</local_path>
203  // <parent_file>/WINDOWS/system32/ntmsapi.dll</parent_file>
204  // </derived_file>
205  // <derived_file>
206  // <local_path>C:\cases\Small\ModuleOutput\Sample Executable Ingest Module\job_1_derived_file_1.txt</local_path>
207  // <parent_file>/WINDOWS/system32/ntmsapi.dll/job_1_derived_file_0.txt</parent_file>
208  // </derived_file>
209  // </derived_files>
210  // <artifacts>
211  // <artifact type="TSK_INTERESTING_FILE_HIT">
212  // <source_file>/WINDOWS/system32/ntmsapi.dll</source_file>
213  // <attribute type="TSK_SET_NAME">
214  // <value>SampleInterestingFilesSet</value>
215  // <source_module>Sample Executable Ingest Module</source_module>
216  // </attribute>
217  // </artifact>
218  // <artifact type="SampleArtifactType">
219  // <source_file>/WINDOWS/system32/ntmsapi.dll/job_1_derived_file_0.txt</source_file>
220  // <attribute type="SampleArtifactAttributeType">
221  // <value type="text">One</value>
222  // </attribute>
223  // <attribute type="SampleArtifactAttributeType">
224  // <value type="int32">2</value>
225  // </attribute>
226  // <attribute type="SampleArtifactAttributeType">
227  // <value type="int64">3</value>
228  // </attribute>
229  // <attribute type="SampleArtifactAttributeType">
230  // <value type="double">4.0</value>
231  // </attribute>
232  // </artifact>
233  // </artifacts>
234  // <reports>
235  // <report>
236  // <local_path>C:\cases\Small\ModuleOutput\Sample Executable Ingest Module\job_1_report_0.txt</local_path>
237  // <source_module>Sample Executable Ingest Module</source_module>
238  // <report_name>Sample Report</report_name>
239  // </report>
240  // <report>
241  // <local_path>C:\cases\Small\ModuleOutput\Sample Executable Ingest Module\job_1_report_1.txt</local_path>
242  // <source_module>Sample Executable Ingest Module</source_module>
243  // </report>
244  // </reports>
245  // </autopsy_results>
246 
247  // Create the XML DOM document and the root element.
248  DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
249  DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
250  Document doc = docBuilder.newDocument();
251  Element rootElement = doc.createElement(ExternalResultsXMLParser.TagNames.ROOT_ELEM.toString());
252  doc.appendChild(rootElement);
253 
254  // Add a derived files list element to the root element.
255  Element derivedFilesListElement = doc.createElement(ExternalResultsXMLParser.TagNames.DERIVED_FILES_LIST_ELEM.toString());
256  rootElement.appendChild(derivedFilesListElement);
257 
258  // Add derived file elements to the derived files list element. Each
259  // file element gets required local path and parent file child elements.
260  // Note that the local path of the derived file must be to a location in
261  // the case directory or a subdirectory of the case directory and the
262  // parent file must be specified using the path format used in the case
263  // database, e.g., /WINDOWS/system32/ntmsapi.dll, where volume, file
264  // system, etc. are not in the path.
265  for (int i = 0; i < derivedFilePaths.size(); ++i) {
266  String filePath = derivedFilePaths.get(i);
267  Element derivedFileElement = doc.createElement(ExternalResultsXMLParser.TagNames.DERIVED_FILE_ELEM.toString());
268  derivedFilesListElement.appendChild(derivedFileElement);
269  Element localPathElement = doc.createElement(ExternalResultsXMLParser.TagNames.LOCAL_PATH_ELEM.toString());
270  localPathElement.setTextContent(filePath);
271  derivedFileElement.appendChild(localPathElement);
272  Element parentPathElement = doc.createElement(ExternalResultsXMLParser.TagNames.PARENT_FILE_ELEM.toString());
273  if (i == 0) {
274  parentPathElement.setTextContent(this.fileInCaseDatabase);
275  } else {
276  parentPathElement.setTextContent(this.derivedFileInCaseDatabase);
277  }
278  derivedFileElement.appendChild(parentPathElement);
279  }
280 
281  // Add an artifacts list element to the root element.
282  Element artifactsListElement = doc.createElement(ExternalResultsXMLParser.TagNames.ARTIFACTS_LIST_ELEM.toString());
283  rootElement.appendChild(artifactsListElement);
284 
285  // Add an artifact element to the artifacts list element with the required
286  // artifact type attribute. A standard artifact type is used as the type
287  // attribute of this artifact element.
288  Element artifactElement = doc.createElement(ExternalResultsXMLParser.TagNames.ARTIFACT_ELEM.toString());
289  artifactElement.setAttribute(ExternalResultsXMLParser.AttributeNames.TYPE_ATTR.toString(), ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getLabel());
290  artifactsListElement.appendChild(artifactElement);
291 
292  // Add the required source file element to the artifact element. Note
293  // that source file must be either the local path of a derived file or a
294  // file in the case database.
295  Element fileElement = doc.createElement(ExternalResultsXMLParser.TagNames.SOURCE_FILE_ELEM.toString());
296  fileElement.setTextContent(this.fileInCaseDatabase);
297  artifactElement.appendChild(fileElement);
298 
299  // Add an artifact attribute element to the artifact element. A standard
300  // artifact attribute type is used as the required type XML attribute of
301  // the artifact attribute element.
302  Element artifactAttrElement = doc.createElement(ExternalResultsXMLParser.TagNames.ATTRIBUTE_ELEM.toString());
303  artifactAttrElement.setAttribute(ExternalResultsXMLParser.AttributeNames.TYPE_ATTR.toString(), ATTRIBUTE_TYPE.TSK_SET_NAME.getLabel());
304  artifactElement.appendChild(artifactAttrElement);
305 
306  // Add the required value element to the artifact attribute element,
307  // with an optional type XML attribute of ExternalXML.VALUE_TYPE_TEXT,
308  // which is the default.
309  Element artifactAttributeValueElement = doc.createElement(ExternalResultsXMLParser.TagNames.VALUE_ELEM.toString());
310  artifactAttributeValueElement.setTextContent("SampleInterestingFilesSet");
311  artifactAttrElement.appendChild(artifactAttributeValueElement);
312 
313  // Add an optional source module element to the artifact attribute
314  // element.
315  Element artifactAttrSourceElement = doc.createElement(ExternalResultsXMLParser.TagNames.SOURCE_MODULE_ELEM.toString());
316  artifactAttrSourceElement.setTextContent(moduleName);
317  artifactAttrElement.appendChild(artifactAttrSourceElement);
318 
319  // Add an artifact element with a user-defined type.
320  artifactElement = doc.createElement(ExternalResultsXMLParser.TagNames.ARTIFACT_ELEM.toString());
321  artifactElement.setAttribute(ExternalResultsXMLParser.AttributeNames.TYPE_ATTR.toString(), "SampleArtifactType");
322  artifactsListElement.appendChild(artifactElement);
323 
324  // Add the required source file element.
325  fileElement = doc.createElement(ExternalResultsXMLParser.TagNames.SOURCE_FILE_ELEM.toString());
326  fileElement.setTextContent(this.derivedFileInCaseDatabase);
327  artifactElement.appendChild(fileElement);
328 
329  // Add artifact attribute elements with user-defined types to the
330  // artifact element, adding value elements of assorted types.
331  for (int i = 0; i < 4; ++i) {
332  artifactAttrElement = doc.createElement(ExternalResultsXMLParser.TagNames.ATTRIBUTE_ELEM.toString());
333  artifactAttrElement.setAttribute(ExternalResultsXMLParser.AttributeNames.TYPE_ATTR.toString(), "SampleArtifactAttributeType");
334  artifactElement.appendChild(artifactAttrElement);
335  artifactAttributeValueElement = doc.createElement(ExternalResultsXMLParser.TagNames.VALUE_ELEM.toString());
336  switch (i) {
337  case 0:
338  artifactAttributeValueElement.setAttribute(ExternalResultsXMLParser.AttributeNames.TYPE_ATTR.toString(), ExternalResultsXMLParser.AttributeValues.VALUE_TYPE_TEXT.toString());
339  artifactAttributeValueElement.setTextContent("One");
340  break;
341  case 1:
342  artifactAttributeValueElement.setAttribute(ExternalResultsXMLParser.AttributeNames.TYPE_ATTR.toString(), ExternalResultsXMLParser.AttributeValues.VALUE_TYPE_INT32.toString());
343  artifactAttributeValueElement.setTextContent("2");
344  break;
345  case 2:
346  artifactAttributeValueElement.setAttribute(ExternalResultsXMLParser.AttributeNames.TYPE_ATTR.toString(), ExternalResultsXMLParser.AttributeValues.VALUE_TYPE_INT64.toString());
347  artifactAttributeValueElement.setTextContent("3");
348  break;
349  case 3:
350  artifactAttributeValueElement.setAttribute(ExternalResultsXMLParser.AttributeNames.TYPE_ATTR.toString(), ExternalResultsXMLParser.AttributeValues.VALUE_TYPE_DOUBLE.toString());
351  artifactAttributeValueElement.setTextContent("4.0");
352  break;
353  }
354  artifactAttrElement.appendChild(artifactAttributeValueElement);
355  }
356 
357  // Add a reports list element to the root element.
358  Element reportsListElement = doc.createElement(ExternalResultsXMLParser.TagNames.REPORTS_LIST_ELEM.toString());
359  rootElement.appendChild(reportsListElement);
360 
361  // Add report elements to the reports list element. Each report element
362  // gets required local path and source module child elements. There is
363  // also an optional report name element. Note that the local path of the
364  // report must be to a location in the case directory or a subdirectory
365  // of the case directory and the parent file must be specified using the
366  // path format used in the case database, e.g., /WINDOWS/system32/ntmsapi.dll,
367  // where volume, file system, etc. are not in the path.
368  for (int i = 0; i < reportPaths.size(); ++i) {
369  String reportPath = reportPaths.get(i);
370  Element reportElement = doc.createElement(ExternalResultsXMLParser.TagNames.REPORT_ELEM.toString());
371  reportsListElement.appendChild(reportElement);
372  Element reportPathElement = doc.createElement(ExternalResultsXMLParser.TagNames.LOCAL_PATH_ELEM.toString());
373  reportPathElement.setTextContent(reportPath);
374  reportElement.appendChild(reportPathElement);
375  Element reportSourceModuleElement = doc.createElement(ExternalResultsXMLParser.TagNames.SOURCE_MODULE_ELEM.toString());
376  reportSourceModuleElement.setTextContent(moduleName);
377  reportElement.appendChild(reportSourceModuleElement);
378  if (i == 0) {
379  Element reportNameElement = doc.createElement(ExternalResultsXMLParser.TagNames.REPORT_NAME_ELEM.toString());
380  reportNameElement.setTextContent("Sample Report");
381  reportElement.appendChild(reportNameElement);
382  }
383  }
384 
385  TransformerFactory transformerFactory = TransformerFactory.newInstance();
386  Transformer transformer = transformerFactory.newTransformer();
387  DOMSource source = new DOMSource(doc);
388  StreamResult result = new StreamResult(new File(resultsFilePath));
389  transformer.transform(source, result);
390  }
391 }
static int execute(ProcessBuilder processBuilder)
Definition: ExecUtil.java:97
static IngestMessage createErrorMessage(String source, String subject, String detailsHtml)
void generateSimulatedResultsFile(List< String > derivedFilePaths, List< String > reportPaths, String resultsFilePath)
Logger getLogger(String moduleDisplayName)
void postMessage(final IngestMessage message)
ProcessResult process(Content dataSource, DataSourceIngestModuleProgress progressBar)
static synchronized IngestServices getInstance()

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