1
我試圖找到一種方法來允許單個進程作爲高級用戶啓動,但禁止此進程啓動任何子進程的令牌 - 在某種程度上,這種方式可以「密封」令牌。這背後的原因是阻止用戶啓動cmd.exe並獲得對系統的完全訪問權限。有什麼辦法可以「密封」一個標記,以便子進程不能繼承它嗎?
我已經查看了過程特權常量,我沒有看到任何可用於實現此功能的東西。
我試圖找到一種方法來允許單個進程作爲高級用戶啓動,但禁止此進程啓動任何子進程的令牌 - 在某種程度上,這種方式可以「密封」令牌。這背後的原因是阻止用戶啓動cmd.exe並獲得對系統的完全訪問權限。有什麼辦法可以「密封」一個標記,以便子進程不能繼承它嗎?
我已經查看了過程特權常量,我沒有看到任何可用於實現此功能的東西。
我不認爲你可以密封令牌,但你可以與工作對象控制子進程的創建:
static BOOL SpawnProcessAndTerminateGrandchildren(PTSTR Cmdline)
{
HANDLE hJob = CreateJobObject(0, 0);
if (!hJob) return false;
JOBOBJECT_BASIC_LIMIT_INFORMATION jobli;
jobli.LimitFlags = JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
jobli.ActiveProcessLimit = 1;
BOOL retval = SetInformationJobObject(hJob, JobObjectBasicLimitInformation, &jobli, sizeof(jobli));
PROCESS_INFORMATION pi;
if (retval)
{
STARTUPINFO si;
ZeroMemory(&si, sizeof(si)), si.cb = sizeof(si);
retval = CreateProcess(0, Cmdline, 0, 0, false, CREATE_SUSPENDED|CREATE_BREAKAWAY_FROM_JOB|CREATE_NEW_CONSOLE, 0, 0, &si, &pi);
}
if (retval)
{
if (AssignProcessToJobObject(hJob, pi.hProcess)) // This can fail if we are already in a job
{
ResumeThread(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
}
else
TerminateProcess(pi.hProcess, ERROR_OPERATION_ABORTED);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
CloseHandle(hJob);
return retval;
}
int main(int argc, ...)
{
TCHAR cmd[] = TEXT("cmd.exe /k regedit"); // cmd.exe is our child, regedit is the grandchild spawned by cmd.exe
SpawnProcessAndTerminateGrandchildren(cmd);
return 0;
}
如果你想要更多的控制,你可以使用JobObjectAssociateCompletionPortInformation讓您得到JOB_OBJECT_MSG_NEW_PROCESS消息每次新的子進程被創建。
好主意雖然不幸提升的應用程序可能是任何東西,是未知的。我的思維模式傾向於: - 創建一個以升級用戶身份啓動進程的服務。 - 獲取對它的標記的引用並存儲此引用。 - 註冊WMI偵聽器以檢查應用程序啓動 - 如果啓動的應用程序具有與提升應用程序相同的標記/特權,則會自動終止子進程。 – slashp
我想你可以通過ObRegisterCallbacks與內核模式驅動程序做到這一點。但這將是一個非常淺薄的保護:任何人都可以使升級過程啓動cmd.exe,幾乎可以肯定地讓高級進程執行任何cmd.exe可以執行的操作,等等。 (包括禁用您的保護機制,然後*啓動cmd.exe!) –