Skip to content

Commit

Permalink
regdump knows flow-record
Browse files Browse the repository at this point in the history
  • Loading branch information
janstarke committed Oct 4, 2024
1 parent 9976bc7 commit 64eb685
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 27 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ clap = {version = "4.5", features = ["derive", "wrap_help", "cargo"] }
clap-verbosity-flag = "2.0.0"
csv = "1.2.2"
encoding_rs = "0.8"
flow-record = "0.4.6"
flow-record = "0.4.7"
#flow-record = {path="../flow-record"}

## setting release_max_level_info conflicts with evtx
Expand Down
22 changes: 19 additions & 3 deletions src/bin/regdump/cli.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
use std::{path::PathBuf, fs::File};

use clap::{Parser, ValueHint};
use clap::{Parser, ValueEnum, ValueHint};
use dfir_toolkit::common::HasVerboseFlag;
use log::LevelFilter;
use nt_hive2::{HiveParseMode, Hive};
use strum_macros::Display;

#[derive(ValueEnum, Clone, Display)]
pub (crate) enum OutputFormat {
/// registry export format format
#[strum(serialize = "reg")]
Reg,

/// bodyfile format
#[strum(serialize = "bodyfile")]
Bodyfile,

/// flow record format (<https://docs.rs/flow-record>)
#[strum(serialize = "record")]
Record
}

/// parses registry hive files and prints a bodyfile
#[derive(Parser)]
Expand All @@ -19,8 +35,8 @@ pub (crate) struct Cli {
pub (crate) logfiles: Vec<PathBuf>,

/// print as bodyfile format
#[clap(short('b'), long("bodyfile"))]
pub (crate) display_bodyfile: bool,
#[clap(short('F'), long("format"), default_value_t=OutputFormat::Reg)]
pub (crate) format: OutputFormat,

/// ignore the base block (e.g. if it was encrypted by some ransomware)
#[clap(short('I'), long)]
Expand Down
72 changes: 55 additions & 17 deletions src/bin/regdump/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use anyhow::{bail, Result};

use chrono::{DateTime, Utc};
use dfir_toolkit::common::bodyfile::Bodyfile3Line;
use dfir_toolkit::common::{FancyParser, FormattableDatetime};
use flow_record::derive::*;
use flow_record::prelude::*;
use nt_hive2::*;
use simplelog::{Config, SimpleLogger};
use std::fs::File;
use std::io::{Read, Seek};
use std::io::{Read, Seek, Write};

use crate::cli::Cli;

Expand All @@ -15,12 +18,18 @@ fn main() -> Result<()> {
let mut cli = Cli::parse_cli();
let _ = SimpleLogger::init(cli.verbose.log_level_filter(), Config::default());

fn do_print_key<RS>(hive: &mut Hive<RS, CleanHive>, root_key: &KeyNode, cli: &Cli) -> Result<()>
fn do_print_key<RS, W>(
hive: &mut Hive<RS, CleanHive>,
root_key: &KeyNode,
cli: &Cli,
ser: &mut Serializer<W>,
) -> Result<()>
where
RS: Read + Seek,
W: Write,
{
let mut path = Vec::new();
print_key(hive, root_key, &mut path, cli)
print_key(hive, root_key, &mut path, cli, ser)
}

match File::open(&cli.hive_file) {
Expand All @@ -45,7 +54,8 @@ fn main() -> Result<()> {
};

let root_key = &clean_hive.root_key_node().unwrap();
do_print_key(&mut clean_hive, root_key, &cli).unwrap();
let mut serializer = Serializer::new(std::io::stdout());
do_print_key(&mut clean_hive, root_key, &cli, &mut serializer).unwrap();
}
Err(why) => {
eprintln!(
Expand All @@ -59,35 +69,63 @@ fn main() -> Result<()> {
Ok(())
}

fn print_key<RS>(
#[derive(FlowRecord)]
#[flow_record(version = 1, source = "regdump", classification = "reg")]
struct RegistryKey<'d> {
path: String,
ctime: &'d DateTime<Utc>,
values_count: usize
}

fn print_key<RS, W>(
hive: &mut Hive<RS, CleanHive>,
keynode: &KeyNode,
path: &mut Vec<String>,
cli: &Cli,
ser: &mut Serializer<W>,
) -> Result<()>
where
RS: Read + Seek,
W: Write,
{
path.push(keynode.name().to_string());

let current_path = path.join("\\");
if cli.display_bodyfile {
let bf_line = Bodyfile3Line::new()
.with_name(&current_path)
.with_ctime(keynode.timestamp().into());
println!("{}", bf_line);
} else {
if cli.hide_timestamps {
println!("\n[{}]", &current_path);
} else {
println!("\n[{}]; {}", &current_path, FormattableDatetime::from(keynode.timestamp()));

match cli.format {
cli::OutputFormat::Reg => {
if cli.hide_timestamps {
println!("\n[{}]", &current_path);
} else {
println!(
"\n[{}]; {}",
&current_path,
FormattableDatetime::from(keynode.timestamp())
);
}

print_values(keynode);
}

print_values(keynode);
cli::OutputFormat::Bodyfile => {
let bf_line = Bodyfile3Line::new()
.with_name(&current_path)
.with_ctime(keynode.timestamp().into());
println!("{}", bf_line);
}

cli::OutputFormat::Record => {
let key = RegistryKey {
path: current_path,
ctime: keynode.timestamp(),
values_count: keynode.values().len()
};
ser.serialize(key)?;
}
}

for sk in keynode.subkeys(hive).unwrap().iter() {
print_key(hive, &sk.borrow(), path, cli)?;
print_key(hive, &sk.borrow(), path, cli, ser)?;
}
path.pop();

Expand Down

0 comments on commit 64eb685

Please # to comment.