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

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