From ae6cc41489ab770b90e301e7d6418459b258edd0 Mon Sep 17 00:00:00 2001 From: DastInDark <2350416+hitenkoku@users.noreply.github.com> Date: Sun, 24 Jul 2022 19:37:15 +0900 Subject: [PATCH] Removed hide-record-id option due to adjusted output of recordID from profile --- src/detections/detection.rs | 5 ---- src/detections/message.rs | 53 +++++++++++++++++++++++++++++++++++-- src/detections/utils.rs | 53 +++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 7 deletions(-) diff --git a/src/detections/detection.rs b/src/detections/detection.rs index daf431e9..6a90a5d5 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -304,11 +304,6 @@ impl Detection { } else { Option::None }; - let rec_id = if !*IS_HIDE_RECORD_ID { - Some(String::default()) - } else { - None - }; let detect_info = DetectInfo { filepath: "-".to_owned(), diff --git a/src/detections/message.rs b/src/detections/message.rs index fd041e20..3acc6315 100644 --- a/src/detections/message.rs +++ b/src/detections/message.rs @@ -72,7 +72,6 @@ lazy_static! { ); pub static ref PIVOT_KEYWORD_LIST_FLAG: bool = configs::CONFIG.read().unwrap().args.pivot_keywords_list; - pub static ref IS_HIDE_RECORD_ID: bool = configs::CONFIG.read().unwrap().args.hide_record_id; pub static ref DEFAULT_DETAILS: HashMap = get_default_details(&format!( "{}/default_details.txt", configs::CONFIG @@ -136,12 +135,62 @@ pub fn insert_message(detect_info: DetectInfo, event_time: DateTime) { /// メッセージを設定 pub fn insert(event_record: &Value, output: String, mut detect_info: DetectInfo) { - detect_info.detail = parse_message(event_record, output); + let parsed_detail =parse_message(event_record, output).chars() + .filter(|&c| !c.is_control()) + .collect::(); + + detect_info.detail = if parsed_detail.is_empty() { + "-".to_string() + } else { + parsed_detail + }; + let default_time = Utc.ymd(1970, 1, 1).and_hms(0, 0, 0); let time = get_event_time(event_record).unwrap_or(default_time); + for (k, v) in detect_info.ext_field.clone() { + let converted_reserve_info = convert_profile_reserved_info(v, detect_info.clone(), time); + detect_info.ext_field.insert(k, parse_message(event_record, converted_reserve_info)); + } insert_message(detect_info, time) } +/// profileで用いられる予約語の情報を変換する関数 +fn convert_profile_reserved_info (output:String, detect_info: DetectInfo, time: DateTime) -> String { + let config_reserved_info:HashMap = HashMap::from([ + ("Timestamp".to_string(), format_time(&time,false)), + ("Computer".to_string(), detect_info.computername), + ("Channel".to_string(), detect_info.channel), + ("Level".to_string(), detect_info.level), + ("EventID".to_string(), detect_info.eventid), + ("MitreAttack".to_string(), detect_info.tag_info), + ("RecordID".to_string(), detect_info.record_id.unwrap_or_else(|| "-".to_string())), + ("RuleTitle".to_string(), detect_info.alert), + ("Details".to_string(), detect_info.detail), + ("RecordInformation".to_string(), detect_info.record_information.unwrap_or_else(|| "-".to_string())), + ("RuleFile".to_string(), detect_info.rulepath), + ("EvtxFile".to_string(), detect_info.filepath), + ]); + let mut ret = output; + let mut convert_target:HashMap = HashMap::new(); + for caps in ALIASREGEX.captures_iter(&ret) { + let full_target_str = &caps[0]; + let target_length = full_target_str.chars().count() - 2; // The meaning of 2 is two percent + let target_str = full_target_str + .chars() + .skip(1) + .take(target_length) + .collect::(); + if let Some(reserved) = config_reserved_info.get(&target_str) { + convert_target.insert(full_target_str.to_string(), reserved.to_string()); + } + } + convert_target.into_iter().for_each(|(k, v)| { + ret = ret.replace(&k, &v); + }); + ret +} + +/// メッセージ内の%で囲まれた箇所をエイリアスとしてをレコード情報を参照して置き換える関数 fn parse_message(event_record: &Value, output: String) -> String { let mut return_message: String = output; let mut hash_map: HashMap = HashMap::new(); diff --git a/src/detections/utils.rs b/src/detections/utils.rs index 1dec5959..40f2c14b 100644 --- a/src/detections/utils.rs +++ b/src/detections/utils.rs @@ -7,6 +7,7 @@ use crate::detections::configs::CURRENT_EXE_PATH; use std::path::Path; use std::path::PathBuf; +use chrono::Local; use termcolor::Color; use tokio::runtime::Builder; @@ -386,6 +387,58 @@ pub fn check_setting_path(base_path: &Path, path: &str) -> PathBuf { } } +///タイムゾーンに合わせた情報を情報を取得する関数 +pub fn format_time(time: &DateTime, date_only: bool) -> String { + if configs::CONFIG.read().unwrap().args.utc { + format_rfc(time, date_only) + } else { + format_rfc(&time.with_timezone(&Local), date_only) + } +} + +/// return rfc time format string by option +fn format_rfc(time: &DateTime, date_only: bool) -> String +where + Tz::Offset: std::fmt::Display, +{ + let time_args = &configs::CONFIG.read().unwrap().args; + if time_args.rfc_2822 { + if date_only { + time.format("%a, %e %b %Y").to_string() + } else { + time.format("%a, %e %b %Y %H:%M:%S %:z").to_string() + } + } else if time_args.rfc_3339 { + if date_only { + time.format("%Y-%m-%d").to_string() + } else { + time.format("%Y-%m-%d %H:%M:%S%.6f%:z").to_string() + } + } else if time_args.us_time { + if date_only { + time.format("%m-%d-%Y").to_string() + } else { + time.format("%m-%d-%Y %I:%M:%S%.3f %p %:z").to_string() + } + } else if time_args.us_military_time { + if date_only { + time.format("%m-%d-%Y").to_string() + } else { + time.format("%m-%d-%Y %H:%M:%S%.3f %:z").to_string() + } + } else if time_args.european_time { + if date_only { + time.format("%d-%m-%Y").to_string() + } else { + time.format("%d-%m-%Y %H:%M:%S%.3f %:z").to_string() + } + } else if date_only { + time.format("%Y-%m-%d").to_string() + } else { + time.format("%Y-%m-%d %H:%M:%S%.3f %:z").to_string() + } +} + #[cfg(test)] mod tests { use std::path::Path;