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;
 
   58 final class ExtractSru 
extends Extract {
 
   60     private static final Logger logger = Logger.getLogger(ExtractSru.class.getName());
 
   62     private IngestJobContext context;
 
   64     private static final String APPLICATION_USAGE_SOURCE_NAME = 
"System Resource Usage - Application Usage"; 
 
   65     private static final String NETWORK_USAGE_SOURCE_NAME = 
"System Resource Usage - Network Usage";
 
   68     private static final String MODULE_NAME = 
"extractSRU"; 
 
   70     private static final String SRU_TOOL_FOLDER = 
"markmckinnon"; 
 
   71     private static final String SRU_TOOL_NAME_WINDOWS_32 = 
"Export_Srudb_32.exe"; 
 
   72     private static final String SRU_TOOL_NAME_WINDOWS_64 = 
"Export_Srudb_64.exe"; 
 
   73     private static final String SRU_TOOL_NAME_LINUX = 
"Export_Srudb_Linux.exe"; 
 
   74     private static final String SRU_TOOL_NAME_MAC = 
"Export_srudb_macos"; 
 
   75     private static final String SRU_OUTPUT_FILE_NAME = 
"Output.txt"; 
 
   76     private static final String SRU_ERROR_FILE_NAME = 
"Error.txt"; 
 
   78     private static final Map<String, AbstractFile> applicationFilesFound = 
new HashMap<>();
 
   81         "ExtractSru_module_name=System Resource Usage Extractor" 
   84         super(Bundle.ExtractSru_module_name());
 
   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" 
   93     void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
 
   95         this.context = context;
 
   97         String modOutPath = Case.getCurrentCase().getModuleDirectory() + File.separator + 
"sru";
 
   98         File dir = 
new File(modOutPath);
 
   99         if (dir.exists() == 
false) {
 
  103         String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), 
"sru", context.getJobId()); 
 
  104         String softwareHiveFileName = getSoftwareHiveFile(dataSource, tempDirPath);
 
  106         if (softwareHiveFileName == null) {
 
  110         AbstractFile sruAbstractFile = getSruFile(dataSource, tempDirPath);
 
  112         if (sruAbstractFile == null) {
 
  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"); 
 
  123         if (context.dataSourceIngestIsCancelled()) {
 
  128             String modOutFile = modOutPath + File.separator + sruAbstractFile.getId() + 
"_srudb.db3";
 
  129             String sruFileName = tempDirPath + File.separator + sruAbstractFile.getId() + 
"_" + sruAbstractFile.getName();
 
  131             extractSruFiles(sruDumper, sruFileName, modOutFile, tempDirPath, softwareHiveFileName);
 
  133             findSruExecutedFiles(modOutFile, dataSource);
 
  135             createNetUsageArtifacts(modOutFile, sruAbstractFile);
 
  136             createAppUsageArtifacts(modOutFile, sruAbstractFile);
 
  137         } 
catch (IOException ex) {
 
  138             logger.log(Level.SEVERE, 
"Error processing SRUDB.dat file", ex); 
 
  139             this.addErrorMessage(Bundle.ExtractSru_process_error_executing_export_srudb_program());
 
  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" 
  156     String getSoftwareHiveFile(Content dataSource, String tempDirPath) {
 
  157         FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
 
  159         List<AbstractFile> softwareHiveFiles;
 
  162             softwareHiveFiles = fileManager.findFiles(dataSource, 
"SOFTWARE"); 
 
  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); 
 
  169         String softwareHiveFileName = null;
 
  171         for (AbstractFile softwareFile : softwareHiveFiles) {
 
  173             if (softwareFile.getParentPath().endsWith(
"/config/")) {
 
  174                 softwareHiveFileName = tempDirPath + File.separator + softwareFile.getId() + 
"_" + softwareFile.getName();
 
  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); 
 
  185         return softwareHiveFileName;
 
  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" 
  200     AbstractFile getSruFile(Content dataSource, String tempDirPath) {
 
  201         FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
 
  203         List<AbstractFile> sruFiles;
 
  206             sruFiles = fileManager.findFiles(dataSource, 
"SRUDB.DAT"); 
 
  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); 
 
  213         AbstractFile sruAbstractFile = null;
 
  215         for (AbstractFile sruFile : sruFiles) {
 
  217             String sruFileName = tempDirPath + File.separator + sruFile.getId() + 
"_" + sruFile.getName();
 
  218             sruAbstractFile = sruFile;
 
  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); 
 
  229         return sruAbstractFile;
 
  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);
 
  246         List<String> commandLine = 
new ArrayList<>();
 
  247         commandLine.add(sruExePath);
 
  248         commandLine.add(sruFile);  
 
  249         commandLine.add(softwareHiveFile);
 
  250         commandLine.add(tempOutFile);
 
  252         ProcessBuilder processBuilder = 
new ProcessBuilder(commandLine);
 
  253         processBuilder.redirectOutput(outputFilePath.toFile());
 
  254         processBuilder.redirectError(errFilePath.toFile());
 
  256         ExecUtil.execute(processBuilder, 
new DataSourceIngestModuleProcessTerminator(context, 
true));
 
  259     private String getPathForSruDumper() {
 
  261         if (PlatformUtil.isWindowsOS()) {
 
  262             if (PlatformUtil.is64BitOS()) {
 
  263                 path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_64);
 
  265                 path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_WINDOWS_32);
 
  268             if (
"Linux".equals(PlatformUtil.getOSName())) {
 
  269                 path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_LINUX);
 
  271                 path = Paths.get(SRU_TOOL_FOLDER, SRU_TOOL_NAME_MAC);
 
  274         File sruToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
 
  275                 ExtractSru.class.getPackage().getName(), 
false);
 
  276         if (sruToolFile != null) {
 
  277             return sruToolFile.getAbsolutePath();
 
  283     private void findSruExecutedFiles(String sruDb, Content dataSource) {
 
  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 '!!%'"; 
 
  290         try (SQLiteDBConnect tempdbconnect = 
new SQLiteDBConnect(
"org.sqlite.JDBC", 
"jdbc:sqlite:" + sruDb); 
 
  291                 ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
 
  293             while (resultSet.next()) {
 
  295                 if (context.dataSourceIngestIsCancelled()) {
 
  296                     logger.log(Level.INFO, 
"Cancelled SRU Artifact Creation."); 
 
  300                 String applicationName = resultSet.getString(
"application_name"); 
 
  301                 String sourceName = resultSet.getString(
"source_name"); 
 
  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(
" ["));
 
  309                 List<AbstractFile> sourceFiles;
 
  311                     sourceFiles = fileManager.
findFiles(dataSource, fileName, filePath); 
 
  312                     for (AbstractFile sourceFile : sourceFiles) {
 
  313                         if (sourceFile.getParentPath().endsWith(filePath)) {
 
  314                             applicationFilesFound.put(sourceName.toLowerCase(), sourceFile);
 
  318                 } 
catch (TskCoreException ex) {
 
  319                     logger.log(Level.WARNING, String.format(
"Error finding actual file %s. file may not exist", normalizePathName)); 
 
  322         } 
catch (SQLException ex) {
 
  323             logger.log(Level.WARNING, 
"Error while trying to read into a sqlite db.", ex);
 
  328     private void createNetUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) {
 
  329         List<BlackboardArtifact> bba = 
new ArrayList<>();
 
  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;"; 
 
  335         try (SQLiteDBConnect tempdbconnect = 
new SQLiteDBConnect(
"org.sqlite.JDBC", 
"jdbc:sqlite:" + sruDb); 
 
  336                 ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
 
  338             while (resultSet.next()) {
 
  340                 if (context.dataSourceIngestIsCancelled()) {
 
  341                     logger.log(Level.INFO, 
"Cancelled SRU Net Usage Artifact Creation."); 
 
  345                 String applicationName = resultSet.getString(
"Application_Name"); 
 
  346                 String formattedApplicationName = resultSet.getString(
"formatted_Application_name");
 
  347                 Long executionTime = Long.valueOf(resultSet.getInt(
"ExecutionTime")); 
 
  348                 Long bytesSent = Long.valueOf(resultSet.getInt(
"bytesSent")); 
 
  349                 Long bytesRecvd = Long.valueOf(resultSet.getInt(
"BytesRecvd")); 
 
  350                 String userName = resultSet.getString(
"User_Name"); 
 
  352                 Collection<BlackboardAttribute> bbattributes = Arrays.asList(
 
  353                         new BlackboardAttribute(
 
  354                                 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
 
  355                                 formattedApplicationName),
 
  356                         new BlackboardAttribute(
 
  357                                 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(),
 
  359                         new BlackboardAttribute(
 
  360                                 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
 
  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));
 
  370                     BlackboardArtifact bbart = createArtifactWithAttributes(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN, sruAbstractFile, bbattributes);
 
  372                     BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart);
 
  373                     if (associateBbArtifact != null) {
 
  374                         bba.add(associateBbArtifact);
 
  376                 } 
catch (TskCoreException ex) {
 
  377                     logger.log(Level.SEVERE, 
"Exception Adding Artifact.", ex);
 
  381         } 
catch (SQLException ex) {
 
  382             logger.log(Level.SEVERE, 
"Error while trying to read into a sqlite db.", ex);
 
  385         if(!context.dataSourceIngestIsCancelled()) {
 
  390     private void createAppUsageArtifacts(String sruDb, AbstractFile sruAbstractFile) {
 
  391         List<BlackboardArtifact> bba = 
new ArrayList<>();
 
  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;"; 
 
  397         try (SQLiteDBConnect tempdbconnect = 
new SQLiteDBConnect(
"org.sqlite.JDBC", 
"jdbc:sqlite:" + sruDb); 
 
  398                 ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
 
  400             while (resultSet.next()) {
 
  402                 if (context.dataSourceIngestIsCancelled()) {
 
  403                     logger.log(Level.INFO, 
"Cancelled SRU Net Usage Artifact Creation."); 
 
  407                 String applicationName = resultSet.getString(
"Application_Name"); 
 
  408                 String formattedApplicationName = resultSet.getString(
"formatted_application_name");
 
  409                 Long executionTime = Long.valueOf(resultSet.getInt(
"ExecutionTime")); 
 
  410                 String userName = resultSet.getString(
"User_Name");
 
  412                 Collection<BlackboardAttribute> bbattributes = Arrays.asList(
 
  413                         new BlackboardAttribute(
 
  414                                 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
 
  415                                 formattedApplicationName),
 
  416                         new BlackboardAttribute(
 
  417                                 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_USER_NAME, getName(),
 
  419                         new BlackboardAttribute(
 
  420                                 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
 
  422                         new BlackboardAttribute(
 
  423                                 BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), APPLICATION_USAGE_SOURCE_NAME));
 
  426                     BlackboardArtifact bbart = createArtifactWithAttributes(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN, sruAbstractFile, bbattributes);
 
  428                     BlackboardArtifact associateBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), bbart);
 
  429                     if (associateBbArtifact != null) {
 
  430                         bba.add(associateBbArtifact);
 
  432                 } 
catch (TskCoreException ex) {
 
  433                     logger.log(Level.SEVERE, 
"Exception Adding Artifact.", ex);
 
  437         } 
catch (SQLException ex) {
 
  438             logger.log(Level.SEVERE, 
"Error while trying to read into a sqlite db.", ex);
 
  441         if(!context.dataSourceIngestIsCancelled()) {
 
  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);
 
List< AbstractFile > findFiles(String fileName)