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

Copyright © 2012-2024 Sleuth Kit Labs. Generated on: Mon Mar 17 2025
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.