#scanner #ioc #dionysos #regex #buffer #thread #filenames

已删除 dionysos-provider-derive

dionysos的 derive crate:用于多种IoC的Scanner

0.1.2 2022年1月24日
0.1.0 2022年1月22日

#28#filenames

GPL-3.0 许可证

5KB
50 代码行

Crates.io Crates.io Crates.io (latest) GitHub Workflow Status GitHub Workflow Status GitHub Workflow Status Codecov

dionysos

多种IoC的Scanner

安装

sudo apt install libyara-dev
cargo install dionysos

功能

功能 详情
扫描器 filenames(正则表达式),相似filenames(Levenshtein),yara,哈希值
输出格式 可读文本(txt),逗号分隔值(csv,符合RFC4180),JavaScript对象表示法(json),可以使用--format <txt|csv|json>选择
压缩文件扫描 支持zip、xz、gz和bz2压缩文件的yara-scan;请参阅-C选项。请注意,文件将被解压缩到解压缩缓冲区,每个线程都有自己的解压缩缓冲区。请确保您有足够的内存。如果您需要更大的缓冲区,可以使用--threads限制线程数。
特殊功能 使用--evtx--reg在Windows evtx文件和Windows注册表分区内进行yara-scan

用法

Usage: dionysos [OPTIONS]

Options:
  -v, --verbose...
          Increase logging verbosity
  -q, --quiet...
          Decrease logging verbosity
  -P, --path <PATH>
          path which must be scanned
  -f, --format <OUTPUT_FORMAT>
          output format [default: txt] [possible values: csv, txt, json]
  -O, --output-file <OUTPUT_FILE>
          path of the file to write results to. Specify '-' write to STDOUT,
          which is the default
  -Y, --yara <YARA>
          use yara scanner with the specified ruleset. This can be a single
          file, a zip file or a directory containing lots of yara files. Yara
          files must end with 'yar' or 'yara', and zip files must end with 'zip'
      --yara-timeout <YARA_TIMEOUT>
          timeout for the yara scanner, in seconds [default: 240]
  -s, --print-strings
          print matching strings (only used by yara currently)
      --evtx
          also do YARA scan in Windows EVTX records (exported as JSON)
      --reg
          also do YARA scan in Windows registry hive files
  -C, --scan-compressed
          allow yara to scan compressed files. Currently, xz, bz2 and gz are
          supported
      --decompression-buffer <DECOMPRESSION_BUFFER_SIZE>
          maximum size (in MiB) of decompression buffer (per thread), which is
          used to scan compressed files [default: 128]
      --exclude-pattern <EXCLUDE_PATTERN>
          do not scan files whose names match the specified regular expression
          (case sensitive match)
  -H, --file-hash <FILE_HASH>
          Hash of file to match against. Use any of MD5, SHA1 or SHA256. This
          parameter can be specified multiple times
  -F, --filename <FILENAMES>
          regular expression to match against the basename of files. This
          parameter can be specified multiple times
      --levenshtein
          run the Levenshtein scanner
  -p, --threads <THREADS>
          use the specified NUMBER of threads [default: 24]
      --progress
          display a progress bar (requires counting the number of files to be
          scanned before a progress bar can be displayed)
  -L, --log-file <LOG_FILE>
          path of the file to write error logs to. Error logs will always be
          appended Be aware that this are not the results (e.g. matching yara
          rules) of this program
  -h, --help
          Print help
  -V, --version
          Print version

开发者指南

如何添加扫描器

1. 为扫描器实现特殊的结果类型

例如,假设我们想要扫描匹配正则表达式的文件。我们的查找类型可能看起来像这样

struct FilenameFinding {
    filename: String,
    pattern: regex::Regex,
}

每个查找类型都需要实现DisplayScannerFinding

impl ScannerFinding for FilenameFinding {

    fn format_readable(&self, file: &str, _show_details: bool) -> Vec<String> {
        vec![
            format!("the name of '{}' matches the pattern /{}/", file, self.pattern)
        ]
    }

    fn format_csv<'a, 'b>(&'b self, file: &'a str) -> HashSet<crate::scanner_result::CsvLine> {
        hashset![CsvLine::new("Filename", &self.filename, file, String::new())]
    }

    fn to_json(&self, file: &str) -> serde_json::Value {
        json!({
            "01_scanner": "filename",
            "02_suspicious_file": file,
            "03_pattern": format!("{}", self.pattern)
        })
    }
}

2. 扫描器的实现

FilenameScanner为例,它尝试执行简单的文件名匹配

pub struct FilenameScanner {
    patterns: Vec<regex::Regex>,
}

impl FilenameScanner {
    pub fn new(patterns: Vec<regex::Regex>) -> Self {
        Self {   
            patterns,
        }
    }
}

impl Display for FilenameScanner {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", "FilenameScanner")
    }
}

impl FileScanner for FilenameScanner
{
    fn scan_file(&self, file: &DirEntry) -> Vec<anyhow::Result<Box<dyn ScannerFinding>>> {
        let file = file.path();
        let filename = file.to_str().unwrap();
        let mut results = Vec::new();
        for pattern in self.patterns.iter() {
            if pattern.is_match(&filename) {
                results.push(
                    Ok(
                        Box::new(
                            FilenameFinding{
                                filename: filename.to_owned(),
                                pattern: pattern.clone()
                            }
                        ) as Box<dyn ScannerFinding>
                    )
                )
            }
        }
        results
    }
}

3. 将您的扫描器添加到扫描器链中

它目前硬编码在Dionysos::run()中(在src/dionysos.rs

依赖项

~1.5MB
~35K SLoC