#forensics #cybersecurity #registry #parser #windows

forensic-rs

一个基于Rust的框架,用于构建分析取证证据的工具,可以作为库在多个项目中重用,无需做任何更改

24个版本 (12个破坏性)

0.13.0 2024年4月5日
0.12.0 2024年3月4日
0.11.0 2024年2月27日
0.7.4 2023年11月28日
0.1.6 2022年11月24日

#131 in 解析器实现

Download history 12/week @ 2024-04-22 4/week @ 2024-04-29 10/week @ 2024-05-06 52/week @ 2024-05-13 75/week @ 2024-05-20 28/week @ 2024-05-27 35/week @ 2024-06-03 69/week @ 2024-06-10 14/week @ 2024-06-17 28/week @ 2024-06-24 9/week @ 2024-07-01 26/week @ 2024-07-08 49/week @ 2024-07-15 47/week @ 2024-07-22 69/week @ 2024-07-29 23/week @ 2024-08-05

每月189次下载
8 crates 中使用

MIT 许可证

240KB
5.5K SLoC

Forensic-rs

crates.io documentation MIT License Rust

一个基于Rust的框架,用于构建分析取证证据的工具,可以作为库在多个项目中重用,无需做任何更改。

注意:目前仍处于Alpha版本

社区

Discord

加入 Discord上的讨论,讨论与ForensicRS相关的一切。

简介

该框架背后的想法是允许重用取证证据分析工具。因此,框架将解析或读取证据的分析工具的代码与访问读取值的代码(注册表键、文件、SQL行)解耦。因此,分析UAL证据的工具可以用于无论证据是在三明治的结果中作为ZIP文件还是直接在文件系统上。

这样,如果我们想制作一个类似于Plaso的三明治处理器、EDR中的一个模块,甚至是一个具有图形界面的工具,如Eric Zimmerman的Registry Explorer,都可以使用Rust代码的可靠性和其易于集成到Python脚本中的优势。

支持的证据

  • Windows注册表:见RegistryReader特质。
  • SQL数据库:见SqlStatement特质。在sql_tests中还有一个围绕sqlite crate的基本包装示例。
  • 文件系统:有了这个特性,我们可以读取文件和目录。这非常有用,因为我们可以堆叠文件系统:一个ZIP文件中的OleObject中的文件,而这个ZIP文件也包含在另一个ZIP文件中。请参阅虚拟文件系统及其使用标准库(std::fs)的实现StdVirtualFS

注册表示例

因此,在这个框架中,我们将有允许我们访问Windows注册表的库。一个用于实时环境,使用Windows API,另一个用于解析注册表分区的文件。因此,我们还将有从注册表中提取数据的库,这些库需要从注册表访问实现中解耦。

这就是这个框架使用特性和帮助的地方

pub trait RegistryReader {
    fn open_key(&mut self, hkey : RegHiveKey, key_name : &str) -> ForensicResult<RegHiveKey>;
    fn read_value(&self, hkey : RegHiveKey, value_name : &str) -> ForensicResult<RegValue>;
    fn enumerate_values(&self, hkey : RegHiveKey) -> ForensicResult<Vec<String>>;
    fn enumerate_keys(&self, hkey : RegHiveKey) -> ForensicResult<Vec<String>>;
    fn key_at(&self, hkey : RegHiveKey, pos : u32) -> ForensicResult<String>;
    fn value_at(&self, hkey : RegHiveKey, pos : u32) -> ForensicResult<String>;
}

因此,现在我们可以编写我们的分析库,而不需要知道我们是在访问实时系统还是分区文件。

  • LiveRegistry库:实现了RegistryReader特性。
  • HiveParser库:实现了RegistryReader特性。
  • ShellBags分析器:接受一个RegistryReader作为参数来访问注册表。

ShellBags分析器可以用于EDR类似代理,或者在取证案例中作为分析工具。

SQL示例

SQL特性的sqlite数据库测试中提取。

let conn = prepare_db();
let w_conn = prepare_wrapper(conn);
let mut statement = w_conn.prepare("SELECT name, age FROM users;").unwrap();
test_database_content(statement.as_mut()).expect("Should not return error");

fn test_database_content<'a>(statement : &mut dyn SqlStatement) -> ForensicResult<()> {
    assert!(statement.next()?);
    let name : String = statement.read(0)?.try_into()?;
    let age : usize = statement.read(1)?.try_into()?;
    assert_eq!("Alice", name);
    assert_eq!(42, age);
    assert!(statement.next()?);
    let name : String = statement.read(0)?.try_into()?;
    let age : usize = statement.read(1)?.try_into()?;
    assert_eq!("Bob", name);
    assert_eq!(69, age);
    assert!(!statement.next()?);
    Ok(())
}

VFS示例

StdVirtualFS的sqlite数据库测试中提取。

const CONTENT: &'static str = "File_Content_Of_VFS";
let tmp = std::env::temp_dir();
let tmp_file = tmp.join("test_vfs_file.txt");
let mut file = std::fs::File::create(&tmp_file).unwrap();
file.write_all(CONTENT.as_bytes()).unwrap();
drop(file);

let std_vfs = StdVirtualFS::new();
test_file_content(&std_vfs,&tmp_file);

fn test_file_content(std_vfs : &impl VirtualFileSystem, tmp_file : &PathBuf) {
    let content = std_vfs.read_to_string(tmp_file).unwrap();
    assert_eq!(CONTENT, content);
    
}

日志

为了简化模块、插件和库的开发,提供了一些与logcrate语法相同的宏。

// For production use initialize_logger(logger) instead of testing_logger_dummy()
let log_receiver = testing_logger_dummy();
error!("This is log name: {}", "ERROR");
warn!("This is log name: {}", "WARN");
info!("This is log name: {}", "INFO");
debug!("This is log name: {}", "DEBUG");
trace!("This is log name: {}", "TRACE");
assert_eq!("This is log name: ERROR", log_receiver.recv().unwrap());

通知和警报

为了简化处理或分析工件时异常的检测,我们可以使用通知。它使用与logcrate相似的语法。

// For production use initialize_notifier(notifier) instead of testing_notifier_dummy()
let notification_receiver = testing_notifier_dummy();
notify_high!(NotificationType::AntiForensicsDetected, "The registry key {} is not present. The only possibility is that someone deleted it.", r"HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList");
assert_eq!(r"The registry key HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList is not present. The only possibility is that someone deleted it.", notification_receiver.recv().unwrap().data);

库列表

依赖关系

~110–345KB