Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ use alloc::vec::Vec;
use anyhow::Result as AnyhowResult;
#[cfg(feature = "stdlib")]
use eldritch_core::Value;
#[cfg(unix)]
use nix::unistd::{Gid, Group, Uid, User};
#[cfg(feature = "stdlib")]
use std::fs;
#[cfg(feature = "stdlib")]
Expand Down Expand Up @@ -71,8 +69,7 @@ fn list_impl(path: String) -> AnyhowResult<Vec<BTreeMap<String, Value>>> {

#[cfg(feature = "stdlib")]
fn create_dict_from_file(path: &Path) -> AnyhowResult<BTreeMap<String, Value>> {
use alloc::format;

use super::metadata;
let metadata = fs::metadata(path)?;
let mut dict = BTreeMap::new();

Expand All @@ -92,43 +89,10 @@ fn create_dict_from_file(path: &Path) -> AnyhowResult<BTreeMap<String, Value>> {

dict.insert("size".to_string(), Value::Int(metadata.len() as i64));

// Permissions (simplified)
#[cfg(unix)]
use ::std::os::unix::fs::PermissionsExt;
#[cfg(unix)]
let perms = format!("{:o}", metadata.permissions().mode());
#[cfg(not(unix))]
let perms = if metadata.permissions().readonly() {
"r"
} else {
"rw"
}
.to_string();

dict.insert("permissions".to_string(), Value::String(perms));

// Owner and Group
#[cfg(unix)]
{
use ::std::os::unix::fs::MetadataExt;
let uid = metadata.uid();
let gid = metadata.gid();

let user = User::from_uid(Uid::from_raw(uid)).ok().flatten();
let group = Group::from_gid(Gid::from_raw(gid)).ok().flatten();

let owner_name = user.map(|u| u.name).unwrap_or_else(|| uid.to_string());
let group_name = group.map(|g| g.name).unwrap_or_else(|| gid.to_string());

dict.insert("owner".to_string(), Value::String(owner_name));
dict.insert("group".to_string(), Value::String(group_name));
}
#[cfg(not(unix))]
{
// Fallback for Windows or others
dict.insert("owner".to_string(), Value::String("".to_string()));
dict.insert("group".to_string(), Value::String("".to_string()));
}
let meta = metadata::get_metadata(path)?;
dict.insert("permissions".to_string(), Value::String(meta.permissions));
dict.insert("owner".to_string(), Value::String(meta.owner));
dict.insert("group".to_string(), Value::String(meta.group));

// Absolute Path
let abs_path = path.canonicalize().unwrap_or_else(|_| path.to_path_buf());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#[cfg(feature = "stdlib")]
use alloc::string::String;
#[cfg(feature = "stdlib")]
use alloc::string::ToString;
#[cfg(feature = "stdlib")]
use anyhow::Result as AnyhowResult;
#[cfg(feature = "stdlib")]
use std::fs;
#[cfg(feature = "stdlib")]
use std::path::Path;

#[cfg(feature = "stdlib")]
pub struct FileMetadata {
pub owner: String,
pub group: String,
pub permissions: String,
}

#[cfg(feature = "stdlib")]
pub fn get_metadata(path: &Path) -> AnyhowResult<FileMetadata> {
let metadata = fs::metadata(path)?;

// Permissions
#[cfg(unix)]
use ::std::os::unix::fs::PermissionsExt;
#[cfg(unix)]
let perms = alloc::format!("{:o}", metadata.permissions().mode());
#[cfg(not(unix))]
let perms = if metadata.permissions().readonly() {
"r"
} else {
"rw"
}
.to_string();

// Owner and Group
#[cfg(unix)]
let (owner, group) = {
use ::std::os::unix::fs::MetadataExt;
use nix::unistd::{Gid, Group, Uid, User};

let uid = metadata.uid();
let gid = metadata.gid();

let user = User::from_uid(Uid::from_raw(uid)).ok().flatten();
let group_obj = Group::from_gid(Gid::from_raw(gid)).ok().flatten();

let owner_name = user.map(|u| u.name).unwrap_or_else(|| uid.to_string());
let group_name = group_obj.map(|g| g.name).unwrap_or_else(|| gid.to_string());
(owner_name, group_name)
};

#[cfg(not(unix))]
let (owner, group) = { ("".to_string(), "".to_string()) };

Ok(FileMetadata {
owner,
group,
permissions: perms,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod follow_impl;
pub mod is_dir_impl;
pub mod is_file_impl;
pub mod list_impl;
pub mod metadata;
pub mod mkdir_impl;
pub mod move_impl;
pub mod parent_dir_impl;
Expand Down
3 changes: 2 additions & 1 deletion implants/lib/eldritchv2/stdlib/eldritch-libreport/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ edition = "2024"
eldritch-core = { workspace = true }
eldritch-macros = { workspace = true }
eldritch-agent = { workspace = true, optional = true }
eldritch-libfile = { workspace = true }
pb = { workspace = true, optional = true }
spin = { version = "0.10.0", features = ["rwlock"] }

[features]
default = ["stdlib"]
stdlib = ["dep:pb", "dep:eldritch-agent"]
stdlib = ["dep:pb", "dep:eldritch-agent", "eldritch-libfile/stdlib"]
fake_bindings = []
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@ use pb::c2::TaskContext;
use pb::{c2, eldritch};

pub fn file(agent: Arc<dyn Agent>, task_context: TaskContext, path: String) -> Result<(), String> {
use eldritch_libfile::std::metadata;

let content = std::fs::read(&path).map_err(|e| e.to_string())?;
let meta = metadata::get_metadata(std::path::Path::new(&path)).map_err(|e| e.to_string())?;

let metadata = eldritch::FileMetadata {
path: path.clone(),
permissions: meta.permissions,
owner: meta.owner,
group: meta.group,
..Default::default()
};
let file_msg = eldritch::File {
Expand Down
Loading