我创建了一些使用PssCaptureSnapshot
执行进程克隆的代码,然后执行克隆的小型转储。
但是,在某些进程中,我在运行PssCaptureSnapshot
时运行被拒绝(以提升方式运行)。这根本不是问题,实际上我无法执行克隆的过程也无法使用ProcDump(来自SysInternals的工具)进行克隆。
然而,奇怪的是,如果我打开PowerShell PSSession
到localhost并从那里运行我的应用程序......创建克隆没有问题!
现在突然出现的是......特权。所以我检查了PSSession
内部的权限,以及那些外面的... Bingo! PSSession实际上具有人类已知的所有权限,而在PSSession之外我只有少数权限。
没什么大不了的,我想......我只是开始分配自己的权限,一次一个,在两者之间调用PssCaptureSnapshot
。当我停止拒绝访问时,我知道我需要哪种权限!
这个计划万无一失。那是......直到我没有分配的权限,我仍然被拒绝访问...
所以现在我真的抓着吸管:为什么它在PSSession内部工作但不在外部,当所有特权(理论上)相同时?如何进一步排除故障?
任何帮助都将不胜感激。
PS:如果您认为它有用,我会很乐意发布代码。但请记住,我得到一个访问被拒绝的事实,它在PSSession内部工作,但不在和之外的事实,ProcDump也不能为这些进程创建克隆...我不认为代码是相关的。
修改
whoami / all
的结果本地会议:
USER INFORMATION
----------------
User Name SID
================== ===========================================
xxxxxxxxxxxxxxxxxx S-1-5-21-1509752874-53682476-648048294-1107
GROUP INFORMATION
-----------------
(listing only groups that appear in this session, but don't appear in the other)
NT AUTHORITY\REMOTE INTERACTIVE LOGON Well-known group S-1-5-14 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
=============================== ========================================= ========
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeSecurityPrivilege Manage auditing and security log Disabled
SeTakeOwnershipPrivilege Take ownership of files or other objects Disabled
SeLoadDriverPrivilege Load and unload device drivers Disabled
SeSystemProfilePrivilege Profile system performance Disabled
SeSystemtimePrivilege Change the system time Disabled
SeProfileSingleProcessPrivilege Profile single process Disabled
SeIncreaseBasePriorityPrivilege Increase scheduling priority Disabled
SeCreatePagefilePrivilege Create a pagefile Disabled
SeBackupPrivilege Back up files and directories Disabled
SeRestorePrivilege Restore files and directories Disabled
SeShutdownPrivilege Shut down the system Disabled
SeDebugPrivilege Debug programs Enabled
SeSystemEnvironmentPrivilege Modify firmware environment values Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeRemoteShutdownPrivilege Force shutdown from a remote system Disabled
SeUndockPrivilege Remove computer from docking station Disabled
SeManageVolumePrivilege Perform volume maintenance tasks Disabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
SeTimeZonePrivilege Change the time zone Disabled
SeCreateSymbolicLinkPrivilege Create symbolic links Disabled
USER CLAIMS INFORMATION
-----------------------
User claims unknown.
Kerberos support for Dynamic Access Control on this device has been disabled.
在PSSession中:
USER INFORMATION
----------------
User Name SID
================== ===========================================
xxxxxxxxxxxxxxxxxx S-1-5-21-1509752874-53682476-648048294-1107
GROUP INFORMATION
-----------------
(listing only groups that appear in this session, but don't appear in the other)
NT AUTHORITY\NETWORK Well-known group S-1-5-2
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
=============================== ========================================= =======
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Enabled
SeSecurityPrivilege Manage auditing and security log Enabled
SeTakeOwnershipPrivilege Take ownership of files or other objects Enabled
SeLoadDriverPrivilege Load and unload device drivers Enabled
SeSystemProfilePrivilege Profile system performance Enabled
SeSystemtimePrivilege Change the system time Enabled
SeProfileSingleProcessPrivilege Profile single process Enabled
SeIncreaseBasePriorityPrivilege Increase scheduling priority Enabled
SeCreatePagefilePrivilege Create a pagefile Enabled
SeBackupPrivilege Back up files and directories Enabled
SeRestorePrivilege Restore files and directories Enabled
SeShutdownPrivilege Shut down the system Enabled
SeDebugPrivilege Debug programs Enabled
SeSystemEnvironmentPrivilege Modify firmware environment values Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeRemoteShutdownPrivilege Force shutdown from a remote system Enabled
SeUndockPrivilege Remove computer from docking station Enabled
SeManageVolumePrivilege Perform volume maintenance tasks Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
SeTimeZonePrivilege Change the time zone Enabled
SeCreateSymbolicLinkPrivilege Create symbolic links Enabled
USER CLAIMS INFORMATION
-----------------------
User claims unknown.
Kerberos support for Dynamic Access Control on this device has been disabled.
答案 0 :(得分:3)
首先,我们发现PssCaptureSnapshot
只有在使用PSS_CAPTURE_VA_CLONE
标志调用时才会失败 - 因此捕获过程中所有可复制页面的快照。
尽管我们有进程句柄以及对进程的所有必需访问权(比如PROCESS_ALL_ACCESS
) - 对于某些进程PssCaptureSnapshot
返回错误。为什么?
我注意到只有当某个作业中的进程正在运行时,错误。 (为了确定这一点,我们可以使用IsProcessInJob
)和PssCaptureSnapshot
在这种情况下可以返回2个不同的错误:
ERROR_NOT_ENOUGH_QUOTA
- 我在win8.1和win10中查看它 - 它
返回说某些chrome.exe
进程(并非所有进程)ERROR_ACCESS_DENIED
- 此错误仅在我们处理的过程中发生
想要快照 - 在另一个会话中运行(比较我们的流程)和这个
仅在win8.1中 - 在win10中没有此错误,即使进入
工作和另一场会议。了解为什么会发生这种情况 - 需要了解PssCaptureSnapshot
内部实现PSS_CAPTURE_VA_CLONE
语义的方式。它通过fork目标进程(是的,在Windows下的fork)来实现。对于此任务,使用了未记录的ZwCreateProcessEx
api。当 SectionHandle == 0 时(win32 CreateProcess
总是在这里传递创建在exe文件上的部分(如果现在说完全为真CreateProcess
使用另一个api,这是早期的))ZwCreateProcessEx
克隆(fork)进程( ParentProcess )而不是基于 SectionHandle (基于某些exe文件)创建新的
但如果 ParentProcess 在作业中 - 子(我们的分叉)进程也将被放置在此作业中。这可能是问题。
第一份工作可以限制工作中的工艺数量。如果说工作有这个限制 - 工作中不超过1个进程 - ZwCreateProcessEx
并且失败并显示错误STATUS_QUOTA_EXCEEDED
- 结果PssCaptureSnapshot
返回给我们ERROR_NOT_ENOUGH_QUOTA
。这是chrome.exe
案例 - 出于安全原因,某些chrome进程在作业中运行(在1个进程中有限制)(此进程也有 Untrusted Mandatory Level 但这与问题无关)
但即使在win8.1中作业对活动进程数没有限制(或者我们没有超过此限制) - 作业属于另一个会话 - 使用STATUS_ACCESS_DENIED
进行调用失败。为什么这个 ?这个已经内部的实现细节,现在(在Windows 10中)它发生了变化 - 不再是这个错误 - 我们可以派生进程,即使它在作业和另一个会话中。一些提示为什么我们可以进入AssignProcessToJobObject
页面:
作业中的所有进程必须在与...相同的会话中运行 工作
所以这里有一些与作业对象和交叉会话相关的窗口限制。
如果有趣的话,如何在Windows 8.1上重现/测试此错误?对于我看起来最简单的方法 - 在会话0中运行一些Windows服务 - 这个服务必须对系统不起作用(容易启动/停止它)并拥有自己的exe。为了我的外观" msdtc.exe"完美的受害者。所以打开它,首先尝试快照,而不是放在工作中,然后再尝试快照。并查看不同的内容:
NTSTATUS status;
BOOLEAN b;
if (0 <= (status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &b)))
{
// GetProcessIdByName custom function not shown here
if (ULONG dwProcessId = GetProcessIdByName(L"msdtc.exe"))
{
DbgPrint("found dwProcessId=%x\n", dwProcessId);
if (HANDLE hProcess = OpenProcess(PROCESS_CREATE_PROCESS|PROCESS_QUERY_LIMITED_INFORMATION |
PROCESS_SET_QUOTA|PROCESS_TERMINATE , FALSE, dwProcessId))
{
BOOL bInJob;
if (IsProcessInJob(hProcess, 0, &bInJob))
{
if (!bInJob)
{
HPSS SnapshotHandle;
ULONG err;
if (!(err = PssCaptureSnapshot(hProcess, PSS_CAPTURE_VA_CLONE, 0,&SnapshotHandle)))
{
PssFreeSnapshot(NtCurrentProcess(), SnapshotHandle);
}
DbgPrint("PssCaptureSnapshot=%u\n", err);
if (HANDLE hJob = CreateJobObject(0, 0))
{
bInJob = AssignProcessToJobObject(hJob, hProcess);
CloseHandle(hJob);
if (bInJob)
{
if (IsProcessInJob(hProcess, 0, &bInJob) && bInJob)
{
DbgPrint("process in job now!\n");
if (!(err = PssCaptureSnapshot(hProcess, PSS_CAPTURE_VA_CLONE, 0,&SnapshotHandle)))
{
PssFreeSnapshot(NtCurrentProcess(), SnapshotHandle);
}
DbgPrint("PssCaptureSnapshot=%u\n", err);
}
else
{
DbgPrint("process not in job !?\n");
}
}
else
{
DbgPrint("AssignProcessToJobObject error=%u\n", GetLastError());
}
}
else
{
DbgPrint("CreateJobObject error=%u\n", GetLastError());
}
}
else
{
DbgPrint("process already in job\n");
}
}
else
{
DbgPrint("IsProcessInJob error=%u\n", GetLastError());
}
CloseHandle(hProcess);
}
else
{
DbgPrint("OpenProcess error=%u\n", GetLastError());
}
}
}
else
{
DbgPrint("RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE)=%x\n", status);
}
在Windows 8.1中我得到了下一个dbgprint:
found dwProcessId=950
PssCaptureSnapshot=0
process in job now!
PssCaptureSnapshot=5
但在Windows 10中另一张图片:
found dwProcessId=4d0
PssCaptureSnapshot=0
process in job now!
PssCaptureSnapshot=0
这是windows bug还是功能 - 很难说