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

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