From 860c318b065edc238818b5e319d264078c1ccd77 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Thu, 23 Nov 2023 22:15:13 +0900 Subject: [PATCH 01/11] feat: added powershell classic data fields extraction option --- src/afterfact.rs | 13 +++ src/detections/configs.rs | 22 +++++ src/detections/detection.rs | 13 ++- src/detections/field_extract.rs | 118 ++++++++++++++++++++++++ src/detections/mod.rs | 1 + src/detections/rule/condition_parser.rs | 4 +- src/detections/rule/count.rs | 13 ++- src/detections/rule/matchers.rs | 4 +- src/detections/rule/mod.rs | 7 +- src/detections/rule/selectionnodes.rs | 4 +- src/detections/utils.rs | 18 +++- src/main.rs | 11 +++ src/options/htmlreport.rs | 4 + src/options/profile.rs | 4 + src/timeline/metrics.rs | 2 + src/timeline/timelines.rs | 6 ++ src/yaml.rs | 1 + 17 files changed, 232 insertions(+), 13 deletions(-) create mode 100644 src/detections/field_extract.rs diff --git a/src/afterfact.rs b/src/afterfact.rs index c56e07e8d..1a68c193c 100644 --- a/src/afterfact.rs +++ b/src/afterfact.rs @@ -1945,6 +1945,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2034,6 +2035,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2273,6 +2275,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2364,6 +2367,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2589,6 +2593,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: true, remove_duplicate_detections: false, no_wizard: true, @@ -2678,6 +2683,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2914,6 +2920,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: true, remove_duplicate_detections: false, no_wizard: true, @@ -3003,6 +3010,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: true, remove_duplicate_detections: false, no_wizard: true, @@ -3324,6 +3332,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -3492,6 +3501,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -3580,6 +3590,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -3757,6 +3768,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -3845,6 +3857,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/configs.rs b/src/detections/configs.rs index 5224b95ca..5b98f1b25 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -83,6 +83,7 @@ pub struct StoredStatic { pub exclude_eid: HashSet, pub include_status: HashSet, // 読み込み対象ルールのステータスのセット。*はすべてのステータスを読み込む pub field_data_map: Option, + pub field_data_extraction: bool, pub enable_recover_records: bool, pub timeline_offset: Option, } @@ -496,6 +497,13 @@ impl StoredStatic { .unwrap(), )) }; + + let field_data_extraction_flag = match &input_config.as_ref().unwrap().action { + Some(Action::CsvTimeline(opt)) => opt.output_options.field_data_extraction, + Some(Action::JsonTimeline(opt)) => opt.output_options.field_data_extraction, + _ => false, + }; + let enable_recover_records = match &input_config.as_ref().unwrap().action { Some(Action::CsvTimeline(opt)) => opt.output_options.input_args.recover_records, Some(Action::JsonTimeline(opt)) => opt.output_options.input_args.recover_records, @@ -629,6 +637,7 @@ impl StoredStatic { include_eid, exclude_eid, field_data_map, + field_data_extraction: field_data_extraction_flag, enable_recover_records, timeline_offset, include_status: HashSet::new(), @@ -1476,6 +1485,10 @@ pub struct OutputOption { #[arg(help_heading = Some("General Options"), short='C', long = "clobber", display_order = 290, requires = "output")] pub clobber: bool, + /// Enable PowerShell Classic Data field extraction (default: disabled) + #[arg(help_heading = Some("Output"), long = "field-data-extraction", display_order = 390)] + pub field_data_extraction: bool, + /// Disable field data mapping #[arg(help_heading = Some("Output"), short = 'F', long = "no-field-data-mapping", display_order = 400)] pub no_field: bool, @@ -2160,6 +2173,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: option.include_eid.clone(), exclude_eid: option.exclude_eid.clone(), no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: option.no_wizard, @@ -2198,6 +2212,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2236,6 +2251,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2283,6 +2299,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2330,6 +2347,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2383,6 +2401,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2436,6 +2455,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2685,6 +2705,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2757,6 +2778,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/detection.rs b/src/detections/detection.rs index 5aa3c0185..e4408b76b 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -1246,6 +1246,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1507,6 +1508,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1559,7 +1561,7 @@ mod tests { let keys = detections::rule::get_detection_keys(&dummy_rule); let input_evtxrecord = - utils::create_rec_info(event, test_filepath.to_owned(), &keys, &false); + utils::create_rec_info(event, test_filepath.to_owned(), &keys, &false, &false); Detection::insert_message(&dummy_rule, &input_evtxrecord, &stored_static); let multi = message::MESSAGES.get(&expect_time).unwrap(); let (_, detect_infos) = multi.pair(); @@ -1642,6 +1644,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1694,7 +1697,7 @@ mod tests { let keys = detections::rule::get_detection_keys(&dummy_rule); let input_evtxrecord = - utils::create_rec_info(event, test_filepath.to_owned(), &keys, &false); + utils::create_rec_info(event, test_filepath.to_owned(), &keys, &false, &false); Detection::insert_message(&dummy_rule, &input_evtxrecord, &stored_static); let multi = message::MESSAGES.get(&expect_time).unwrap(); let (_, detect_infos) = multi.pair(); @@ -1773,6 +1776,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1842,7 +1846,7 @@ mod tests { let keys = detections::rule::get_detection_keys(&rule_node); let input_evtxrecord = - utils::create_rec_info(event, test_filepath.to_owned(), &keys, &false); + utils::create_rec_info(event, test_filepath.to_owned(), &keys, &false, &false); Detection::insert_message(&rule_node, &input_evtxrecord, &stored_static.clone()); let multi = message::MESSAGES.get(&expect_time).unwrap(); let (_, detect_infos) = multi.pair(); @@ -1917,6 +1921,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1987,7 +1992,7 @@ mod tests { let keys = detections::rule::get_detection_keys(&rule_node); let input_evtxrecord = - utils::create_rec_info(event, test_filepath.to_owned(), &keys, &false); + utils::create_rec_info(event, test_filepath.to_owned(), &keys, &false, &false); Detection::insert_message(&rule_node, &input_evtxrecord, &stored_static.clone()); let multi = message::MESSAGES.get(&expect_time).unwrap(); let (_, detect_infos) = multi.pair(); diff --git a/src/detections/field_extract.rs b/src/detections/field_extract.rs new file mode 100644 index 000000000..824e28d28 --- /dev/null +++ b/src/detections/field_extract.rs @@ -0,0 +1,118 @@ +use itertools::enumerate; +use serde_json::Value; + +pub fn extract_fields(channel: Option, event_id: Option, data: &mut Value) { + if let Some(ch) = channel { + if let Some(eid) = event_id { + if ch == "Windows PowerShell" + && (eid == "400" || eid == "403" || eid == "600" || eid == "800") + { + extract_powershell_classic_data_fields(data); + } + } + } +} + +fn extract_powershell_classic_data_fields(data: &mut Value) { + match data { + Value::Object(map) => { + for (_, val) in map { + extract_powershell_classic_data_fields(val); + } + } + Value::Array(vec) => { + for (i, val) in enumerate(vec) { + if i == 2 { + if let Some(powershell_data_str) = val.as_str() { + let map_val: std::collections::HashMap<&str, &str> = powershell_data_str + .trim() + .split("\n\t") + .map(|s| s.trim_end_matches("\r\n")) + .filter_map(|s| s.split_once('=')) + .collect(); + if let Ok(extracted_fields) = serde_json::to_value(map_val) { + *val = extracted_fields + } + } + } + } + } + _ => {} + } +} + +#[cfg(test)] +mod tests { + use crate::detections::field_extract::extract_fields; + use serde_json::Value; + + #[test] + fn test_powershell_classic_data_fields_extraction() { + let record_json_str = r#" +{ + "Event": { + "System": { + "EventID": 400, + "Channel": "Windows PowerShell" + }, + "EventData": { + "Data": [ + "Available", + "None", + "NewEngineState=Available" + ] + } + } +}"#; + + let mut val = serde_json::from_str(record_json_str).unwrap(); + extract_fields( + Some("Windows PowerShell".to_string()), + Some("400".to_string()), + &mut val, + ); + let extracted_fields = val + .get("Event") + .unwrap() + .get("EventData") + .unwrap() + .get("Data") + .unwrap() + .get(2) + .unwrap() + .get("NewEngineState") + .unwrap(); + assert_eq!( + extracted_fields, + &serde_json::Value::String("Available".to_string()) + ); + } + + #[test] + fn test_powershell_classic_data_fields_extraction_data_2_missing() { + let record_json_str = r#" +{ + "Event": { + "System": { + "EventID": 400, + "Channel": "Windows PowerShell" + }, + "EventData": { + "Data": [ + "Available", + "None" + ] + } + } +}"#; + + let original_val: Value = serde_json::from_str(record_json_str).unwrap(); + let mut val = serde_json::from_str(record_json_str).unwrap(); + extract_fields( + Some("Windows PowerShell".to_string()), + Some("400".to_string()), + &mut val, + ); + assert_eq!(original_val, val); + } +} diff --git a/src/detections/mod.rs b/src/detections/mod.rs index 4b528a46a..5f8cc5f37 100644 --- a/src/detections/mod.rs +++ b/src/detections/mod.rs @@ -1,6 +1,7 @@ pub mod configs; pub mod detection; pub mod field_data_map; +pub mod field_extract; pub mod message; pub mod rule; pub mod utils; diff --git a/src/detections/rule/condition_parser.rs b/src/detections/rule/condition_parser.rs index 0af6f71a4..798eca430 100644 --- a/src/detections/rule/condition_parser.rs +++ b/src/detections/rule/condition_parser.rs @@ -606,6 +606,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -632,7 +633,8 @@ mod tests { match serde_json::from_str(record_str) { Ok(record) => { let keys = detections::rule::get_detection_keys(&rule_node); - let recinfo = utils::create_rec_info(record, "testpath".to_owned(), &keys, &false); + let recinfo = + utils::create_rec_info(record, "testpath".to_owned(), &keys, &false, &false); assert_eq!( rule_node.select( &recinfo, diff --git a/src/detections/rule/count.rs b/src/detections/rule/count.rs index 086f6fd13..d09eccc4c 100644 --- a/src/detections/rule/count.rs +++ b/src/detections/rule/count.rs @@ -630,6 +630,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -942,7 +943,8 @@ mod tests { match serde_json::from_str(record) { Ok(rec) => { let keys = detections::rule::get_detection_keys(&rule_node); - let recinfo = utils::create_rec_info(rec, "testpath".to_owned(), &keys, &false); + let recinfo = + utils::create_rec_info(rec, "testpath".to_owned(), &keys, &false, &false); let _result = rule_node.select( &recinfo, dummy_stored_static.verbose_flag, @@ -1717,8 +1719,13 @@ mod tests { match serde_json::from_str(record_str) { Ok(record) => { let keys = detections::rule::get_detection_keys(&rule_node); - let recinfo = - utils::create_rec_info(record, "testpath".to_owned(), &keys, &false); + let recinfo = utils::create_rec_info( + record, + "testpath".to_owned(), + &keys, + &false, + &false, + ); let result = &rule_node.select( &recinfo, dummy_stored_static.verbose_flag, diff --git a/src/detections/rule/matchers.rs b/src/detections/rule/matchers.rs index 5989e238d..602ee5ff3 100644 --- a/src/detections/rule/matchers.rs +++ b/src/detections/rule/matchers.rs @@ -865,6 +865,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -881,7 +882,8 @@ mod tests { match serde_json::from_str(record_str) { Ok(record) => { let keys = detections::rule::get_detection_keys(&rule_node); - let recinfo = utils::create_rec_info(record, "testpath".to_owned(), &keys, &false); + let recinfo = + utils::create_rec_info(record, "testpath".to_owned(), &keys, &false, &false); assert_eq!( rule_node.select( &recinfo, diff --git a/src/detections/rule/mod.rs b/src/detections/rule/mod.rs index 0a734e4f6..3dd5dfcfa 100644 --- a/src/detections/rule/mod.rs +++ b/src/detections/rule/mod.rs @@ -450,6 +450,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -480,7 +481,8 @@ mod tests { match serde_json::from_str(record_str) { Ok(record) => { let keys = detections::rule::get_detection_keys(&rule_node); - let recinfo = utils::create_rec_info(record, "testpath".to_owned(), &keys, &false); + let recinfo = + utils::create_rec_info(record, "testpath".to_owned(), &keys, &false, &false); assert_eq!( rule_node.select( &recinfo, @@ -1049,7 +1051,8 @@ mod tests { match serde_json::from_str(record_str) { Ok(record) => { let keys = detections::rule::get_detection_keys(&rule_node); - let recinfo = utils::create_rec_info(record, "testpath".to_owned(), &keys, &false); + let recinfo = + utils::create_rec_info(record, "testpath".to_owned(), &keys, &false, &false); let result = rule_node.select( &recinfo, dummy_stored_static.verbose_flag, diff --git a/src/detections/rule/selectionnodes.rs b/src/detections/rule/selectionnodes.rs index c9a013940..92dc8635e 100644 --- a/src/detections/rule/selectionnodes.rs +++ b/src/detections/rule/selectionnodes.rs @@ -573,6 +573,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -593,7 +594,8 @@ mod tests { match serde_json::from_str(record_str) { Ok(record) => { let keys = detections::rule::get_detection_keys(&rule_node); - let recinfo = utils::create_rec_info(record, "testpath".to_owned(), &keys, &false); + let recinfo = + utils::create_rec_info(record, "testpath".to_owned(), &keys, &false, &false); assert_eq!( rule_node.select( &recinfo, diff --git a/src/detections/utils.rs b/src/detections/utils.rs index b44006446..110f2bf8f 100644 --- a/src/detections/utils.rs +++ b/src/detections/utils.rs @@ -35,6 +35,7 @@ use super::detection::EvtxRecordInfo; use super::message::AlertMessage; use crate::detections::field_data_map::{convert_field_data, FieldDataMap, FieldDataMapKey}; +use crate::detections::field_extract::extract_fields; use memchr::memmem; pub fn concat_selection_key(key_list: &Nested) -> String { @@ -299,10 +300,11 @@ pub fn create_tokio_runtime(thread_number: Option) -> Runtime { // EvtxRecordInfoを作成します。 pub fn create_rec_info( - data: Value, + mut data: Value, path: String, keys: &Nested, recovered_record: &bool, + enable_field_extraction: &bool, ) -> EvtxRecordInfo { // 高速化のための処理 @@ -315,6 +317,8 @@ pub fn create_rec_info( let binding = STORED_EKEY_ALIAS.read().unwrap(); let eventkey_alias = binding.as_ref().unwrap(); + let mut event_id = None; + let mut channel = None; for key in keys.iter() { let val = get_event_value(key, &data, eventkey_alias); if val.is_none() { @@ -326,8 +330,19 @@ pub fn create_rec_info( continue; } + if *enable_field_extraction { + if key == "EventID" { + event_id = val.clone(); + } + if key == "Channel" { + channel = val.clone(); + } + } key_2_values.insert(key.to_string(), val.unwrap()); } + if *enable_field_extraction { + extract_fields(channel, event_id, &mut data); + } // EvtxRecordInfoを作る let data_str = data.to_string(); @@ -1056,6 +1071,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/main.rs b/src/main.rs index 9589ed500..4d918b302 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1407,6 +1407,7 @@ impl App { records_per_detect, &path, self.rule_keys.to_owned(), + stored_static.field_data_extraction, )); // timeline機能の実行 @@ -1578,6 +1579,7 @@ impl App { records_per_detect, &path, self.rule_keys.to_owned(), + stored_static.field_data_extraction, )); // timeline機能の実行 @@ -1600,7 +1602,9 @@ impl App { records_per_detect: Vec<(Value, bool)>, path: &dyn Display, rule_keys: Nested, + enable_field_extraction: bool, ) -> Vec { + let enable_field_extraction = Arc::new(enable_field_extraction); let path = Arc::new(path.to_string()); let rule_keys = Arc::new(rule_keys); let threads: Vec> = { @@ -1608,12 +1612,14 @@ impl App { |(rec, recovered_record_flag)| -> JoinHandle { let arc_rule_keys = Arc::clone(&rule_keys); let arc_path = Arc::clone(&path); + let arc_enable_field_extraction = Arc::clone(&enable_field_extraction); spawn(async move { utils::create_rec_info( rec, arc_path.to_string(), &arc_rule_keys, &recovered_record_flag, + &arc_enable_field_extraction, ) }) }, @@ -1886,6 +1892,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2048,6 +2055,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2131,6 +2139,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2212,6 +2221,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2295,6 +2305,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/options/htmlreport.rs b/src/options/htmlreport.rs index b8494a09e..e04f60673 100644 --- a/src/options/htmlreport.rs +++ b/src/options/htmlreport.rs @@ -296,6 +296,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -360,6 +361,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -427,6 +429,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -491,6 +494,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/options/profile.rs b/src/options/profile.rs index 1be2f49cd..84304f49d 100644 --- a/src/options/profile.rs +++ b/src/options/profile.rs @@ -473,6 +473,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -598,6 +599,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -673,6 +675,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -778,6 +781,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/timeline/metrics.rs b/src/timeline/metrics.rs index 849c06aba..dd36607fc 100644 --- a/src/timeline/metrics.rs +++ b/src/timeline/metrics.rs @@ -382,6 +382,7 @@ mod tests { "testpath".to_string(), &Nested::::new(), &false, + &false, )); // テスト2: レコードのチャンネル名がaliasに含まれていない場合 @@ -399,6 +400,7 @@ mod tests { "testpath2".to_string(), &Nested::::new(), &false, + &false, )); let include_computer: HashSet = HashSet::new(); diff --git a/src/timeline/timelines.rs b/src/timeline/timelines.rs index 7d9389454..110d4b32b 100644 --- a/src/timeline/timelines.rs +++ b/src/timeline/timelines.rs @@ -583,6 +583,7 @@ mod tests { "testpath".to_string(), &Nested::::new(), &false, + &false, )); timeline .stats @@ -619,6 +620,7 @@ mod tests { "testpath2".to_string(), &Nested::::new(), &false, + &false, )); // テスト3: Event.System.@timestampにタイムスタンプが含まれる場合 @@ -643,6 +645,7 @@ mod tests { "testpath2".to_string(), &Nested::::new(), &false, + &false, )); let mut expect: HashMap< @@ -763,6 +766,7 @@ mod tests { "testpath2".to_string(), &Nested::::new(), &false, + &false, )); let include_computer: HashSet = HashSet::new(); @@ -860,6 +864,7 @@ mod tests { "testpath2".to_string(), &Nested::::new(), &false, + &false, )); let timestamp_attribe_record_str = r#"{ @@ -883,6 +888,7 @@ mod tests { "testpath2".to_string(), &Nested::::new(), &false, + &false, )); timeline diff --git a/src/yaml.rs b/src/yaml.rs index 328df971a..ea61ce074 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -554,6 +554,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, + field_data_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, From 24697f510267cd6ca94d078cab089fee1805e034 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Thu, 23 Nov 2023 23:07:02 +0900 Subject: [PATCH 02/11] chg: extract Data[1] field when eid==800 --- src/detections/field_extract.rs | 55 +++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/detections/field_extract.rs b/src/detections/field_extract.rs index 824e28d28..c7c45337b 100644 --- a/src/detections/field_extract.rs +++ b/src/detections/field_extract.rs @@ -7,22 +7,23 @@ pub fn extract_fields(channel: Option, event_id: Option, data: & if ch == "Windows PowerShell" && (eid == "400" || eid == "403" || eid == "600" || eid == "800") { - extract_powershell_classic_data_fields(data); + let data_field_index = if eid == "800" { 1 } else { 2 }; + extract_powershell_classic_data_fields(data, data_field_index); } } } } -fn extract_powershell_classic_data_fields(data: &mut Value) { +fn extract_powershell_classic_data_fields(data: &mut Value, data_field_index: usize) { match data { Value::Object(map) => { for (_, val) in map { - extract_powershell_classic_data_fields(val); + extract_powershell_classic_data_fields(val, data_field_index); } } Value::Array(vec) => { for (i, val) in enumerate(vec) { - if i == 2 { + if i == data_field_index { if let Some(powershell_data_str) = val.as_str() { let map_val: std::collections::HashMap<&str, &str> = powershell_data_str .trim() @@ -47,7 +48,7 @@ mod tests { use serde_json::Value; #[test] - fn test_powershell_classic_data_fields_extraction() { + fn test_powershell_classic_data_fields_extraction_400() { let record_json_str = r#" { "Event": { @@ -82,14 +83,50 @@ mod tests { .unwrap() .get("NewEngineState") .unwrap(); - assert_eq!( - extracted_fields, - &serde_json::Value::String("Available".to_string()) + assert_eq!(extracted_fields, &Value::String("Available".to_string())); + } + + #[test] + fn test_powershell_classic_data_fields_extraction_800() { + let record_json_str = r#" +{ + "Event": { + "System": { + "EventID": 800, + "Channel": "Windows PowerShell" + }, + "EventData": { + "Data": [ + "Available", + "NewEngineState=Available", + "None" + ] + } + } +}"#; + + let mut val = serde_json::from_str(record_json_str).unwrap(); + extract_fields( + Some("Windows PowerShell".to_string()), + Some("800".to_string()), + &mut val, ); + let extracted_fields = val + .get("Event") + .unwrap() + .get("EventData") + .unwrap() + .get("Data") + .unwrap() + .get(1) + .unwrap() + .get("NewEngineState") + .unwrap(); + assert_eq!(extracted_fields, &Value::String("Available".to_string())); } #[test] - fn test_powershell_classic_data_fields_extraction_data_2_missing() { + fn test_powershell_classic_data_fields_extraction_400_data_2_missing() { let record_json_str = r#" { "Event": { From 994e320a6dd6497d10b6b3752e7c3c3e4242529b Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 24 Nov 2023 14:17:26 +0900 Subject: [PATCH 03/11] chg: enable pwsh field extraction by default --- src/afterfact.rs | 26 ++++++++++----------- src/detections/configs.rs | 30 ++++++++++++------------- src/detections/detection.rs | 10 ++++----- src/detections/rule/condition_parser.rs | 2 +- src/detections/rule/count.rs | 2 +- src/detections/rule/matchers.rs | 2 +- src/detections/rule/mod.rs | 2 +- src/detections/rule/selectionnodes.rs | 2 +- src/detections/utils.rs | 8 +++---- src/main.rs | 18 +++++++-------- src/options/htmlreport.rs | 8 +++---- src/options/profile.rs | 8 +++---- src/yaml.rs | 2 +- 13 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/afterfact.rs b/src/afterfact.rs index 1a68c193c..9d38fb707 100644 --- a/src/afterfact.rs +++ b/src/afterfact.rs @@ -1945,7 +1945,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2035,7 +2035,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2275,7 +2275,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2367,7 +2367,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2593,7 +2593,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: true, remove_duplicate_detections: false, no_wizard: true, @@ -2683,7 +2683,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2920,7 +2920,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: true, remove_duplicate_detections: false, no_wizard: true, @@ -3010,7 +3010,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: true, remove_duplicate_detections: false, no_wizard: true, @@ -3332,7 +3332,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -3501,7 +3501,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -3590,7 +3590,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -3768,7 +3768,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -3857,7 +3857,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/configs.rs b/src/detections/configs.rs index 5b98f1b25..9740320d6 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -499,8 +499,8 @@ impl StoredStatic { }; let field_data_extraction_flag = match &input_config.as_ref().unwrap().action { - Some(Action::CsvTimeline(opt)) => opt.output_options.field_data_extraction, - Some(Action::JsonTimeline(opt)) => opt.output_options.field_data_extraction, + Some(Action::CsvTimeline(opt)) => opt.output_options.no_pwsh_field_extraction, + Some(Action::JsonTimeline(opt)) => opt.output_options.no_pwsh_field_extraction, _ => false, }; @@ -1485,14 +1485,14 @@ pub struct OutputOption { #[arg(help_heading = Some("General Options"), short='C', long = "clobber", display_order = 290, requires = "output")] pub clobber: bool, - /// Enable PowerShell Classic Data field extraction (default: disabled) - #[arg(help_heading = Some("Output"), long = "field-data-extraction", display_order = 390)] - pub field_data_extraction: bool, - /// Disable field data mapping #[arg(help_heading = Some("Output"), short = 'F', long = "no-field-data-mapping", display_order = 400)] pub no_field: bool, + /// Disable PowerShell Classic Data field extraction + #[arg(help_heading = Some("Output"), long = "no-pwsh-field-extraction", display_order = 410)] + pub no_pwsh_field_extraction: bool, + /// Duplicate field data will be replaced with "DUP" #[arg( help_heading = Some("Output"), @@ -2173,7 +2173,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: option.include_eid.clone(), exclude_eid: option.exclude_eid.clone(), no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: option.no_wizard, @@ -2212,7 +2212,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2251,7 +2251,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2299,7 +2299,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2347,7 +2347,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2401,7 +2401,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2455,7 +2455,7 @@ fn extract_output_options(config: &Config) -> Option { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2705,7 +2705,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2778,7 +2778,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/detection.rs b/src/detections/detection.rs index e4408b76b..e6c82d8c2 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -1246,7 +1246,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1508,7 +1508,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1644,7 +1644,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1776,7 +1776,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -1921,7 +1921,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/rule/condition_parser.rs b/src/detections/rule/condition_parser.rs index 798eca430..b74d9d1d4 100644 --- a/src/detections/rule/condition_parser.rs +++ b/src/detections/rule/condition_parser.rs @@ -606,7 +606,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/rule/count.rs b/src/detections/rule/count.rs index d09eccc4c..673769147 100644 --- a/src/detections/rule/count.rs +++ b/src/detections/rule/count.rs @@ -630,7 +630,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/rule/matchers.rs b/src/detections/rule/matchers.rs index 602ee5ff3..e6fd6bd10 100644 --- a/src/detections/rule/matchers.rs +++ b/src/detections/rule/matchers.rs @@ -865,7 +865,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/rule/mod.rs b/src/detections/rule/mod.rs index 3dd5dfcfa..bb685dbed 100644 --- a/src/detections/rule/mod.rs +++ b/src/detections/rule/mod.rs @@ -450,7 +450,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/rule/selectionnodes.rs b/src/detections/rule/selectionnodes.rs index 92dc8635e..14e547354 100644 --- a/src/detections/rule/selectionnodes.rs +++ b/src/detections/rule/selectionnodes.rs @@ -573,7 +573,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/detections/utils.rs b/src/detections/utils.rs index 110f2bf8f..5c96d56f8 100644 --- a/src/detections/utils.rs +++ b/src/detections/utils.rs @@ -304,7 +304,7 @@ pub fn create_rec_info( path: String, keys: &Nested, recovered_record: &bool, - enable_field_extraction: &bool, + no_pwsh_field_extraction: &bool, ) -> EvtxRecordInfo { // 高速化のための処理 @@ -330,7 +330,7 @@ pub fn create_rec_info( continue; } - if *enable_field_extraction { + if !*no_pwsh_field_extraction { if key == "EventID" { event_id = val.clone(); } @@ -340,7 +340,7 @@ pub fn create_rec_info( } key_2_values.insert(key.to_string(), val.unwrap()); } - if *enable_field_extraction { + if !*no_pwsh_field_extraction { extract_fields(channel, event_id, &mut data); } @@ -1071,7 +1071,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/main.rs b/src/main.rs index 4d918b302..f24f4fe54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1602,9 +1602,9 @@ impl App { records_per_detect: Vec<(Value, bool)>, path: &dyn Display, rule_keys: Nested, - enable_field_extraction: bool, + no_pwsh_field_extraction: bool, ) -> Vec { - let enable_field_extraction = Arc::new(enable_field_extraction); + let no_pwsh_field_extraction = Arc::new(no_pwsh_field_extraction); let path = Arc::new(path.to_string()); let rule_keys = Arc::new(rule_keys); let threads: Vec> = { @@ -1612,14 +1612,14 @@ impl App { |(rec, recovered_record_flag)| -> JoinHandle { let arc_rule_keys = Arc::clone(&rule_keys); let arc_path = Arc::clone(&path); - let arc_enable_field_extraction = Arc::clone(&enable_field_extraction); + let arc_no_pwsh_field_extraction = Arc::clone(&no_pwsh_field_extraction); spawn(async move { utils::create_rec_info( rec, arc_path.to_string(), &arc_rule_keys, &recovered_record_flag, - &arc_enable_field_extraction, + &arc_no_pwsh_field_extraction, ) }) }, @@ -1892,7 +1892,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2055,7 +2055,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2139,7 +2139,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2221,7 +2221,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -2305,7 +2305,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/options/htmlreport.rs b/src/options/htmlreport.rs index e04f60673..963bedb5e 100644 --- a/src/options/htmlreport.rs +++ b/src/options/htmlreport.rs @@ -296,7 +296,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -361,7 +361,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -429,7 +429,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -494,7 +494,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/options/profile.rs b/src/options/profile.rs index 84304f49d..12fca5833 100644 --- a/src/options/profile.rs +++ b/src/options/profile.rs @@ -473,7 +473,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -599,7 +599,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -675,7 +675,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, @@ -781,7 +781,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, diff --git a/src/yaml.rs b/src/yaml.rs index ea61ce074..866b42e1b 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -554,7 +554,7 @@ mod tests { include_eid: None, exclude_eid: None, no_field: false, - field_data_extraction: false, + no_pwsh_field_extraction: false, remove_duplicate_data: false, remove_duplicate_detections: false, no_wizard: true, From 3537a102fc18988349822a9c1731eb2f028d9c9b Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 24 Nov 2023 21:11:53 +0900 Subject: [PATCH 04/11] chg: keep the original Data field --- src/detections/field_extract.rs | 50 +++++++++++++++++---------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/detections/field_extract.rs b/src/detections/field_extract.rs index c7c45337b..78a2333cf 100644 --- a/src/detections/field_extract.rs +++ b/src/detections/field_extract.rs @@ -1,4 +1,3 @@ -use itertools::enumerate; use serde_json::Value; pub fn extract_fields(channel: Option, event_id: Option, data: &mut Value) { @@ -14,32 +13,43 @@ pub fn extract_fields(channel: Option, event_id: Option, data: & } } -fn extract_powershell_classic_data_fields(data: &mut Value, data_field_index: usize) { +fn extract_powershell_classic_data_fields( + data: &mut Value, + data_field_index: usize, +) -> Option { match data { Value::Object(map) => { - for (_, val) in map { - extract_powershell_classic_data_fields(val, data_field_index); + let mut extracted_fields = None; + for (_, val) in &mut *map { + extracted_fields = extract_powershell_classic_data_fields(val, data_field_index); + if extracted_fields.is_some() { + break; + } + } + if let Some(Value::Object(fields)) = extracted_fields { + for (key, val) in fields { + map.insert(key, val); + } } } Value::Array(vec) => { - for (i, val) in enumerate(vec) { - if i == data_field_index { - if let Some(powershell_data_str) = val.as_str() { - let map_val: std::collections::HashMap<&str, &str> = powershell_data_str - .trim() - .split("\n\t") - .map(|s| s.trim_end_matches("\r\n")) - .filter_map(|s| s.split_once('=')) - .collect(); - if let Ok(extracted_fields) = serde_json::to_value(map_val) { - *val = extracted_fields - } + if let Some(val) = vec.get(data_field_index) { + if let Some(powershell_data_str) = val.as_str() { + let fields_data: std::collections::HashMap<&str, &str> = powershell_data_str + .trim() + .split("\n\t") + .map(|s| s.trim_end_matches("\r\n")) + .filter_map(|s| s.split_once('=')) + .collect(); + if let Ok(extracted_fields) = serde_json::to_value(fields_data) { + return Some(extracted_fields); } } } } _ => {} } + None } #[cfg(test)] @@ -77,10 +87,6 @@ mod tests { .unwrap() .get("EventData") .unwrap() - .get("Data") - .unwrap() - .get(2) - .unwrap() .get("NewEngineState") .unwrap(); assert_eq!(extracted_fields, &Value::String("Available".to_string())); @@ -116,10 +122,6 @@ mod tests { .unwrap() .get("EventData") .unwrap() - .get("Data") - .unwrap() - .get(1) - .unwrap() .get("NewEngineState") .unwrap(); assert_eq!(extracted_fields, &Value::String("Available".to_string())); From 4018ae3e28e9e6bd0ead81e0191add1d8bd85f75 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 24 Nov 2023 22:45:58 +0900 Subject: [PATCH 05/11] fix: added extracted fields to key2values --- src/detections/field_extract.rs | 37 ++++++++++++++++++++++++--------- src/detections/utils.rs | 2 +- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/detections/field_extract.rs b/src/detections/field_extract.rs index 78a2333cf..34565aec0 100644 --- a/src/detections/field_extract.rs +++ b/src/detections/field_extract.rs @@ -1,44 +1,54 @@ +use hashbrown::HashMap; use serde_json::Value; -pub fn extract_fields(channel: Option, event_id: Option, data: &mut Value) { +pub fn extract_fields( + channel: Option, + event_id: Option, + data: &mut Value, + key_2_values: &mut HashMap, +) { if let Some(ch) = channel { if let Some(eid) = event_id { if ch == "Windows PowerShell" && (eid == "400" || eid == "403" || eid == "600" || eid == "800") { - let data_field_index = if eid == "800" { 1 } else { 2 }; - extract_powershell_classic_data_fields(data, data_field_index); + let target_data_index = if eid == "800" { 1 } else { 2 }; + extract_powershell_classic_fields(data, target_data_index, key_2_values); } } } } -fn extract_powershell_classic_data_fields( +fn extract_powershell_classic_fields( data: &mut Value, - data_field_index: usize, + data_index: usize, + key_2_values: &mut HashMap, ) -> Option { match data { Value::Object(map) => { let mut extracted_fields = None; for (_, val) in &mut *map { - extracted_fields = extract_powershell_classic_data_fields(val, data_field_index); + extracted_fields = extract_powershell_classic_fields(val, data_index, key_2_values); if extracted_fields.is_some() { break; } } if let Some(Value::Object(fields)) = extracted_fields { for (key, val) in fields { - map.insert(key, val); + map.insert(key.clone(), val.clone()); + if let Value::String(s) = val { + key_2_values.insert(key, s.to_string()); + } } } } Value::Array(vec) => { - if let Some(val) = vec.get(data_field_index) { + if let Some(val) = vec.get(data_index) { if let Some(powershell_data_str) = val.as_str() { let fields_data: std::collections::HashMap<&str, &str> = powershell_data_str .trim() .split("\n\t") - .map(|s| s.trim_end_matches("\r\n")) + .map(|s| s.trim_end_matches("\r\n").trim_end_matches('\r')) .filter_map(|s| s.split_once('=')) .collect(); if let Ok(extracted_fields) = serde_json::to_value(fields_data) { @@ -55,6 +65,7 @@ fn extract_powershell_classic_data_fields( #[cfg(test)] mod tests { use crate::detections::field_extract::extract_fields; + use hashbrown::HashMap; use serde_json::Value; #[test] @@ -77,10 +88,12 @@ mod tests { }"#; let mut val = serde_json::from_str(record_json_str).unwrap(); + let mut key2values: HashMap = HashMap::new(); extract_fields( Some("Windows PowerShell".to_string()), Some("400".to_string()), &mut val, + &mut key2values, ); let extracted_fields = val .get("Event") @@ -112,10 +125,12 @@ mod tests { }"#; let mut val = serde_json::from_str(record_json_str).unwrap(); + let mut key2values: HashMap = HashMap::new(); extract_fields( Some("Windows PowerShell".to_string()), Some("800".to_string()), &mut val, + &mut key2values, ); let extracted_fields = val .get("Event") @@ -147,11 +162,13 @@ mod tests { let original_val: Value = serde_json::from_str(record_json_str).unwrap(); let mut val = serde_json::from_str(record_json_str).unwrap(); + let mut key2values: HashMap = HashMap::new(); extract_fields( Some("Windows PowerShell".to_string()), Some("400".to_string()), &mut val, + &mut key2values, ); assert_eq!(original_val, val); } -} +} \ No newline at end of file diff --git a/src/detections/utils.rs b/src/detections/utils.rs index 5c96d56f8..281faef5a 100644 --- a/src/detections/utils.rs +++ b/src/detections/utils.rs @@ -341,7 +341,7 @@ pub fn create_rec_info( key_2_values.insert(key.to_string(), val.unwrap()); } if !*no_pwsh_field_extraction { - extract_fields(channel, event_id, &mut data); + extract_fields(channel, event_id, &mut data, &mut key_2_values); } // EvtxRecordInfoを作る From c9dc9876b279b79e8aafcc165d0c2b23ed6a2198 Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Fri, 24 Nov 2023 22:47:56 +0900 Subject: [PATCH 06/11] fix: apply fmt --- src/detections/field_extract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detections/field_extract.rs b/src/detections/field_extract.rs index 34565aec0..736f7e1e3 100644 --- a/src/detections/field_extract.rs +++ b/src/detections/field_extract.rs @@ -171,4 +171,4 @@ mod tests { ); assert_eq!(original_val, val); } -} \ No newline at end of file +} From 9e2964e2a847a1c70291787c000c1c7324dd924c Mon Sep 17 00:00:00 2001 From: fukusuket <41001169+fukusuket@users.noreply.github.com> Date: Sat, 25 Nov 2023 00:46:56 +0900 Subject: [PATCH 07/11] refactor: changed variable name --- src/detections/configs.rs | 6 +++--- src/main.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/detections/configs.rs b/src/detections/configs.rs index 9740320d6..bb3e90158 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -83,7 +83,7 @@ pub struct StoredStatic { pub exclude_eid: HashSet, pub include_status: HashSet, // 読み込み対象ルールのステータスのセット。*はすべてのステータスを読み込む pub field_data_map: Option, - pub field_data_extraction: bool, + pub no_pwsh_field_extraction: bool, pub enable_recover_records: bool, pub timeline_offset: Option, } @@ -498,7 +498,7 @@ impl StoredStatic { )) }; - let field_data_extraction_flag = match &input_config.as_ref().unwrap().action { + let no_pwsh_field_extraction_flag = match &input_config.as_ref().unwrap().action { Some(Action::CsvTimeline(opt)) => opt.output_options.no_pwsh_field_extraction, Some(Action::JsonTimeline(opt)) => opt.output_options.no_pwsh_field_extraction, _ => false, @@ -637,7 +637,7 @@ impl StoredStatic { include_eid, exclude_eid, field_data_map, - field_data_extraction: field_data_extraction_flag, + no_pwsh_field_extraction: no_pwsh_field_extraction_flag, enable_recover_records, timeline_offset, include_status: HashSet::new(), diff --git a/src/main.rs b/src/main.rs index f24f4fe54..9c795211e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1407,7 +1407,7 @@ impl App { records_per_detect, &path, self.rule_keys.to_owned(), - stored_static.field_data_extraction, + stored_static.no_pwsh_field_extraction, )); // timeline機能の実行 @@ -1579,7 +1579,7 @@ impl App { records_per_detect, &path, self.rule_keys.to_owned(), - stored_static.field_data_extraction, + stored_static.no_pwsh_field_extraction, )); // timeline機能の実行 From 8c14b997ab3a9915f209e57cdce8cc94b91a5ab5 Mon Sep 17 00:00:00 2001 From: Yamato Security <71482215+YamatoSecurity@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:46:28 +0900 Subject: [PATCH 08/11] update changelog --- CHANGELOG-Japanese.md | 6 ++++++ CHANGELOG.md | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGELOG-Japanese.md b/CHANGELOG-Japanese.md index b729656ff..4b9e9cb25 100644 --- a/CHANGELOG-Japanese.md +++ b/CHANGELOG-Japanese.md @@ -1,5 +1,11 @@ # 変更点 +## 2.x.x [xxxx/xx/xx] + +**新機能:** + +- PowerShell classicログのフィールドを抽出するようにした。(`--no-pwsh-field-extraction`で無効化できる) (#1220) (@fukusuket) + ## 2.10.1 [2023/11/12] "Kamemushi Release" **改善:** diff --git a/CHANGELOG.md b/CHANGELOG.md index 32942e58a..32b1dd6ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes +## 2.x.x [xxxx/xx/xx] + +**New Features:** + +- Extraction of fields from PowerShell classic logs. (Can disable with `--no-pwsh-field-extraction`) (#1220) (@fukusuket) + ## 2.10.1 [2023/11/13] "Kamemushi Release" **Enhancements:** From 46555c2f1bfe4885665d621bcb89c0dbccf198e6 Mon Sep 17 00:00:00 2001 From: Yamato Security <71482215+YamatoSecurity@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:47:34 +0900 Subject: [PATCH 09/11] update help menu msg --- src/detections/configs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detections/configs.rs b/src/detections/configs.rs index bb3e90158..66b83ab36 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -1489,7 +1489,7 @@ pub struct OutputOption { #[arg(help_heading = Some("Output"), short = 'F', long = "no-field-data-mapping", display_order = 400)] pub no_field: bool, - /// Disable PowerShell Classic Data field extraction + /// Disable field extration of PowerShell classic logs #[arg(help_heading = Some("Output"), long = "no-pwsh-field-extraction", display_order = 410)] pub no_pwsh_field_extraction: bool, From ac0cb2aeb7547a19906bda2958581eb8d2941991 Mon Sep 17 00:00:00 2001 From: Yamato Security <71482215+YamatoSecurity@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:52:43 +0900 Subject: [PATCH 10/11] update hayabusa ver --- Cargo.lock | 102 +++++++++++++++++++++++++++++------------------------ Cargo.toml | 4 +-- 2 files changed, 58 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 13661700f..e5e754aa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" +checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" dependencies = [ "serde", ] @@ -241,10 +241,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.84" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ + "jobserver", "libc", ] @@ -633,9 +634,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" dependencies = [ "libc", "windows-sys 0.48.0", @@ -730,9 +731,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -756,9 +757,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "git2" @@ -799,7 +800,7 @@ dependencies = [ [[package]] name = "hayabusa" -version = "2.10.1" +version = "2.10.2-dev" dependencies = [ "aho-corasick", "base64", @@ -823,7 +824,7 @@ dependencies = [ "indexmap 2.1.0", "indicatif", "is_elevated", - "itertools 0.11.0", + "itertools 0.12.0", "krapslog", "lazy_static", "libmimalloc-sys", @@ -909,9 +910,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -994,9 +995,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" dependencies = [ "either", ] @@ -1027,6 +1028,15 @@ dependencies = [ "libc", ] +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.65" @@ -1388,9 +1398,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.59" +version = "0.10.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -1429,9 +1439,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.95" +version = "0.9.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" dependencies = [ "cc", "libc", @@ -1471,9 +1481,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" @@ -1531,9 +1541,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -1698,9 +1708,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.1", "errno", @@ -1711,9 +1721,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", "ring", @@ -1779,18 +1789,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -1928,9 +1938,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -2066,9 +2076,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.8.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" +checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" dependencies = [ "base64", "flate2", @@ -2082,9 +2092,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -2181,9 +2191,9 @@ checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "winapi" @@ -2385,18 +2395,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.25" +version = "0.7.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.25" +version = "0.7.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" dependencies = [ "proc-macro2", "quote", @@ -2405,6 +2415,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index bc9c533df..89aa555a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "hayabusa" -version = "2.10.1" +version = "2.10.2-dev" repository = "https://github.com/Yamato-Security/hayabusa" authors = ["Yamato Security @SecurityYamato"] edition = "2021" -rust-version = "1.73.0" +rust-version = "1.74.0" include = ["src/**/*", "LICENSE.txt", "README.md", "CHANGELOG.md"] [dependencies] From 15a1fab3aca605ef4e301e018c0a3b6a4b23365d Mon Sep 17 00:00:00 2001 From: Yamato Security <71482215+YamatoSecurity@users.noreply.github.com> Date: Sun, 26 Nov 2023 11:52:52 +0900 Subject: [PATCH 11/11] update ver msg --- src/detections/configs.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/detections/configs.rs b/src/detections/configs.rs index 66b83ab36..8823e32f4 100644 --- a/src/detections/configs.rs +++ b/src/detections/configs.rs @@ -737,7 +737,7 @@ fn check_thread_number(config: &Config) -> Option { pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n hayabusa.exe csv-timeline [OPTIONS]\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n hayabusa.exe csv-timeline [OPTIONS]\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 290 @@ -747,7 +747,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n hayabusa.exe json-timeline [OPTIONS]\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n hayabusa.exe json-timeline [OPTIONS]\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 360 @@ -757,7 +757,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n hayabusa.exe logon-summary [OPTIONS]\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n hayabusa.exe logon-summary [OPTIONS]\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 383 @@ -767,7 +767,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n hayabusa.exe eid-metrics [OPTIONS]\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n hayabusa.exe eid-metrics [OPTIONS]\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 310 @@ -777,7 +777,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n hayabusa.exe pivot-keywords-list [OPTIONS]\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n hayabusa.exe pivot-keywords-list [OPTIONS]\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 420 @@ -787,7 +787,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n hayabusa.exe search <--keywords \"\" OR --regex \"\"> [OPTIONS]\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n hayabusa.exe search <--keywords \"\" OR --regex \"\"> [OPTIONS]\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 450 @@ -797,7 +797,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n {usage}\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n {usage}\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 470 @@ -807,7 +807,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n {usage}\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n {usage}\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 380 @@ -817,7 +817,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n {usage}\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n {usage}\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 451 @@ -835,7 +835,7 @@ pub enum Action { #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n {usage}\n\n{all-args}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n {usage}\n\n{all-args}", term_width = 400, disable_help_flag = true, display_order = 290 @@ -1652,7 +1652,7 @@ pub struct ComputerMetricsOption { #[derive(Parser, Clone, Debug)] #[clap( author = "Yamato Security (https://github.com/Yamato-Security/hayabusa - @SecurityYamato)", - help_template = "\nHayabusa v2.10.1 - Kamemushi-Tsubushi Release\n{author-with-newline}\n{usage-heading}\n hayabusa.exe [OPTIONS]\n hayabusa.exe help \n\n{all-args}{options}", + help_template = "\nHayabusa v2.10.2 - Dev Build\n{author-with-newline}\n{usage-heading}\n hayabusa.exe [OPTIONS]\n hayabusa.exe help \n\n{all-args}{options}", term_width = 400, disable_help_flag = true )]