Autopsy  4.15.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
ExtractSru.java
Go to the documentation of this file.
1  /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2020 Basis Technology Corp.
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.recentactivity;
20 
21 import java.io.File;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.nio.file.Path;
25 import java.nio.file.Paths;
26 import java.sql.ResultSet;
27 import java.sql.SQLException;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.logging.Level;
34 import java.util.Map;
35 import org.apache.commons.io.FilenameUtils;
36 import org.openide.modules.InstalledFileLocator;
37 import org.openide.util.NbBundle.Messages;
48 import org.sleuthkit.datamodel.AbstractFile;
49 import org.sleuthkit.datamodel.Blackboard;
50 import org.sleuthkit.datamodel.BlackboardArtifact;
51 import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
52 import org.sleuthkit.datamodel.BlackboardAttribute;
53 import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
54 import org.sleuthkit.datamodel.Content;
55 import org.sleuthkit.datamodel.TskCoreException;
56 
57 
62 final class ExtractSru extends Extract {
63 
64  private static final Logger logger = Logger.getLogger(ExtractSru.class.getName());
65 
66  private IngestJobContext context;
67 
68  private static final String APPLICATION_USAGE_SOURCE_NAME = "System Resource Usage - Application Usage"; //NON-NLS
69  private static final String NETWORK_USAGE_SOURCE_NAME = "System Resource Usage - Network Usage";
70 
71 // private static final String ARTIFACT_ATTRIBUTE_NAME = "TSK_ARTIFACT_NAME"; //NON-NLS
72 
73  private static final String MODULE_NAME = "extractSRU"; //NON-NLS
74 
75  private static final String SRU_TOOL_FOLDER = "markmckinnon"; //NON-NLS
76  private static final String SRU_TOOL_NAME_WINDOWS_32 = "Export_Srudb_32.exe"; //NON-NLS
77  private static final String SRU_TOOL_NAME_WINDOWS_64 = "Export_Srudb_64.exe"; //NON-NLS
78  private static final String SRU_TOOL_NAME_LINUX = "Export_Srudb_Linux.exe"; //NON-NLS
79  private static final String SRU_TOOL_NAME_MAC = "Export_srudb_macos"; //NON-NLS
80  private static final String SRU_OUTPUT_FILE_NAME = "Output.txt"; //NON-NLS
81  private static final String SRU_ERROR_FILE_NAME = "Error.txt"; //NON-NLS
82 
83  private static final Map<String, AbstractFile> applicationFilesFound = new HashMap<>();
84 
85  @Messages({
86  "ExtractSru_module_name=System Resource Usage Extractor"
87  })
88  ExtractSru() {
89  this.moduleName = Bundle.ExtractSru_module_name();
90  }
91 
92  @Messages({
93  "ExtractSru_error_finding_export_srudb_program=Error finding export_srudb program",
94  "ExtractSru_process_error_executing_export_srudb_program=Error running export_srudb program"
95  })
96 
97  @Override
98  void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
99 
100  this.context = context;
101 
102  String modOutPath = Case.getCurrentCase().getModuleDirectory() + File.separator + "sru";
103  File dir = new File(modOutPath);
104  if (dir.exists() == false) {
105  dir.mkdirs();
106  }
107 
108  String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "sru"); //NON-NLS
109  String softwareHiveFileName = getSoftwareHiveFile(dataSource, tempDirPath);
110 
111  if (softwareHiveFileName == null) {
112  return;
113  }
114 
115  AbstractFile sruAbstractFile = getSruFile(dataSource, tempDirPath);
116 
117  if (sruAbstractFile == null) {
118  return; //If we cannot find the srudb.dat file we cannot proceed which is ok
119  }
120 
121  final String sruDumper = getPathForSruDumper();
122  if (sruDumper == null) {
123  this.addErrorMessage(Bundle.ExtractSru_error_finding_export_srudb_program());
124  logger.log(Level.SEVERE, "Error finding export_srudb program"); //NON-NLS
125  return; //If we cannot find the export_srudb program we cannot proceed
126  }
127 
128  if (context.dataSourceIngestIsCancelled()) {
129  return;
130  }
131 
132  try {
133  String modOutFile = modOutPath + File.separator + sruAbstractFile.getId() + "_srudb.db3";
134  String sruFileName = tempDirPath + File.separator + sruAbstractFile.getId() + "_" + sruAbstractFile.getName();
135 
136  extractSruFiles(sruDumper, sruFileName, modOutFile, tempDirPath, softwareHiveFileName);
137 
138  findSruExecutedFiles(modOutFile, dataSource);
139 
140  createNetUsageArtifacts(modOutFile, sruAbstractFile);
141  createAppUsageArtifacts(modOutFile, sruAbstractFile);
142  } catch (IOException ex) {
143  this.addErrorMessage(Bundle.ExtractSru_process_error_executing_export_srudb_program());
144  logger.log(Level.SEVERE, "SRUDB.dat file not found"); //NON-NLS
145  }
146  }
147 
148  @Messages({
149  "ExtractSru_process_errormsg_find_software_hive=Unable to find SOFTWARE HIVE file",
150  "ExtractSru_process_errormsg_write_software_hive=Unable to write SOFTWARE HIVE file"
151  })
152 
161  String getSoftwareHiveFile(Content dataSource, String tempDirPath) {
162  FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
163 
164  List<AbstractFile> softwareHiveFiles;
165 
166  try {
167  softwareHiveFiles = fileManager.findFiles(dataSource, "SOFTWARE"); //NON-NLS
168  } catch (TskCoreException ex) {
169  this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_software_hive());
170  logger.log(Level.WARNING, "Unable to find SOFTWARE HIVE file.", ex); //NON-NLS
171  return null; // No need to continue
172  }
173 
174  String softwareHiveFileName = null;
175 
176  for (AbstractFile softwareFile : softwareHiveFiles) {
177 
178  if (softwareFile.getParentPath().endsWith("/config/")) {
179  softwareHiveFileName = tempDirPath + File.separator + softwareFile.getId() + "_" + softwareFile.getName();
180 
181  try {
182  ContentUtils.writeToFile(softwareFile, new File(softwareHiveFileName));
183  } catch (IOException ex) {
184  this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_software_hive());
185  logger.log(Level.WARNING, String.format("Unable to write %s to temp directory. File name: %s", softwareFile.getName(), softwareFile), ex); //NON-NLS
186  return null;
187  }
188  }
189  }
190  return softwareHiveFileName;
191  }
192 
193  @Messages({
194  "ExtractSru_process_errormsg_find_srudb_dat=Unable to find srudb.dat file",
195  "ExtractSru_process_errormsg_write_srudb_dat=Unable to write srudb.dat file"
196  })
205  AbstractFile getSruFile(Content dataSource, String tempDirPath) {
206  FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
207 
208  List<AbstractFile> sruFiles;
209 
210  try {
211  sruFiles = fileManager.findFiles(dataSource, "SRUDB.DAT"); //NON-NLS
212  } catch (TskCoreException ex) {
213  this.addErrorMessage(Bundle.ExtractSru_process_errormsg_find_srudb_dat());
214  logger.log(Level.WARNING, "Unable to find SRUDB.DAT file.", ex); //NON-NLS
215  return null; // No need to continue
216  }
217 
218  AbstractFile sruAbstractFile = null;
219 
220  for (AbstractFile sruFile : sruFiles) {
221 
222  String sruFileName = tempDirPath + File.separator + sruFile.getId() + "_" + sruFile.getName();
223  sruAbstractFile = sruFile;
224 
225  try {
226  ContentUtils.writeToFile(sruFile, new File(sruFileName));
227  } catch (IOException ex) {
228  this.addErrorMessage(Bundle.ExtractSru_process_errormsg_write_srudb_dat());
229  logger.log(Level.WARNING, String.format("Unable to write %s to temp directory. File name: %s", sruFile.getName(), sruFile), ex); //NON-NLS
230  return null;
231  }
232 
233  }
234  return sruAbstractFile;
235  }
236 
247  void extractSruFiles(String sruExePath, String sruFile, String tempOutFile, String tempOutPath, String softwareHiveFile) throws IOException {
248  final Path outputFilePath = Paths.get(tempOutPath, SRU_OUTPUT_FILE_NAME);
249  final Path errFilePath = Paths.get(tempOutPath, SRU_ERROR_FILE_NAME);
250 
251  List<String> commandLine = new ArrayList<>();
252  commandLine.add(sruExePath);
253  commandLine.add(sruFile); //NON-NLS
254  commandLine.add(softwareHiveFile);
255  commandLine.add(tempOutFile);
256 
257  ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
258  processBuilder.redirectOutput(outputFilePath.toFile());
259  processBuilder.redirectError(errFilePath.toFile());
260 
261  ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
262  }
263 
264  private String getPathForSruDumper() {
265  Path path = null;
266  if (PlatformUtil.isWindowsOS()) {
267  if (PlatformUtil.is64BitOS()) {
268  path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_64);
269  } else {
270  path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_32);
271  }
272  } else {
273  if ("Linux".equals(PlatformUtil.getOSName())) {
274  path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_LINUX);
275  } else {
276  path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_MAC);
277  }
278  }
279  File sruToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
280  ExtractSru.class.getPackage().getName(), false);
281  if (sruToolFile != null) {
282  return sruToolFile.getAbsolutePath();
283  }
284 
285  return null;
286  }
287 
288  private void findSruExecutedFiles(String sruDb, Content dataSource) {
289 
290  org.sleuthkit.autopsy.casemodule.services.FileManager fileManager = currentCase.getServices().getFileManager();
291 
292  String sqlStatement = "SELECT DISTINCT SUBSTR(LTRIM(IdBlob, '\\Device\\HarddiskVolume'), INSTR(LTRIM(IdBlob, '\\Device\\HarddiskVolume'), '\\')) "
293  + " application_name, idBlob source_name FROM SruDbIdMapTable WHERE idType = 0 AND idBlob NOT LIKE '!!%'"; //NON-NLS
294 
295  try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS
296  ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
297 
298  while (resultSet.next()) {
299 
300  if (context.dataSourceIngestIsCancelled()) {
301  logger.log(Level.INFO, "Cancelled SRU Artifact Creation."); //NON-NLS
302  return;
303  }
304 
305  String applicationName = resultSet.getString("application_name"); //NON-NLS
306  String sourceName = resultSet.getString("source_name"); //NON-NLS
307 
308  String normalizePathName = FilenameUtils.normalize(applicationName, true);
309  String fileName = FilenameUtils.getName(normalizePathName);
310  String filePath = FilenameUtils.getPath(normalizePathName);
311  if (fileName.contains(" [")) {
312  fileName = fileName.substring(0, fileName.indexOf(" ["));
313  }
314  List<AbstractFile> sourceFiles;
315  try {
316  sourceFiles = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS
317  for (AbstractFile sourceFile : sourceFiles) {
318  if (sourceFile.getParentPath().endsWith(filePath)) {
319  applicationFilesFound.put(sourceName.toLowerCase(), sourceFile);
320  }
321  }
322 
323  } catch (TskCoreException ex) {
324  logger.log(Level.WARNING, String.format("Error finding actual file %s. file may not exist", normalizePathName)); //NON-NLS
325  }
326  }
327  } catch (SQLException ex) {
328  logger.log(Level.WARNING, "Error while trying to read into a sqlite db.", ex);//NON-NLS
329  }
330 
331  }
332 
333  private void createNetUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) {
334  List<BlackboardArtifact> bba = new ArrayList<>();
335 
336  String sqlStatement = "SELECT STRFTIME('%s', timestamp) ExecutionTime, Application_Name, User_Name, "
337  + " bytesSent, BytesRecvd FROM network_Usage , SruDbIdMapTable "
338  + " where appId = IdIndex and IdType = 0 order by ExecutionTime;"; //NON-NLS
339 
340  try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS
341  ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
342 
343  while (resultSet.next()) {
344 
345  if (context.dataSourceIngestIsCancelled()) {
346  logger.log(Level.INFO, "Cancelled SRU Net Usage Artifact Creation."); //NON-NLS
347  return;
348  }
349 
350  String applicationName = resultSet.getString("Application_Name"); //NON-NLS
351  Long executionTime = Long.valueOf(resultSet.getInt("ExecutionTime")); //NON-NLS
352  Long bytesSent = Long.valueOf(resultSet.getInt("bytesSent")); //NON-NLS
353  Long bytesRecvd = Long.valueOf(resultSet.getInt("BytesRecvd")); //NON-NLS
354  String userName = resultSet.getString("User_Name"); //NON-NLS
355 
356  Collection<BlackboardAttribute> bbattributes = Arrays.asList(
357  new BlackboardAttribute(
358  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
359  applicationName),//NON-NLS
360  new BlackboardAttribute(
361  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(),
362  userName),
363  new BlackboardAttribute(
364  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
365  executionTime),
366  new BlackboardAttribute(
367  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_BYTES_SENT, getName(), bytesSent),
368  new BlackboardAttribute(
369  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_BYTES_RECEIVED, getName(), bytesRecvd),
370  new BlackboardAttribute(
371  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), NETWORK_USAGE_SOURCE_NAME));
372 
373  try {
374  BlackboardArtifact bbart = sruAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN);
375  bbart.addAttributes(bbattributes);
376  bba.add(bbart);
377  BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart);
378  if (associateBbArtifact != null) {
379  bba.add(associateBbArtifact);
380  }
381  } catch (TskCoreException ex) {
382  logger.log(Level.SEVERE, "Exception Adding Artifact.", ex);//NON-NLS
383  }
384  }
385 
386  } catch (SQLException ex) {
387  logger.log(Level.SEVERE, "Error while trying to read into a sqlite db.", ex);//NON-NLS
388  }
389 
390  try {
391  blackboard.postArtifacts(bba, MODULE_NAME);
392  } catch (Blackboard.BlackboardException ex) {
393  logger.log(Level.SEVERE, "Error Posting Artifact.", ex);//NON-NLS
394  }
395  }
396 
397  private void createAppUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) {
398  List<BlackboardArtifact> bba = new ArrayList<>();
399 
400  String sqlStatement = "SELECT STRFTIME('%s', timestamp) ExecutionTime, Application_Name, User_Name "
401  + " FROM Application_Resource_Usage, SruDbIdMapTable WHERE "
402  + " idType = 0 and idIndex = appId order by ExecutionTime;"; //NON-NLS
403 
404  try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + sruDb); //NON-NLS
405  ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
406 
407  while (resultSet.next()) {
408 
409  if (context.dataSourceIngestIsCancelled()) {
410  logger.log(Level.INFO, "Cancelled SRU Net Usage Artifact Creation."); //NON-NLS
411  return;
412  }
413 
414  String applicationName = resultSet.getString("Application_Name"); //NON-NLS
415  Long executionTime = Long.valueOf(resultSet.getInt("ExecutionTime")); //NON-NLS
416  String userName = resultSet.getString("User_Name");
417 
418  Collection<BlackboardAttribute> bbattributes = Arrays.asList(
419  new BlackboardAttribute(
420  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
421  applicationName),//NON-NLS
422  new BlackboardAttribute(
423  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(),
424  userName),
425  new BlackboardAttribute(
426  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
427  executionTime),
428  new BlackboardAttribute(
429  BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), APPLICATION_USAGE_SOURCE_NAME));
430 
431  try {
432  BlackboardArtifact bbart = sruAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN);
433  bbart.addAttributes(bbattributes);
434  bba.add(bbart);
435  BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart);
436  if (associateBbArtifact != null) {
437  bba.add(associateBbArtifact);
438  }
439  } catch (TskCoreException ex) {
440  logger.log(Level.SEVERE, "Exception Adding Artifact.", ex);//NON-NLS
441  }
442  }
443 
444  } catch (SQLException ex) {
445  logger.log(Level.SEVERE, "Error while trying to read into a sqlite db.", ex);//NON-NLS
446  }
447 
448  try {
449  blackboard.postArtifacts(bba, MODULE_NAME);
450  } catch (Blackboard.BlackboardException ex) {
451  logger.log(Level.SEVERE, "Error Posting Artifact.", ex);//NON-NLS
452  }
453  }
454 
464  private BlackboardArtifact createAssociatedArtifact(String filePathName, BlackboardArtifact bba) {
465  if (applicationFilesFound.containsKey(filePathName)) {
466  AbstractFile sourceFile = applicationFilesFound.get(filePathName);
467  Collection<BlackboardAttribute> bbattributes2 = new ArrayList<>();
468  bbattributes2.addAll(Arrays.asList(
469  new BlackboardAttribute(TSK_ASSOCIATED_ARTIFACT, this.getName(),
470  bba.getArtifactID())));
471 
472  BlackboardArtifact associatedObjectBba = createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, sourceFile, bbattributes2);
473  if (associatedObjectBba != null) {
474  return associatedObjectBba;
475  }
476  }
477 
478  return null;
479  }
480 
481 }
synchronized List< AbstractFile > findFiles(String fileName)

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