Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

also find case insensitive filenames #59

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pol_export = []
evtxscan = ["evtx"]
evtxcat = ["evtx", "colored_json", "term-table", "termsize"]
evtxls = ["evtx", "colored", "lazy-regex", "regex", "sigpipe", "dfirtk-eventdata"]
evtxanalyze = ["evtx", "dfirtk-sessionevent-derive", "dfirtk-eventdata", "exitcode"]
evtxanalyze = ["evtx", "dfirtk-sessionevent-derive", "dfirtk-eventdata", "exitcode", "walkdir"]
evtx2bodyfile = ["evtx", "getset", "ouroboros", "indicatif"]
ipgrep = []
ts2date = ["regex"]
Expand Down Expand Up @@ -162,6 +162,7 @@ lazy-regex = {version = "3.0.0", optional=true}
sigpipe = {version = "0", optional=true}
phf = {version = "0.11", optional=true}
exitcode = {version="1.1.2", optional=true}
walkdir = {version="2.5.0", optional=true}

# evtx2bodyfile
indicatif = {version="0.17", optional=true}
Expand Down
29 changes: 0 additions & 29 deletions src/bin/evtxanalyze/cli.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::{io::stdout, path::PathBuf};

use anyhow::bail;
use clap::{Parser, Subcommand, ValueEnum, ValueHint};
use dfir_toolkit::common::HasVerboseFlag;
use log::LevelFilter;
Expand Down Expand Up @@ -83,20 +82,6 @@ impl Cli {
evtx_files_dir,
session_id,
} => {
if !evtx_files_dir.exists() {
bail!(
"directory '{}' does not exist. Aborting now.",
evtx_files_dir.to_string_lossy()
)
}

if !evtx_files_dir.is_dir() {
bail!(
"'{}' is no directory. Aborting now.",
evtx_files_dir.to_string_lossy()
);
}

let sessions = SessionStore::import(evtx_files_dir, true)?;
match sessions.find_session(session_id) {
None => log::error!("no value found for session id {session_id}"),
Expand All @@ -120,20 +105,6 @@ impl Cli {
evtx_files_dir,
include_anonymous,
} => {
if !evtx_files_dir.exists() {
bail!(
"directory '{}' does not exist. Aborting now.",
evtx_files_dir.to_string_lossy()
)
}

if !evtx_files_dir.is_dir() {
bail!(
"'{}' is no directory. Aborting now.",
evtx_files_dir.to_string_lossy()
);
}

let sessions = SessionStore::import(evtx_files_dir, *include_anonymous)?;

let mut csv_writer = csv::Writer::from_writer(stdout());
Expand Down
85 changes: 61 additions & 24 deletions src/bin/evtxanalyze/sessions/session_store.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use std::{collections::HashMap, path::Path};

use anyhow::bail;
use dfirtk_eventdata::SessionId;
use evtx::EvtxParser;
use walkdir::WalkDir;

use super::{Session, SessionEvent};

static KNOWN_FILES: & [&str] = &[
static KNOWN_FILES: &[&str] = &[
"Security.evtx",
"Microsoft-Windows-TerminalServices-RDPClient%4Operational.evtx",
"Microsoft-Windows-TerminalServices-RemoteConnectionManager%4Operational.evtx",
"Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx"
"Microsoft-Windows-TerminalServices-LocalSessionManager%4Operational.evtx",
];

pub struct SessionStore {
Expand All @@ -18,21 +20,59 @@ pub struct SessionStore {

impl SessionStore {
pub fn import(evtx_files_dir: &Path, include_anonymous: bool) -> Result<Self, anyhow::Error> {
if !evtx_files_dir.exists() {
bail!(
"directory '{}' does not exist. Aborting now.",
evtx_files_dir.to_string_lossy()
)
}

if !evtx_files_dir.is_dir() {
bail!(
"'{}' is no directory. Aborting now.",
evtx_files_dir.to_string_lossy()
);
}

let mut sessions = Self {
sessions: HashMap::<SessionId, Session>::new(),
};


for filename in KNOWN_FILES {
let path = evtx_files_dir.join(filename);

if ! path.exists() {
log::error!("expected file '{}', but it does not exist. Omitting it...", path.display());
continue;
let mut path = evtx_files_dir.join(filename);

// maybe we have troubles with case sensitivity
// Let's try this:
if !path.exists() {
let mut files = WalkDir::new(evtx_files_dir)
.max_depth(1)
.into_iter()
.filter_map(Result::ok)
.filter(|f| f.file_name().to_string_lossy().to_lowercase() == filename.to_lowercase());

if let Some(first_entry) = files.next() {
path = first_entry.into_path();

// there should be no more entry, otherwise
// the filename is unambigious
if let Some(next_entry) = files.next() {
log::error!(
"expected file '{filename}', but there exist \
multiple variants of this name. I found at least \
'{}' and '{}'. Omitting those files...",
path.file_name().unwrap().to_string_lossy(),
next_entry.file_name().to_string_lossy()
);
continue;
}
}
}

if ! path.is_file() {
log::error!("tried to read '{}', but it is not a file. Omiting it...", path.display());
if !path.is_file() {
log::error!(
"tried to read '{}', but it is not a file. Omiting it...",
path.display()
);
continue;
}

Expand Down Expand Up @@ -76,19 +116,16 @@ impl SessionStore {
}

pub fn find_session(&self, index: &str) -> Option<&Session> {
self.sessions.iter().find(|(k, _)| {
match k {
SessionId::ActivityId(id)|
SessionId::SessionName(id)|
SessionId::LogonId(id) |
SessionId::SessionId(id) => {
index == id
}
SessionId::None(id) => {
index == id.to_string()
},
}
}).map(|(_, v)| v)
self.sessions
.iter()
.find(|(k, _)| match k {
SessionId::ActivityId(id)
| SessionId::SessionName(id)
| SessionId::LogonId(id)
| SessionId::SessionId(id) => index == id,
SessionId::None(id) => index == id.to_string(),
})
.map(|(_, v)| v)
}
}

Expand All @@ -102,4 +139,4 @@ impl IntoIterator for SessionStore {
v.sort();
v.into_iter()
}
}
}
Loading