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