diff --git a/src/afterfact.rs b/src/afterfact.rs index 9a84b2ff..076e5578 100644 --- a/src/afterfact.rs +++ b/src/afterfact.rs @@ -43,9 +43,14 @@ pub struct Colors { /// level_color.txtファイルを読み込み対応する文字色のマッピングを返却する関数 pub fn set_output_color() -> HashMap { let read_result = utils::read_csv( - utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "config/level_color.txt") - .to_str() - .unwrap(), + utils::check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "config/level_color.txt", + true, + ) + .unwrap() + .to_str() + .unwrap(), ); let mut color_map: HashMap = HashMap::new(); if configs::CONFIG.read().unwrap().args.no_color { diff --git a/src/detections/configs.rs b/src/detections/configs.rs index feda62a4..13cd7a4c 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -52,7 +52,7 @@ impl Default for ConfigReader<'_> { } } -#[derive(Parser)] +#[derive(Parser, Clone)] #[clap( name = "Hayabusa", usage = "hayabusa.exe [OTHER-ACTIONS] [OPTIONS]", @@ -242,23 +242,33 @@ impl ConfigReader<'_> { .help_template("\n\nUSAGE:\n {usage}\n\nOPTIONS:\n{options}"); ConfigReader { app: build_cmd, - args: parse, + args: parse.clone(), headless_help: String::default(), event_timeline_config: load_eventcode_info( - utils::check_setting_path( - &CURRENT_EXE_PATH.to_path_buf(), - "rules/config/statistics_event_info.txt", - ) - .to_str() - .unwrap(), + utils::check_setting_path(&parse.config, "statistics_event_info.txt", false) + .unwrap_or_else(|| { + utils::check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "rules/config/statistics_event_info.txt", + true, + ) + .unwrap() + }) + .to_str() + .unwrap(), ), target_eventids: load_target_ids( - utils::check_setting_path( - &CURRENT_EXE_PATH.to_path_buf(), - "rules/config/target_event_IDs.txt", - ) - .to_str() - .unwrap(), + utils::check_setting_path(&parse.config, "target_event_IDs.txt", false) + .unwrap_or_else(|| { + utils::check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "rules/config/target_event_IDs.txt", + true, + ) + .unwrap() + }) + .to_str() + .unwrap(), ), } } diff --git a/src/detections/message.rs b/src/detections/message.rs index 9aff48c5..e3a3d235 100644 --- a/src/detections/message.rs +++ b/src/detections/message.rs @@ -49,30 +49,32 @@ lazy_static! { pub static ref STATISTICS_FLAG: bool = configs::CONFIG.read().unwrap().args.statistics; pub static ref LOGONSUMMARY_FLAG: bool = configs::CONFIG.read().unwrap().args.logon_summary; pub static ref TAGS_CONFIG: HashMap = create_output_filter_config( - utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "config/mitre_tactics.txt") - .to_str() + utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "config/mitre_tactics.txt", true) + .unwrap().to_str() .unwrap(), ); pub static ref CH_CONFIG: HashMap = create_output_filter_config( - utils::check_setting_path( - &CURRENT_EXE_PATH.to_path_buf(), - "rules/config/channel_abbreviations.txt" - ) + utils::check_setting_path(&configs::CONFIG.read().unwrap().args.config, "channel_abbreviations.txt", false).unwrap_or_else(|| { + utils::check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "rules/config/channel_abbreviations.txt", true + ).unwrap() + }) .to_str() .unwrap(), ); pub static ref PIVOT_KEYWORD_LIST_FLAG: bool = configs::CONFIG.read().unwrap().args.pivot_keywords_list; - pub static ref DEFAULT_DETAILS: HashMap = get_default_details(&format!( - "{}/default_details.txt", - configs::CONFIG - .read() - .unwrap() - .args - .config - .as_path() - .display() - )); + pub static ref DEFAULT_DETAILS: HashMap = get_default_details( + utils::check_setting_path(&configs::CONFIG.read().unwrap().args.config, "default_details.txt", false).unwrap_or_else(|| { + utils::check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "rules/config/default_details.txt", true + ).unwrap() + }) + .to_str() + .unwrap() + ); pub static ref LEVEL_ABBR: LinkedHashMap = LinkedHashMap::from_iter([ ("critical".to_string(), "crit".to_string()), ("high".to_string(), "high".to_string()), diff --git a/src/detections/utils.rs b/src/detections/utils.rs index d678bb07..aa01e624 100644 --- a/src/detections/utils.rs +++ b/src/detections/utils.rs @@ -73,7 +73,8 @@ pub fn value_to_string(value: &Value) -> Option { pub fn read_txt(filename: &str) -> Result, String> { let filepath = if filename.starts_with("./") { - check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), filename) + check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), filename, true) + .unwrap() .to_str() .unwrap() .to_string() @@ -380,11 +381,13 @@ pub fn make_ascii_titlecase(s: &mut str) -> String { } /// base_path/path が存在するかを確認し、存在しなければカレントディレクトリを参照するpathを返す関数 -pub fn check_setting_path(base_path: &Path, path: &str) -> PathBuf { +pub fn check_setting_path(base_path: &Path, path: &str, ignore_err: bool) -> Option { if base_path.join(path).exists() { - base_path.join(path) + Some(base_path.join(path)) + } else if ignore_err { + Some(Path::new(path).to_path_buf()) } else { - Path::new(path).to_path_buf() + None } } @@ -613,23 +616,31 @@ mod tests { let exist_path = Path::new("./test_files").to_path_buf(); let not_exist_path = Path::new("not_exist_path").to_path_buf(); assert_eq!( - check_setting_path(¬_exist_path, "rules") + check_setting_path(¬_exist_path, "rules", true) + .unwrap() .to_str() .unwrap(), "rules" ); assert_eq!( - check_setting_path(¬_exist_path, "fake") + check_setting_path(¬_exist_path, "fake", true) + .unwrap() .to_str() .unwrap(), "fake" ); assert_eq!( - check_setting_path(&exist_path, "rules").to_str().unwrap(), + check_setting_path(&exist_path, "rules", true) + .unwrap() + .to_str() + .unwrap(), exist_path.join("rules").to_str().unwrap() ); assert_eq!( - check_setting_path(&exist_path, "fake").to_str().unwrap(), + check_setting_path(&exist_path, "fake", true) + .unwrap() + .to_str() + .unwrap(), "fake" ); } diff --git a/src/main.rs b/src/main.rs index 539b8973..230e4bd6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,8 +7,8 @@ use bytesize::ByteSize; use chrono::{DateTime, Datelike, Local}; use evtx::{EvtxParser, ParserSettings}; use hashbrown::{HashMap, HashSet}; -use hayabusa::detections::configs::CURRENT_EXE_PATH; use hayabusa::detections::configs::{load_pivot_keywords, TargetEventTime, TARGET_EXTENSIONS}; +use hayabusa::detections::configs::{CONFIG, CURRENT_EXE_PATH}; use hayabusa::detections::detection::{self, EvtxRecordInfo}; use hayabusa::detections::message::{ AlertMessage, ERROR_LOG_PATH, ERROR_LOG_STACK, LOGONSUMMARY_FLAG, PIVOT_KEYWORD_LIST_FLAG, @@ -80,7 +80,9 @@ impl App { utils::check_setting_path( &CURRENT_EXE_PATH.to_path_buf(), "config/pivot_keywords.txt", + true, ) + .unwrap() .to_str() .unwrap(), ); @@ -148,13 +150,15 @@ impl App { // カレントディレクトリ以外からの実行の際にrules-configオプションの指定がないとエラーが発生することを防ぐための処理 if configs::CONFIG.read().unwrap().args.config == Path::new("./rules/config") { configs::CONFIG.write().unwrap().args.config = - utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "./rules/config"); + utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "./rules/config", true) + .unwrap(); } // カレントディレクトリ以外からの実行の際にrulesオプションの指定がないとエラーが発生することを防ぐための処理 if configs::CONFIG.read().unwrap().args.rules == Path::new("./rules") { configs::CONFIG.write().unwrap().args.rules = - utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "./rules"); + utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "./rules", true) + .unwrap(); } if let Some(csv_path) = &configs::CONFIG.read().unwrap().args.output { @@ -264,9 +268,18 @@ impl App { let level_tuning_config_path = match level_tuning_val { Some(path) => path.to_owned(), _ => utils::check_setting_path( - &CURRENT_EXE_PATH.to_path_buf(), - "./rules/config/level_tuning.txt", + &CONFIG.read().unwrap().args.config, + "level_tuning.txt", + false, ) + .unwrap_or_else(|| { + utils::check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "./rules/config/level_tuning.txt", + true, + ) + .unwrap() + }) .display() .to_string(), }; @@ -469,10 +482,10 @@ impl App { } fn print_contributors(&self) { - match fs::read_to_string(utils::check_setting_path( - &CURRENT_EXE_PATH.to_path_buf(), - "contributors.txt", - )) { + match fs::read_to_string( + utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "contributors.txt", true) + .unwrap(), + ) { Ok(contents) => { write_color_buffer( &BufferWriter::stdout(ColorChoice::Always), @@ -721,7 +734,10 @@ impl App { /// output logo fn output_logo(&self) { - let fp = utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "art/logo.txt"); + println!("dbg output start"); + println!("dbg | {}", &CURRENT_EXE_PATH.to_path_buf().display()); + let fp = utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "art/logo.txt", true) + .unwrap(); let content = fs::read_to_string(fp).unwrap_or_default(); let output_color = if configs::CONFIG.read().unwrap().args.no_color { None @@ -748,7 +764,8 @@ impl App { match eggs.get(exec_datestr) { None => {} Some(path) => { - let egg_path = utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), path); + let egg_path = + utils::check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), path, true).unwrap(); let content = fs::read_to_string(egg_path).unwrap_or_default(); write_color_buffer( &BufferWriter::stdout(ColorChoice::Always), diff --git a/src/options/profile.rs b/src/options/profile.rs index 70e0e9cf..7483c26f 100644 --- a/src/options/profile.rs +++ b/src/options/profile.rs @@ -15,13 +15,20 @@ lazy_static! { pub static ref PROFILES: Option> = load_profile( check_setting_path( &CURRENT_EXE_PATH.to_path_buf(), - "config/default_profile.yaml" + "config/default_profile.yaml", + true ) + .unwrap() .to_str() .unwrap(), - check_setting_path(&CURRENT_EXE_PATH.to_path_buf(), "config/profiles.yaml") - .to_str() - .unwrap() + check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "config/profiles.yaml", + true + ) + .unwrap() + .to_str() + .unwrap() ); pub static ref LOAEDED_PROFILE_ALIAS: HashSet = HashSet::from_iter( PROFILES