我尝试从提升的流程创建中等或低完整性流程。我知道还有其他这样的问题,但是他们主要关注使用资源管理器或任务计划程序等变通方法,我想坚持使用CreateRestrictedToken()
+ CreateProcessAsUser()
。
我认为必须有可能以某种方式执行此操作,因为我相信UAC在您登录时执行此操作但我无法将令牌中的所有内容看作普通的UAC中IL令牌。
通过使用CreateRestrictedToken(hThisProcessToken, LUA_TOKEN, ...)
创建令牌,然后在调用TokenOwner
之前设置TokenDefaultDacl
,TokenIntegrityLevel
和CreateProcessAsUser()
,您可以获得80%。
其余问题包括TokenVirtualizationAllowed
,TokenVirtualizationEnabled
,TokenElevation
,TokenElevationType
和TokenMandatoryPolicy
,其中SetTokenInformation()
因ERROR_PRIVILEGE_NOT_HELD或ERROR_INVALID_PARAMETER而失败。
如果我以SYSTEM @ SECURITY_MANDATORY_SYSTEM_RID运行并启用了所有权限而不是Administrator @ SECURITY_MANDATORY_HIGH_RID,那么我可以设置TokenMandatoryPolicy
和TokenVirtualization*
但设置TokenElevation*
仍然失败! (目前仅在Windows 8上测试过)
令牌中没有正确的TokenElevation*
值是一个大问题,因为Internet Explorer无法以保护模式启动,因为它认为令牌已提升。
SetTokenInformation()
的{{3}}没有说明可以设置哪些TOKEN_INFORMATION_CLASS
项目以及需要哪些特权,我不明白你为什么会这样做不允许将这些设置为降低与令牌的实际完整性级别(TokenIntegrityLevel
)匹配的安全值。
使用documentation创建SAFER_LEVELID_NORMALUSER
令牌不能解决任何这些问题,还会创建比正常的中型IL令牌更受限制的令牌。
我从早期的Vista / Longhorn时代找到了Safer API的人,从那以后没有任何改变?
答案 0 :(得分:0)
function CreateLowProcess(szProcessName: WideString; const IntegritySid: UnicodeString=''): Boolean;
var
hToken: THandle;
hNewToken: THandle;
szIntegritySid: WideString;
pIntegritySid: PSID;
TIL: TOKEN_MANDATORY_LABEL;
ProcInfo: PROCESS_INFORMATION;
startupInfo: TStartupInfo;
const
SE_GROUP_INTEGRITY = $00000020;
TokenIntegrityLevel = 25;
SLowIntegritySid: UnicodeString = 'S-1-16-4096';
SMediumIntegritySid: UnicodeString = 'S-1-16-8192';
SHighIntegritySid: UnicodeString = 'S-1-16-12288';
SSystemIntegritySid: UnicodeString = 'S-1-16-16384';
begin
{
Designing Applications to Run at a Low Integrity Level
http://msdn.microsoft.com/en-us/library/bb625960.aspx
To start a low-integrity process:
- Duplicate the handle of the current process, which is at medium integrity level.
- Use SetTokenInformation to set the integrity level in the access token to Low.
- Use CreateProcessAsUser to create a new process using the handle to the low integrity access token.
CreateProcessAsUser updates the security descriptor in the new child process and the security descriptor
for the access token to match the integrity level of the low-integrity access token.
}
// Low integrity SID
if IntegritySid <> '' then
szIntegritySid := IntegritySid
else
szIntegritySid := SLowIntegritySid;
// szIntegritySid := 'S-1-5-32-545'; //BUILTIN\USERS
ZeroMemory(@startupInfo, sizeof(startupInfo));
if (not OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE or TOKEN_ADJUST_DEFAULT or TOKEN_QUERY or TOKEN_ASSIGN_PRIMARY,
{var}hToken)) then
RaiseLastOSError;
try
if (not DuplicateTokenEx(hToken, 0, nil, SecurityImpersonation, TokenPrimary, {var}hNewToken)) then
RaiseLastOSError;
try
pIntegritySid := StringToSid(szIntegritySid); //free with LocalFree
try
TIL._Label.Attributes := SE_GROUP_INTEGRITY;
TIL._Label.Sid := pIntegritySid;
// Set the process integrity level
if (not SetTokenInformation(hNewToken, TTokenInformationClass(TokenIntegrityLevel), @TIL,
sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid))) then
RaiseLastOSError;
//Create the new process at Low integrity
Result := CreateProcessAsUserW(
hNewToken,
nil,
PWideChar(szProcessName),
nil, //ProcessAttributes
nil, //ThreadAttributes
False, //bInheritHandles
0, //dwCreationFlags
nil, //lpEnvironment
nil, //lpCurrentDirectory
startupInfo,
ProcInfo);
finally
LocalFree(HLOCAL(pIntegritySid));
end;
finally
CloseHandle(hNewToken);
end;
finally
CloseHandle(hToken);
end;
end;