从 vista 开始也存在 Mandatory Integrity Control。提升的进程具有带有 SYSTEM_MANDATORY_LABEL_NO_WRITE_UP 和 SYSTEM_MANDATORY_LABEL_NO_READ_UP 掩码的高强制标签 (S-1-16-12288)。从另一个方面来看,未提升的进程在令牌中具有中等强制级别 (S-1-16-8192)。因此,当它尝试使用 PROCESS_QUERY_INFORMATION 打开进程时,它是进程对象的通用读取的一部分 - 我们通常无法从非提升进程(中级)执行此操作以获取提升进程(高标签和 SYSTEM_MANDATORY_LABEL_NO_READ_UP)。
对于让PROCESS_QUERY_INFORMATION 提升的进程从未提升的打开 - 我们需要更改提升的进程强制标签。或将其设置为中或低,或删除SYSTEM_MANDATORY_LABEL_NO_READ_UP 标志。最后一个选项 - 最适合我的外观
对于删除SYSTEM_MANDATORY_LABEL_NO_READ_UP,我们可以使用下一个代码:
// hProcess must have READ_CONTROL | WRITE_OWNER
ULONG RemoveNoReadUp(HANDLE hProcess = NtCurrentProcess())
{
union {
PVOID buf;
PSECURITY_DESCRIPTOR pSD;
};
ULONG cb = 0, rcb = 128;
static volatile UCHAR guz = 0;
PVOID stack = alloca(guz);
ULONG err;
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (GetKernelObjectSecurity(hProcess, LABEL_SECURITY_INFORMATION, pSD, cb, &rcb))
{
BOOL bPresent, bDefault;
PACL Acl;
if (!GetSecurityDescriptorSacl(pSD, &bPresent, &Acl, &bDefault))
{
return GetLastError();
}
if (bPresent)
{
if (DWORD AceCount = Acl->AceCount)
{
union {
PVOID pv;
PBYTE pb;
PACE_HEADER pAH;
PSYSTEM_MANDATORY_LABEL_ACE pMLA;
};
pv = Acl + 1;
do
{
if (pAH->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
{
if (pMLA->Mask & SYSTEM_MANDATORY_LABEL_NO_READ_UP)
{
pMLA->Mask &= ~SYSTEM_MANDATORY_LABEL_NO_READ_UP;
return SetKernelObjectSecurity(hProcess, LABEL_SECURITY_INFORMATION, pSD)
? NOERROR : GetLastError();
}
}
} while (pb += pAH->AceSize, --AceCount);
}
}
return ERROR_NOT_FOUND;
}
} while ((err = GetLastError()) == ERROR_INSUFFICIENT_BUFFER);
return err;
}