mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-06 21:00:22 +00:00
Yara ingest module
This commit is contained in:
parent
621e828b72
commit
09d0c6e5f6
10
.gitignore
vendored
10
.gitignore
vendored
@ -89,3 +89,13 @@ hs_err_pid*.log
|
|||||||
*.img
|
*.img
|
||||||
*.vhd
|
*.vhd
|
||||||
*.E01
|
*.E01
|
||||||
|
|
||||||
|
/thirdparty/yara/yarabridge/yarabridge/x64/
|
||||||
|
/thirdparty/yara/yarabridge/yarabridge.VC.db
|
||||||
|
/thirdparty/yara/yarabridge/yarabridge.VC.VC.opendb
|
||||||
|
/thirdparty/yara/yarabridge/x64/
|
||||||
|
/thirdparty/yara/YaraWrapperTest/nbproject/private/
|
||||||
|
/thirdparty/yara/YaraWrapperTest/build/
|
||||||
|
/thirdparty/yara/YaraJNIWrapper/dist/
|
||||||
|
/thirdparty/yara/YaraJNIWrapper/build/
|
||||||
|
/thirdparty/yara/YaraJNIWrapper/nbproject/private/
|
||||||
|
@ -98,6 +98,10 @@
|
|||||||
<copy file="${thirdparty.dir}/jdom/jdom-2.0.5.jar" todir="${ext.dir}" />
|
<copy file="${thirdparty.dir}/jdom/jdom-2.0.5.jar" todir="${ext.dir}" />
|
||||||
<copy file="${thirdparty.dir}/jdom/jdom-2.0.5-contrib.jar" todir="${ext.dir}" />
|
<copy file="${thirdparty.dir}/jdom/jdom-2.0.5-contrib.jar" todir="${ext.dir}" />
|
||||||
<copy file="${thirdparty.dir}/DatCon/3.6.9/DatCon.jar" todir="${ext.dir}" />
|
<copy file="${thirdparty.dir}/DatCon/3.6.9/DatCon.jar" todir="${ext.dir}" />
|
||||||
|
<!--Copy iLeapp to release-->
|
||||||
|
<copy todir="${basedir}/release/yara" >
|
||||||
|
<fileset dir="${thirdparty.dir}/yara/bin"/>
|
||||||
|
</copy>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,6 +118,7 @@ file.reference.StixLib.jar=release\\modules\\ext\\StixLib.jar
|
|||||||
file.reference.threetenbp-1.3.3.jar=release\\modules\\ext\\threetenbp-1.3.3.jar
|
file.reference.threetenbp-1.3.3.jar=release\\modules\\ext\\threetenbp-1.3.3.jar
|
||||||
file.reference.webp-imageio-sejda-0.1.0.jar=release\\modules\\ext\\webp-imageio-sejda-0.1.0.jar
|
file.reference.webp-imageio-sejda-0.1.0.jar=release\\modules\\ext\\webp-imageio-sejda-0.1.0.jar
|
||||||
file.reference.xmpcore-5.1.3.jar=release\\modules\\ext\\xmpcore-5.1.3.jar
|
file.reference.xmpcore-5.1.3.jar=release\\modules\\ext\\xmpcore-5.1.3.jar
|
||||||
|
file.reference.YaraJNIWrapper.jar=release/modules/ext/YaraJNIWrapper.jar
|
||||||
file.reference.zookeeper-3.4.6.jar=release\\modules\\ext\\zookeeper-3.4.6.jar
|
file.reference.zookeeper-3.4.6.jar=release\\modules\\ext\\zookeeper-3.4.6.jar
|
||||||
javac.source=1.8
|
javac.source=1.8
|
||||||
javac.compilerargs=-Xlint -Xlint:-serial
|
javac.compilerargs=-Xlint -Xlint:-serial
|
||||||
|
@ -547,18 +547,10 @@
|
|||||||
<runtime-relative-path>ext/checker-compat-qual-2.5.3.jar</runtime-relative-path>
|
<runtime-relative-path>ext/checker-compat-qual-2.5.3.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\checker-compat-qual-2.5.3.jar</binary-origin>
|
<binary-origin>release\modules\ext\checker-compat-qual-2.5.3.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
|
||||||
<runtime-relative-path>ext/sleuthkit-4.10.1.jar</runtime-relative-path>
|
|
||||||
<binary-origin>release/modules/ext/sleuthkit-4.10.1.jar</binary-origin>
|
|
||||||
</class-path-extension>
|
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/animal-sniffer-annotations-1.17.jar</runtime-relative-path>
|
<runtime-relative-path>ext/animal-sniffer-annotations-1.17.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\animal-sniffer-annotations-1.17.jar</binary-origin>
|
<binary-origin>release\modules\ext\animal-sniffer-annotations-1.17.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
<class-path-extension>
|
|
||||||
<runtime-relative-path>ext/sleuthkit-caseuco-4.10.1.jar</runtime-relative-path>
|
|
||||||
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.10.1.jar</binary-origin>
|
|
||||||
</class-path-extension>
|
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/gax-1.44.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/gax-1.44.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\gax-1.44.0.jar</binary-origin>
|
<binary-origin>release\modules\ext\gax-1.44.0.jar</binary-origin>
|
||||||
@ -567,6 +559,10 @@
|
|||||||
<runtime-relative-path>ext/jsoup-1.10.3.jar</runtime-relative-path>
|
<runtime-relative-path>ext/jsoup-1.10.3.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\jsoup-1.10.3.jar</binary-origin>
|
<binary-origin>release\modules\ext\jsoup-1.10.3.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/YaraJNIWrapper.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/YaraJNIWrapper.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/grpc-context-1.19.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/grpc-context-1.19.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\grpc-context-1.19.0.jar</binary-origin>
|
<binary-origin>release\modules\ext\grpc-context-1.19.0.jar</binary-origin>
|
||||||
@ -671,6 +667,10 @@
|
|||||||
<runtime-relative-path>ext/grpc-alts-1.19.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/grpc-alts-1.19.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\grpc-alts-1.19.0.jar</binary-origin>
|
<binary-origin>release\modules\ext\grpc-alts-1.19.0.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/sleuthkit-caseuco-4.10.1.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/sleuthkit-caseuco-4.10.1.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/jdom-2.0.5.jar</runtime-relative-path>
|
<runtime-relative-path>ext/jdom-2.0.5.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\jdom-2.0.5.jar</binary-origin>
|
<binary-origin>release\modules\ext\jdom-2.0.5.jar</binary-origin>
|
||||||
@ -795,6 +795,10 @@
|
|||||||
<runtime-relative-path>ext/sevenzipjbinding-AllPlatforms.jar</runtime-relative-path>
|
<runtime-relative-path>ext/sevenzipjbinding-AllPlatforms.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\sevenzipjbinding-AllPlatforms.jar</binary-origin>
|
<binary-origin>release\modules\ext\sevenzipjbinding-AllPlatforms.jar</binary-origin>
|
||||||
</class-path-extension>
|
</class-path-extension>
|
||||||
|
<class-path-extension>
|
||||||
|
<runtime-relative-path>ext/sleuthkit-4.10.1.jar</runtime-relative-path>
|
||||||
|
<binary-origin>release/modules/ext/sleuthkit-4.10.1.jar</binary-origin>
|
||||||
|
</class-path-extension>
|
||||||
<class-path-extension>
|
<class-path-extension>
|
||||||
<runtime-relative-path>ext/jutf7-1.0.0.jar</runtime-relative-path>
|
<runtime-relative-path>ext/jutf7-1.0.0.jar</runtime-relative-path>
|
||||||
<binary-origin>release\modules\ext\jutf7-1.0.0.jar</binary-origin>
|
<binary-origin>release\modules\ext\jutf7-1.0.0.jar</binary-origin>
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.guicomponeontutils;
|
||||||
|
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import org.sleuthkit.autopsy.guiutils.CheckBoxJList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract implementation of CheckBoxJList.CheckboxListItem so that
|
||||||
|
* implementing classes have default implementation.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractCheckboxListItem implements CheckBoxJList.CheckboxListItem {
|
||||||
|
|
||||||
|
private boolean checked = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChecked() {
|
||||||
|
return checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setChecked(boolean checked) {
|
||||||
|
this.checked = checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasIcon() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Icon getIcon() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -32,8 +32,10 @@ import javax.swing.ListSelectionModel;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A JList that renders the list items as check boxes.
|
* A JList that renders the list items as check boxes.
|
||||||
|
*
|
||||||
|
* @param <T> An object that implements CheckboxListItem
|
||||||
*/
|
*/
|
||||||
final class CheckBoxJList<T extends CheckBoxJList.CheckboxListItem> extends JList<T> {
|
public final class CheckBoxJList<T extends CheckBoxJList.CheckboxListItem> extends JList<T> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@ -42,7 +44,7 @@ final class CheckBoxJList<T extends CheckBoxJList.CheckboxListItem> extends JLis
|
|||||||
* a checkbox in CheckBoxJList.
|
* a checkbox in CheckBoxJList.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
interface CheckboxListItem {
|
public interface CheckboxListItem {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the checkbox state.
|
* Returns the checkbox state.
|
||||||
@ -83,7 +85,7 @@ final class CheckBoxJList<T extends CheckBoxJList.CheckboxListItem> extends JLis
|
|||||||
/**
|
/**
|
||||||
* Construct a new JCheckBoxList.
|
* Construct a new JCheckBoxList.
|
||||||
*/
|
*/
|
||||||
CheckBoxJList() {
|
public CheckBoxJList() {
|
||||||
initalize();
|
initalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,12 +136,15 @@ final class CheckBoxJList<T extends CheckBoxJList.CheckboxListItem> extends JLis
|
|||||||
checkbox.setSelected(value.isChecked());
|
checkbox.setSelected(value.isChecked());
|
||||||
checkbox.setBackground(list.getBackground());
|
checkbox.setBackground(list.getBackground());
|
||||||
checkbox.setEnabled(list.isEnabled());
|
checkbox.setEnabled(list.isEnabled());
|
||||||
|
checkbox.setOpaque(list.isOpaque());
|
||||||
label.setText(value.getDisplayName());
|
label.setText(value.getDisplayName());
|
||||||
label.setEnabled(list.isEnabled());
|
label.setEnabled(list.isEnabled());
|
||||||
|
label.setOpaque(list.isOpaque());
|
||||||
if (value.hasIcon()) {
|
if (value.hasIcon()) {
|
||||||
label.setIcon(value.getIcon());
|
label.setIcon(value.getIcon());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setOpaque(list.isOpaque());
|
||||||
setEnabled(list.isEnabled());
|
setEnabled(list.isEnabled());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
5
Core/src/org/sleuthkit/autopsy/modules/yara/Bundle.properties-MERGED
Executable file
5
Core/src/org/sleuthkit/autopsy/modules/yara/Bundle.properties-MERGED
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
Yara_Module_Description=With the YARA ingest module you use YARA rule files to search files for textual or binary patterns.
|
||||||
|
Yara_Module_Name=YARA
|
||||||
|
YaraIngestModule_no_ruleSets=Unable to run YARA ingest, list of YARA rule sets was empty.
|
||||||
|
YaraIngestModule_windows_error_msg=The YARA ingest module is only available on 64bit Windows.
|
||||||
|
YaraIngestModule_yarac_not_found=Unable to compile YARA rules files. Unable to find executable at.
|
207
Core/src/org/sleuthkit/autopsy/modules/yara/YaraIngestHelper.java
Executable file
207
Core/src/org/sleuthkit/autopsy/modules/yara/YaraIngestHelper.java
Executable file
@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.yara;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.openide.modules.InstalledFileLocator;
|
||||||
|
import org.openide.util.NbBundle;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException;
|
||||||
|
import org.sleuthkit.autopsy.modules.yara.rules.RuleSet;
|
||||||
|
import org.sleuthkit.autopsy.modules.yara.rules.RuleSetManager;
|
||||||
|
import org.sleuthkit.autopsy.yara.YaraJNIWrapper;
|
||||||
|
import org.sleuthkit.autopsy.yara.YaraWrapperException;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_YARA_HIT;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods for scanning files for yara rule matches.
|
||||||
|
*/
|
||||||
|
final class YaraIngestHelper {
|
||||||
|
|
||||||
|
private static final String YARA_DIR = "yara";
|
||||||
|
private static final String YARA_C_EXE = "yarac64.exe";
|
||||||
|
private static final String MODULE_NAME = YaraIngestModuleFactory.getModuleName();
|
||||||
|
|
||||||
|
private YaraIngestHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses the yarac tool to compile the rules in the given rule sets.
|
||||||
|
*
|
||||||
|
* @param ruleSetNames List of names of the selected rule sets.
|
||||||
|
* @param tempDir Path of the directory to put the compiled rule files.
|
||||||
|
*
|
||||||
|
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
|
||||||
|
*/
|
||||||
|
static void compileRules(List<String> ruleSetNames, Path outputDir) throws IngestModuleException {
|
||||||
|
if (ruleSetNames == null || ruleSetNames.isEmpty()) {
|
||||||
|
throw new IngestModule.IngestModuleException(Bundle.YaraIngestModule_no_ruleSets());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find javac
|
||||||
|
File exeFile = InstalledFileLocator.getDefault().locate(
|
||||||
|
Paths.get(YARA_DIR, YARA_C_EXE).toString(),
|
||||||
|
YaraIngestModule.class.getPackage().getName(), false);
|
||||||
|
|
||||||
|
if (exeFile == null) {
|
||||||
|
throw new IngestModuleException(Bundle.YaraIngestModule_yarac_not_found());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RuleSet set : getRuleSetsForNames(ruleSetNames)) {
|
||||||
|
compileRuleSet(set, outputDir, exeFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan the given AbstractFile for yara rule matches from the rule sets in
|
||||||
|
* the given directory creating a blackboard artifact for each matching
|
||||||
|
* rule.
|
||||||
|
*
|
||||||
|
* The baseDirectory should contain a series of directories one for each
|
||||||
|
* rule set.
|
||||||
|
*
|
||||||
|
* @param file The file to scan.
|
||||||
|
* @param baseDirectory Base directory for the compiled rule sets.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
static List<BlackboardArtifact> scanFileForMatches(AbstractFile file, File baseDirectory) throws TskCoreException, YaraWrapperException {
|
||||||
|
List<BlackboardArtifact> artifacts = new ArrayList<>();
|
||||||
|
|
||||||
|
byte[] fileBytes = new byte[(int) file.getSize()];
|
||||||
|
file.read(fileBytes, 0, fileBytes.length);
|
||||||
|
|
||||||
|
File[] ruleSetDirectories = baseDirectory.listFiles();
|
||||||
|
for (File ruleSetDirectory : ruleSetDirectories) {
|
||||||
|
List<String> ruleMatches = YaraIngestHelper.scanFileForMatches(fileBytes, ruleSetDirectory);
|
||||||
|
if (!ruleMatches.isEmpty()) {
|
||||||
|
artifacts.addAll(YaraIngestHelper.createArtifact(file, ruleSetDirectory.getName(), ruleMatches));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return artifacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scan the given file byte array for rule matches using the YaraJNIWrapper
|
||||||
|
* API.
|
||||||
|
*
|
||||||
|
* @param fileBytes
|
||||||
|
* @param ruleSetDirectory
|
||||||
|
*
|
||||||
|
* @return List of rules that match from the given file from the given rule
|
||||||
|
* set. Empty list is returned if no matches where found.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
private static List<String> scanFileForMatches(byte[] fileBytes, File ruleSetDirectory) throws TskCoreException, YaraWrapperException {
|
||||||
|
List<String> matchingRules = new ArrayList<>();
|
||||||
|
|
||||||
|
File[] ruleSetCompiledFileList = ruleSetDirectory.listFiles();
|
||||||
|
|
||||||
|
for (File ruleFile : ruleSetCompiledFileList) {
|
||||||
|
matchingRules.addAll(YaraJNIWrapper.findRuleMatch(ruleFile.getAbsolutePath(), fileBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return matchingRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a list of Blackboard Artifacts, one for each matching rule.
|
||||||
|
*
|
||||||
|
* @param abstractFile File to add artifact to.
|
||||||
|
* @param ruleSetName Name rule set with matching rule.
|
||||||
|
* @param matchingRules Matching rule.
|
||||||
|
*
|
||||||
|
* @return List of artifacts or empty list if none were found.
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
private static List<BlackboardArtifact> createArtifact(AbstractFile abstractFile, String ruleSetName, List<String> matchingRules) throws TskCoreException {
|
||||||
|
List<BlackboardArtifact> artifacts = new ArrayList<>();
|
||||||
|
for (String rule : matchingRules) {
|
||||||
|
BlackboardArtifact artifact = abstractFile.newArtifact(TSK_YARA_HIT);
|
||||||
|
List<BlackboardAttribute> attributes = new ArrayList<>();
|
||||||
|
|
||||||
|
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME, ruleSetName));
|
||||||
|
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_CATEGORY, MODULE_NAME, rule));
|
||||||
|
|
||||||
|
artifact.addAttributes(attributes);
|
||||||
|
artifacts.add(artifact);
|
||||||
|
}
|
||||||
|
return artifacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"YaraIngestModule_yarac_not_found=Unable to compile YARA rules files. Unable to find executable at.",
|
||||||
|
"YaraIngestModule_no_ruleSets=Unable to run YARA ingest, list of YARA rule sets was empty."
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles the rule files in the given rule set.
|
||||||
|
*
|
||||||
|
* The compiled rule files are created in outputDir\RuleSetName.
|
||||||
|
*
|
||||||
|
* @param set RuleSet for which to compile files.
|
||||||
|
* @param outputDir Output directory for the compiled rule files.
|
||||||
|
* @param yarac yarac executeable file.
|
||||||
|
*
|
||||||
|
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
|
||||||
|
*/
|
||||||
|
static private void compileRuleSet(RuleSet set, Path outputDir, File yarac) throws IngestModuleException {
|
||||||
|
File tempFolder = Paths.get(outputDir.toString(), set.getName()).toFile();
|
||||||
|
if (!tempFolder.exists()) {
|
||||||
|
tempFolder.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<File> fileList = set.getRuleFiles();
|
||||||
|
for (File file : fileList) {
|
||||||
|
List<String> commandList = new ArrayList<>();
|
||||||
|
commandList.add(String.format("\"%s\"", yarac.toString()));
|
||||||
|
commandList.add(String.format("\"%s\"", file.toString()));
|
||||||
|
commandList.add(String.format("\"%s\"", Paths.get(tempFolder.getAbsolutePath(), "compiled_" + file.getName())));
|
||||||
|
|
||||||
|
ProcessBuilder builder = new ProcessBuilder(commandList);
|
||||||
|
try {
|
||||||
|
ExecUtil.execute(builder);
|
||||||
|
} catch (SecurityException | IOException ex) {
|
||||||
|
throw new IngestModuleException(String.format("Failed to compile Yara rules file", file.toString()), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of RuleSet objects for the given list of RuleSet names.
|
||||||
|
*
|
||||||
|
* @param names List of RuleSet names.
|
||||||
|
*
|
||||||
|
* @return List of RuleSet or empty list if none of the names matched
|
||||||
|
* existing rules.
|
||||||
|
*/
|
||||||
|
private static List<RuleSet> getRuleSetsForNames(List<String> names) {
|
||||||
|
List<RuleSet> ruleSetList = new ArrayList<>();
|
||||||
|
|
||||||
|
RuleSetManager manager = new RuleSetManager();
|
||||||
|
for (RuleSet set : manager.getRuleSetList()) {
|
||||||
|
if (names.contains(set.getName())) {
|
||||||
|
ruleSetList.add(set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ruleSetList;
|
||||||
|
}
|
||||||
|
}
|
106
Core/src/org/sleuthkit/autopsy/modules/yara/YaraIngestJobSettings.java
Executable file
106
Core/src/org/sleuthkit/autopsy/modules/yara/YaraIngestJobSettings.java
Executable file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.yara;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.modules.yara.rules.RuleSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IngestJobSettings for the YARA ingest module.
|
||||||
|
*/
|
||||||
|
public final class YaraIngestJobSettings implements IngestModuleIngestJobSettings {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private List<String> selectedRuleSetNames;
|
||||||
|
private boolean onlyExecutableFiles;
|
||||||
|
|
||||||
|
// Default constructor.
|
||||||
|
YaraIngestJobSettings() {
|
||||||
|
onlyExecutableFiles = true;
|
||||||
|
selectedRuleSetNames = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param selected List of selected rules.
|
||||||
|
* @param onlyExecutableFiles Process only executable files.
|
||||||
|
*/
|
||||||
|
public YaraIngestJobSettings(List<RuleSet> selected, boolean onlyExecutableFiles) {
|
||||||
|
this.selectedRuleSetNames = new ArrayList<>();
|
||||||
|
|
||||||
|
for (RuleSet set : selected) {
|
||||||
|
selectedRuleSetNames.add(set.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onlyExecutableFiles = onlyExecutableFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of rule name sets that were selected in the ingest
|
||||||
|
* settings panel.
|
||||||
|
*
|
||||||
|
* @return List of selected RuleSet names.
|
||||||
|
*/
|
||||||
|
public List<String> getSelectedRuleSetNames() {
|
||||||
|
return Collections.unmodifiableList(selectedRuleSetNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the list of selected rule names.
|
||||||
|
*
|
||||||
|
* @param selected List of selected rule Sets.
|
||||||
|
*/
|
||||||
|
void setSelectedRuleSetNames(List<RuleSet> selected) {
|
||||||
|
this.selectedRuleSetNames = new ArrayList<>();
|
||||||
|
for (RuleSet set : selected) {
|
||||||
|
selectedRuleSetNames.add(set.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process only executable Files.
|
||||||
|
*
|
||||||
|
* @return If true the ingest module should process only executable files,
|
||||||
|
* if false process all files.
|
||||||
|
*/
|
||||||
|
public boolean onlyExecutableFiles() {
|
||||||
|
return onlyExecutableFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to process only executable files or all files.
|
||||||
|
*
|
||||||
|
* @param onlyExecutableFiles True if the ingest module should only process
|
||||||
|
* executable files.
|
||||||
|
*/
|
||||||
|
void setOnlyExecuteableFile(boolean onlyExecutableFiles) {
|
||||||
|
this.onlyExecutableFiles = onlyExecutableFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getVersionNumber() {
|
||||||
|
return serialVersionUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
168
Core/src/org/sleuthkit/autopsy/modules/yara/YaraIngestModule.java
Executable file
168
Core/src/org/sleuthkit/autopsy/modules/yara/YaraIngestModule.java
Executable file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.yara;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
|
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModuleAdapter;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
|
||||||
|
import org.sleuthkit.autopsy.yara.YaraWrapperException;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.Blackboard;
|
||||||
|
import org.sleuthkit.datamodel.Blackboard.BlackboardException;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ingest module that runs the yara against the given files.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class YaraIngestModule extends FileIngestModuleAdapter {
|
||||||
|
|
||||||
|
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
|
||||||
|
private final static Logger logger = Logger.getLogger(YaraIngestModule.class.getName());
|
||||||
|
private static final String YARA_DIR = "yara";
|
||||||
|
private static final Map<Long, Path> pathsByJobId = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private final YaraIngestJobSettings settings;
|
||||||
|
|
||||||
|
private IngestJobContext context = null;
|
||||||
|
private Long jobId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param settings
|
||||||
|
*/
|
||||||
|
YaraIngestModule(YaraIngestJobSettings settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"YaraIngestModule_windows_error_msg=The YARA ingest module is only available on 64bit Windows.",})
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startUp(IngestJobContext context) throws IngestModuleException {
|
||||||
|
this.context = context;
|
||||||
|
this.jobId = context.getJobId();
|
||||||
|
|
||||||
|
if (!PlatformUtil.isWindowsOS() || !PlatformUtil.is64BitOS()) {
|
||||||
|
throw new IngestModule.IngestModuleException(Bundle.YaraIngestModule_windows_error_msg());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refCounter.incrementAndGet(jobId) == 1) {
|
||||||
|
// compile the selected rules & put into temp folder based on jobID
|
||||||
|
Path tempDir = getTempDirectory(jobId);
|
||||||
|
|
||||||
|
YaraIngestHelper.compileRules(settings.getSelectedRuleSetNames(), tempDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutDown() {
|
||||||
|
if (context != null && refCounter.decrementAndGet(jobId) == 0) {
|
||||||
|
// do some clean up.
|
||||||
|
Path jobPath = pathsByJobId.get(jobId);
|
||||||
|
if (jobPath != null) {
|
||||||
|
jobPath.toFile().delete();
|
||||||
|
pathsByJobId.remove(jobId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProcessResult process(AbstractFile file) {
|
||||||
|
|
||||||
|
if (settings.onlyExecutableFiles()) {
|
||||||
|
String extension = file.getNameExtension();
|
||||||
|
if (!extension.equals("exe")) {
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the file if its 0 in length.
|
||||||
|
if (file.getSize() == 0) {
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<BlackboardArtifact> artifacts = YaraIngestHelper.scanFileForMatches(file, getTempDirectory(jobId).toFile());
|
||||||
|
|
||||||
|
if(!artifacts.isEmpty()) {
|
||||||
|
Blackboard blackboard = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard();
|
||||||
|
blackboard.postArtifacts(artifacts, YaraIngestModuleFactory.getModuleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (BlackboardException | NoCurrentCaseException | IngestModuleException | TskCoreException | YaraWrapperException ex) {
|
||||||
|
logger.log(Level.SEVERE, "YARA ingest module failed to process file.", ex);
|
||||||
|
return ProcessResult.ERROR;
|
||||||
|
}
|
||||||
|
return ProcessResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the temp directory for this jobId. If the folder does not exit it
|
||||||
|
* will be created.
|
||||||
|
*
|
||||||
|
* @param jobId The current jobId
|
||||||
|
*
|
||||||
|
* @return The path of the temporary directory for the given jobId.
|
||||||
|
*
|
||||||
|
* @throws org.sleuthkit.autopsy.ingest.IngestModule.IngestModuleException
|
||||||
|
*/
|
||||||
|
private synchronized Path getTempDirectory(long jobId) throws IngestModuleException {
|
||||||
|
Path jobPath = pathsByJobId.get(jobId);
|
||||||
|
if (jobPath != null) {
|
||||||
|
return jobPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path baseDir;
|
||||||
|
try {
|
||||||
|
baseDir = Paths.get(Case.getCurrentCaseThrows().getTempDirectory(), YARA_DIR);
|
||||||
|
} catch (NoCurrentCaseException ex) {
|
||||||
|
throw new IngestModuleException("Failed to create YARA ingest model temp directory, no open case.", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the base yara directory, as needed
|
||||||
|
if (!baseDir.toFile().exists()) {
|
||||||
|
baseDir.toFile().mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
String randomDirName = String.format("%s_%d", RandomStringUtils.randomAlphabetic(8), jobId);
|
||||||
|
jobPath = Paths.get(baseDir.toString(), randomDirName);
|
||||||
|
jobPath.toFile().mkdir();
|
||||||
|
|
||||||
|
pathsByJobId.put(jobId, jobPath);
|
||||||
|
|
||||||
|
return jobPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
92
Core/src/org/sleuthkit/autopsy/modules/yara/YaraIngestModuleFactory.java
Executable file
92
Core/src/org/sleuthkit/autopsy/modules/yara/YaraIngestModuleFactory.java
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.yara;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
import org.openide.util.lookup.ServiceProvider;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
|
import org.sleuthkit.autopsy.ingest.FileIngestModule;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactory;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||||
|
import org.sleuthkit.autopsy.modules.yara.ui.YaraIngestSettingsPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory that creates ingest modules that use the Yara rule set definitions
|
||||||
|
* to identify files that may be of interest to the user.
|
||||||
|
*/
|
||||||
|
@ServiceProvider(service = IngestModuleFactory.class)
|
||||||
|
public class YaraIngestModuleFactory extends IngestModuleFactoryAdapter {
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"Yara_Module_Name=YARA",
|
||||||
|
"Yara_Module_Description=With the YARA ingest module you use YARA rule files to search files for textual or binary patterns."
|
||||||
|
})
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleDisplayName() {
|
||||||
|
return getModuleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleDescription() {
|
||||||
|
return Bundle.Yara_Module_Description();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModuleVersionNumber() {
|
||||||
|
return Version.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasIngestJobSettingsPanel() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettingsPanel getIngestJobSettingsPanel(IngestModuleIngestJobSettings settings) {
|
||||||
|
return new YaraIngestSettingsPanel((YaraIngestJobSettings)settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettings getDefaultIngestJobSettings() {
|
||||||
|
return new YaraIngestJobSettings(new ArrayList<>(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFileIngestModuleFactory() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings settings) {
|
||||||
|
return new YaraIngestModule((YaraIngestJobSettings) settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the ingest module.
|
||||||
|
*
|
||||||
|
* @return Ingest module name.
|
||||||
|
*/
|
||||||
|
static String getModuleName() {
|
||||||
|
return Bundle.Yara_Module_Name();
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
package org.sleuthkit.autopsy.modules.yara.rules;
|
package org.sleuthkit.autopsy.modules.yara.rules;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -26,7 +27,9 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* Represents a yara rule set which is a collection of yara rule files.
|
* Represents a yara rule set which is a collection of yara rule files.
|
||||||
*/
|
*/
|
||||||
public class RuleSet implements Comparable<RuleSet> {
|
public class RuleSet implements Comparable<RuleSet>, Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Path path;
|
private final Path path;
|
||||||
|
@ -8,3 +8,7 @@ RuleSetDetailsPanel.setDetailsLabel.text=Set Details
|
|||||||
RuleSetDetailsPanel.openFolderButton.text=Open Folder
|
RuleSetDetailsPanel.openFolderButton.text=Open Folder
|
||||||
RuleSetPanel.descriptionField.text=This module allows you to find files the match Yara rules. Each set has a list of Yara rule files. A file need only match one rule in the set to be found.
|
RuleSetPanel.descriptionField.text=This module allows you to find files the match Yara rules. Each set has a list of Yara rule files. A file need only match one rule in the set to be found.
|
||||||
RuleSetDetailsPanel.openLabel.text=Place rule files in the set's folder. They will be compiled before use.
|
RuleSetDetailsPanel.openLabel.text=Place rule files in the set's folder. They will be compiled before use.
|
||||||
|
YaraIngestSettingsPanel.border.title=Select YARA rule sets to enable during ingest:
|
||||||
|
YaraIngestSettingsPanel.allFilesButton.text=All Files
|
||||||
|
YaraIngestSettingsPanel.allFilesButton.toolTipText=
|
||||||
|
YaraIngestSettingsPanel.executableFilesButton.text=Only Executable Files
|
||||||
|
@ -10,6 +10,10 @@ RuleSetDetailsPanel.setDetailsLabel.text=Set Details
|
|||||||
RuleSetDetailsPanel.openFolderButton.text=Open Folder
|
RuleSetDetailsPanel.openFolderButton.text=Open Folder
|
||||||
RuleSetPanel.descriptionField.text=This module allows you to find files the match Yara rules. Each set has a list of Yara rule files. A file need only match one rule in the set to be found.
|
RuleSetPanel.descriptionField.text=This module allows you to find files the match Yara rules. Each set has a list of Yara rule files. A file need only match one rule in the set to be found.
|
||||||
RuleSetDetailsPanel.openLabel.text=Place rule files in the set's folder. They will be compiled before use.
|
RuleSetDetailsPanel.openLabel.text=Place rule files in the set's folder. They will be compiled before use.
|
||||||
|
YaraIngestSettingsPanel.border.title=Select YARA rule sets to enable during ingest:
|
||||||
|
YaraIngestSettingsPanel.allFilesButton.text=All Files
|
||||||
|
YaraIngestSettingsPanel.allFilesButton.toolTipText=
|
||||||
|
YaraIngestSettingsPanel.executableFilesButton.text=Only Executable Files
|
||||||
# {0} - rule set name
|
# {0} - rule set name
|
||||||
YaraRuleSetOptionPanel_badName_msg=Rule set name {0} already exists.\nRule set names must be unique.
|
YaraRuleSetOptionPanel_badName_msg=Rule set name {0} already exists.\nRule set names must be unique.
|
||||||
YaraRuleSetOptionPanel_badName_title=Create Rule Set
|
YaraRuleSetOptionPanel_badName_title=Create Rule Set
|
||||||
|
87
Core/src/org/sleuthkit/autopsy/modules/yara/ui/YaraIngestSettingsPanel.form
Executable file
87
Core/src/org/sleuthkit/autopsy/modules/yara/ui/YaraIngestSettingsPanel.form
Executable file
@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<NonVisualComponents>
|
||||||
|
<Component class="javax.swing.ButtonGroup" name="buttonGroup">
|
||||||
|
</Component>
|
||||||
|
</NonVisualComponents>
|
||||||
|
<Properties>
|
||||||
|
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||||
|
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
|
||||||
|
<TitledBorder title="Select YARA rule sets to enable during ingest:">
|
||||||
|
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/modules/yara/ui/Bundle.properties" key="YaraIngestSettingsPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</TitledBorder>
|
||||||
|
</Border>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="scrollPane">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="18" weightX="1.0" weightY="1.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
</Container>
|
||||||
|
<Container class="javax.swing.JPanel" name="buttonPanel">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JRadioButton" name="allFilesButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||||
|
<ComponentRef name="buttonGroup"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/yara/ui/Bundle.properties" key="YaraIngestSettingsPanel.allFilesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/yara/ui/Bundle.properties" key="YaraIngestSettingsPanel.allFilesButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JRadioButton" name="executableFilesButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
|
||||||
|
<ComponentRef name="buttonGroup"/>
|
||||||
|
</Property>
|
||||||
|
<Property name="selected" type="boolean" value="true"/>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/modules/yara/ui/Bundle.properties" key="YaraIngestSettingsPanel.executableFilesButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
182
Core/src/org/sleuthkit/autopsy/modules/yara/ui/YaraIngestSettingsPanel.java
Executable file
182
Core/src/org/sleuthkit/autopsy/modules/yara/ui/YaraIngestSettingsPanel.java
Executable file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2020 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.modules.yara.ui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.swing.DefaultListModel;
|
||||||
|
import org.sleuthkit.autopsy.guicomponeontutils.AbstractCheckboxListItem;
|
||||||
|
import org.sleuthkit.autopsy.guiutils.CheckBoxJList;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettingsPanel;
|
||||||
|
import org.sleuthkit.autopsy.modules.yara.YaraIngestJobSettings;
|
||||||
|
import org.sleuthkit.autopsy.modules.yara.rules.RuleSet;
|
||||||
|
import org.sleuthkit.autopsy.modules.yara.rules.RuleSetManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Yara Ingest settings panel.
|
||||||
|
*/
|
||||||
|
public class YaraIngestSettingsPanel extends IngestModuleIngestJobSettingsPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final CheckBoxJList<RuleSetListItem> checkboxList;
|
||||||
|
private final DefaultListModel<RuleSetListItem> listModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form YaraIngestSettingsPanel
|
||||||
|
*/
|
||||||
|
YaraIngestSettingsPanel() {
|
||||||
|
initComponents();
|
||||||
|
listModel = new DefaultListModel<>();
|
||||||
|
checkboxList = new CheckBoxJList<>();
|
||||||
|
scrollPane.setViewportView(checkboxList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public YaraIngestSettingsPanel(YaraIngestJobSettings settings) {
|
||||||
|
this();
|
||||||
|
|
||||||
|
List<String> setNames = settings.getSelectedRuleSetNames();
|
||||||
|
|
||||||
|
checkboxList.setModel(listModel);
|
||||||
|
checkboxList.setOpaque(false);
|
||||||
|
RuleSetManager manager = new RuleSetManager();
|
||||||
|
List<RuleSet> ruleSetList = manager.getRuleSetList();
|
||||||
|
for (RuleSet set : ruleSetList) {
|
||||||
|
RuleSetListItem item = new RuleSetListItem(set);
|
||||||
|
item.setChecked(setNames.contains(set.getName()));
|
||||||
|
listModel.addElement(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
allFilesButton.setSelected(!settings.onlyExecutableFiles());
|
||||||
|
executableFilesButton.setSelected(settings.onlyExecutableFiles());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IngestModuleIngestJobSettings getSettings() {
|
||||||
|
List<RuleSet> selectedRules = new ArrayList<>();
|
||||||
|
|
||||||
|
Enumeration<RuleSetListItem> enumeration = listModel.elements();
|
||||||
|
while (enumeration.hasMoreElements()) {
|
||||||
|
RuleSetListItem item = enumeration.nextElement();
|
||||||
|
if (item.isChecked()) {
|
||||||
|
selectedRules.add(item.getRuleSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new YaraIngestJobSettings(selectedRules, executableFilesButton.isSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RuleSet wrapper class for Checkbox JList model.
|
||||||
|
*/
|
||||||
|
private final class RuleSetListItem extends AbstractCheckboxListItem {
|
||||||
|
|
||||||
|
private final RuleSet ruleSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RuleSetListItem constructor.
|
||||||
|
*
|
||||||
|
* @param set RuleSet object to display in list.
|
||||||
|
*/
|
||||||
|
RuleSetListItem(RuleSet set) {
|
||||||
|
this.ruleSet = set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the RuleSet.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
RuleSet getRuleSet() {
|
||||||
|
return ruleSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return ruleSet.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
java.awt.GridBagConstraints gridBagConstraints;
|
||||||
|
|
||||||
|
buttonGroup = new javax.swing.ButtonGroup();
|
||||||
|
scrollPane = new javax.swing.JScrollPane();
|
||||||
|
buttonPanel = new javax.swing.JPanel();
|
||||||
|
allFilesButton = new javax.swing.JRadioButton();
|
||||||
|
executableFilesButton = new javax.swing.JRadioButton();
|
||||||
|
|
||||||
|
setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(YaraIngestSettingsPanel.class, "YaraIngestSettingsPanel.border.title"))); // NOI18N
|
||||||
|
setLayout(new java.awt.GridBagLayout());
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.weighty = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(0, 5, 5, 5);
|
||||||
|
add(scrollPane, gridBagConstraints);
|
||||||
|
|
||||||
|
buttonPanel.setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
buttonGroup.add(allFilesButton);
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(allFilesButton, org.openide.util.NbBundle.getMessage(YaraIngestSettingsPanel.class, "YaraIngestSettingsPanel.allFilesButton.text")); // NOI18N
|
||||||
|
allFilesButton.setToolTipText(org.openide.util.NbBundle.getMessage(YaraIngestSettingsPanel.class, "YaraIngestSettingsPanel.allFilesButton.toolTipText")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
buttonPanel.add(allFilesButton, gridBagConstraints);
|
||||||
|
|
||||||
|
buttonGroup.add(executableFilesButton);
|
||||||
|
executableFilesButton.setSelected(true);
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(executableFilesButton, org.openide.util.NbBundle.getMessage(YaraIngestSettingsPanel.class, "YaraIngestSettingsPanel.executableFilesButton.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
||||||
|
buttonPanel.add(executableFilesButton, gridBagConstraints);
|
||||||
|
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 1;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
add(buttonPanel, gridBagConstraints);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JRadioButton allFilesButton;
|
||||||
|
private javax.swing.ButtonGroup buttonGroup;
|
||||||
|
private javax.swing.JPanel buttonPanel;
|
||||||
|
private javax.swing.JRadioButton executableFilesButton;
|
||||||
|
private javax.swing.JScrollPane scrollPane;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
@ -179,9 +179,7 @@ is divided into following sections:
|
|||||||
</and>
|
</and>
|
||||||
</condition>
|
</condition>
|
||||||
<condition property="have.tests">
|
<condition property="have.tests">
|
||||||
<or>
|
<or/>
|
||||||
<available file="${test.src.dir}"/>
|
|
||||||
</or>
|
|
||||||
</condition>
|
</condition>
|
||||||
<condition property="have.sources">
|
<condition property="have.sources">
|
||||||
<or>
|
<or>
|
||||||
@ -289,7 +287,6 @@ is divided into following sections:
|
|||||||
</target>
|
</target>
|
||||||
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
|
<target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
|
||||||
<fail unless="src.dir">Must set src.dir</fail>
|
<fail unless="src.dir">Must set src.dir</fail>
|
||||||
<fail unless="test.src.dir">Must set test.src.dir</fail>
|
|
||||||
<fail unless="build.dir">Must set build.dir</fail>
|
<fail unless="build.dir">Must set build.dir</fail>
|
||||||
<fail unless="dist.dir">Must set dist.dir</fail>
|
<fail unless="dist.dir">Must set dist.dir</fail>
|
||||||
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
|
<fail unless="build.classes.dir">Must set build.classes.dir</fail>
|
||||||
@ -588,9 +585,6 @@ is divided into following sections:
|
|||||||
<j2seproject3:junit-prototype>
|
<j2seproject3:junit-prototype>
|
||||||
<customizePrototype>
|
<customizePrototype>
|
||||||
<batchtest todir="${build.test.results.dir}">
|
<batchtest todir="${build.test.results.dir}">
|
||||||
<fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
|
|
||||||
<filename name="@{testincludes}"/>
|
|
||||||
</fileset>
|
|
||||||
<fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
|
<fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
|
||||||
<filename name="${test.binarytestincludes}"/>
|
<filename name="${test.binarytestincludes}"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
@ -613,11 +607,7 @@ is divided into following sections:
|
|||||||
<condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
|
<condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
|
||||||
<isset property="test.method"/>
|
<isset property="test.method"/>
|
||||||
</condition>
|
</condition>
|
||||||
<union id="test.set">
|
<union id="test.set"/>
|
||||||
<fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
|
|
||||||
<filename name="@{testincludes}"/>
|
|
||||||
</fileset>
|
|
||||||
</union>
|
|
||||||
<taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
|
<taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
|
||||||
<testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="YaraJNIWrapper" testname="TestNG tests" workingDir="${work.dir}">
|
<testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="YaraJNIWrapper" testname="TestNG tests" workingDir="${work.dir}">
|
||||||
<xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
|
<xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
|
||||||
@ -1544,14 +1534,14 @@ is divided into following sections:
|
|||||||
<!-- You can override this target in the ../build.xml file. -->
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
</target>
|
</target>
|
||||||
<target depends="-init-source-module-properties" if="named.module.internal" name="-init-test-javac-module-properties-with-module">
|
<target depends="-init-source-module-properties" if="named.module.internal" name="-init-test-javac-module-properties-with-module">
|
||||||
<j2seproject3:modulename property="test.module.name" sourcepath="${test.src.dir}"/>
|
<j2seproject3:modulename property="test.module.name" sourcepath=""/>
|
||||||
<condition else="${empty.dir}" property="javac.test.sourcepath" value="${test.src.dir}">
|
<condition else="${empty.dir}" property="javac.test.sourcepath" value="">
|
||||||
<and>
|
<and>
|
||||||
<isset property="test.module.name"/>
|
<isset property="test.module.name"/>
|
||||||
<length length="0" string="${test.module.name}" when="greater"/>
|
<length length="0" string="${test.module.name}" when="greater"/>
|
||||||
</and>
|
</and>
|
||||||
</condition>
|
</condition>
|
||||||
<condition else="--patch-module ${module.name}=${test.src.dir} --add-reads ${module.name}=ALL-UNNAMED" property="javac.test.compilerargs" value="--add-reads ${test.module.name}=ALL-UNNAMED">
|
<condition else="--patch-module ${module.name}= --add-reads ${module.name}=ALL-UNNAMED" property="javac.test.compilerargs" value="--add-reads ${test.module.name}=ALL-UNNAMED">
|
||||||
<and>
|
<and>
|
||||||
<isset property="test.module.name"/>
|
<isset property="test.module.name"/>
|
||||||
<length length="0" string="${test.module.name}" when="greater"/>
|
<length length="0" string="${test.module.name}" when="greater"/>
|
||||||
@ -1592,17 +1582,15 @@ is divided into following sections:
|
|||||||
</target>
|
</target>
|
||||||
<target depends="-init-test-javac-module-properties-with-module,-init-test-module-properties-without-module" name="-init-test-module-properties"/>
|
<target depends="-init-test-javac-module-properties-with-module,-init-test-module-properties-without-module" name="-init-test-module-properties"/>
|
||||||
<target if="do.depend.true" name="-compile-test-depend">
|
<target if="do.depend.true" name="-compile-test-depend">
|
||||||
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
|
<j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir=""/>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
|
<target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
|
||||||
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${javac.test.sourcepath}" srcdir="${test.src.dir}">
|
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${javac.test.sourcepath}" srcdir="">
|
||||||
<customize>
|
<customize>
|
||||||
<compilerarg line="${javac.test.compilerargs}"/>
|
<compilerarg line="${javac.test.compilerargs}"/>
|
||||||
</customize>
|
</customize>
|
||||||
</j2seproject3:javac>
|
</j2seproject3:javac>
|
||||||
<copy todir="${build.test.classes.dir}">
|
<copy todir="${build.test.classes.dir}"/>
|
||||||
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
|
||||||
</copy>
|
|
||||||
</target>
|
</target>
|
||||||
<target name="-post-compile-test">
|
<target name="-post-compile-test">
|
||||||
<!-- Empty placeholder for easier customization. -->
|
<!-- Empty placeholder for easier customization. -->
|
||||||
@ -1616,14 +1604,12 @@ is divided into following sections:
|
|||||||
<target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
|
<target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
|
||||||
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||||
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
|
<j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
|
||||||
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}, module-info.java" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}">
|
<j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}, module-info.java" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="" srcdir="">
|
||||||
<customize>
|
<customize>
|
||||||
<compilerarg line="${javac.test.compilerargs}"/>
|
<compilerarg line="${javac.test.compilerargs}"/>
|
||||||
</customize>
|
</customize>
|
||||||
</j2seproject3:javac>
|
</j2seproject3:javac>
|
||||||
<copy todir="${build.test.classes.dir}">
|
<copy todir="${build.test.classes.dir}"/>
|
||||||
<fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
|
||||||
</copy>
|
|
||||||
</target>
|
</target>
|
||||||
<target name="-post-compile-test-single">
|
<target name="-post-compile-test-single">
|
||||||
<!-- Empty placeholder for easier customization. -->
|
<!-- Empty placeholder for easier customization. -->
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
annotation.processing.enabled=true
|
annotation.processing.enabled=true
|
||||||
annotation.processing.enabled.in.editor=false
|
annotation.processing.enabled.in.editor=false
|
||||||
annotation.processing.processor.options=
|
|
||||||
annotation.processing.processors.list=
|
annotation.processing.processors.list=
|
||||||
annotation.processing.run.all.processors=true
|
annotation.processing.run.all.processors=true
|
||||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||||
|
application.title=YaraJNIWrapper
|
||||||
|
application.vendor=kelly
|
||||||
build.classes.dir=${build.dir}/classes
|
build.classes.dir=${build.dir}/classes
|
||||||
build.classes.excludes=**/*.java,**/*.form
|
build.classes.excludes=**/*.java,**/*.form
|
||||||
# This directory is removed when the project is cleaned:
|
# This directory is removed when the project is cleaned:
|
||||||
@ -32,10 +33,13 @@ dist.jar=${dist.dir}/YaraJNIWrapper.jar
|
|||||||
dist.javadoc.dir=${dist.dir}/javadoc
|
dist.javadoc.dir=${dist.dir}/javadoc
|
||||||
dist.jlink.dir=${dist.dir}/jlink
|
dist.jlink.dir=${dist.dir}/jlink
|
||||||
dist.jlink.output=${dist.jlink.dir}/YaraJNIWrapper
|
dist.jlink.output=${dist.jlink.dir}/YaraJNIWrapper
|
||||||
|
endorsed.classpath=
|
||||||
excludes=
|
excludes=
|
||||||
|
file.reference.yara-lib=src/org/sleuthkit/autopsy/yara/lib
|
||||||
includes=**
|
includes=**
|
||||||
jar.compress=false
|
jar.compress=false
|
||||||
javac.classpath=
|
javac.classpath=\
|
||||||
|
${file.reference.yara-lib}
|
||||||
# Space-separated list of extra javac options
|
# Space-separated list of extra javac options
|
||||||
javac.compilerargs=
|
javac.compilerargs=
|
||||||
javac.deprecation=false
|
javac.deprecation=false
|
||||||
@ -90,4 +94,3 @@ run.test.modulepath=\
|
|||||||
${javac.test.modulepath}
|
${javac.test.modulepath}
|
||||||
source.encoding=UTF-8
|
source.encoding=UTF-8
|
||||||
src.dir=src
|
src.dir=src
|
||||||
test.src.dir=test
|
|
||||||
|
@ -7,9 +7,7 @@
|
|||||||
<source-roots>
|
<source-roots>
|
||||||
<root id="src.dir"/>
|
<root id="src.dir"/>
|
||||||
</source-roots>
|
</source-roots>
|
||||||
<test-roots>
|
<test-roots/>
|
||||||
<root id="test.src.dir"/>
|
|
||||||
</test-roots>
|
|
||||||
</data>
|
</data>
|
||||||
</configuration>
|
</configuration>
|
||||||
</project>
|
</project>
|
||||||
|
@ -18,9 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.yara;
|
package org.sleuthkit.autopsy.yara;
|
||||||
|
|
||||||
import java.net.URISyntaxException;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.io.FileOutputStream;
|
||||||
import java.nio.file.Paths;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -31,18 +33,12 @@ import java.util.logging.Logger;
|
|||||||
*/
|
*/
|
||||||
public class YaraJNIWrapper {
|
public class YaraJNIWrapper {
|
||||||
|
|
||||||
// Load the yarabridge.dll which should be located in the same directory as
|
|
||||||
// the jar file. If we need to use this code for debugging the dll this
|
|
||||||
// code will need to be modified to add that support.
|
|
||||||
static {
|
static {
|
||||||
Path directoryPath = null;
|
|
||||||
try {
|
try {
|
||||||
directoryPath = Paths.get(YaraJNIWrapper.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent().toAbsolutePath();
|
extractAndLoadDll();
|
||||||
} catch (URISyntaxException ex) {
|
} catch (IOException | YaraWrapperException ex) {
|
||||||
Logger.getLogger(YaraJNIWrapper.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(YaraJNIWrapper.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
String libraryPath = Paths.get(directoryPath != null ? directoryPath.toString() : "", "yarabridge.dll").toAbsolutePath().toString();
|
|
||||||
System.load(libraryPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +55,36 @@ public class YaraJNIWrapper {
|
|||||||
*/
|
*/
|
||||||
static public native List<String> findRuleMatch(String compiledRulesPath, byte[] byteBuffer) throws YaraWrapperException;
|
static public native List<String> findRuleMatch(String compiledRulesPath, byte[] byteBuffer) throws YaraWrapperException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy yarabridge.dll from inside the jar to a temp file that can be loaded
|
||||||
|
* with System.load.
|
||||||
|
*
|
||||||
|
* To make this work, the dll needs to be in the same folder as this source
|
||||||
|
* file. The dll needs to be located somewhere in the jar class path.
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
* @throws YaraWrapperException
|
||||||
|
*/
|
||||||
|
static private void extractAndLoadDll() throws IOException, YaraWrapperException {
|
||||||
|
File tempFile = File.createTempFile("lib", null);
|
||||||
|
tempFile.deleteOnExit();
|
||||||
|
try (InputStream in = YaraJNIWrapper.class.getResourceAsStream("yarabridge.dll")) {
|
||||||
|
if (in == null) {
|
||||||
|
throw new YaraWrapperException("native library was not found in jar file.");
|
||||||
|
}
|
||||||
|
try (OutputStream out = new FileOutputStream(tempFile)) {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int lengthRead;
|
||||||
|
while ((lengthRead = in.read(buffer)) > 0) {
|
||||||
|
out.write(buffer, 0, lengthRead);
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.load(tempFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* private constructor.
|
* private constructor.
|
||||||
*/
|
*/
|
||||||
|
BIN
thirdparty/yara/YaraJNIWrapper/src/org/sleuthkit/autopsy/yara/yarabridge.dll
vendored
Executable file
BIN
thirdparty/yara/YaraJNIWrapper/src/org/sleuthkit/autopsy/yara/yarabridge.dll
vendored
Executable file
Binary file not shown.
@ -35,7 +35,7 @@ dist.jlink.dir=${dist.dir}/jlink
|
|||||||
dist.jlink.output=${dist.jlink.dir}/YaraWrapperTest
|
dist.jlink.output=${dist.jlink.dir}/YaraWrapperTest
|
||||||
endorsed.classpath=
|
endorsed.classpath=
|
||||||
excludes=
|
excludes=
|
||||||
file.reference.YaraJNIWrapper.jar=../bin/YaraJNIWrapper.jar
|
file.reference.YaraJNIWrapper.jar=../YaraJNIWrapper/dist/YaraJNIWrapper.jar
|
||||||
includes=**
|
includes=**
|
||||||
jar.compress=false
|
jar.compress=false
|
||||||
javac.classpath=\
|
javac.classpath=\
|
||||||
|
BIN
thirdparty/yara/bin/YaraJNIWrapper.jar
vendored
BIN
thirdparty/yara/bin/YaraJNIWrapper.jar
vendored
Binary file not shown.
BIN
thirdparty/yara/bin/yarabridge.dll
vendored
BIN
thirdparty/yara/bin/yarabridge.dll
vendored
Binary file not shown.
BIN
thirdparty/yara/bin/yarac64.exe
vendored
Executable file
BIN
thirdparty/yara/bin/yarac64.exe
vendored
Executable file
Binary file not shown.
@ -113,7 +113,7 @@
|
|||||||
<AdditionalDependencies>ws2_32.lib;crypt32.lib;libyara64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>ws2_32.lib;crypt32.lib;libyara64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy "$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName).dll" "$(SolutionDir)..\bin\$(ProjectName).dll"</Command>
|
<Command>copy "$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName).dll" "$(SolutionDir)..\YaraJNIWrapper\src\org\sleuthkit\autopsy\yara\$(ProjectName).dll"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@ -153,7 +153,7 @@
|
|||||||
<AdditionalDependencies>ws2_32.lib;crypt32.lib;libyara64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>ws2_32.lib;crypt32.lib;libyara64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy "$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName).dll" "$(SolutionDir)..\bin\$(ProjectName).dll"</Command>
|
<Command>copy "$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName).dll" "$(SolutionDir)..\YaraJNIWrapper\src\org\sleuthkit\autopsy\yara\$(ProjectName).dll"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user