37 个版本 (18 个稳定版)

1.2.6 2024年2月28日
1.2.4 2023年5月22日
1.2.0 2023年3月2日
1.1.0 2022年12月15日
0.1.4 2022年1月28日

#217文件系统

Download history 3/week @ 2024-05-31 1/week @ 2024-06-07 2/week @ 2024-06-28 44/week @ 2024-07-05 99/week @ 2024-07-26 12/week @ 2024-08-02

每月下载量:111

GPL-3.0 许可证

370KB
2K SLoC

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

dionysos

各种 IoC 的扫描器

安装

sudo apt install libyara-dev
cargo install dionysos

功能

功能 详细信息
扫描器 文件名(正则表达式),相似文件名(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)中

依赖关系

~21–34MB
~576K SLoC