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

2
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "rules"]
path = rules
url = git@github.com:Yamato-Security/hayabusa-rules.git
url = https://github.com/Yamato-Security/hayabusa-rules.git

156
Cargo.lock generated
View File

@@ -77,9 +77,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
version = "0.3.63"
version = "0.3.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6"
checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f"
dependencies = [
"addr2line",
"cc",
@@ -170,6 +170,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "camino"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f3132262930b0522068049f5870a856ab8affc80c70d08b6ecb785771a6fc23"
dependencies = [
"serde",
]
[[package]]
name = "cargo-platform"
version = "0.1.2"
@@ -181,13 +190,13 @@ dependencies = [
[[package]]
name = "cargo_metadata"
version = "0.12.3"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714a157da7991e23d90686b9524b9e12e0407a108647f52e9328f4b3d51ac7f"
checksum = "ba2ae6de944143141f6155a473a6b02f66c7c3f9f47316f802f80204ebfe6e12"
dependencies = [
"camino",
"cargo-platform",
"semver 0.11.0",
"semver-parser 0.10.2",
"semver 1.0.4",
"serde",
"serde_json",
]
@@ -197,6 +206,9 @@ name = "cc"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
@@ -764,6 +776,21 @@ version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
[[package]]
name = "git2"
version = "0.13.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6"
dependencies = [
"bitflags",
"libc",
"libgit2-sys",
"log",
"openssl-probe",
"openssl-sys",
"url 2.2.2",
]
[[package]]
name = "glob"
version = "0.3.0"
@@ -815,6 +842,7 @@ dependencies = [
"dotenv",
"evtx",
"flate2",
"git2",
"hashbrown 0.12.0",
"hex 0.4.3",
"hhmmss",
@@ -831,7 +859,7 @@ dependencies = [
"serde_json",
"slack-hook",
"static_vcruntime",
"tokio 1.16.0",
"tokio 1.16.1",
"yaml-rust",
]
@@ -1048,6 +1076,15 @@ dependencies = [
"libc",
]
[[package]]
name = "jobserver"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
dependencies = [
"libc",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
@@ -1066,9 +1103,49 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.115"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a8d982fa7a96a000f6ec4cfe966de9703eccde29750df2bb8949da91b0e818d"
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
[[package]]
name = "libgit2-sys"
version = "0.12.26+1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494"
dependencies = [
"cc",
"libc",
"libssh2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
]
[[package]]
name = "libssh2-sys"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca"
dependencies = [
"cc",
"libc",
"libz-sys",
"openssl-sys",
"pkg-config",
"vcpkg",
]
[[package]]
name = "libz-sys"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "linked-hash-map"
@@ -1087,9 +1164,9 @@ dependencies = [
[[package]]
name = "lock_api"
version = "0.4.5"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
dependencies = [
"scopeguard",
]
@@ -1368,7 +1445,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api 0.4.5",
"lock_api 0.4.6",
"parking_lot_core 0.8.5",
]
@@ -1425,15 +1502,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]]
name = "pin-project-lite"
version = "0.2.8"
@@ -1473,9 +1541,9 @@ dependencies = [
[[package]]
name = "pulldown-cmark"
version = "0.8.0"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8"
checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
dependencies = [
"bitflags",
"memchr",
@@ -1796,9 +1864,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "security-framework"
version = "2.5.0"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d09d3c15d814eda1d6a836f2f2b56a6abc1446c8a34351cb3180d3db92ffe4ce"
checksum = "3fed7948b6c68acbb6e20c334f55ad635dc0f75506963de4464289fbd3b051ac"
dependencies = [
"bitflags",
"core-foundation",
@@ -1809,9 +1877,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
version = "2.5.0"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e90dd10c41c6bfc633da6e0c659bd25d31e0791e5974ac42970267d59eba87f7"
checksum = "a57321bf8bc2362081b2599912d2961fe899c0efadf1b4b2f8d48b3e253bb96c"
dependencies = [
"core-foundation-sys",
"libc",
@@ -1823,16 +1891,15 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser 0.7.0",
"semver-parser",
]
[[package]]
name = "semver"
version = "0.11.0"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
dependencies = [
"semver-parser 0.10.2",
"serde",
]
@@ -1842,15 +1909,6 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "semver-parser"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
dependencies = [
"pest",
]
[[package]]
name = "serde"
version = "1.0.136"
@@ -1931,9 +1989,9 @@ dependencies = [
[[package]]
name = "skeptic"
version = "0.13.6"
version = "0.13.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "188b810342d98f23f0bb875045299f34187b559370b041eb11520c905370a888"
checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8"
dependencies = [
"bytecount",
"cargo_metadata",
@@ -2230,9 +2288,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.16.0"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95e99d373042c30406d317cfc5bfad7b5d604bdd31dab72cf8739abebaa64aee"
checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a"
dependencies = [
"bytes 1.1.0",
"libc",
@@ -2387,12 +2445,6 @@ dependencies = [
"cfg-if 0.1.10",
]
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "unicase"
version = "2.6.0"
@@ -2668,6 +2720,6 @@ dependencies = [
[[package]]
name = "zeroize"
version = "1.5.1"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4062c749be08d90be727e9c5895371c3a0e49b90ba2b9592dc7afda95cc2b719"
checksum = "7c88870063c39ee00ec285a2f8d6a966e5b6fb2becc4e8dac77ed0d370ed6006"

View File

@@ -31,6 +31,7 @@ pbr = "*"
hashbrown = "0.12.*"
colored = "2.*"
hex = "0.4.*"
git2="0.13"
[target.'cfg(windows)'.dependencies]
is_elevated = "0.1.2"

View File

@@ -140,11 +140,12 @@ Hayabusaの[Releases](https://github.com/Yamato-Security/hayabusa/releases)か
git clone https://github.com/Yamato-Security/hayabusa.git --recursive
```
`--recursive` をつけ忘れた場合、サブモジュールとして管理されている `rules/` 内のファイルが取得できません。
以下のコマンドでサブモジュールを取得してください
--recursive をつけ忘れた場合、サブモジュールとして管理されている rules/ 内のファイルが取得できません。
Hayabusaでは検知ルールを`rules/`フォルダの取得はコンパイル後に以下のコマンドでルールの最新版を取得することができます
rulesフォルダ配下でファイルを削除や更新をしていた場合は更新されないのでその場合はrulesフォルダを他の名前にリネームしたうえで以下のコマンドを打ってください。
```bash
git submodule update --init
.\hayabusa.exe -u
```
# ソースコードからのコンパイル(任意)
@@ -199,13 +200,14 @@ USAGE:
-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.'
@@ -226,7 +228,8 @@ FLAGS:
--rfc-3339 Output date and time in RFC 3339 format. (example: 2006-08-07T12:34:56.485214
-06:00)
-s, --statistics Prints statistics of event IDs.
-u, --utc Output time in UTC format. (default: local time)
-u, --update-rules Clone latest hayabusa-rule
-U, --utc Output time in UTC format. (default: local time)
-V, --version Prints version information
-v, --verbose Output verbose information.
@@ -241,7 +244,6 @@ OPTIONS:
--start-timeline <STARTTIMELINE> Start time of the event to load from event file. (example: '2018/11/28
12:00:00 +09:00')
-t, --thread-number <NUMBER> Thread number. (default: optimal number for performance.)
```
## 使用例

View File

@@ -138,11 +138,14 @@ You can also `git clone` the repository with the following command and compile b
git clone https://github.com/Yamato-Security/hayabusa.git --recursive
```
If you forget to use `--recursive` option, `rules/` files which managed in submodule did not cloned.
Use following command to import submodules.
If you forget to use --recursive option, rules/ files which managed in submodule did not cloned.
You can get latest Hayabusa rules with the execute following command.
When you modified or erased in rules/ , update is failed.
In this case, you can get latest Hayabusa if you renamed rules folder and execute following command.
```bash
git submodule update --init
.\hayabusa.exe -u
```
# Compiling from source (Optional)

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)]