merge feature/yaml

This commit is contained in:
ichiichi11
2020-11-11 23:20:14 +09:00
10 changed files with 143 additions and 60 deletions

View File

@@ -1,3 +1,4 @@
use clap::{App, AppSettings, Arg, ArgMatches};
use std::fs::File;
use std::io::prelude::*;
use std::sync::Once;
@@ -6,6 +7,7 @@ use std::sync::Once;
pub struct SingletonReader {
pub regex: Vec<Vec<String>>,
pub whitelist: Vec<Vec<String>>,
pub args: ArgMatches<'static>,
}
pub fn singleton() -> Box<SingletonReader> {
@@ -17,6 +19,7 @@ pub fn singleton() -> Box<SingletonReader> {
let singleton = SingletonReader {
regex: read_csv("regexes.txt"),
whitelist: read_csv("whitelist.txt"),
args: build_app().get_matches(),
};
SINGLETON = Some(Box::new(singleton));
@@ -26,6 +29,33 @@ pub fn singleton() -> Box<SingletonReader> {
}
}
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())
})
.unwrap();
App::new(program)
.about("Yea! (Yamato Event Analyzer). Aiming to be the world's greatest Windows event log analysis tool!")
.version("0.0.1")
.author("Author name <author@example.com>")
.setting(AppSettings::VersionlessSubcommands)
.arg(Arg::from_usage("-f --filepath=[FILEPATH] 'event file path'"))
.arg(Arg::from_usage("--attackhunt=[ATTACK_HUNT] 'Attack Hunt'"))
.arg(Arg::from_usage("--csv-timeline=[CSV_TIMELINE] 'csv output timeline'"))
.arg(Arg::from_usage("--human-readable-timeline=[HUMAN_READABLE_TIMELINE] 'human readable timeline'"))
.arg(Arg::from_usage("-l --lang=[LANG] 'output language'"))
.arg(Arg::from_usage("-t --timezone=[TIMEZONE] 'timezone setting'"))
.arg(Arg::from_usage("-d --directory 'event log files directory'"))
.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 read_csv(filename: &str) -> Vec<Vec<String>> {
let mut f = File::open(filename).expect("file not found!!!");
let mut contents: String = String::new();

View File

@@ -1,9 +1,10 @@
mod application;
mod applocker;
mod common;
mod configs;
pub mod configs;
pub mod detection;
mod powershell;
pub mod print;
mod security;
mod sysmon;
mod system;

View File

@@ -2,7 +2,6 @@ use crate::detections::utils;
use crate::models::event;
use regex::Regex;
use std::collections::HashMap;
extern crate csv;
pub struct PowerShell {}
@@ -25,6 +24,7 @@ impl PowerShell {
if event_id != "4103" {
return;
}
let default = String::from("");
let commandline = event_data.get("ContextInfo").unwrap_or(&default);
@@ -48,6 +48,7 @@ impl PowerShell {
if event_id != "4104" {
return;
}
let default = String::from("");
let path = event_data.get("Path").unwrap().to_string();
if path == "".to_string() {

63
src/detections/print.rs Normal file
View File

@@ -0,0 +1,63 @@
extern crate chrono;
extern crate lazy_static;
use chrono::{DateTime, TimeZone, Utc};
use lazy_static::lazy_static;
use std::collections::BTreeMap;
use std::sync::Mutex;
#[derive(Debug)]
pub struct Message {
map: BTreeMap<DateTime<Utc>, Vec<String>>,
}
lazy_static! {
pub static ref MESSAGES: Mutex<Message> = Mutex::new(Message::new());
}
impl Message {
pub fn new() -> Self {
let messages: BTreeMap<DateTime<Utc>, Vec<String>> = BTreeMap::new();
Message { map: messages }
}
/// メッセージを設定
pub fn insert(&mut self, time: DateTime<Utc>, message: String) {
match self.map.get_mut(&time) {
Some(v) => {
v.push(message.to_string());
}
None => {
let m = vec![message.to_string(); 1];
self.map.insert(time, m);
}
}
}
/// メッセージを返す
pub fn get(&self, time: DateTime<Utc>) -> Vec<String> {
match self.map.get(&time) {
Some(v) => (&v).to_vec(),
None => Vec::new(),
}
}
/// Messageのなかに入っているメッセージすべてを表示する
pub fn debug(&self) {
println!("{:?}", self.map);
}
}
#[test]
fn test_create_and_append_message() {
let mut message = Message::new();
let poke = Utc.ymd(1996, 2, 27).and_hms(1, 5, 1);
let taka = Utc.ymd(2000, 1, 21).and_hms(9, 6, 1);
message.insert(poke, "TEST".to_string());
message.insert(poke, "TEST2".to_string());
message.insert(taka, "TEST3".to_string());
let display = format!("{}", format_args!("{:?}", message));
let expect = "Message { map: {1996-02-27T01:05:01Z: [\"TEST\", \"TEST2\"], 2000-01-21T09:06:01Z: [\"TEST3\"]} }";
assert_eq!(display, expect);
}

View File

@@ -56,27 +56,23 @@ pub fn check_command(
let re = Regex::new(r"'.*$").unwrap();
base64.push_str(&re.replace_all(&base64.to_string(), ""));
}
if !base64.is_empty() {
if Regex::new(r"Compression.GzipStream.*Decompress")
.unwrap()
.is_match(commandline)
{
/*
if let decoded = base64::decode(&base64) {
let mut d = GzDecoder::new(decoded.as_slice());
let mut uncompressed = String::new();
d.read_to_string(&mut uncompressed).unwrap();
println!("Decoded : {}", uncompressed);
text.push_str("Base64-encoded and compressed function\n");
if let Ok(decoded) = base64::decode(&base64) {
if !base64.is_empty() {
if Regex::new(r"Compression.GzipStream.*Decompress")
.unwrap()
.is_match(commandline)
{
let mut d = GzDecoder::new(decoded.as_slice());
let mut uncompressed = String::new();
d.read_to_string(&mut uncompressed).unwrap();
println!("Decoded : {}", uncompressed);
text.push_str("Base64-encoded and compressed function\n");
} else {
println!("Decoded : {}", str::from_utf8(decoded.as_slice()).unwrap());
text.push_str("Base64-encoded function\n");
text.push_str(&check_obfu(str::from_utf8(decoded.as_slice()).unwrap()));
text.push_str(&check_regex(str::from_utf8(decoded.as_slice()).unwrap(), 0));
}
*/
} else {
let decoded = base64::decode(base64).unwrap();
println!("Decoded : {}", str::from_utf8(decoded.as_slice()).unwrap());
text.push_str("Base64-encoded function\n");
text.push_str(&check_obfu(str::from_utf8(decoded.as_slice()).unwrap()));
text.push_str(&check_regex(str::from_utf8(decoded.as_slice()).unwrap(), 0));
}
}
if !text.is_empty() {