added update command #391 (#392)

* add git2 crate #391

* added Update option #391

* updated readme #391

* fixed cargo.lock

* fixed option if-statement #391

* changed utc short option and rule-update short option #391

* updated readme

* updated readme

* fixed -u long option & version number update #391

* added fast-forwarding rules repository #391

* updated command line option #391

* moved output logo prev update rule

* fixed readme #391

* removed recursive option in readme

* English message update.

* cargo fmt

* Added update command#391 submodule ver (#401)

* changed rules update from clone and pull to submodule update #391

* fixed document

* changed unnecessary clone recursively to clone only

* English message update. ( 4657c35e5c cherry-pick)

* added create rules folder when rules folder is not exist

* fixed gitmodules github-rules url from ssh to https

Co-authored-by: Tanaka Zakku <71482215+YamatoSecurity@users.noreply.github.com>

* added caution case of update failed in readme #391

* fixed document

* added output error in case of loaded rule count is 0  #391 #392

 https://github.com/Yamato-Security/hayabusa/pull/392#issuecomment-1050276570

* --update-rules typo

* removed unused library call

Co-authored-by: Tanaka Zakku <71482215+YamatoSecurity@users.noreply.github.com>
This commit is contained in:
DustInDark
2022-02-26 18:18:03 +09:00
committed by GitHub
parent 568ce6764c
commit 02b1d7f07c
7 changed files with 204 additions and 64 deletions

View File

@@ -61,13 +61,14 @@ fn build_app<'a>() -> ArgMatches<'a> {
-v --verbose 'Output verbose information.'
-D --enable-deprecated-rules 'Enable sigma rules marked as deprecated.'
-n --enable-noisy-rules 'Enable rules marked as noisy.'
-u --update-rules 'Clone latest hayabusa-rule'
-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)'
--rfc-3339 'Output date and time in RFC 3339 format. (example: 2006-08-07T12:34:56.485214 -06:00)'
-u --utc 'Output time in UTC format. (default: local time)'
-U --utc 'Output time in UTC format. (default: local time)'
-t --thread-number=[NUMBER] 'Thread number. (default: optimal number for performance.)'
-s --statistics 'Prints statistics of event IDs.'
-q --quiet 'Quiet mode. Do not display the launch banner.'

View File

@@ -7,6 +7,7 @@ extern crate static_vcruntime;
use chrono::Datelike;
use chrono::{DateTime, Local};
use evtx::{EvtxParser, ParserSettings};
use git2::Repository;
use hayabusa::detections::detection::{self, EvtxRecordInfo};
use hayabusa::detections::print::AlertMessage;
use hayabusa::detections::print::ERROR_LOG_PATH;
@@ -24,6 +25,7 @@ use serde_json::Value;
use std::collections::{HashMap, HashSet};
use std::ffi::OsStr;
use std::fmt::Display;
use std::fs::create_dir;
use std::io::BufWriter;
use std::path::Path;
use std::sync::Arc;
@@ -72,10 +74,28 @@ impl App {
&analysis_start_time.day().to_owned()
));
}
if configs::CONFIG
.read()
.unwrap()
.args
.is_present("update-rules")
{
match self.update_rules() {
Ok(_ok) => println!("Rules updated successfully."),
Err(e) => {
AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&format!("Failed to update rules. {:?} ", e),
)
.ok();
}
}
return;
}
if !Path::new("./config").exists() {
AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&"Hayabusa could not find the config directory.\nPlease run it from the Hayabusa root directory.\nExample: ./bin/hayabusa-1.0.0-windows-x64.exe".to_string()
&"Hayabusa could not find the config directory.\nPlease run it from the Hayabusa root directory.\nExample: ./hayabusa-1.0.0-windows-x64.exe".to_string()
)
.ok();
return;
@@ -276,6 +296,16 @@ impl App {
configs::CONFIG.read().unwrap().args.value_of("rules"),
&filter::exclude_ids(),
);
if rule_files.len() == 0 {
AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&"No rules were loaded. Please download the latest rules with the --update-rules option.\r\n".to_string(),
)
.ok();
return;
}
let mut pb = ProgressBar::new(evtx_files.len() as u64);
pb.show_speed = false;
self.rule_keys = self.get_all_keys(&rule_files);
@@ -472,6 +502,57 @@ impl App {
}
}
}
/// update rules(hayabusa-rules subrepository)
fn update_rules(&self) -> Result<(), git2::Error> {
let open_result = Repository::open(Path::new("."));
if open_result.is_err() {
AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&"Failed to open the git repository.".to_string(),
)
.ok();
println!(
"Attempting to git clone the hayabusa-rules repository into the rules folder."
);
// レポジトリが開けなかった段階でhayabusa rulesのgit cloneを実施する
return self.clone_rules();
}
let rules_path = Path::new("./rules");
if !rules_path.exists() {
create_dir(rules_path).ok();
}
let hayabusa_repo = open_result.unwrap();
let submodules = hayabusa_repo.submodules()?;
for mut submodule in submodules {
submodule.update(true, None)?;
}
return Ok(());
}
/// git clone でhauyabusa-rules レポジトリをrulesフォルダにgit cloneする関数
fn clone_rules(&self) -> Result<(), git2::Error> {
match Repository::clone(
"https://github.com/Yamato-Security/hayabusa-rules.git",
"rules",
) {
Ok(_repo) => {
println!("Finished cloning the hayabusa-rules repository.");
return Ok(());
}
Err(e) => {
AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&format!(
"Failed to git clone into the rules folder. Please rename your rules folder name. {}",
e
),
)
.ok();
return Err(git2::Error::from_str(&String::default()));
}
};
}
}
#[cfg(test)]