system权限创建用户权限进程

来源:互联网 发布:知乎怎么发不了文章 编辑:程序博客网 时间:2024/05/19 14:50

windows编程的人都知道,在其操作系统下,进程被创建,通常被赋予很多属性,其中一项属性就是用户名,及进程所属的权限。打开任务管理器,可查看到(查看不到,点击查看,选择列即可)

这里写图片描述

通常桌面系统explorer的权限是User权限,即用户权限的,它可以是你administrator,可以是你PC的名字,可以是Guest等,所以我们开启并运行的所有进程都继承它的权限。
若想运行具备system权限的explorer,则可参考以前的文章

切换具有SYSTEM权限的控制台或桌面

在添加服务后,服务所对应的进程权限是SYSTEM权限,那么由这个SYSTEM调用的所有子进程,在常规下,都将是SYSTEM权限,如果有这样一个需求,需要通过服务调用某个具备User权限的进程,则需要通过CreateProcess
API的扩展即,CreateProcessAsUser.

WINADVAPI BOOLWINAPI CreateProcessAsUser (    __in_opt    HANDLE hToken,    __in_opt    LPCSTR lpApplicationName,    __inout_opt LPSTR lpCommandLine,    __in_opt    LPSECURITY_ATTRIBUTES lpProcessAttributes,    __in_opt    LPSECURITY_ATTRIBUTES lpThreadAttributes,    __in        BOOL bInheritHandles,    __in        DWORD dwCreationFlags,    __in_opt    LPVOID lpEnvironment,    __in_opt    LPCSTR lpCurrentDirectory,    __in        LPSTARTUPINFOA lpStartupInfo,    __out       LPPROCESS_INFORMATION lpProcessInformation);

其中hToken是最关键的,它表示进程所需要的会话令牌,通俗点就是权限的一个标识,有了它,就可以创建其他权限的进程了。

hToken的获取,网上资料特别多,就不列举了,这里直接贴关键代码

int CreateProcessByToken(LPSTR lpTokenProcessName,LPSTR lpProcess,LPSTR lpCommend){    HANDLE hToken = 0;    LPSTR lpName = lpTokenProcessName;    HANDLE hProcessSnap = 0;    PROCESSENTRY32 pe32 = {0};    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);    pe32.dwSize = sizeof(PROCESSENTRY32);    for(Process32First(hProcessSnap,&pe32);Process32Next(hProcessSnap,&pe32);)    {        if(strcmp(strupr(pe32.szExeFile),strupr(lpName))) continue;        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID);        OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);        CloseHandle(hProcessSnap);    }    if(hToken == 0) return 0;    STARTUPINFO si;    PROCESS_INFORMATION pi;    ZeroMemory(&si,sizeof(STARTUPINFO));    si.cb = sizeof(STARTUPINFO);    si.lpDesktop = "winsta0\\default";    si.dwFlags = STARTF_USESHOWWINDOW;    si.wShowWindow = SW_HIDE;    return CreateProcessAsUser(hToken,lpProcess,lpCommend,0,0,FALSE,NORMAL_PRIORITY_CLASS,0,0,&si,&pi);}

调用方式为

char tokenname[64]="explorer.exe";CreateProcessByToken(tokenname,0,"myservice_userchild.exe");

注意第一参数必须是非常量的,因为使用了strupr。
添加服务并启用服务,可以看到启动的子进程为User用户名了。

这里写图片描述

添加服务的方法太easy

sc create myservice_service_service binPath= "E:\code\system2user\Debug\myservice.exe" type= own start= auto

完整的示例已分享

http://download.csdn.net/detail/huanglong8/9708203

看过《windows核心编程》的小伙伴们,肯定比较熟悉第四章,在第四章中有讲到获取进程信息的示例和相关技术说明。于是乎,我又做了如下实验,windows进程的用户名很多,还有NETWORK SERVICE,LOCAL SERVICE等,那么SYSTEM是否再获取token后,仍然可以调用出具备此权限的子进程呢?改写代码,将子进程调用加入到循环中。

for(Process32First(hProcessSnap,&pe32);Process32Next(hProcessSnap,&pe32);){    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID);    OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);    STARTUPINFO si;    PROCESS_INFORMATION pi;    ZeroMemory(&si,sizeof(STARTUPINFO));    si.cb = sizeof(STARTUPINFO);    si.lpDesktop = "winsta0\\default";    si.dwFlags = STARTF_USESHOWWINDOW;    si.wShowWindow = SW_HIDE;    CreateProcessAsUser(hToken,lpProcess,lpCommend,0,0,FALSE,NORMAL_PRIORITY_CLASS,0,0,&si,&pi);}

启动服务后,发现调用的子进程中并没有SERVICE的权限进程。
这里写图片描述

在用LookupAccountSid 函数进行遍历获取用户名时,和书籍提供的样例程序是一样的,获取到了SYSTEM,USER,SERVICE等一系列权限token,但使用CreateProcessAsUser时,却针对其他权限调用失败,很是困惑。查阅网上的说法,说事因为主进程权限不够导致。所以,我便切换到SYSTEM用户桌面下。

启动服务,仍然是上面那种情况,失败。
但控制台直接调用,却意外成功了。

这里写图片描述

惊奇的发现,居然没有User,好吧,我已慌乱。

按照网上的说法,需要提主进程的权限,参考核心编程中的样例,试过了,并未成功,所以就不贴出来了。

由此可以知道,如果SYSTEM启动用户权限进程是可以做到的,但是启动其他权限进程,则无法做到。不知道有没有其他小伙伴有更好的示例和方法,欢迎分享啊。

最后贴出最佳的解决方案,针对Windows桌面应用程序,在系统框架上,我会选择,一个服务对应一个权限进程,一个随用户桌面的自启动程序随用户权限,这样子,分而治之也不会太乱,至少,用这种跨权限调用子进程的方法风险太高。

0 0
原创粉丝点击