Merge pull request #578 from Yamato-Security/487-specified-field-data-from-multi-data-in-details
specified field data from multi data in details and output column bug fix
This commit is contained in:
@@ -2,10 +2,18 @@
|
||||
|
||||
## v1.3.1 [2022/xx/xx]
|
||||
|
||||
**新機能:**
|
||||
|
||||
- ルール内の`details`で複数の`Data`レコードから特定のデータを指定して出力できるようにした。 (#487) (@hitenkoku)
|
||||
|
||||
**改善:**
|
||||
|
||||
- LinuxとmacOSのバイナリサイズをより小さくするために、デバッグシンボルをストリップします。(#568) (@YamatoSecurity)
|
||||
|
||||
**バグ修正:**
|
||||
|
||||
- 対応するオプションを付与していないときにもRecordIDとRecordInformationの列が出力されていたのを修正した。 (#577) (@hitenkoku)
|
||||
|
||||
## v1.3.0 [2022/06/06]
|
||||
|
||||
**新機能:**
|
||||
|
||||
@@ -2,10 +2,18 @@
|
||||
|
||||
## v1.3.1 [2022/xx/xx]
|
||||
|
||||
**New Features:**
|
||||
|
||||
- You can now specify specific fields when there are multiple fields with the same name (Ex: `Data`). In the `details` line in a rule, specify a placeholder like `%Data[1]%` to display the first `Data` field. (#487) (@hitenkoku)
|
||||
|
||||
**Enhancements:**
|
||||
|
||||
- Strip debug symbols by default for smaller Linux and macOS binaries. (#568) (@YamatoSecurity)
|
||||
|
||||
**Bug Fixes:**
|
||||
|
||||
- fixed bug that RecordID and RecordInformation column is showed when options is not enabled. (#577) (@hitenkoku)
|
||||
|
||||
## v1.3.0 [2022/06/06]
|
||||
|
||||
**New Features:**
|
||||
|
||||
Generated
+54
-2
@@ -568,6 +568,21 @@ version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
@@ -699,6 +714,7 @@ dependencies = [
|
||||
"linked-hash-map",
|
||||
"lock_api",
|
||||
"num_cpus",
|
||||
"openssl",
|
||||
"pbr",
|
||||
"prettytable-rs",
|
||||
"quick-xml 0.23.0",
|
||||
@@ -1103,12 +1119,47 @@ version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "111.20.0+1.1.1o"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92892c4f87d56e376e469ace79f1128fdaded07646ddf73aa0be4706ff712dec"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.74"
|
||||
@@ -1118,6 +1169,7 @@ dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
@@ -1801,9 +1853,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.34"
|
||||
version = "0.1.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
|
||||
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"pin-project-lite",
|
||||
|
||||
+2
-2
@@ -576,8 +576,8 @@ Hayabusaの結果は`level`毎に文字色が変わります。
|
||||
|
||||
## イベント頻度タイムライン
|
||||
|
||||
`--visualize-timeline`オプションを使うことで、検知したイベントの数が5以上の時、頻度のタイムライン(スパークライン)を画面に出力します。
|
||||
マーカーの数は最大10個です。デフォルトのCommand PromptとPowerShell Promptでは文字化けされるので、Windows TerminalやiTerm2等のターミナルをご利用ください。
|
||||
`-V`または`--visualize-timeline`オプションを使うことで、検知したイベントの数が5以上の時、頻度のタイムライン(スパークライン)を画面に出力します。
|
||||
マーカーの数は最大10個です。デフォルトのCommand PromptとPowerShell Promptでは文字化けがでるので、Windows TerminalやiTerm2等のターミナルをご利用ください。
|
||||
|
||||
## 最多検知日の出力
|
||||
|
||||
|
||||
+18
-3
@@ -414,7 +414,23 @@ enum ColPos {
|
||||
|
||||
fn _get_serialized_disp_output(dispformat: Option<DisplayFormat>) -> String {
|
||||
if dispformat.is_none() {
|
||||
return "Timestamp|Computer|Channel|EventID|Level|RuleTitle|Details|RecordID|RecordInformation\n".to_string();
|
||||
let mut titles = vec![
|
||||
"Timestamp",
|
||||
"Computer",
|
||||
"Channel",
|
||||
"EventID",
|
||||
"Level",
|
||||
"RuleTitle",
|
||||
"Details",
|
||||
];
|
||||
let arg_match = &configs::CONFIG.read().unwrap().args;
|
||||
if arg_match.is_present("display-record-id") {
|
||||
titles.push("RecordID");
|
||||
}
|
||||
if arg_match.is_present("full-data") {
|
||||
titles.push("RecordInformation");
|
||||
}
|
||||
return format!("{}\n", titles.join("|"));
|
||||
}
|
||||
let mut disp_serializer = csv::WriterBuilder::new()
|
||||
.double_quote(false)
|
||||
@@ -734,8 +750,7 @@ mod tests {
|
||||
let test_timestamp = Utc
|
||||
.datetime_from_str("1996-02-27T01:05:01Z", "%Y-%m-%dT%H:%M:%SZ")
|
||||
.unwrap();
|
||||
let expect_header =
|
||||
"Timestamp|Computer|Channel|EventID|Level|RuleTitle|Details|RecordID|RecordInformation\n";
|
||||
let expect_header = "Timestamp|Computer|Channel|EventID|Level|RuleTitle|Details\n";
|
||||
let expect_tz = test_timestamp.with_timezone(&Local);
|
||||
|
||||
let expect_no_header = expect_tz
|
||||
|
||||
+113
-1
@@ -42,7 +42,8 @@ pub struct AlertMessage {}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref MESSAGES: Mutex<Message> = Mutex::new(Message::new());
|
||||
pub static ref ALIASREGEX: Regex = Regex::new(r"%[a-zA-Z0-9-_]+%").unwrap();
|
||||
pub static ref ALIASREGEX: Regex = Regex::new(r"%[a-zA-Z0-9-_\[\]]+%").unwrap();
|
||||
pub static ref SUFFIXREGEX: Regex = Regex::new(r"\[([0-9]+)\]").unwrap();
|
||||
pub static ref ERROR_LOG_PATH: String = format!(
|
||||
"./logs/errorlog-{}.log",
|
||||
Local::now().format("%Y%m%d_%H%M%S")
|
||||
@@ -171,6 +172,18 @@ impl Message {
|
||||
tmp_event_record = record;
|
||||
}
|
||||
}
|
||||
let suffix_match = SUFFIXREGEX.captures(&target_str);
|
||||
let suffix: i64 = match suffix_match {
|
||||
Some(cap) => cap.get(1).map_or(-1, |a| a.as_str().parse().unwrap_or(-1)),
|
||||
None => -1,
|
||||
};
|
||||
if suffix >= 1 {
|
||||
tmp_event_record = tmp_event_record
|
||||
.get("Data")
|
||||
.unwrap()
|
||||
.get((suffix - 1) as usize)
|
||||
.unwrap_or(tmp_event_record);
|
||||
}
|
||||
let hash_value = get_serde_number_to_string(tmp_event_record);
|
||||
if hash_value.is_some() {
|
||||
if let Some(hash_value) = hash_value {
|
||||
@@ -541,6 +554,105 @@ mod tests {
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
/// output test when no exist info in target record output and described key-value data in eventkey_alias.txt
|
||||
fn test_parse_message_multiple_no_suffix_in_record() {
|
||||
let mut message = Message::new();
|
||||
let json_str = r##"
|
||||
{
|
||||
"Event": {
|
||||
"EventData": {
|
||||
"CommandLine": "parsetest3",
|
||||
"Data": [
|
||||
"data1",
|
||||
"data2",
|
||||
"data3"
|
||||
]
|
||||
},
|
||||
"System": {
|
||||
"TimeCreated_attributes": {
|
||||
"SystemTime": "1996-02-27T01:05:01Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"##;
|
||||
let event_record: Value = serde_json::from_str(json_str).unwrap();
|
||||
let expected = "commandline:parsetest3 data:[\"data1\",\"data2\",\"data3\"]";
|
||||
assert_eq!(
|
||||
message.parse_message(
|
||||
&event_record,
|
||||
"commandline:%CommandLine% data:%Data%".to_owned()
|
||||
),
|
||||
expected,
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
/// output test when no exist info in target record output and described key-value data in eventkey_alias.txt
|
||||
fn test_parse_message_multiple_with_suffix_in_record() {
|
||||
let mut message = Message::new();
|
||||
let json_str = r##"
|
||||
{
|
||||
"Event": {
|
||||
"EventData": {
|
||||
"CommandLine": "parsetest3",
|
||||
"Data": [
|
||||
"data1",
|
||||
"data2",
|
||||
"data3"
|
||||
]
|
||||
},
|
||||
"System": {
|
||||
"TimeCreated_attributes": {
|
||||
"SystemTime": "1996-02-27T01:05:01Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"##;
|
||||
let event_record: Value = serde_json::from_str(json_str).unwrap();
|
||||
let expected = "commandline:parsetest3 data:data2";
|
||||
assert_eq!(
|
||||
message.parse_message(
|
||||
&event_record,
|
||||
"commandline:%CommandLine% data:%Data[2]%".to_owned()
|
||||
),
|
||||
expected,
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
/// output test when no exist info in target record output and described key-value data in eventkey_alias.txt
|
||||
fn test_parse_message_multiple_no_exist_in_record() {
|
||||
let mut message = Message::new();
|
||||
let json_str = r##"
|
||||
{
|
||||
"Event": {
|
||||
"EventData": {
|
||||
"CommandLine": "parsetest3",
|
||||
"Data": [
|
||||
"data1",
|
||||
"data2",
|
||||
"data3"
|
||||
]
|
||||
},
|
||||
"System": {
|
||||
"TimeCreated_attributes": {
|
||||
"SystemTime": "1996-02-27T01:05:01Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"##;
|
||||
let event_record: Value = serde_json::from_str(json_str).unwrap();
|
||||
let expected = "commandline:parsetest3 data:n/a";
|
||||
assert_eq!(
|
||||
message.parse_message(
|
||||
&event_record,
|
||||
"commandline:%CommandLine% data:%Data[0]%".to_owned()
|
||||
),
|
||||
expected,
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
/// test of loading output filter config by output_tag.txt
|
||||
fn test_load_output_tag() {
|
||||
let actual =
|
||||
|
||||
Reference in New Issue
Block a user