Skip to content

Commit

Permalink
Merge pull request #1354 from Yamato-Security/1342-output-agg-result-…
Browse files Browse the repository at this point in the history
…under-details-json

chg: output agg condition's JSON result as `Details`'s child element
  • Loading branch information
YamatoSecurity committed May 27, 2024
2 parents 2173b4e + 7f1387b commit 31d2c69
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 37 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG-Japanese.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
- `count`で複数のグループを指定できるようにした。例: `count() by IpAddress,SubStatus,LogonType >= 2`。また、出力される結果を更新した。例: `[condition] count(TargetUserName) by IpAddress > 3 in timeframe [result] count: 4 TargetUserName:tanaka/Administrator/adsyncadmin/suzuki IpAddress:- timeframe:5m` -> `Count: 4 ¦ TargetUserName: tanaka/Administrator/adsyncadmin/suzuki ¦ IpAddress: -` (#1339) (@fukusuket)
- リリースモードでのオーバーフローチェックを有効にした。(#1348) (@YamatoSecurity)
- フィールドデータマッピングファイル(`rules/config/data_mapping/*.yaml`)で任意の`Provider_Name`フィールドを指定できるようにし、`Data[x]`表記に対応した。(#1350) (@fukusuket)
- カウントルールのJSON出力で、フィールド情報が分離されるようになった。 (#1342) (@fukusuket)
- 以前: `"Details": "[condition] count() by IpAddress >= 5 in timeframe [result] count:3558 IpAddress:192.168.198.149 timeframe:5m"`
- 現在: `"Details": { "Count": 3558, "IpAddress": "192.168.198.149" }`

## 2.15.0 [2024/04/20] "Sonic Release"

Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
- You can now specify multiple groups with `count`. Ex: `count() by IpAddress,SubStatus,LogonType >= 2` Also, the output has been updated. Ex: `[condition] count(TargetUserName) by IpAddress > 3 in timeframe [result] count: 4 TargetUserName:tanaka/Administrator/adsyncadmin/suzuki IpAddress:- timeframe:5m` -> `Count: 4 ¦ TargetUserName: tanaka/Administrator/adsyncadmin/suzuki ¦ IpAddress: -` (#1339) (@fukusuket)
- Enabled overflow checks in release mode. (#1348) (@YamatoSecurity)
- Added support for specifying an optional `Provider_Name` field in field data mapping files (`rules/config/data_mapping/*.yaml`) as well as support for `Data[x]` notation. (#1350) (@fukusuket)
- JSON output in count rules now separates field information. (#1342) (@fukusuket)
- Before: `"Details": "[condition] count() by IpAddress >= 5 in timeframe [result] count:3558 IpAddress:192.168.198.149 timeframe:5m"`
- After: `"Details": { "Count": 3558, "IpAddress": "192.168.198.149" }`

## 2.15.0 [2024/04/20] "Sonic Release"

Expand Down
90 changes: 53 additions & 37 deletions src/afterfact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1886,48 +1886,43 @@ pub fn output_json_str(
continue;
}
let details_target_stock = details_target_stocks.unwrap();
// aggregation conditionの場合は分解せずにそのまま出力する
if detect_info.is_condition {
let details_val =
if details_target_stock.is_empty() || details_target_stock[0] == "-" {
"-".into()
} else {
details_target_stock[0].clone()
};
output_stock.push(_create_json_output_format(
key,
&details_val,
key.starts_with('\"'),
details_val.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 mut children_output_stock: HashMap<CompactString, Vec<CompactString>> =
HashMap::new();
let mut children_output_order = vec![];
for contents in details_target_stock.iter() {
let (key, value) = contents.split_once(':').unwrap_or_default();
let output_key = _convert_valid_json_str(&[key.trim()], false);
let fmted_val = _convert_valid_json_str(&[value.trim()], false);
if let RawEntryMut::Vacant(_) = children_output_stock
.raw_entry_mut()
.from_key(output_key.as_str())
{
children_output_order.push(output_key.clone());
if detect_info.is_condition {
if details_target_stock[0] == "-" {
output_stock.push(_create_json_output_format(
key,
details_target_stock[0].as_str(),
key.starts_with('\"'),
details_target_stock[0].starts_with('\"'),
4,
));
if jsonl_output_flag {
target.push(output_stock.join(""));
} else {
target.push(output_stock.join("\n"));
}
continue;
}
children_output_stock
.entry(output_key.into())
.or_insert(vec![])
.push(fmted_val.into());
let splitted_agg_details = details_target_stock[0]
.split(" ¦ ")
.map(|x| x.into())
.collect_vec();
process_target_stock(
&splitted_agg_details,
&mut children_output_stock,
&mut children_output_order,
);
} else {
process_target_stock(
details_target_stock,
&mut children_output_stock,
&mut children_output_order,
);
}
output_stock.push(format!(" \"{key}\": {{"));

// ルール内での表示順に合わせた表示順を戻した配列
let mut sorted_children_output_stock: Vec<(
&CompactString,
Expand Down Expand Up @@ -2062,6 +2057,27 @@ pub fn output_json_str(
}
}

fn process_target_stock(
details_target_stock: &[CompactString],
children_output_stock: &mut HashMap<CompactString, Vec<CompactString>>,
children_output_order: &mut Vec<CompactString>,
) {
for contents in details_target_stock.iter() {
let (key, value) = contents.split_once(':').unwrap_or_default();
let output_key = _convert_valid_json_str(&[key.trim()], false);
let fmted_val = _convert_valid_json_str(&[value.trim()], false);
if let RawEntryMut::Vacant(_) = children_output_stock
.raw_entry_mut()
.from_key(output_key.as_str())
{
children_output_order.push(output_key.clone().into());
}
children_output_stock
.entry(output_key.into())
.or_insert(vec![])
.push(fmted_val.into());
}
}
/// output detected rule author name function.
fn output_detected_rule_authors(
rule_author_counter: &HashMap<CompactString, i128>,
Expand Down

0 comments on commit 31d2c69

Please sign in to comment.