Skip to content

Commit

Permalink
Various bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
noproto committed Jul 26, 2021
1 parent 4702f09 commit 892e3f8
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 165 deletions.
2 changes: 1 addition & 1 deletion src/application/common/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ macro_rules! build_hash {
// Load hash modules
// TODO: Make sure this doesn't conflict with crate namespace
mod hashes {
automod::dir!(pub "src/application/common/hash/hashes");
automod::dir!(pub "common/hash/hashes");
}

// Collect hashes in distributed slice
Expand Down
6 changes: 5 additions & 1 deletion src/application/platforms/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,9 @@ fn os_version_value(line: &str) -> Result<String, Box<dyn Error>> {
}

pub fn is_superuser() -> bool {
unsafe { libc::getuid() == 0 }
#[cfg(feature = "whitelist_test")]
let res: bool = true;
#[cfg(not(feature = "whitelist_test"))]
let res: bool = unsafe { libc::getuid() == 0 };
res
}
2 changes: 1 addition & 1 deletion src/library/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ crate-type = ["cdylib"]

# Cross-platform dependencies
[dependencies]
libc = { version = "0.2" }
libc = { version = "^0.2.98" }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
rusqlite = { version = "0.25", features = ["bundled"] }
Expand Down
2 changes: 1 addition & 1 deletion src/library/common/action/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ macro_rules! build_action {

// Load action modules
mod actions {
automod::dir!(pub "src/library/common/action/actions");
automod::dir!(pub "common/action/actions");
}

// Collect actions in distributed slice
Expand Down
2 changes: 1 addition & 1 deletion src/library/common/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ macro_rules! build_hash {
// Load hash modules
// TODO: Make sure this doesn't conflict with crate namespace
mod hashes {
automod::dir!(pub "src/library/common/hash/hashes");
automod::dir!(pub "common/hash/hashes");
}

// Collect hashes in distributed slice
Expand Down
135 changes: 135 additions & 0 deletions src/library/common/hook.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use crate::common::{action,
db};
use std::{ffi::OsString,
lazy::SyncLazy,
sync::Mutex};

pub static CUR_PROG: SyncLazy<Mutex<OsString>> = SyncLazy::new(|| Mutex::new(OsString::new()));
pub static FN_STACK: SyncLazy<Mutex<Vec<(i64, usize)>>> = SyncLazy::new(|| Mutex::new(vec![]));

#[allow(unused_mut)]
pub unsafe extern "C" fn generic_hook(mut arg1: usize, mut args: ...) -> isize {
/*
Generic hook: a variadic function capable of interposing other functions through runtime polymorphism
Linux:
Notes on limitations of WhiteBeam's generic Linux hook, planned to be resolved in future versions of WhiteBeam:
- Can receive any function call and arguments, but hardcoded to call functions with up to 6 arguments
(supports 1,587 out of 1,589 glibc functions)
- 6 out of 1,589 glibc functions are unsupported due to no VaList equivalent
(argp_failure, fcntl, ioctl, makecontext, strfmon, syscall, and ulimit)
- No known security implications while Execution and Filesystem hooks are enforcing prevention mode
Windows:
- Can receive any function call and arguments
macOS:
Untested
*/
// TODO: Test zero argument case
// Program
let src_prog: String = { CUR_PROG.lock().expect("WhiteBeam: Failed to lock mutex").clone().into_string().expect("WhiteBeam: Invalid executable name") };
// Hook
let stack_hook: (i64, usize) = { FN_STACK.lock().expect("WhiteBeam: Failed to lock mutex").pop().expect("WhiteBeam: Lost track of environment") };
let stack_hook_id = stack_hook.0;
let stack_hook_addr = stack_hook.1;
let mut hook: db::HookRow = {
let hook_cache_lock = db::HOOK_CACHE.lock().expect("WhiteBeam: Failed to lock mutex");
let hook_option = hook_cache_lock.iter().find(|hook| hook.id == stack_hook_id);
hook_option.expect("WhiteBeam: Lost track of environment").clone()
};
let hook_orig = hook.clone();
// Arguments
// TODO: Create Rust structures here with generic T and enum of Datatype rather than passing pointers and leaking memory
// Converted back into respective C datatypes when Actions are completed
// https://doc.rust-lang.org/book/ch10-01-syntax.html
// https://stackoverflow.com/questions/40559931/vector-store-mixed-types-of-data-in-rust
let mut arg_vec: Vec<db::ArgumentRow> = {
let arg_cache_lock = db::ARG_CACHE.lock().expect("WhiteBeam: Failed to lock mutex");
arg_cache_lock.iter().filter(|arg| arg.hook == stack_hook_id).map(|arg| arg.clone()).collect()
};
let mut argc: usize = arg_vec.iter().filter(|arg| arg.parent.is_none()).count();
// FIXME: Refactor block, this won't work for edge cases
// TODO: Only do this for parent arguments?
if argc > 0 {
let mut current_arg_idx = 0;
arg_vec[current_arg_idx].real = arg1 as usize;
current_arg_idx += 1;
for i in current_arg_idx..argc {
if arg_vec[current_arg_idx].variadic {
// TODO: arg_vec.splice()
let mut loops: usize = 0;
let mut do_break: bool = false;
let mut next_argv: usize = args.arg();
while !(do_break) {
// Excess parameters are truncated in ConsumeVariadic action
if next_argv == 0 {
do_break = true;
}
if loops == 0 {
arg_vec[i].real = next_argv;
} else {
let mut cloned_arg = arg_vec[i].clone();
cloned_arg.real = next_argv;
current_arg_idx += 1;
arg_vec.insert(current_arg_idx, cloned_arg);
}
if do_break {
break;
}
next_argv = args.arg();
loops += 1;
}
current_arg_idx += 1;
} else {
arg_vec[current_arg_idx].real = args.arg();
current_arg_idx += 1;
}
}
}
// Rules
let mut rules: Vec<db::RuleRow> = {
let rule_cache_lock = db::RULE_CACHE.lock().expect("WhiteBeam: Failed to lock mutex");
let all_arg_ids: Vec<i64> = arg_vec.iter().map(|arg| arg.id).collect();
rule_cache_lock.iter().filter(|rule| all_arg_ids.contains(&rule.arg)).map(|rule| rule.clone()).collect()
};
// Actions
for rule in rules {
// TODO: Eliminate redundancy
// TODO: Is clone of src_prog needed?
let (hook_new, arg_vec_new, do_return, return_value) = action::process_action(src_prog.clone(), rule, hook, arg_vec);
hook = hook_new;
arg_vec = arg_vec_new;
if do_return {
return return_value;
}
};
// Dispatch
// FIXME: Bug in some *64 functions like open64 => openat and fopen64 => fdopen
// TODO: Generic symbol resolution
let fn_addr = match hook_orig.symbol.as_ref() {
"open64" => libc::openat as *const u8,
_ => crate::platforms::linux::dlsym_next_relative(&hook.symbol, stack_hook_addr)
};
let hooked_fn_zargs: unsafe extern "C" fn() -> isize = std::mem::transmute(fn_addr);
let hooked_fn_margs: unsafe extern "C" fn(arg1: usize, args: ...) -> isize = std::mem::transmute(fn_addr);
let par_args: Vec<&db::ArgumentRow> = arg_vec.iter().filter(|arg| arg.parent.is_none()).collect(); // Parent arguments
argc = par_args.len();
let ret: isize = match argc {
0 => hooked_fn_zargs(),
1 => hooked_fn_margs(par_args[0].real),
2 => hooked_fn_margs(par_args[0].real, par_args[1].real),
3 => hooked_fn_margs(par_args[0].real, par_args[1].real, par_args[2].real),
4 => hooked_fn_margs(par_args[0].real, par_args[1].real, par_args[2].real, par_args[3].real),
5 => hooked_fn_margs(par_args[0].real, par_args[1].real, par_args[2].real, par_args[3].real, par_args[4].real),
6 => hooked_fn_margs(par_args[0].real, par_args[1].real, par_args[2].real, par_args[3].real, par_args[4].real, par_args[5].real),
// Unsupported
_ => panic!("WhiteBeam: Unsupported operation"),
};
// TODO: Post actions
let (do_return, return_value) = action::process_post_action(src_prog.clone(), hook_orig, hook, arg_vec);
if do_return {
return return_value;
}
ret
}
2 changes: 2 additions & 0 deletions src/library/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Generic hook
pub mod hook;
// Datatype conversion functions
pub mod convert;
// Database
Expand Down
Loading

0 comments on commit 892e3f8

Please sign in to comment.