19 package org.sleuthkit.autopsy.modules.yara;
 
   22 import java.io.IOException;
 
   23 import java.nio.file.Path;
 
   24 import java.nio.file.Paths;
 
   25 import java.util.ArrayList;
 
   26 import java.util.List;
 
   27 import org.openide.modules.InstalledFileLocator;
 
   28 import org.openide.util.NbBundle;
 
   47 final class YaraIngestHelper {
 
   49     private static final String YARA_DIR = 
"yara";
 
   50     private static final String YARA_C_EXE = 
"yarac64.exe";
 
   51     private static final String MODULE_NAME = YaraIngestModuleFactory.getModuleName();
 
   53     private YaraIngestHelper() {
 
   64     static void compileRules(List<String> ruleSetNames, Path outputDir) 
throws IngestModuleException {
 
   65         if (ruleSetNames == null || ruleSetNames.isEmpty()) {
 
   66             throw new IngestModule.IngestModuleException(Bundle.YaraIngestModule_no_ruleSets());
 
   70         File exeFile = InstalledFileLocator.getDefault().locate(
 
   71                 Paths.get(YARA_DIR, YARA_C_EXE).toString(),
 
   72                 YaraIngestModule.class.getPackage().getName(), 
false);
 
   74         if (exeFile == null) {
 
   75             throw new IngestModuleException(Bundle.YaraIngestModule_yarac_not_found());
 
   78         for (RuleSet set : getRuleSetsForNames(ruleSetNames)) {
 
   79             compileRuleSet(set, outputDir, exeFile);
 
   96     static List<BlackboardArtifact> scanFileForMatches(AbstractFile file, File baseRuleSetDirectory, byte[] fileData, 
int fileDataSize, 
int timeout) 
throws TskCoreException, YaraWrapperException {
 
   97         List<BlackboardArtifact> artifacts = 
new ArrayList<>();
 
   99         File[] ruleSetDirectories = baseRuleSetDirectory.listFiles();
 
  100         for (File ruleSetDirectory : ruleSetDirectories) {
 
  102             List<String> ruleMatches = YaraIngestHelper.scanFileForMatches(fileData, fileDataSize, ruleSetDirectory, timeout);
 
  103             if (!ruleMatches.isEmpty()) {
 
  104                 artifacts.addAll(YaraIngestHelper.createArtifact(file, ruleSetDirectory.getName(), ruleMatches));
 
  126     static List<BlackboardArtifact> scanFileForMatches(AbstractFile file, File baseRuleSetDirectory, File localFile, 
int timeout) 
throws TskCoreException, YaraWrapperException {
 
  127         List<BlackboardArtifact> artifacts = 
new ArrayList<>();
 
  129         File[] ruleSetDirectories = baseRuleSetDirectory.listFiles();
 
  130         for (File ruleSetDirectory : ruleSetDirectories) {
 
  131             List<String> ruleMatches = YaraIngestHelper.scanFileForMatch(localFile, ruleSetDirectory, timeout);
 
  132             if (!ruleMatches.isEmpty()) {
 
  133                 artifacts.addAll(YaraIngestHelper.createArtifact(file, ruleSetDirectory.getName(), ruleMatches));
 
  152     private static List<String> scanFileForMatches(byte[] fileBytes, 
int fileSize, File ruleSetDirectory, 
int timeout) 
throws YaraWrapperException {
 
  153         List<String> matchingRules = 
new ArrayList<>();
 
  155         File[] ruleSetCompiledFileList = ruleSetDirectory.listFiles();
 
  157         for (File ruleFile : ruleSetCompiledFileList) {
 
  158             matchingRules.addAll(YaraJNIWrapper.findRuleMatch(ruleFile.getAbsolutePath(), fileBytes, fileSize, timeout));
 
  161         return matchingRules;
 
  177     private static List<String> scanFileForMatch(File scanFile, File ruleSetDirectory, 
int timeout) 
throws YaraWrapperException {
 
  178         List<String> matchingRules = 
new ArrayList<>();
 
  180         File[] ruleSetCompiledFileList = ruleSetDirectory.listFiles();
 
  182         for (File ruleFile : ruleSetCompiledFileList) {
 
  183             matchingRules.addAll(YaraJNIWrapper.findRuleMatchFile(ruleFile.getAbsolutePath(), scanFile.getAbsolutePath(), timeout));
 
  186         return matchingRules;
 
  200     private static List<BlackboardArtifact> createArtifact(AbstractFile abstractFile, String ruleSetName, List<String> matchingRules) 
throws TskCoreException {
 
  201         List<BlackboardArtifact> artifacts = 
new ArrayList<>();
 
  202         for (String rule : matchingRules) {
 
  204             List<BlackboardAttribute> attributes = 
new ArrayList<>();
 
  206             attributes.add(
new BlackboardAttribute(TSK_SET_NAME, MODULE_NAME, ruleSetName));
 
  207             attributes.add(
new BlackboardAttribute(TSK_RULE, MODULE_NAME, rule));
 
  209             BlackboardArtifact artifact = abstractFile.newAnalysisResult(BlackboardArtifact.Type.TSK_YARA_HIT, Score.SCORE_NOTABLE, null, ruleSetName, rule, attributes)
 
  210                     .getAnalysisResult();
 
  212             artifacts.add(artifact);
 
  218         "YaraIngestModule_yarac_not_found=Unable to compile YARA rules files. Unable to find executable at.",
 
  219         "YaraIngestModule_no_ruleSets=Unable to run YARA ingest, list of YARA rule sets was empty." 
  233     static private void compileRuleSet(RuleSet set, Path outputDir, File yarac) 
throws IngestModuleException {
 
  234         File tempFolder = Paths.get(outputDir.toString(), set.getName()).toFile();
 
  235         if (!tempFolder.exists()) {
 
  239         List<File> fileList = set.getRuleFiles();
 
  240         for (File file : fileList) {
 
  241             List<String> commandList = 
new ArrayList<>();
 
  242             commandList.add(String.format(
"\"%s\"", yarac.toString()));
 
  243             commandList.add(String.format(
"\"%s\"", file.toString()));
 
  244             commandList.add(String.format(
"\"%s\"", Paths.get(tempFolder.getAbsolutePath(), 
"compiled_" + file.getName())));
 
  246             ProcessBuilder builder = 
new ProcessBuilder(commandList);
 
  248                 int result = ExecUtil.execute(builder);
 
  250                     throw new IngestModuleException(String.format(
"Failed to compile Yara rules file %s. Compile error %d", file.toString(), result));
 
  252             } 
catch (SecurityException | IOException ex) {
 
  253                 throw new IngestModuleException(String.format(
"Failed to compile Yara rules file, %s", file.toString()), ex);
 
  267     private static List<RuleSet> getRuleSetsForNames(List<String> names) {
 
  268         List<RuleSet> ruleSetList = 
new ArrayList<>();
 
  270         RuleSetManager manager = RuleSetManager.getInstance();
 
  271         for (RuleSet set : manager.getRuleSetList()) {
 
  272             if (names.contains(set.getName())) {
 
  273                 ruleSetList.add(set);