An offensive version of runas
in Rust with extra features.
As a security researcher, I've found this tool incredibly valuable.
This is a fork of the original repository that continues to build upon the solid foundation laid by Victor.
- Introduction
- Installation
- Core Features
- CLI Usage
- Security Considerations
- References
- Contributing
- License
This crate provides both a CLI and a Rust crate for spawning processes under different Windows user accounts, with support for privileges, secure token manipulation, profile/environment loading, and more. It's designed for security testing and red teaming operations.
Add runas-rs
to your project by updating your Cargo.toml
:
cargo add runas-rs
The library provides advanced process creation and management capabilities:
use runas_rs::{Runas, Options};
use anyhow::Result;
fn main() -> Result<()> {
let output = Runas::new("username", "password", Some("DOMAIN"))
.options(Options::Env | Options::Profile)?
.run("cmd.exe /c whoami")?;
println!("Output: {}", output);
Ok(())
}
Available process creation options:
Options::Env
- Use current user's environmentOptions::Profile
- Load full user profileOptions::NoProfile
- Skip profile loadingOptions::NetOnly
- Remote access onlyOptions::NewConsole
- New console windowOptions::NewProcessGroup
- New process groupOptions::NewWindow
- New windowOptions::Suspended
- Create suspendedOptions::DebugProcess
- Debug flagOptions::DebugOnlyThisProcess
- Debug child processesOptions::ProtectedProcess
- Protected process flag
Comprehensive token manipulation capabilities:
use runas_rs::Token;
use anyhow::Result;
fn main() -> Result<()> {
// Check integrity level
let level = Token::integrity_level()?;
println!("Integrity Level: {}", level);
// Check privileges
if Token::has_privilege("SeAssignPrimaryTokenPrivilege")? {
println!("Privilege available");
}
// Enable privilege
if Token::enable_privilege("SeImpersonatePrivilege")? {
println!("Privilege enabled");
}
Ok(())
}
Multiple injection techniques supported:
use runas_rs::{ProcessInjector, InjectionConfig, InjectionTechnique};
use anyhow::Result;
fn main() -> Result<()> {
let config = InjectionConfig {
pid: 1234,
technique: InjectionTechnique::CreateRemoteThread,
shellcode: vec![0x90, 0x90, 0x90],
wait_for_completion: true,
stealth_mode: false,
};
ProcessInjector::inject(&config)?;
Ok(())
}
Available injection techniques:
- CreateRemoteThread
- NtMapViewOfSection
- QueueUserAPC
- SetWindowsHookEx
- Process Hollowing
Advanced memory manipulation capabilities:
use runas_rs::ProcessMemory;
use anyhow::Result;
fn main() -> Result<()> {
let process_handle = ProcessMemory::open_process(1234, PROCESS_ALL_ACCESS)?;
// Allocate memory
let address = ProcessMemory::allocate_memory(process_handle, 1024, MemoryProtection::ReadWrite)?;
// Write data
let data = vec![0x90, 0x90, 0x90];
ProcessMemory::write_bytes(process_handle, address, &data)?;
// Read data
let read_data = ProcessMemory::read_bytes(process_handle, address, 3)?;
Ok(())
}
Comprehensive monitoring and hooking capabilities:
use runas_rs::{ProcessMonitor, HookType};
use anyhow::Result;
fn main() -> Result<()> {
let mut monitor = ProcessMonitor::new(1234)?;
// Install hook
let hook_bytes = vec![0x90, 0x90, 0x90];
monitor.install_hook(HookType::Inline, 0x12345678, &hook_bytes)?;
// Monitor memory
let memory_info = monitor.get_memory_info(0x12345678)?;
Ok(())
}
Available hook types:
- Inline Hooking
- IAT Hooking
- EAT Hooking
- VEH Hooking
- Trampoline Hooking
- Hotpatch Hooking
- Hardware Breakpoint Hooking
Job object and sandboxing capabilities:
use runas_rs::{JobObject, JobLimit, JobUIRestriction};
use anyhow::Result;
fn main() -> Result<()> {
let job_object = JobObject::new()?;
// Set limits
job_object.set_limits(&[
JobLimit::BreakawayOk,
JobLimit::DieOnUnhandledException,
JobLimit::KillOnJobClose,
])?;
// Set UI restrictions
job_object.set_ui_restrictions(&[
JobUIRestriction::Desktop,
JobUIRestriction::DisplaySettings,
])?;
Ok(())
}
The CLI binary provides command-line access to core functionality:
C:\> runas.exe -u joao -p joao -c "whoami" --profile
desktop-34dc0j2\joao
CLI Options:
-u <USERNAME>
- Username-p <PASSWORD>
- Password-d, --domain <DOMAIN>
- Domain (optional)-c, --command <COMMAND>
- Command to execute-e
- Use current environment--profile
- Load user profile--noprofile
- Skip profile loading--netonly
- Remote access only--new-console
- New console window--new-process-group
- New process group--new-window
- New window--suspended
- Create suspended--debug-process
- Debug flag--debug-only-this-process
- Debug child processes--protected-process
- Protected process flag
Special thanks to:
- @joaoviictorti for creating this outstanding project.
- Pavel - CreateProcessAsUser vs. CreateProcessWithTokenW
- Pavel - Window Stations and Desktops
- RunasCs
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the GPL-3.0 license.