diff --git a/contributors.txt b/contributors.txt index 03c81c17..95d6f486 100644 --- a/contributors.txt +++ b/contributors.txt @@ -1,7 +1,6 @@ Hayabusa was possible thanks to the following people (in alphabetical order): Akira Nishikawa (@nishikawaakira): Previous lead developer, core hayabusa rule support, etc... -DustInDark(@hitenkoku): Core Developer Garigariganzy (@garigariganzy31): Developer, event ID statistics implementation, etc... ItiB (@itiB_S144) : Core developer, sigmac hayabusa backend, rule creation, etc... James Takai / hachiyone(@hach1yon): Current lead developer, tokio multi-threading, sigma aggregation logic, sigmac backend, rule creation, sigma count implementation etc… @@ -14,7 +13,6 @@ Hayabusa would not have been possible without first creating RustyBlue, so we wo Zach Mathis (@yamatosecurity, Yamato Security Founder): Project Leader Nishikawa Akira (@nishikawaakira): Lead Developer -DustInDark (@hitenkoku): Core Developer kazuminn (@k47_um1n): Core Developer itiB (@itiB_S144): Core Developer James Takai / hachiyone (@hach1yon): Core Developer diff --git a/logs/.gitkeep b/logs/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/detections/detection.rs b/src/detections/detection.rs index 77fa1e76..f7807364 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -2,7 +2,7 @@ extern crate csv; use crate::detections::configs; use crate::detections::print::AlertMessage; -use crate::detections::print::ERROR_LOG_PATH; +use crate::detections::print::ERROR_LOG_STACK; use crate::detections::print::MESSAGES; use crate::detections::print::QUIET_ERRORS_FLAG; use crate::detections::rule; @@ -14,7 +14,6 @@ use crate::yaml::ParseYaml; use hashbrown; use serde_json::Value; use std::collections::HashMap; -use std::fs::OpenOptions; use std::io::BufWriter; use std::sync::Arc; use tokio::{runtime::Runtime, spawn, task::JoinHandle}; @@ -66,16 +65,10 @@ impl Detection { AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok(); } if !*QUIET_ERRORS_FLAG { - AlertMessage::alert( - &mut BufWriter::new( - OpenOptions::new() - .append(true) - .open(ERROR_LOG_PATH.to_string()) - .unwrap(), - ), - &errmsg, - ) - .ok(); + ERROR_LOG_STACK + .lock() + .unwrap() + .push(format!("[ERROR] {}", errmsg)); } return vec![]; } @@ -93,7 +86,7 @@ impl Detection { AlertMessage::warn(&mut std::io::stdout().lock(), &errmsg_body).ok(); err_msgs.iter().for_each(|err_msg| { - AlertMessage::warn(&mut std::io::stdout().lock(), &err_msg.to_string()).ok(); + AlertMessage::warn(&mut std::io::stdout().lock(), err_msg).ok(); }); parseerror_count += 1; println!(""); // 一行開けるためのprintln diff --git a/src/detections/print.rs b/src/detections/print.rs index d7ddab4e..380c2858 100644 --- a/src/detections/print.rs +++ b/src/detections/print.rs @@ -46,6 +46,7 @@ lazy_static! { .unwrap() .args .is_present("quiet-errors"); + pub static ref ERROR_LOG_STACK: Mutex> = Mutex::new(Vec::new()); } impl Message { @@ -203,24 +204,30 @@ impl AlertMessage { if !path.parent().unwrap().exists() { create_dir(path.parent().unwrap()).ok(); } - // 1行目は必ず実行したコマンド情報を入れておく。 - let mut ret = BufWriter::new(File::create(path).unwrap()); - - ret.write( - format!( - "user input: {:?}\n", - format_args!( - "{}", - env::args() - .map(|arg| arg) - .collect::>() - .join(" ") + let mut error_log_writer = BufWriter::new(File::create(path).unwrap()); + error_log_writer + .write( + format!( + "user input: {:?}\n", + format_args!( + "{}", + env::args() + .map(|arg| arg) + .collect::>() + .join(" ") + ) ) + .as_bytes(), ) - .as_bytes(), - ) - .unwrap(); - ret.flush().ok(); + .unwrap(); + for error_log in ERROR_LOG_STACK.lock().unwrap().iter() { + writeln!(error_log_writer, "{}", error_log).ok(); + } + println!( + "Errors were generated. Please check {} for details.", + ERROR_LOG_PATH.to_string() + ); + println!(""); } /// ERRORメッセージを表示する関数 @@ -232,18 +239,6 @@ impl AlertMessage { pub fn warn(w: &mut W, contents: &String) -> io::Result<()> { writeln!(w, "[WARN] {}", contents) } - - /// エラーログへのERRORメッセージの出力数を確認して、0であったらファイルを削除する。1以上あればエラーを書き出した旨を標準出力に表示する - pub fn output_error_log_exist() { - if *QUIET_ERRORS_FLAG { - return; - } - println!( - "Errors were generated. Please check {} for details.", - ERROR_LOG_PATH.to_string() - ); - println!(""); - } } #[cfg(test)] diff --git a/src/detections/rule/count.rs b/src/detections/rule/count.rs index b49759ec..5a29752b 100644 --- a/src/detections/rule/count.rs +++ b/src/detections/rule/count.rs @@ -1,6 +1,6 @@ use crate::detections::configs; use crate::detections::print::AlertMessage; -use crate::detections::print::ERROR_LOG_PATH; +use crate::detections::print::ERROR_LOG_STACK; use crate::detections::print::QUIET_ERRORS_FLAG; use crate::detections::rule::AggResult; use crate::detections::rule::AggregationParseInfo; @@ -9,7 +9,6 @@ use crate::detections::rule::RuleNode; use chrono::{DateTime, TimeZone, Utc}; use hashbrown::HashMap; use serde_json::Value; -use std::fs::OpenOptions; use std::io::BufWriter; use std::num::ParseIntError; use std::path::Path; @@ -95,16 +94,10 @@ fn get_alias_value_in_record( AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok(); } if !*QUIET_ERRORS_FLAG { - AlertMessage::alert( - &mut BufWriter::new( - OpenOptions::new() - .append(true) - .open(ERROR_LOG_PATH.to_string()) - .unwrap(), - ), - &errmsg, - ) - .ok(); + ERROR_LOG_STACK + .lock() + .unwrap() + .push(format!("[ERROR] {}", errmsg)); } return None; } @@ -203,16 +196,10 @@ impl TimeFrameInfo { AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok(); } if !*QUIET_ERRORS_FLAG { - AlertMessage::alert( - &mut BufWriter::new( - OpenOptions::new() - .append(true) - .open(ERROR_LOG_PATH.to_string()) - .unwrap(), - ), - &errmsg, - ) - .ok(); + ERROR_LOG_STACK + .lock() + .unwrap() + .push(format!("[ERROR] {}", errmsg)); } } return TimeFrameInfo { @@ -246,16 +233,10 @@ pub fn get_sec_timeframe(timeframe: &Option) -> Option { AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok(); } if !*QUIET_ERRORS_FLAG { - AlertMessage::alert( - &mut BufWriter::new( - OpenOptions::new() - .append(true) - .open(ERROR_LOG_PATH.to_string()) - .unwrap(), - ), - &errmsg, - ) - .ok(); + ERROR_LOG_STACK + .lock() + .unwrap() + .push(format!("[ERROR] {}", errmsg.to_string())); } return Option::None; } diff --git a/src/main.rs b/src/main.rs index a4c89a77..31cc573c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use evtx::{EvtxParser, ParserSettings}; use hayabusa::detections::detection::{self, EvtxRecordInfo}; use hayabusa::detections::print::AlertMessage; use hayabusa::detections::print::ERROR_LOG_PATH; +use hayabusa::detections::print::ERROR_LOG_STACK; use hayabusa::detections::print::QUIET_ERRORS_FLAG; use hayabusa::detections::rule::{get_detection_keys, RuleNode}; use hayabusa::filter; @@ -18,7 +19,6 @@ use pbr::ProgressBar; use serde_json::Value; use std::collections::{HashMap, HashSet}; use std::fmt::Display; -use std::fs::OpenOptions; use std::io::BufWriter; use std::path::Path; use std::sync::Arc; @@ -84,14 +84,6 @@ impl App { return; } } - if !configs::CONFIG - .read() - .unwrap() - .args - .is_present("quiet-errors") - { - AlertMessage::create_error_log(ERROR_LOG_PATH.to_string()); - } if let Some(filepath) = configs::CONFIG.read().unwrap().args.value_of("filepath") { if !filepath.ends_with(".evtx") { AlertMessage::alert( @@ -126,7 +118,11 @@ impl App { let analysis_duration = analysis_end_time.signed_duration_since(analysis_start_time); println!("Elapsed Time: {}", &analysis_duration.hhmmssxxx()); println!(""); - AlertMessage::output_error_log_exist(); + + // Qオプションを付けた場合もしくはパースのエラーがない場合はerrorのstackが9となるのでエラーログファイル自体が生成されない。 + if ERROR_LOG_STACK.lock().unwrap().len() > 0 { + AlertMessage::create_error_log(ERROR_LOG_PATH.to_string()); + } } fn collect_evtxfiles(&self, dirpath: &str) -> Vec { @@ -137,16 +133,10 @@ impl App { AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok(); } if !*QUIET_ERRORS_FLAG { - AlertMessage::alert( - &mut BufWriter::new( - OpenOptions::new() - .append(true) - .open(ERROR_LOG_PATH.to_string()) - .unwrap(), - ), - &errmsg, - ) - .ok(); + ERROR_LOG_STACK + .lock() + .unwrap() + .push(format!("[ERROR] {}", errmsg)); } return vec![]; } @@ -255,16 +245,10 @@ impl App { .ok(); } if !*QUIET_ERRORS_FLAG { - AlertMessage::alert( - &mut BufWriter::new( - OpenOptions::new() - .append(true) - .open(ERROR_LOG_PATH.to_string()) - .unwrap(), - ), - &errmsg, - ) - .ok(); + ERROR_LOG_STACK + .lock() + .unwrap() + .push(format!("[ERROR] {}", errmsg)); } continue; } diff --git a/src/yaml.rs b/src/yaml.rs index bb59143c..005ceedf 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -3,13 +3,12 @@ extern crate yaml_rust; use crate::detections::configs; use crate::detections::print::AlertMessage; -use crate::detections::print::ERROR_LOG_PATH; +use crate::detections::print::ERROR_LOG_STACK; use crate::detections::print::QUIET_ERRORS_FLAG; use crate::filter::RuleExclude; use std::collections::HashMap; use std::ffi::OsStr; use std::fs; -use std::fs::OpenOptions; use std::io; use std::io::BufWriter; use std::io::{BufReader, Read}; @@ -84,15 +83,10 @@ impl ParseYaml { AlertMessage::warn(&mut BufWriter::new(std::io::stderr().lock()), &errmsg)?; } if !*QUIET_ERRORS_FLAG { - AlertMessage::warn( - &mut BufWriter::new( - OpenOptions::new() - .append(true) - .open(ERROR_LOG_PATH.to_string()) - .unwrap(), - ), - &errmsg, - )?; + ERROR_LOG_STACK + .lock() + .unwrap() + .push(format!("[WARN] {}", errmsg)); } self.errorrule_count += 1; return io::Result::Ok(ret); @@ -110,15 +104,10 @@ impl ParseYaml { AlertMessage::warn(&mut BufWriter::new(std::io::stderr().lock()), &errmsg)?; } if !*QUIET_ERRORS_FLAG { - AlertMessage::warn( - &mut BufWriter::new( - OpenOptions::new() - .append(true) - .open(ERROR_LOG_PATH.to_string()) - .unwrap(), - ), - &errmsg, - )?; + ERROR_LOG_STACK + .lock() + .unwrap() + .push(format!("[WARN] {}", errmsg)); } self.errorrule_count += 1; return io::Result::Ok(ret);