2010年6月30日星期三

在vista中跳过uac获得高权限

在window中(包括vista)最高权限是system account,拥有所有权限,该账户是专门为service配置的(个人猜测)。在vista中,在权限方面,微软使用了一种新的访问控制UAC,在administrators的帐户下面,用户启动进程的权限也仅仅是一般user的权限,若想使进程跑在administrator权限下面,就要使用run as administrator,通过uac使用户确认当前的操作,才能真正获得administrator的权限。vista使一般的程序跑在普通用户的权限下,提高了系统的安全性,但如果程序的确需要提高到 administrator的权限下才能正常工作(如调用驱动接口 etc)那么上述提高进程的流程比较繁琐。现在我们讲述另一种提高权限的方法,绕过uac。



该方法就是通过service来启动程序,这样就能提高权限到system account的级别(比administrator还高),因为service可以运行在system accout下面,(在servcie的配置中有logon选项设置,log on as system account.所以上面我说system account 专门为service配置)通过service运行的进程自然就具有了system account的权限。这个方法在windows xp下也经常使用,并且很容易实现,但是在vista下面就稍微有点麻烦,在vista下变麻烦是因为微软对service 运行的session有了改动。



那么下面先讲一下vista和xp下的针对service的改动,在xp下,service和app都是运行在同一个session的不同station下面,xp的第一个登陆账户运行在session 0中,所有的service 和app也都运行 在session中,第二个启动的账户运行在session 1中只有app,第三个类同第二个等。这样app和service运行在一个session中,那么app和service是很容易通信的 如 sendmessage mapfile pipe …etc,而在vista下,它把session 0 隔离了,成为service专用session ,所有的service都运行在session 0中,第一个账户运行在session 1中,第二个类同,这样在不同的session 下app和service通信就比较麻烦,需要global类通信如(name pipe,socket etc)。从上面的论述可以看出,微软这么改的目的也是为了安全性。



现在我们就开始讲提高进程的运行权限,先讲xp吧,这个比较容易。在xp下想要把进程提高到无所不能的system account权限,那就要做一个service,然后通过serivce启动进程。直接createprocess就可以实现了 ,简单吧。那么在vista下面呢,因为service在session 0下,所以不能直接createprocess去创建,因为这样创建出来的进程会跑在session 0 下面,而不是当前得user桌面下面。要用CreateProcessAsUser去创建,而该api需要一个当前session 下面的service token,听上去好复杂是不是,呵呵,其实也挺简单得,首先就是DuplicateTokenEx一个当前service的token 完成一步,然后修改成当前user的session ,这样就完成了。下面就看以下代码,这样就更容易理解了:



VOID RunAp()

{

HANDLE hUserTokenDup,hPToken,hProcess;

DWORD dwCreationFlags;

DWORD dwSessionId = WTSGetActiveConsoleSessionId();



hProcess =::GetCurrentProcess();

LOGVAR(_T("dwSessionId value : %u\n"),dwSessionId);

if(!::OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hPToken))

{

int abcd = GetLastError();

LOGVAR(_T("Process token open Error: %u\n"),GetLastError());

}

DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hUserTokenDup);



//change Token session id

if(! SetTokenInformation(hUserTokenDup,TokenSessionId,&dwSessionId,sizeof(DWORD)))

{

LOGVAR(_T("Set Token Information value Error: %u\n"),GetLastError());

}



//binding environment path

LPVOID pEnv =NULL;

dwCreationFlags = NORMAL_PRIORITY_CLASS
CREATE_NEW_CONSOLE;

if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE))

{

dwCreationFlags
=CREATE_UNICODE_ENVIRONMENT;

}

else

pEnv=NULL;



// Launch the process in the client's logon session.

PROCESS_INFORMATION pi;

STARTUPINFO si;

ZeroMemory(&si, sizeof(STARTUPINFO));

si.cb= sizeof(STARTUPINFO);

si.lpDesktop = _T("winsta0\\default");

ZeroMemory(&pi, sizeof(pi));

CreateProcessAsUser(hUserTokenDup,

_T("E:\\SVN\\Shared\\FrameworkFoundation\\build\\debug\\bin\\PrivateSafe.exe"),

NULL,

NULL,

NULL,

FALSE,

dwCreationFlags,

pEnv,

NULL,

&si,

&pi

);

CloseHandle(hUserTokenDup);

CloseHandle(hPToken);

if(pEnv)

DestroyEnvironmentBlock (pEnv);



return ;

}

没有评论:

发表评论