首页
社区
课程
招聘
[求助]Windows下如何通过service进程启动桌面进程绕过UAC
发表于: 2018-11-12 14:13 7824

[求助]Windows下如何通过service进程启动桌面进程绕过UAC

2018-11-12 14:13
7824
大家好,目前我有个后台服务和前台GUI程序,都需要开机启动。目前后台服务可以自启动,但前台程序在Win7以上无法通过CreateProcessAsUser拉起(无法弹出UAC权限框),导致前台GUI进程无法使用。目前可以的使用两种自启动方式:
1. 写入系统启动项中,但是可以被用户手工禁用/删除,无法进行保护;
2. 加入计划任务列表,同样可以被用户手工禁用/删除,无法进行保护。

但最终需求是既能随系统启动而运行,又需要防止被用户直接或者间接通过安全软件(360卫士等)禁掉,之前的思路是在后台服务中通过 CreateProcessAsUser拉起并进行守护,但随着vista后引入UAC后,提权需要弹框确认,而前台界面上也无法看到确认框(即便能弹出来也不合适),有什么办法可以绕过UAC,或者别的更加安全的启动方式呢?

网上也查过一些方法,试过通过获取explorer进程令牌的方式创建进程,但测试时SetTokenInformation接口总是返回1314错误(客户端没有所需的特权)。下面是我试过的代码:
bool CreateUserSystemProcess(const wstring& procName)
{
	HANDLE hToken, hDuplicatedToken = NULL;
	LPVOID lpEnvironment = NULL;
	bool ret = false;
	do 
	{
		if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
		{
			OutputTrace(L"OpenProcessToken() error: %d\n", GetLastError());
			break;
		}

		if (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hDuplicatedToken))
		{
			OutputTrace(L"DuplicateTokenEx() error: %d\n", GetLastError());
			break;
		}

		DWORD SessionId = WTSGetActiveConsoleSessionId();
		if (!SetTokenInformation(hToken, TokenSessionId, &SessionId, sizeof(DWORD)))
		{
			OutputTrace(L"SetTokenInformation( ) error: %d\n", GetLastError());
			break;
		}

		if (!CreateEnvironmentBlock(&lpEnvironment, hDuplicatedToken, FALSE))
		{
			OutputTrace(L"CreateEnvironmentBlock() error: %d\n", GetLastError());
			break;
		}

		STARTUPINFO si = { 0 };
		PROCESS_INFORMATION pi = { 0 };
		si.cb = sizeof(si);
		if (!CreateProcessAsUser(hToken, procName.c_str(), NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
			lpEnvironment, NULL, &si, &pi))
		{
			OutputTrace(L"CreateProcessAsUser() error: %d\n", GetLastError());
			break;
		}

		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		OutputTrace(L"CreateProcessAsUser() success...........\n");
	} while (0);

	if (NULL != hToken)
		CloseHandle(hToken);
	if (NULL != hDuplicatedToken)
		CloseHandle(hDuplicatedToken);
	if (NULL != lpEnvironment)
		DestroyEnvironmentBlock(lpEnvironment);

	return ret;
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 12
活跃值: (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
用服务拉起前台进程就好了嘛,
很多过uac就这样做的,常规方式
CreateProcessAsUser 是对的,

最后于 2018-11-12 15:07 被MaMy编辑 ,原因:
2018-11-12 15:03
0
雪    币: 687
活跃值: (320)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
用服务启动进程不行么?
2018-11-12 15:45
0
雪    币: 17
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
MaMy 用服务拉起前台进程就好了嘛,很多过uac就这样做的,常规方式 CreateProcessAsUser 是对的,
不行啊,拉起来后进程是起来了,但是界面无法出来,我们前台是个托盘程序,这样拉起后点击没反应,应该是被UAC卡住了
2018-11-12 16:58
0
雪    币: 17
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
thisisroot 用服务启动进程不行么?
通过CreateProcessAsUser启动,进程倒是能起来,但是界面弹不出来啊
2018-11-12 16:59
0
雪    币: 12848
活跃值: (9147)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
6
前台别要这么高权限不就好了
高权限操作让后台进程做
2018-11-12 17:02
0
雪    币: 17
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
hzqst 前台别要这么高权限不就好了 高权限操作让后台进程做
但是SYSTEM用户进程拉起的就是高权限的,所以我也像上面通过获取explorer进程令牌方式启动和explorer权限一样的前台程序,但是失败了。现在主要是启动方式,要么会被禁掉,要么界面弹不出来。
2018-11-12 17:08
0
雪    币: 407
活跃值: (1816)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
下一个奇迹 但是SYSTEM用户进程拉起的就是高权限的,所以我也像上面通过获取explorer进程令牌方式启动和explorer权限一样的前台程序,但是失败了。现在主要是启动方式,要么会被禁掉,要么界面弹不出来。
啧,高权限的进程是可以以低权限启动进程的,浏览器不就是最好的例子么
2018-11-12 21:30
1
雪    币: 687
活跃值: (320)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
下一个奇迹 通过CreateProcessAsUser启动,进程倒是能起来,但是界面弹不出来啊
晚上回家不忘记的话,发你个代码- -好多年前写的了
2018-11-13 08:22
0
雪    币: 17
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
thisisroot 晚上回家不忘记的话,发你个代码- -好多年前写的了
好的,多谢
2018-11-13 09:46
0
雪    币: 17
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
Thead 啧,高权限的进程是可以以低权限启动进程的,浏览器不就是最好的例子么
我就试过在服务里通过获取explorer令牌以低权限启动,但是一直报错
2018-11-14 10:01
0
雪    币: 407
活跃值: (1816)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
Process Hacker有个以指定账户运行程序的功能,那应该是你想要的
2018-11-16 16:06
1
雪    币: 193
活跃值: (1247)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
穿透Session 0 隔离
2018-11-22 14:23
0
雪    币: 174
活跃值: (108)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
1.获取explorer的token 获取用户token,再复制;
2.复制token后直接CreateEnvironmentBlock即可,普通用户权限无需SetTokenInformation;

获取admin权限的话:
1.GetCurrentProcess;
2.OpenProcessToken;
3.DuplicateTokenEx,注意要用 MAXIMUM_ALLOWED 权限去复制 ;
4.SetTokenInformation;
5.CreateProcessAsUser,注意需要指定可交互的窗口站"WinSta0\Default";
最后于 2019-4-3 14:06 被wx_空气编辑 ,原因:
2019-4-3 09:45
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
15
提权其实可以不弹框,只要有cpuz就好
2019-4-3 10:26
0
雪    币: 635
活跃值: (1016)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
16
get!
2019-4-8 09:15
0
雪    币: 27
活跃值: (127)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
本人使用以下代码来获取 explorer 的 token:
BOOL WINAPI GetShellProcessToken(HANDLE *phToken)
{
	HWND hwndShell = GetShellWindow();
	BOOL bResult = IsWindow(hwndShell);
	if (bResult)
	{
		DWORD dwProcessId = 0;
		GetWindowThreadProcessId(hwndShell, &dwProcessId);
		if (dwProcessId > 0)
		{
			HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
			if (hProcess != nullptr)
			{
				bResult = OpenProcessToken(hProcess, TOKEN_QUERY, phToken);
				CloseHandle(hProcess);
			}
		}
	}
	return bResult;
}
2019-4-11 13:20
0
游客
登录 | 注册 方可回帖
返回
//