session0穿透-server降权打开程序

有点累 随便写写

在win7以后,win服务虽然是system的高权 但因为不在同一session的缘故,无法再可以控制桌面,包括显示ui,获取句柄,截图,弹窗等等。。

这样我在做进程守护的时候就遇到了些问题,守护的程序出现执行却无反馈的情况,查了很多例子,需要CreateProcessAsUser来调动程序就可以解决,需要注意这个CreateProcessAsUser需要system权限,仅admin是不行的,虽然网上有例子说可以手动提升admin权限,但我在本地安全策略里添加了相关权限依旧不行。

CreateProcessAsUser,打开程序之前需要一个令牌降权,有两种方法一个是获取用户的令牌

dwSessionID = ::WTSGetActiveConsoleSessionId();//获取用户id
        if (FALSE == ::WTSQueryUserToken(dwSessionID,&hToken)//hToken获取到令牌
{
    int i = GetLastError();//获取错误编码
}

另一种方法是通过获取其他程序的令牌,当然这种很有可能出现意外

LPWSTR lpa = ConvertCharToLPWSTR(_T("EXPLORER.EXE"))
GetTokenByName(hToken,lpa)
BOOL   GetTokenByName(HANDLE   &hToken, LPWSTR   lpName)
{
    if (!lpName)
    {
        return   FALSE;
    }
    HANDLE  hProcessSnap = NULL;
    BOOL  bRet = FALSE;
    PROCESSENTRY32   pe32 = { 0 };
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return   (FALSE);

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (Process32First(hProcessSnap, &pe32))
    {
        do
        {
            CString exefile = pe32.szExeFile;
            CString paraname = lpName;
            LPCSTR cname = wtoc(lpName).c_str;
            if (!exefile.CompareNoCase(cname))
            {
                HANDLE   hProcess =
                    OpenProcess(PROCESS_QUERY_INFORMATION,
                        FALSE, pe32.th32ProcessID);
                bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
                CloseHandle(hProcessSnap);
                return   (bRet);
            }
        } while (Process32Next(hProcessSnap, &pe32));
        bRet = TRUE;
    }
    else
        bRet = FALSE;

    CloseHandle(hProcessSnap);
    return   (bRet);
}

我使用的是第一种方案,这里只写出降权call程序的代码,server的太多就不写了

#include "pch.h"
#include <UserEnv.h>
#include <WtsApi32.h>
//#include <afx.h>
#include <tchar.h>
#pragma comment(lib, "UserEnv.lib")
#pragma comment(lib, "WtsApi32.lib")

// 突破SESSION 0隔离创建用户进程  传入程序路径

#define _AFXDLL

BOOL CreateUserProcess(char *lpszFileName)
{
    BOOL bRet = TRUE;
    DWORD dwSessionID = 0;
    HANDLE hToken = NULL;
    HANDLE hDuplicatedToken = NULL;
    LPVOID lpEnvironment = NULL;
    STARTUPINFO si = { 0 };
    PROCESS_INFORMATION pi = { 0 };
    si.cb = sizeof(si);

    do
    {
        // 获得当前Session ID
        dwSessionID = ::WTSGetActiveConsoleSessionId();
        LPCWSTR err = _T("ERROR");
        


        // 获得当前Session的用户令牌
        if (FALSE == ::WTSQueryUserToken(dwSessionID, &hToken))
        {    
            int i = GetLastError();
            //ShowMessage("WTSQueryUserToken", "ERROR");
            MessageBox(GetForegroundWindow(), err, _T("WTSQueryUserToken"), 1);
            bRet = FALSE;
            break;
        }

        // 复制令牌
        if (FALSE == ::DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
            SecurityIdentification, TokenPrimary, &hDuplicatedToken))
        {
            //ShowMessage("DuplicateTokenEx", "ERROR");
            MessageBox(GetForegroundWindow(), err, _T("DuplicateTokenEx"), 1);
            bRet = FALSE;
            break;
        }

        // 创建用户Session环境
        if (FALSE == ::CreateEnvironmentBlock(&lpEnvironment,
            hDuplicatedToken, FALSE))
        {
            //ShowMessage("CreateEnvironmentBlock", "ERROR");
            MessageBox(GetForegroundWindow(), err, _T("CreateEnvironmentBlock"), 1);
            bRet = FALSE;
            break;
        }

        

        // 在复制的用户Session下执行应用程序,创建进程
        if (FALSE == ::CreateProcessAsUser(hDuplicatedToken,
            lpszFileName, NULL, NULL, NULL, FALSE,
            NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
            lpEnvironment, NULL, &si, &pi))
        {
            //ShowMessage("CreateProcessAsUser", "ERROR");
            MessageBox(GetForegroundWindow(), err, _T("CreateProcessAsUser"), 1);
            bRet = FALSE;
            break;
        }

    } while (FALSE);
    // 关闭句柄, 释放资源
    if (lpEnvironment)
    {
        ::DestroyEnvironmentBlock(lpEnvironment);
    }
    if (hDuplicatedToken)
    {
        ::CloseHandle(hDuplicatedToken);
    }
    if (hToken)
    {
        ::CloseHandle(hToken);
    }
    return bRet;
}

int main(int argc, char* argv[])

{
    char a[] = "calc.exe";
    CreateUserProcess(a);
        return 0;
}

这个可能在编码上有点问题,应该难不道诸位的,最后感谢提供例子的朋友。

累了睡了

猜你喜欢

转载自www.cnblogs.com/moshuixiong/p/12169281.html