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

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.