gpt4 book ai didi

c# - 从 session 0(服务)启动提升的用户进程

转载 作者:太空狗 更新时间:2023-10-29 23:46:03 27 4
gpt4 key购买 nike

<分区>

早上好

这个问题似乎被问过几次,但我无法确定它是否真的可行。我已在 here 发布

没有回复 - 让我们试着问问这里的人。

我的目标是在当前用户上下文中(仅当他们在本地管理员组中时)从服务启动提升的进程(作为管理员)。

我可以毫无问题地获取当前用户 token ,但我无法获取该帐户的辅助/管理员 token !

我已经阅读了很多论坛,但就是无法让它工作(开始认为它不可行)。

我目前的方法:

  • WTSGetActiveConsoleSessionId - 获取事件 session ID
  • WTSQueryUserToken - 获取 session ID 的用户 token
  • 检查 token 是否为管理员 - 而不是。
  • OpenProcess - 已登录用户的 explorer.exe 进程句柄
  • OpenProcessToken - 获取访问 token 的句柄
  • LookupPrivilegeValue - SE_DEBUG 以确认我们可以调整 token 权限
  • DuplicateTokenEx - 用户 token
  • SetTokenInformation
  • AdjustTokenPrivileges
  • CreateEnvironmentBlock - 运行新进程
  • CreateProcessAsUser - 希望在提升的用户上下文中生成进程(不会发生 - 标准用户上下文)

请参阅下面的代码 - 很抱歉它很乱,需要整理并关闭所有句柄。目前这只是实验代码。

public static bool CreateProcessInConsoleSession(String CommandLine, bool bElevate)
{
PROCESS_INFORMATION pi;
bool isadmin = IsUserAnAdmin();

bool bResult = false;
uint dwSessionId, winlogonPid = 0;
IntPtr hUserToken = IntPtr.Zero, hUserTokenDup = IntPtr.Zero,
hPToken = IntPtr.Zero, hProcess = IntPtr.Zero;

Debug.Print("CreateProcessInConsoleSession");
// Log the client on to the local computer.
dwSessionId = WTSGetActiveConsoleSessionId();

// Find the winlogon process
var procEntry = new PROCESSENTRY32();

uint hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE)
{
return false;
}

procEntry.dwSize = (uint)Marshal.SizeOf(procEntry); //sizeof(PROCESSENTRY32);

if (Process32First(hSnap, ref procEntry) == 0)
{
return false;
}

String strCmp = "explorer.exe";
do
{
if (strCmp.IndexOf(procEntry.szExeFile) == 0)
{
// We found a winlogon process...make sure it's running in the console session
uint winlogonSessId = 0;
if (ProcessIdToSessionId(procEntry.th32ProcessID, ref winlogonSessId) &&
winlogonSessId == dwSessionId)
{
winlogonPid = procEntry.th32ProcessID;
break;
}
}
}
while (Process32Next(hSnap, ref procEntry) != 0);

//Get the user token used by DuplicateTokenEx
WTSQueryUserToken(dwSessionId, ref hUserToken);

//Check if the user token is admin
isadmin = CheckIfAdminToken(hUserToken);

var si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = "winsta0\\default";
var tp = new TOKEN_PRIVILEGES();
var luid = new LUID();
hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);

TOKEN_INFORMATION_CLASS tokenInfo = new TOKEN_INFORMATION_CLASS();
uint TokenInfLength = 0 ;

if (
!OpenProcessToken(hProcess,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY
| TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, ref hPToken))
{
Debug.Print(String.Format("CreateProcessInConsoleSession OpenProcessToken error: {0}",
Marshal.GetLastWin32Error()));
}

if (!LookupPrivilegeValue(IntPtr.Zero, SE_DEBUG_NAME, ref luid))
{
Debug.Print(String.Format("CreateProcessInConsoleSession LookupPrivilegeValue error: {0}",
Marshal.GetLastWin32Error()));
}

bool Result;

#region TestToElevate
//http://www.microsoft-questions.com/microsoft/Platform-SDK-Security/35984508/how-to-run-a-process-with-elevated-privileges-run-as-administrat.aspx
// first call gets lenght of TokenInformation
Result = GetTokenInformation(hPToken, TOKEN_INFORMATION_CLASS.TokenUser, IntPtr.Zero , TokenInfLength , out TokenInfLength );
IntPtr TokenInformation = Marshal.AllocHGlobal((int)TokenInfLength);

Result = GetTokenInformation(hPToken, TOKEN_INFORMATION_CLASS.TokenElevation, TokenInformation, TokenInfLength, out TokenInfLength);
if (Result == false)
Result = GetTokenInformation(hPToken, TOKEN_INFORMATION_CLASS.TokenLinkedToken, TokenInformation, TokenInfLength, out TokenInfLength);

isadmin = CheckIfAdminToken(hPToken);
#endregion

var sa = new SECURITY_ATTRIBUTES();
sa.Length = Marshal.SizeOf(sa);

if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa,
(int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)TOKEN_TYPE.TokenPrimary,
ref hUserTokenDup))
{
Debug.Print(
String.Format(
"CreateProcessInConsoleSession DuplicateTokenEx error: {0} Token does not have the privilege.",
Marshal.GetLastWin32Error()));
CloseHandle(hProcess);
CloseHandle(hUserToken);
CloseHandle(hPToken);
return false;
}

if (bElevate)
{
tp.PrivilegeCount = 1;
tp.Privileges = new int[3];
tp.Privileges[2] = SE_PRIVILEGE_ENABLED;
tp.Privileges[1] = luid.HighPart;
tp.Privileges[0] = luid.LowPart;

//Adjust Token privilege
if (!SetTokenInformation(hUserTokenDup, TOKEN_INFORMATION_CLASS.TokenSessionId, ref dwSessionId, (uint)IntPtr.Size))
{
Debug.Print(
String.Format(
"CreateProcessInConsoleSession SetTokenInformation error: {0} Token does not have the privilege.",
Marshal.GetLastWin32Error()));
CloseHandle(hProcess);
CloseHandle(hUserToken);
CloseHandle(hPToken);
CloseHandle(hUserTokenDup);
return false;
}


if (!AdjustTokenPrivileges(hUserTokenDup, false, ref tp, Marshal.SizeOf(tp), /*(PTOKEN_PRIVILEGES)*/ IntPtr.Zero, IntPtr.Zero))
{
int nErr = Marshal.GetLastWin32Error();
if (nErr == ERROR_NOT_ALL_ASSIGNED)
{
Debug.Print(String.Format(
"CreateProcessInConsoleSession AdjustTokenPrivileges error: {0} Token does not have the privilege.", nErr));
}
else
{
Debug.Print(String.Format("CreateProcessInConsoleSession AdjustTokenPrivileges error: {0}", nErr));
}
}
}


isadmin = CheckIfAdminToken(hUserTokenDup);

//Create Environment
uint dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
IntPtr pEnv = IntPtr.Zero;
if (CreateEnvironmentBlock(ref pEnv, hUserTokenDup, true))
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
}
else
{
pEnv = IntPtr.Zero;
}


// Launch the process in the client's logon session.
bResult = CreateProcessAsUser(
hUserTokenDup, // client's access token
null, // file to execute
CommandLine, // command line
ref sa, // pointer to process SECURITY_ATTRIBUTES
ref sa, // pointer to thread SECURITY_ATTRIBUTES
false, // handles are not inheritable
(int)dwCreationFlags, // creation flags
pEnv, // pointer to new environment block
null, // name of current directory
ref si, // pointer to STARTUPINFO structure
out pi // receives information about new process
);
// End impersonation of client.

//GetLastError should be 0
int iResultOfCreateProcessAsUser = Marshal.GetLastWin32Error();

//Close handles task
CloseHandle(hProcess);
CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);
CloseHandle(hPToken);

return (iResultOfCreateProcessAsUser == 0) ? true : false;
}

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com