Skip to content

Commit

Permalink
maybe a fix for missing stuff when not running as root it should see
Browse files Browse the repository at this point in the history
  • Loading branch information
theflakes committed Apr 29, 2023
1 parent 688cdb5 commit 1d4666d
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 12 deletions.
2 changes: 1 addition & 1 deletion 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
@@ -1,6 +1,6 @@
[package]
name = "lin_fh"
version = "0.4.1"
version = "0.4.5"
authors = ["brian kellogg <[email protected]>"]
edition = "2021"

Expand Down
2 changes: 2 additions & 0 deletions src/data_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Options:
-p, --port <port> Destination port to send output to [default: 80]
-l, --limit Limit CPU use
-s, --suidsgid Search for suid and sgid files
- This will search the entire '/' including subdirectories
- Can take a very long time
Note:
If not run as root some telemetry cannot be harvested.
Expand Down
44 changes: 35 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mod mutate;
mod time;

use walkdir::WalkDir;
use std::fs::{self};
use std::{fs::{self}, path::{PathBuf, Path}};
use regex::Regex;
use {data_def::*, file_op::*, mutate::*, time::*};
use std::os::unix::fs::MetadataExt;
Expand Down Expand Up @@ -162,7 +162,7 @@ fn find_paths(text: &str, already_seen: &mut Vec<String>) -> std::io::Result<()>
.expect("Invalid Regex");
}
for c in RE.captures_iter(text) {
let path = std::path::Path::new(&c[1]);
let path = Path::new(&c[1]);
process_file("FileContent", path, already_seen)?;
}
Ok(())
Expand All @@ -172,7 +172,7 @@ fn find_paths(text: &str, already_seen: &mut Vec<String>) -> std::io::Result<()>
check if a given file is one we want to inspect the contents of
for interesting strings and references to other files
*/
fn watch_file(file_path: &std::path::Path, path: &str, already_seen: &mut Vec<String>) -> std::io::Result<()> {
fn watch_file(file_path: &Path, path: &str, already_seen: &mut Vec<String>) -> std::io::Result<()> {
if WATCH_FILES.iter().any(|f| path.contains(f)) {
let data = read_file_string(file_path)?;
if !data.is_empty() {
Expand All @@ -185,7 +185,7 @@ fn watch_file(file_path: &std::path::Path, path: &str, already_seen: &mut Vec<St
}

// harvest a file's metadata
fn process_file(pdt: &str, file_path: &std::path::Path, already_seen: &mut Vec<String>) -> std::io::Result<()> {
fn process_file(pdt: &str, file_path: &Path, already_seen: &mut Vec<String>) -> std::io::Result<()> {
let p: String = file_path.to_string_lossy().into();
if file_path.is_file() && !already_seen.contains(&p.clone()) {
already_seen.push(p); // track files we've processed so we don't process them more than once
Expand Down Expand Up @@ -308,7 +308,7 @@ fn process_open_file(pdt: &str, fd: &str, path: &str, pid: i32, already_seen: &m
TxProcessFile::new(pdt.to_string(), data_type.clone(), get_now()?,
pid, fd.to_string(), path.to_string(),
path_exists(fd)).report_log();
process_file(&data_type, std::path::Path::new(path), already_seen)?;
process_file(&data_type, Path::new(path), already_seen)?;
Ok(())
}

Expand Down Expand Up @@ -337,7 +337,7 @@ fn process_file_descriptors(path: &str, root_path: &str, pid: i32, data_type: &s
}

// gather and report process information via procfs
fn process_process(root_path: &str, bin: std::path::PathBuf, already_seen: &mut Vec<String>) -> std::io::Result<()> {
fn process_process(root_path: &str, bin: PathBuf, already_seen: &mut Vec<String>) -> std::io::Result<()> {
let path: String = resolve_link(&bin)?.to_string_lossy().into();
let exists = path_exists(&path);
let cmd = read_file_string(&push_file_path(root_path, "/cmdline")?)?;
Expand Down Expand Up @@ -483,7 +483,7 @@ fn process_files(pdt: &str, path: &str, mut already_seen: &mut Vec<String>) -> s
"/etc/crontab" => parse_cron(pdt, path)?,
_ => {}
};
process_file(&pdt, std::path::Path::new(path), &mut already_seen)?;
process_file(&pdt, Path::new(path), &mut already_seen)?;
Ok(())
}

Expand Down Expand Up @@ -522,7 +522,7 @@ fn process_directory(pdt: &str, path: &str, mut already_seen: &mut Vec<String>)
Weird issue getting hung on a /proc dir on my box: /proc/4635/task/4635/net
ls: reading directory '/proc/4635/task/4635/net': Invalid argument
total 0
*/
fn find_suid_sgid(already_seen: &mut Vec<String>) -> std::io::Result<()> {
for entry in WalkDir::new("/")
.into_iter()
Expand All @@ -543,6 +543,31 @@ fn find_suid_sgid(already_seen: &mut Vec<String>) -> std::io::Result<()> {
}
}
Ok(())
}*/

// one possible implementation of walking a directory only visiting files
fn find_suid_sgid(dir: &Path, already_seen: &mut Vec<String>) -> std::io::Result<()> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path: PathBuf = entry.path();
if path.is_dir() {
find_suid_sgid(&path, already_seen)?;
} else {
let md = match entry.metadata() {
Ok(d) => d,
Err(_e) => continue // catch any errors so we can finish searching all dirs
};
let mode = md.mode();
let (is_suid, is_sgid) = is_suid_sgid(mode);
if is_suid || is_sgid {
process_file("SuidSgid", &path, already_seen)?;
}
sleep();
}
}
}
Ok(())
}

/*
Expand Down Expand Up @@ -572,8 +597,9 @@ fn main() -> std::io::Result<()> {
Err(_e) => continue};
}
}
// WARNING: searches entire directory structure
if ARGS.flag_suidsgid {
find_suid_sgid(&mut already_seen)?; // WARNING: searches entire directory structure
find_suid_sgid(&push_file_path("/", "")?, &mut already_seen)?;
}
Ok(())
}
2 changes: 1 addition & 1 deletion src/mutate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub fn to_int8(num: &str) -> std::io::Result<i8> {
Therefore have to break the 128bit value into 4 dwords, reverse them and recombine
See: https://users.rust-lang.org/t/convert-hex-socket-notation-to-ip-and-port/33858/8
*/
pub fn u128_to_ipv6 (mut n: u128) -> std::io::Result<::std::net::Ipv6Addr> {
pub fn u128_to_ipv6(mut n: u128) -> std::io::Result<::std::net::Ipv6Addr> {
unsafe { &mut *(&mut n as *mut u128 as *mut [u32; 4]) }
.iter_mut()
.for_each(|n: &mut u32| *n = n.swap_bytes());
Expand Down

0 comments on commit 1d4666d

Please sign in to comment.