Windows中的用户权限和session限制(创建工作在不同用户权限和Session下的进程)

本文探讨了Windows系统中进程的权限与Session的关系。通过修改权限令牌,可以创建具有管理员权限或System权限的进程,并调整其工作在特定Session下。Windows的Session隔离确保了用户间的安全性,尤其是Session 0用于系统服务。示例介绍了如何创建既拥有管理员权限又在Session 1运行的进程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Windows中的进程都会绑定一个token(权限令牌),这个token记录了该进程的权限,不同的用户有不同的权限,所以不同用户下启动的进程时绑定的token是不同的,可以修改这个token,让进程开启或禁用已经拥有的权限(SetTokenInformation)。注意不是增加,是修改,因为token是用户的权限策略,如果该用户没有这个权限,那么在他启动的进程中是不可能增加这个权限的。

Win7之后,windows又引入了session隔离用来保证各个用户之间的安全,特别是session0,是为第一个用户创建的,也就是系统服务,自己创建的服务程序也在这个system用户下,session默认也在0,不过session0创建的子进程可以是其他session的,这个就是通过SetTokenInformation修改token中的sessionid来做到。也就是说我们可以创建一个system权限,又工作在session1下面的进程。

 

创建admin用户进程拥有admin权限:

void CreateProcessAsAdmin()
{
	HANDLE hToken;
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 9208);
	OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
	WCHAR szDesl[] = L"winsta0\\default";
	auto token = GetTokenById(9208);
	STARTUPINFO si = { sizeof(STARTUPINFO) };
	si.lpDesktop = szDesl;
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_SHOW;
	PROCESS_INFORMATION pi;
	WCHAR szApp[] = L"notepad";
	CreateProcessAsUser(token, NULL, szApp, 0, 0, FALSE, 0, 0, 0, &si, &pi);
}

 9208是explore的进程id,获取了admin用户的进程token,然后启动子进程,这个子进程就拥有了admin权限,而且也和explore一样工作在session1下面,因为token中就包含了用户权限信息和session信息。

创建System用户权限,并且工作在session1下面:

int CreateProcessAsSystem()
{
	auto activeSession = WTSGetActiveConsoleSessionId();
	HANDLE hSystemUserToken;
	BOOL ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY | TOKEN_WRITE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_ADJUST_PRIVILEGES,
		&hSystemUserToken);
	if (!ret)
	{
		return -1;
	}

	HANDLE hCopyToken;
	ret = DuplicateTokenEx(hSystemUserToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hCopyToken);
	if (!ret)
	{
		return -4;
	}
	ret = SetTokenInformation(hCopyToken, TokenSessionId, (void*)&activeSession, sizeof(activeSession));
	if (!ret)
	{
		return GetLastError();
	}
	WCHAR szDesl[] = L"winsta0\\default";
	auto token = GetTokenById(9208);
	STARTUPINFO si = { sizeof(STARTUPINFO) };
	si.lpDesktop = szDesl;
	si.dwFlags = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_SHOW;
	PROCESS_INFORMATION pi;
	WCHAR szApp[] = L"notepad";
	ret = CreateProcessAsUser(hCopyToken, NULL, szApp, 0, 0, FALSE, 0, 0, 0, &si, &pi);
	if (!ret)
	{
		return -5;
	}
	return 0;
}

现获取session1的id,然后打开当前进程的token,当前是服务进程所以也就是system用户的token,然后复制,必须复制,因为我们要修改的是子进程的令牌session,然后设置token中的sessionid为session1。创建后的进程为system用户权限,工作在session1中。

 

至于为什么进程既要受用户权限令牌(token)的约束,还要受session的约束(session隔离), 这块的原因还需要细细研究一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值