[Win32] 服务程序开发(3)Session 0隔离(下)创建SYSTEM权限可交互进程

来源:互联网 发布:java map 是否存在key 编辑:程序博客网 时间:2024/05/24 04:57

本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/47662727

在上上篇博文中,我说了如何编写一个系统服务,上一篇,介绍了如何穿透Session 0在当前用户的桌面上创建一个进程,但是缺陷很明显,如果UAC处于开启状态,创建的UI进程没有管理员权限,但是别忘了我们服务的权限令牌,我们可以获取服务自己的权限令牌在用户的桌面上创建一个拥有SYSTEM权限的进程,其中SYSTEM权限比管理员权限还要高,只是访问用户的私有资源时,要多费一番功夫而已。

上一篇:http://blog.csdn.net/zuishikonghuan/article/details/47614907

那么能不能创建管理员权限的进程呢?如果按照以前的方法,是不行的,不是Session的问题,因为那个的原理是获取explorer的令牌,用那个令牌创建进程。但是在UAC开启的状态下,explorer也是没有管理员权限的,所以即使先穿透Session 0创建了SYSTEM权限的进程,也不能这样创建管理员权限的进程。

当然,其他方法应该还是有的,UAC的AppInfo服务不就能直接以SYSTEM权限创建管理员权限的进程么。

下面来看看创建系统权限的进程:

如何在编写服务,如何在服务使用下面的代码请参见:[Win32] 服务程序开发(1)基本概念和服务程序的框架

void ShowMessage(LPWSTR lpszMessage, LPWSTR lpszTitle){// 获得当前Session IDDWORD dwSession = WTSGetActiveConsoleSessionId();DWORD dwResponse = 0;// 显示消息对话框WTSSendMessageW(WTS_CURRENT_SERVER_HANDLE, dwSession,lpszTitle,static_cast<DWORD>((wcslen(lpszTitle) + 1) * sizeof(wchar_t)),lpszMessage,static_cast<DWORD>((wcslen(lpszMessage) + 1) * sizeof(wchar_t)),0, 0, &dwResponse, FALSE);}void CreateUserSysProcess(LPCTSTR Filename){STARTUPINFO si;PROCESS_INFORMATION pi;RtlZeroMemory(&si, sizeof(STARTUPINFO));RtlZeroMemory(&pi, sizeof(PROCESS_INFORMATION));si.cb = sizeof(STARTUPINFO);//si.lpDesktop = TEXT("Winsta0\\default");HANDLE hToken, hDuplicatedToken = NULL;OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);//获取服务自己的令牌DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &hDuplicatedToken);//复制令牌DWORD SessionId = WTSGetActiveConsoleSessionId();//获取会话IDSetTokenInformation(hDuplicatedToken, TokenSessionId, &SessionId, sizeof(DWORD));//设置令牌信息TokenSessionIdLPVOID lpEnvironment = NULL;CreateEnvironmentBlock(&lpEnvironment, hDuplicatedToken, FALSE);//创建用户环境//在当前用户创建进程(CREATE_UNICODE_ENVIRONMENT表示用户环境是Unicode字符串)if (CreateProcessAsUser(hDuplicatedToken, Filename, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, lpEnvironment, NULL, &si, &pi) == 0){ShowMessage(L"在用户界面创建进程失败", L"Error");}//释放资源CloseHandle(pi.hProcess);CloseHandle(pi.hThread);CloseHandle(hToken);CloseHandle(hDuplicatedToken);DestroyEnvironmentBlock(lpEnvironment);}

(汗,刚刚弄错了,把上一篇的代码贴这儿了,现在已经改过来了)

测试结果:在Win8.1、Win7、Win10以及XP下都能很好的工作。

效果图:(开启了在当前用户桌面上的SYSTEM权限的计算器)



都是System权限的程序会话ID不一样,一个是Session 0,一个在当前用户:
 


1 0