diff --git a/config/target_eventids.txt b/config/target_eventids.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/detections/configs.rs b/src/detections/configs.rs index c37a41e3..bab9eaf4 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -1,7 +1,7 @@ use crate::detections::utils; use clap::{App, AppSettings, ArgMatches}; use lazy_static::lazy_static; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::sync::RwLock; lazy_static! { pub static ref CONFIG: RwLock = RwLock::new(ConfigReader::new()); @@ -21,6 +21,7 @@ pub struct ConfigReader { pub args: ArgMatches<'static>, pub event_key_alias_config: EventKeyAliasConfig, pub event_timeline_config: EventInfoConfig, + pub target_eventids: TargetEventIds, } impl ConfigReader { @@ -29,6 +30,7 @@ impl ConfigReader { args: build_app(), event_key_alias_config: load_eventkey_alias("config/eventkey_alias.txt"), event_timeline_config: load_eventcode_info("config/timeline_event_info.txt"), + target_eventids: load_target_ids("config/target_eventids.txt"), } } } @@ -80,6 +82,40 @@ fn is_test_mode() -> bool { return false; } +#[derive(Debug, Clone)] +pub struct TargetEventIds { + ids: HashSet, +} + +impl TargetEventIds { + pub fn new() -> TargetEventIds { + return TargetEventIds { + ids: HashSet::new(), + }; + } + + pub fn is_target(&self, id: &String) -> bool { + // 中身が空の場合は全EventIdを対象とする。 + if self.ids.is_empty() { + return true; + } + return self.ids.contains(id); + } +} + +fn load_target_ids(path: &str) -> TargetEventIds { + let mut ret = TargetEventIds::new(); + let lines = utils::read_txt(path).unwrap(); // ファイルが存在しなければエラーとする + for line in lines { + if line.is_empty() { + continue; + } + ret.ids.insert(line); + } + + return ret; +} + #[derive(Debug, Clone)] pub struct EventKeyAliasConfig { key_to_eventkey: HashMap, diff --git a/src/detections/utils.rs b/src/detections/utils.rs index 1bacfe10..f354c3b5 100644 --- a/src/detections/utils.rs +++ b/src/detections/utils.rs @@ -85,6 +85,10 @@ pub fn read_csv(filename: &str) -> Result>, String> { return Result::Ok(ret); } +pub fn is_target_event_id(s: &String) -> bool { + return configs::CONFIG.read().unwrap().target_eventids.is_target(s); +} + pub fn get_event_id_key() -> String { return "Event.System.EventID".to_string(); } diff --git a/src/main.rs b/src/main.rs index 0eb19097..7898036f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ use hayabusa::omikuji::Omikuji; use hayabusa::{afterfact::after_fact, detections::utils}; use hayabusa::{detections::configs, timeline::timeline::Timeline}; use hhmmss::Hhmmss; +use serde_json::Value; use std::{ fs::{self, File}, path::PathBuf, @@ -172,6 +173,21 @@ fn analysis_file( } let data = record_result.unwrap().data; + + // target_eventids.txtでフィルタする。 + let eventid = utils::get_event_value(&utils::get_event_id_key(), &data); + if eventid.is_some() { + let is_target = match eventid.unwrap() { + Value::String(s) => utils::is_target_event_id(s), + Value::Number(n) => utils::is_target_event_id(&n.to_string()), + _ => true, // レコードからEventIdが取得できない場合は、特にフィルタしない + }; + if !is_target { + continue; + } + } + + // EvtxRecordInfo構造体に変更 let data_string = data.to_string(); let record_info = EvtxRecordInfo::new((&filepath_disp).to_string(), data, data_string); records_per_detect.push(record_info);