added live analysys feature (#398)

* added windows live analysis option #125

* added live analysis option #125

* fixed live analysys condition #125

* changed live analysis option #125

* added live-analysis option in readme #125

* fixed live-analysis check condition #125

* is_elevated crate is only windows #125

* fixed is_elevated build error #125

* fixed is_elevated library crate load

* fixed call way os dependencies crate #125

* fix build error on linux and removed unnecessary create #125

* fixed lack of load crate when build at windows #125

* Update error message

Co-authored-by: Tanaka Zakku <71482215+YamatoSecurity@users.noreply.github.com>
This commit is contained in:
DustInDark
2022-02-15 02:12:45 +09:00
committed by GitHub
parent 9cb54a9192
commit df86958850
6 changed files with 70 additions and 1 deletions

View File

@@ -62,6 +62,7 @@ fn build_app<'a>() -> ArgMatches<'a> {
-D --enable-deprecated-rules 'Enable sigma rules marked as deprecated.'
-n --enable-noisy-rules 'Enable rules marked as noisy.'
-m --min-level=[LEVEL] 'Minimum level for rules. (default: informational)'
-l --live-analysis 'Analyze to WINDIR\\System32\\winevt\\Logs (Windows Only. Need Administrator privileges.)'
--start-timeline=[STARTTIMELINE] 'Start time of the event to load from event file. (example: '2018/11/28 12:00:00 +09:00')'
--end-timeline=[ENDTIMELINE] 'End time of the event to load from event file. (example: '2018/11/28 12:00:00 +09:00')'
--rfc-2822 'Output date and time in RFC 2822 format. (example: Mon, 07 Aug 2006 12:34:56 -0600)'

View File

@@ -33,6 +33,9 @@ use tokio::runtime::Runtime;
use tokio::spawn;
use tokio::task::JoinHandle;
#[cfg(target_os = "windows")]
use {is_elevated::is_elevated, std::env};
// 一度にtimelineやdetectionを実行する行数
const MAX_DETECT_RECORDS: usize = 5000;
@@ -99,7 +102,18 @@ impl App {
println!("Generating Event ID Statistics");
println!("");
}
if let Some(filepath) = configs::CONFIG.read().unwrap().args.value_of("filepath") {
if configs::CONFIG
.read()
.unwrap()
.args
.is_present("live-analysis")
{
let live_analysis_list = self.collect_liveanalysis_files();
if live_analysis_list.is_none() {
return;
}
self.analysis_files(live_analysis_list.unwrap());
} else if let Some(filepath) = configs::CONFIG.read().unwrap().args.value_of("filepath") {
if !filepath.ends_with(".evtx")
|| Path::new(filepath)
.file_stem()
@@ -149,6 +163,41 @@ impl App {
}
}
#[cfg(not(target_os = "windows"))]
fn collect_liveanalysis_files(&self) -> Option<Vec<PathBuf>> {
AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&"-l / --liveanalysis needs to be run as Administrator on Windows.\r\n".to_string(),
)
.ok();
return None;
}
#[cfg(target_os = "windows")]
fn collect_liveanalysis_files(&self) -> Option<Vec<PathBuf>> {
if is_elevated() {
let log_dir = env::var("windir").expect("windir is not found");
let evtx_files =
self.collect_evtxfiles(&[log_dir, "System32\\winevt\\Logs".to_string()].join("/"));
if evtx_files.len() == 0 {
AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&"No .evtx files were found.".to_string(),
)
.ok();
return None;
}
return Some(evtx_files);
} else {
AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&"-l / --liveanalysis needs to be run as Administrator on Windows.\r\n".to_string(),
)
.ok();
return None;
}
}
fn collect_evtxfiles(&self, dirpath: &str) -> Vec<PathBuf> {
let entries = fs::read_dir(dirpath);
if entries.is_err() {