-------December 13,2009
由于blog长期没有维护,之前那篇文章广告积累过多
再加上blogger的删除评论功能又很纠结。
故决定删除原文,重新发布此文
此次发布,未对文章内容进行修改
现在看来,之前这篇文章真的是没有什么效用
而且还有很多疏漏与不当之处
许多地方都很繁琐。
不过,作为我成长过程的一个记录,还是保留下来吧。
---------------------------
新本入手,Vista体验中...
体验过程中发现过去一直在使用的一段代码已经不奏效了。
既然如此,那么公开出来也无妨。
看来Agent Starter就要迎来又一次久违的大改了。
这回比较懒,我就不修改、注释了,也没有处理错误,有疑问,可留言。
功能:在当前进程为SYSTEM权限时,绕过密码登陆,获取当前已登录用户的Token。此Token可用于CreateProcessAsUser。
返回值:成功则是HANDLE,失败返回0.
Story:
在当前进程为SYSTEM权限时,由于CreateProcess等函数创建进程时父进程的权限会被子进程所继承,并且子进程也会登录为系统用户,容易造成子进程在获取用户设置时出错。目前已知CreateProcessAsUser和CreateProcessWithLogonW可以创建不同于父进程用户的子进程。但是由于CreateProcessAsUser所用的Token需要通过LogonUser 获得,而CreateProcessWithLogonW与LogonUser均需要用户名与密码才可进行登录,这使得获取Token失去了随意性。
这时,曾经在网上盛传的DuplicateHandle获取进程HANDLE法便可以用来解决问题。已知Token的ObjectNumber为4。所以我们便可以Duplicate其他进程里面的Token用于CreateProcessAsUser,从而免除登陆用户的麻烦。但是我们的Token要从哪里来呢?想想创建taskmgr.exe的是winlogon.exe,而winlogon.exe显示为SYSTEM用户,创建后的taskmgr则为当前用户。想必那里会隐藏着用户Token。打开Process Explorer看看,果真如此。至此,事情就变得简单了。(另外,winlogon里存在多个用户Token,XP SP3里面只有一个可用于我们的CreateProcessAsUser。Vista下没有可以直接用的。打算研究一下DuplicateTokenEx或许能有帮助)
代码:
HANDLE YGetUserToken()
{
HANDLE ph,h_dup;
ULONG bytesIO,i,NumOfHandle,WinLogon_id;
PVOID buf;
PSYSTEM_HANDLE_INFORMATION h_info;
CHAR InfoBuffer[1000],szAccountName[200], szDomainName[200];
DWORD dwInfoBufferSize,dwAccountSize = 200, dwDomainSize = 200;
bytesIO=0x40000;
buf = 0;
WinLogon_id = NametoPid(L"winlogon.exe");
ph = OpenProcess(PROCESS_DUP_HANDLE,0,WinLogon_id); //YDupHandle(WinLogon_id);
NtAllocateVirtualMemory((HANDLE)-1, &buf, 0, &bytesIO, MEM_COMMIT, PAGE_READWRITE);
NtQuerySystemInformation(SystemHandleInformation, buf, 0x40000, &bytesIO);
NumOfHandle = *(PULONG)buf;
h_info = ( PSYSTEM_HANDLE_INFORMATION )((ULONG)buf+4);
int ai=0;
for (i= 0 ; i<NumOfHandle; i++, h_info++)
{
if (h_info->ProcessId==WinLogon_id&&h_info->ObjectTypeNumber == 4)
{
NtDuplicateObject(ph, (PHANDLE)h_info->Handle, (HANDLE)-1, &h_dup,TOKEN_ALL_ACCESS,0,0);
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
SID_NAME_USE snu;
GetTokenInformation(h_dup,TokenUser,InfoBuffer,1000, &dwInfoBufferSize);
LookupAccountSid(NULL, pTokenUser->User.Sid, szAccountName,&dwAccountSize,szDomainName, &dwDomainSize, &snu);
if(strcmp(szAccountName,"NT ATHORITY\\\)) //Vista:SYSTEM
{
printf(szAccountName);
if(CreateProcessAsUserW(h_dup,NULL,L"winlogon.exe",NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&startupInfo,&ProcessInfo))
{
TerminateProcess(ProcessInfo.hProcess,0);
NtClose(ProcessInfo.hProcess);
NtClose(ProcessInfo.hThread);
break;
}
}
NtClose(ProcessInfo.hProcess);
NtClose(ProcessInfo.hThread);
NtClose(h_dup);
h_dup=0;
}
}
CreateProcess()
NtClose(ph);
bytesIO = 0;
NtFreeVirtualMemory((HANDLE)-1, &buf, &bytesIO, MEM_RELEASE);
return h_dup;
}
沒有留言:
張貼留言