From 313ae243c0112552b534865acae8ed160a65de6e Mon Sep 17 00:00:00 2001 From: DastInDark <2350416+hitenkoku@users.noreply.github.com> Date: Wed, 13 Sep 2023 17:57:25 +0900 Subject: [PATCH] fix(afterfact/detection/message): fixed misprocessing of details field in JSON output #1145 --- src/afterfact.rs | 39 ++++++++++++++++++++++++++----------- src/detections/detection.rs | 2 +- src/detections/message.rs | 34 +++++++++++++++++++------------- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/afterfact.rs b/src/afterfact.rs index c0412a0b4..d75c8ca9c 100644 --- a/src/afterfact.rs +++ b/src/afterfact.rs @@ -1547,15 +1547,24 @@ pub fn output_json_str( Profile::ExtraFieldInfo(_) => "ExtraFieldInfo", _ => "", }; - let details_target_stocks = - details_infos[0].get(&CompactString::from(format!("#{details_key}"))); - if details_target_stocks.is_none() { + let mut details_target_stocks = vec![]; + for details_info in details_infos { + let details_target_stock = + details_info.get(&CompactString::from(format!("#{details_key}"))); + if let Some(tmp_stock) = details_target_stock { + details_target_stocks.extend(tmp_stock); + } + } + + if details_infos[0] + .get(&CompactString::from(format!("#{details_key}"))) + .is_none() + { continue; } // aggregation conditionの場合は分解せずにそのまま出力する - if is_condition { - let agg_result = &details_target_stocks.unwrap(); - if agg_result.is_empty() { + if is_condition && details_key == "Details" { + if details_target_stocks.is_empty() { output_stock.push(format!( "{}", _create_json_output_format( @@ -1567,28 +1576,36 @@ pub fn output_json_str( ) )); } else { + let joined_details_target_stock = + details_target_stocks.iter().join(" "); + let output_str_details_target_stock = + joined_details_target_stock.trim(); output_stock.push(format!( "{}", _create_json_output_format( &key, - agg_result[0].as_str(), + output_str_details_target_stock, key.starts_with('\"'), - agg_result[0].starts_with('\"'), + output_str_details_target_stock.starts_with('\"'), 4 ) )); } + if jsonl_output_flag { + target.push(output_stock.join("")); + } else { + target.push(output_stock.join("\n")); + } continue; } else { output_stock.push(format!(" \"{key}\": {{")); }; - let details_stocks = details_target_stocks.unwrap(); - for (idx, contents) in details_stocks.iter().enumerate() { + for (idx, contents) in details_target_stocks.iter().enumerate() { let (key, value) = contents.split_once(": ").unwrap_or_default(); let output_key = _convert_valid_json_str(&[key], false); let fmted_val = _convert_valid_json_str(&[value], false); - if idx != details_stocks.len() - 1 { + if idx != details_target_stocks.len() - 1 { output_stock.push(format!( "{},", _create_json_output_format( diff --git a/src/detections/detection.rs b/src/detections/detection.rs index 8b576792a..745fdc66a 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -1150,7 +1150,7 @@ impl Detection { for alias in target_alias { let (search_data, _) = message::parse_message( record, - CompactString::from(alias), + &CompactString::from(alias), eventkey_alias, is_csv_output, &FieldDataMapKey::default(), diff --git a/src/detections/message.rs b/src/detections/message.rs index 76b98f958..ed1e28856 100644 --- a/src/detections/message.rs +++ b/src/detections/message.rs @@ -125,13 +125,11 @@ pub fn insert( ), ) { let mut record_details_info_map = HashMap::new(); - println!("dbg timestamp: {:?}", time); - println!("dbg output: {:?}", &output); if !is_agg { //ここの段階でdetailsの内容でaliasを置き換えた内容と各種、key,valueの組み合わせのmapを取得する let (removed_sp_parsed_detail, details_in_record) = parse_message( event_record, - output, + &output, eventkey_alias, is_json_timeline, field_data_map_key, @@ -184,10 +182,20 @@ pub fn insert( } else { replaced_profiles .push((key.to_owned(), Details(detect_info.detail.clone().into()))); - record_details_info_map.insert( + detect_info.details_convert_map.insert( "#Details".into(), detect_info.detail.split(" ¦ ").map(|x| x.into()).collect(), ); + if is_agg { + if output != "-" { + record_details_info_map.insert("#Details".into(), vec![output.clone()]); + } else if detect_info.detail != "-" { + record_details_info_map + .insert("#Details".into(), vec![detect_info.detail.clone()]); + } else { + record_details_info_map.insert("#Details".into(), vec!["-".into()]); + } + } // メモリの節約のためにDetailsの中身を空にする detect_info.detail = CompactString::default(); } @@ -287,7 +295,7 @@ pub fn insert( if let Some(p) = profile_converter.get(key.as_str()) { let (parsed_message, _) = &parse_message( event_record, - CompactString::new(p.to_value()), + &CompactString::new(p.to_value()), eventkey_alias, is_json_timeline, field_data_map_key, @@ -306,7 +314,7 @@ pub fn insert( /// メッセージ内の%で囲まれた箇所をエイリアスとしてレコード情報を参照して置き換える関数 pub fn parse_message( event_record: &Value, - output: CompactString, + output: &CompactString, eventkey_alias: &EventKeyAliasConfig, json_timeline_flag: bool, field_data_map_key: &FieldDataMapKey, @@ -522,7 +530,7 @@ mod tests { assert_eq!( parse_message( &event_record, - CompactString::new("commandline:%CommandLine% computername:%ComputerName%"), + &CompactString::new("commandline:%CommandLine% computername:%ComputerName%"), &load_eventkey_alias( utils::check_setting_path( &CURRENT_EXE_PATH.to_path_buf(), @@ -559,7 +567,7 @@ mod tests { assert_eq!( parse_message( &event_record, - CompactString::new("alias:%NoAlias%"), + &CompactString::new("alias:%NoAlias%"), &load_eventkey_alias( utils::check_setting_path( &CURRENT_EXE_PATH.to_path_buf(), @@ -602,7 +610,7 @@ mod tests { assert_eq!( parse_message( &event_record, - CompactString::new("NoExistAlias:%NoAliasNoHit%"), + &CompactString::new("NoExistAlias:%NoAliasNoHit%"), &load_eventkey_alias( utils::check_setting_path( &CURRENT_EXE_PATH.to_path_buf(), @@ -644,7 +652,7 @@ mod tests { assert_eq!( parse_message( &event_record, - CompactString::new("commandline:%CommandLine% computername:%ComputerName%"), + &CompactString::new("commandline:%CommandLine% computername:%ComputerName%"), &load_eventkey_alias( utils::check_setting_path( &CURRENT_EXE_PATH.to_path_buf(), @@ -691,7 +699,7 @@ mod tests { assert_eq!( parse_message( &event_record, - CompactString::new("commandline:%CommandLine% data:%Data%"), + &CompactString::new("commandline:%CommandLine% data:%Data%"), &load_eventkey_alias( utils::check_setting_path( &CURRENT_EXE_PATH.to_path_buf(), @@ -738,7 +746,7 @@ mod tests { assert_eq!( parse_message( &event_record, - CompactString::new("commandline:%CommandLine% data:%Data[2]%"), + &CompactString::new("commandline:%CommandLine% data:%Data[2]%"), &load_eventkey_alias( utils::check_setting_path( &CURRENT_EXE_PATH.to_path_buf(), @@ -785,7 +793,7 @@ mod tests { assert_eq!( parse_message( &event_record, - CompactString::new("commandline:%CommandLine% data:%Data[0]%"), + &CompactString::new("commandline:%CommandLine% data:%Data[0]%"), &load_eventkey_alias( utils::check_setting_path( &CURRENT_EXE_PATH.to_path_buf(),