19 package org.sleuthkit.autopsy.recentactivity;
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;
35 import org.apache.commons.io.FilenameUtils;
36 import org.openide.modules.InstalledFileLocator;
37 import org.openide.util.NbBundle.Messages;
51 import static org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
53 import static org.
sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
62 final class ExtractSru
extends Extract {
64 private static final Logger logger = Logger.getLogger(ExtractSru.class.getName());
66 private IngestJobContext context;
68 private static final String APPLICATION_USAGE_SOURCE_NAME =
"System Resource Usage - Application Usage";
69 private static final String NETWORK_USAGE_SOURCE_NAME =
"System Resource Usage - Network Usage";
73 private static final String MODULE_NAME =
"extractSRU";
75 private static final String SRU_TOOL_FOLDER =
"markmckinnon";
76 private static final String SRU_TOOL_NAME_WINDOWS_32 =
"Export_Srudb_32.exe";
77 private static final String SRU_TOOL_NAME_WINDOWS_64 =
"Export_Srudb_64.exe";
78 private static final String SRU_TOOL_NAME_LINUX =
"Export_Srudb_Linux.exe";
79 private static final String SRU_TOOL_NAME_MAC =
"Export_srudb_macos";
80 private static final String SRU_OUTPUT_FILE_NAME =
"Output.txt";
81 private static final String SRU_ERROR_FILE_NAME =
"Error.txt";
83 private static final Map<String, AbstractFile> applicationFilesFound =
new HashMap<>();
86 "ExtractSru_module_name=System Resource Usage Extractor"
89 this.moduleName = Bundle.ExtractSru_module_name();
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"
98 void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
100 this.context = context;
102 String modOutPath = Case.getCurrentCase().getModuleDirectory() + File.separator +
"sru";
103 File dir =
new File(modOutPath);
104 if (dir.exists() ==
false) {
108 String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(),
"sru");
109 String softwareHiveFileName = getSoftwareHiveFile(dataSource, tempDirPath);
111 if (softwareHiveFileName == null) {
115 AbstractFile sruAbstractFile = getSruFile(dataSource, tempDirPath);
117 if (sruAbstractFile == null) {
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");
128 if (context.dataSourceIngestIsCancelled()) {
133 String modOutFile = modOutPath + File.separator + sruAbstractFile.getId() +
"_srudb.db3";
134 String sruFileName = tempDirPath + File.separator + sruAbstractFile.getId() +
"_" + sruAbstractFile.getName();
136 extractSruFiles(sruDumper, sruFileName, modOutFile, tempDirPath, softwareHiveFileName);
138 findSruExecutedFiles(modOutFile, dataSource);
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");
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"
161 String getSoftwareHiveFile(Content dataSource, String tempDirPath) {
162 FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
164 List<AbstractFile> softwareHiveFiles;
167 softwareHiveFiles = fileManager.findFiles(dataSource,
"SOFTWARE");
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);
174 String softwareHiveFileName = null;
176 for (AbstractFile softwareFile : softwareHiveFiles) {
178 if (softwareFile.getParentPath().endsWith(
"/config/")) {
179 softwareHiveFileName = tempDirPath + File.separator + softwareFile.getId() +
"_" + softwareFile.getName();
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);
190 return softwareHiveFileName;
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"
205 AbstractFile getSruFile(Content dataSource, String tempDirPath) {
206 FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
208 List<AbstractFile> sruFiles;
211 sruFiles = fileManager.findFiles(dataSource,
"SRUDB.DAT");
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);
218 AbstractFile sruAbstractFile = null;
220 for (AbstractFile sruFile : sruFiles) {
222 String sruFileName = tempDirPath + File.separator + sruFile.getId() +
"_" + sruFile.getName();
223 sruAbstractFile = sruFile;
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);
234 return sruAbstractFile;
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);
251 List<String> commandLine =
new ArrayList<>();
252 commandLine.add(sruExePath);
253 commandLine.add(sruFile);
254 commandLine.add(softwareHiveFile);
255 commandLine.add(tempOutFile);
257 ProcessBuilder processBuilder =
new ProcessBuilder(commandLine);
258 processBuilder.redirectOutput(outputFilePath.toFile());
259 processBuilder.redirectError(errFilePath.toFile());
261 ExecUtil.execute(processBuilder,
new DataSourceIngestModuleProcessTerminator(context));
264 private String getPathForSruDumper() {
266 if (PlatformUtil.isWindowsOS()) {
267 if (PlatformUtil.is64BitOS()) {
268 path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_64);
270 path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_32);
273 if (
"Linux".equals(PlatformUtil.getOSName())) {
274 path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_LINUX);
276 path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_MAC);
279 File sruToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
280 ExtractSru.class.getPackage().getName(),
false);
281 if (sruToolFile != null) {
282 return sruToolFile.getAbsolutePath();
288 private void findSruExecutedFiles(String sruDb, Content dataSource) {
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 '!!%'";
295 try (SQLiteDBConnect tempdbconnect =
new SQLiteDBConnect(
"org.sqlite.JDBC",
"jdbc:sqlite:" + sruDb);
296 ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
298 while (resultSet.next()) {
300 if (context.dataSourceIngestIsCancelled()) {
301 logger.log(Level.INFO,
"Cancelled SRU Artifact Creation.");
305 String applicationName = resultSet.getString(
"application_name");
306 String sourceName = resultSet.getString(
"source_name");
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(
" ["));
314 List<AbstractFile> sourceFiles;
316 sourceFiles = fileManager.
findFiles(dataSource, fileName, filePath);
317 for (AbstractFile sourceFile : sourceFiles) {
318 if (sourceFile.getParentPath().endsWith(filePath)) {
319 applicationFilesFound.put(sourceName.toLowerCase(), sourceFile);
323 }
catch (TskCoreException ex) {
324 logger.log(Level.WARNING, String.format(
"Error finding actual file %s. file may not exist", normalizePathName));
327 }
catch (SQLException ex) {
328 logger.log(Level.WARNING,
"Error while trying to read into a sqlite db.", ex);
333 private void createNetUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) {
334 List<BlackboardArtifact> bba =
new ArrayList<>();
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;";
340 try (SQLiteDBConnect tempdbconnect =
new SQLiteDBConnect(
"org.sqlite.JDBC",
"jdbc:sqlite:" + sruDb);
341 ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
343 while (resultSet.next()) {
345 if (context.dataSourceIngestIsCancelled()) {
346 logger.log(Level.INFO,
"Cancelled SRU Net Usage Artifact Creation.");
350 String applicationName = resultSet.getString(
"Application_Name");
351 Long executionTime = Long.valueOf(resultSet.getInt(
"ExecutionTime"));
352 Long bytesSent = Long.valueOf(resultSet.getInt(
"bytesSent"));
353 Long bytesRecvd = Long.valueOf(resultSet.getInt(
"BytesRecvd"));
354 String userName = resultSet.getString(
"User_Name");
356 Collection<BlackboardAttribute> bbattributes = Arrays.asList(
357 new BlackboardAttribute(
358 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
360 new BlackboardAttribute(
361 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(),
363 new BlackboardAttribute(
364 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
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));
374 BlackboardArtifact bbart = sruAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN);
375 bbart.addAttributes(bbattributes);
377 BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart);
378 if (associateBbArtifact != null) {
379 bba.add(associateBbArtifact);
381 }
catch (TskCoreException ex) {
382 logger.log(Level.SEVERE,
"Exception Adding Artifact.", ex);
386 }
catch (SQLException ex) {
387 logger.log(Level.SEVERE,
"Error while trying to read into a sqlite db.", ex);
391 blackboard.postArtifacts(bba, MODULE_NAME);
392 }
catch (Blackboard.BlackboardException ex) {
393 logger.log(Level.SEVERE,
"Error Posting Artifact.", ex);
397 private void createAppUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) {
398 List<BlackboardArtifact> bba =
new ArrayList<>();
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;";
404 try (SQLiteDBConnect tempdbconnect =
new SQLiteDBConnect(
"org.sqlite.JDBC",
"jdbc:sqlite:" + sruDb);
405 ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
407 while (resultSet.next()) {
409 if (context.dataSourceIngestIsCancelled()) {
410 logger.log(Level.INFO,
"Cancelled SRU Net Usage Artifact Creation.");
414 String applicationName = resultSet.getString(
"Application_Name");
415 Long executionTime = Long.valueOf(resultSet.getInt(
"ExecutionTime"));
416 String userName = resultSet.getString(
"User_Name");
418 Collection<BlackboardAttribute> bbattributes = Arrays.asList(
419 new BlackboardAttribute(
420 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
422 new BlackboardAttribute(
423 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(),
425 new BlackboardAttribute(
426 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
428 new BlackboardAttribute(
429 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), APPLICATION_USAGE_SOURCE_NAME));
432 BlackboardArtifact bbart = sruAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN);
433 bbart.addAttributes(bbattributes);
435 BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart);
436 if (associateBbArtifact != null) {
437 bba.add(associateBbArtifact);
439 }
catch (TskCoreException ex) {
440 logger.log(Level.SEVERE,
"Exception Adding Artifact.", ex);
444 }
catch (SQLException ex) {
445 logger.log(Level.SEVERE,
"Error while trying to read into a sqlite db.", ex);
449 blackboard.postArtifacts(bba, MODULE_NAME);
450 }
catch (Blackboard.BlackboardException ex) {
451 logger.log(Level.SEVERE,
"Error Posting Artifact.", ex);
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())));
472 BlackboardArtifact associatedObjectBba = createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, sourceFile, bbattributes2);
473 if (associatedObjectBba != null) {
474 return associatedObjectBba;
synchronized List< AbstractFile > findFiles(String fileName)