diff --git a/Cargo.lock b/Cargo.lock index 09e48d8c..c3e1647b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1110,6 +1110,7 @@ dependencies = [ "clap", "evtx", "quick-xml 0.17.2", + "regex", "serde", "serde_json", ] diff --git a/src/detections/common.rs b/src/detections/common.rs index e2ad12b9..a9611b5d 100644 --- a/src/detections/common.rs +++ b/src/detections/common.rs @@ -1,15 +1,14 @@ -use std::collections::HashMap; use crate::models::event; +use std::collections::HashMap; #[derive(Debug)] pub struct Common { record_id: u64, date: String, - record_id_list : HashMap, + record_id_list: HashMap, } impl Common { - pub fn new() -> Common { Common { record_id: 0, @@ -19,30 +18,27 @@ impl Common { } pub fn disp(&self) { - for (record_id, date) in self.record_id_list.iter() { + for (record_id, date) in self.record_id_list.iter() { println!("date:{:?} record-id: {:?}", date, record_id); } } pub fn detection(&mut self, system: &event::System, event_data: &HashMap) { - &self.check_record_id(system); - } // // Record IDがシーケンスになっているかチェック // fn check_record_id(&mut self, system: &event::System) { - let event_record_id: u64 = system.event_record_id.parse().unwrap(); if self.record_id > 0 && event_record_id - self.record_id > 1 { - self.record_id_list.insert(self.record_id.to_string() + " - " + &system.event_record_id.to_string(), - self.date.to_string() + " - " + &system.time_created.system_time.to_string()); + self.record_id_list.insert( + self.record_id.to_string() + " - " + &system.event_record_id.to_string(), + self.date.to_string() + " - " + &system.time_created.system_time.to_string(), + ); } self.record_id = event_record_id; self.date = system.time_created.system_time.to_string(); } - } - diff --git a/src/detections/detection.rs b/src/detections/detection.rs index 66647349..81431af3 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -1,22 +1,21 @@ extern crate quick_xml; -use std::collections::BTreeMap; -use std::collections::HashMap; -use crate::models::event; -use evtx::EvtxParser; +use crate::detections::application; use crate::detections::common; use crate::detections::security; use crate::detections::system; -use crate::detections::application; -use quick_xml::de::{DeError}; +use crate::models::event; +use evtx::EvtxParser; +use quick_xml::de::DeError; +use std::collections::BTreeMap; +use std::collections::HashMap; #[derive(Debug)] pub struct Detection { - timeline_list : BTreeMap, + timeline_list: BTreeMap, } impl Detection { - pub fn new() -> Detection { Detection { timeline_list: BTreeMap::new(), @@ -24,12 +23,11 @@ impl Detection { } pub fn start(&mut self, mut parser: EvtxParser) -> Result<(), DeError> { - let mut common: common::Common = common::Common::new(); let mut security = security::Security::new(); let mut system = system::System::new(); let mut application = application::Application::new(); - + for record in parser.records() { match record { Ok(r) => { @@ -37,19 +35,19 @@ impl Detection { let event_id = event.system.event_id.to_string(); let channel = event.system.channel.to_string(); let event_data = event.parse_event_data(); - + &common.detection(&event.system, &event_data); - //&common.detection(&event.system, &event_data); + //&common.detection(&event.system, &event_data); if channel == "Security" { &security.detection(event_id, &event.system, event_data); } else if channel == "System" { &system.detection(); } else if channel == "Application" { - &application.detection(); + &application.detection(event_id, &event.system, event_data); } else { //&other.detection(); } - }, + } Err(e) => eprintln!("{}", e), } } @@ -59,9 +57,7 @@ impl Detection { //////////////////////////// common.disp(); security.disp(); - - return Ok(()) + + return Ok(()); } - } - diff --git a/src/detections/mod.rs b/src/detections/mod.rs index 52c40328..7238b4aa 100644 --- a/src/detections/mod.rs +++ b/src/detections/mod.rs @@ -1,5 +1,5 @@ +mod application; mod common; +pub mod detection; mod security; mod system; -mod application; -pub mod detection; diff --git a/src/detections/security.rs b/src/detections/security.rs index 8d55dfa3..f43d347a 100644 --- a/src/detections/security.rs +++ b/src/detections/security.rs @@ -1,5 +1,5 @@ -use std::collections::HashMap; use crate::models::event; +use std::collections::HashMap; #[derive(Debug)] pub struct Security { @@ -11,7 +11,7 @@ pub struct Security { impl Security { pub fn new() -> Security { - Security{ + Security { alert_all_admin: 0, total_admin_logons: 0, admin_logons: HashMap::new(), @@ -27,8 +27,12 @@ impl Security { } } - pub fn detection(&mut self, event_id: String, system: &event::System, event_data: HashMap) { - + pub fn detection( + &mut self, + event_id: String, + system: &event::System, + event_data: HashMap, + ) { if event_id == "4672" { &self.se_debug_privilege(event_data); } @@ -38,12 +42,10 @@ impl Security { // Special privileges assigned to new logon (possible admin access) // fn se_debug_privilege(&mut self, event_data: HashMap) { - match event_data.get("PrivilegeList") { Some(privileage_list) => { match privileage_list.find("SeDebugPrivilege") { Some(_data) => { - // alert_all_adminが有効であれば、標準出力して知らせる // DeepBlueCLIでは必ず0になっていて、基本的には表示されない。 if self.alert_all_admin == 1 { @@ -53,39 +55,43 @@ impl Security { println!("User SID:{}", event_data["SubjectUserSid"]); println!("Domain:{}", event_data["PrivilegeList"]); } - + self.total_admin_logons += 1; - + // admin_logons配列にusernameが含まれているか確認 match self.admin_logons.get(&event_data["SubjectUserName"]) { Some(sid) => { // 含まれていれば、マルチユーザが管理者としてログインしているか確認 // マルチログオンのデータをセット - if event_data["SubjectUserName"] != event_data["SubjectUserSid"] { // One username with multiple admin logon SIDs - self.multiple_admin_logons.insert(event_data["SubjectUserName"].to_string(),1); - + if event_data["SubjectUserName"] != event_data["SubjectUserSid"] { + // One username with multiple admin logon SIDs + self.multiple_admin_logons + .insert(event_data["SubjectUserName"].to_string(), 1); + let mut count_hash: HashMap = HashMap::new(); - count_hash.insert(event_data["SubjectUserSid"].to_string(), sid[&event_data["SubjectUserSid"]] + 1); - self.admin_logons.insert(event_data["SubjectUserName"].to_string(), count_hash); + count_hash.insert( + event_data["SubjectUserSid"].to_string(), + sid[&event_data["SubjectUserSid"]] + 1, + ); + self.admin_logons.insert( + event_data["SubjectUserName"].to_string(), + count_hash, + ); } - }, + } None => { // admin_logons配列にセットUserNameとSIDとカウンタをセット let mut count_hash: HashMap = HashMap::new(); count_hash.insert(event_data["SubjectUserSid"].to_string(), 1); - self.admin_logons.insert(event_data["SubjectUserName"].to_string(), count_hash); - + self.admin_logons + .insert(event_data["SubjectUserName"].to_string(), count_hash); } } - }, + } None => (), } - }, + } None => (), - } - } - } - diff --git a/src/detections/system.rs b/src/detections/system.rs index da7b3ee5..3c5b6401 100644 --- a/src/detections/system.rs +++ b/src/detections/system.rs @@ -1,15 +1,9 @@ - -pub struct System { - -} +pub struct System {} impl System { - pub fn new() -> System { - System{} + System {} } - pub fn detection(&self) { - - } -} \ No newline at end of file + pub fn detection(&self) {} +} diff --git a/src/lib.rs b/src/lib.rs index d91d16b9..2579ad53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,2 @@ -pub mod models; pub mod detections; +pub mod models; diff --git a/src/main.rs b/src/main.rs index 359c43f0..0777aad0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,19 @@ -extern crate serde; extern crate clap; +extern crate serde; -use evtx::EvtxParser; -use std::{env, process, path::PathBuf}; -use quick_xml::de::{DeError}; -use yamato_event_analyzer::detections::detection; use clap::{App, AppSettings, Arg}; +use evtx::EvtxParser; +use quick_xml::de::DeError; +use std::{env, path::PathBuf, process}; +use yamato_event_analyzer::detections::detection; fn build_app() -> clap::App<'static, 'static> { let program = std::env::args() .nth(0) .and_then(|s| { std::path::PathBuf::from(s) - .file_stem() - .map(|s| s.to_string_lossy().into_owned()) + .file_stem() + .map(|s| s.to_string_lossy().into_owned()) }) .unwrap(); @@ -32,19 +32,17 @@ fn build_app() -> clap::App<'static, 'static> { .arg(Arg::from_usage("-s --statistics 'event statistics'")) .arg(Arg::from_usage("-u --update 'signature update'")) .arg(Arg::from_usage("--credits 'Zachary Mathis, Akira Nishikawa'")) - } fn main() -> Result<(), DeError> { - let args = build_app().get_matches(); - let filepath : Option<&str> = args.value_of("filepath"); - + let filepath: Option<&str> = args.value_of("filepath"); + match filepath { Some(filepath) => parse_file(filepath), None => (), } - + Ok(()) } @@ -55,9 +53,9 @@ fn parse_file(filepath: &str) { Err(e) => { eprintln!("{}", e); process::exit(1); - }, + } }; - + let mut detection = detection::Detection::new(); &detection.start(parser); }