0%

ZwCreateThreadEx远程线程注入

session 0安全机制绕过注入

session 0 隔离机制

https://blog.csdn.net/suppercoder/article/details/17167537

https://www.cnblogs.com/gnielee/archive/2010/04/07/session0-isolation-part1.html

session0会话: 在Windows XP、Windows Server 2003,以及更老版本的Windows操作系统中,服务和应用程序使用相同的会话(Session)运行,而这个会话是由第一个登录到控制台的用户启动的,这个会话即 Session0。

从Windows VISTA开始,只有服务可以托管到SESSION0中,用户应用程序和服务之间会进行隔离,并需要运行在用户登录系统时创建的后续会话中。

如第一个登录用户创建Session1,第二个登录用户创建Session2,以此类推。使用不同会话运行的实体(应用程序或服务)如果不将自己明确标注为全局命名空间,并提供相应的访问控制设置,那么将无法互相发送消息,共享UI元素或共享内核对象。

img

ZwCreateThreadEx函数

在Windows下NtCreateThreadEx是CreateRemoteThread的底层函数,但是NtCreateThreadEx 并未在ntdll.dll中声明 需要手动使用GetProcAddress函数将其地址导出。

在32位下和64位下结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifdef  _WIN64
typedef DWORD(WINAPI* ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown);
#else //32
typedef DWORD(WINAPI* ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown);
#endif

注入方法

  • 1.OpenProcess 打开要注入的进程
  • 2.VirtualAllocEx 在被注入的进程中申请写内存
  • 3.WriteProcessMemory 写入dll路径到申请的内存中
  • 4.LoadlibraryA、GetProcAddress 加载ntdll.dll以获取内核函数ZwCreateThreadEx地址
  • 5.ZwCreateThreadEx 创建远线程实现dll注入
  • 6.释放申请内存的句柄

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <Windows.h>

#ifdef _WIN64
typedef DWORD(WINAPI* MyZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown);
#else //32
typedef DWORD(WINAPI* MyZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown);
#endif


void ZwCreateThreadExInjectDll(int pid, char* dllname) {
int len = strlen(dllname) + 1;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (NULL == hProcess) {
return;
}

//shen
PVOID dllNameAddr = VirtualAllocEx(hProcess, NULL, len, MEM_COMMIT, PAGE_READWRITE);
if (NULL == dllNameAddr) {
CloseHandle(hProcess);
return;
}

WriteProcessMemory(hProcess, dllNameAddr, dllname, len, 0);

HMODULE ntdll = LoadLibraryA("ntdll.dll");
FARPROC funAddr = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");

MyZwCreateThreadEx ZwCreateThreadEx = (MyZwCreateThreadEx)GetProcAddress(ntdll, "ZwCreateThreadEx"); //强转一下类型
if (NULL == ZwCreateThreadEx) {
return;
}
//使用ZwCreateThreadEx创建远程线程
HANDLE remoteThread = 0;

ZwCreateThreadEx(&remoteThread,PROCESS_ALL_ACCESS,NULL,hProcess,funAddr,dllNameAddr,0,0,0,0,NULL);
if (remoteThread == NULL) {
return;
}

CloseHandle(hProcess);
FreeLibrary(ntdll);
}


void main() {

//ZwCreateThreadExInjectDll(10288,"C:\\Users\\test\\source\\repos\\用户层注入\\Debug\\hookdll.dll");

ZwCreateThreadExInjectDll(5584,"C:\\Users\\test\\source\\repos\\用户层注入\\x64\\Debug\\hookdll.dll");

system("pause");
}
img

References

https://www.cnblogs.com/iBinary/p/16026217.html

https://www.cnblogs.com/PeterZ1997/p/10596100.html

https://www.cnblogs.com/nice0e3/p/15318327.html

欢迎关注我的其它发布渠道

------------- 💖 🌞 本 文 结 束 😚 感 谢 您 的 阅 读 🌞 💖 -------------