C# PssCreateSnapshot-访问被拒绝奇数情况
我创建了一些代码,用于使用C# PssCreateSnapshot-访问被拒绝奇数情况,c#,c++,powershell,winapi,pinvoke,C#,C++,Powershell,Winapi,Pinvoke,我创建了一些代码,用于使用pscapturesnashot执行进程克隆,然后执行克隆的小型转储 但是,在某些进程上,当运行pscapturesnashot(以提升状态运行)时,访问被拒绝。这根本不是问题,事实上,我无法对其执行克隆的进程也无法使用ProcDump(SysInternals中的工具)进行克隆 然而,奇怪的是,如果我打开一个PowerShellPSSession到本地主机并从那里运行我的应用程序。。。创建克隆没有问题 现在我突然想到的是。。。特权。因此,我检查了PSSession中的
pscapturesnashot
执行进程克隆,然后执行克隆的小型转储
但是,在某些进程上,当运行pscapturesnashot
(以提升状态运行)时,访问被拒绝。这根本不是问题,事实上,我无法对其执行克隆的进程也无法使用ProcDump(SysInternals中的工具)进行克隆
然而,奇怪的是,如果我打开一个PowerShellPSSession
到本地主机并从那里运行我的应用程序。。。创建克隆没有问题
现在我突然想到的是。。。特权。因此,我检查了PSSession
中的权限与外部的权限,然后。。。答对 了PSSession实际上拥有人类所知的所有特权,而在PSSession之外,我只有少数特权
没什么大不了的,我想。。。我将开始给自己分配特权,一次一个,中间调用pscapturesnashot
。当我不再被拒绝访问时,我知道我需要什么特权
这个计划万无一失。那就是。。。直到我用完了分配的权限,我仍然被拒绝访问
所以现在我真的在抓救命稻草:当所有特权(理论上)都相同时,为什么它在PSSession内部工作而在外部不工作?如何进一步排除故障
任何帮助都将不胜感激
附言:如果你认为有帮助的话,我很乐意发布代码。但请记住,我的访问被拒绝,它在PSSession内部工作,但在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.
内部会话:
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.
经过相当长时间的研究,我们找到了问题的根源 首先,我们发现,当且仅当它使用flag调用时,可能会失败—因此,对于捕获过程中所有可克隆页面的快照来说,也是如此 尽管我们有进程句柄,可以访问所有需要的进程(比如说
process\u all\u access
),但对于某些进程,返回错误。为什么?
我注意到,只有当进程在某个作业中运行时,错误才是。(为了确定这一点,我们可以使用)并且在这种情况下可以返回2个不同的错误:
-我在win8.1和win10中查看此问题-it 返回一些错误\u配额不足\u配额
进程(不是全部)的saychrome.exe
-只有当我们访问的进程 要在另一个会话中运行snap-(比较我们的过程)和此 仅在win8.1中-在win10中没有此错误,即使进程处于 在另一个会话中执行job和错误\u访问\u被拒绝
CreateProcess
始终在此传递在exe文件上创建的节(如果现在说完全正确CreateProcess
使用另一个api,这是早期的))克隆(fork)进程(ParentProcess)而不是基于SectionHandle(基于某些exe文件)创建新的进程
但是如果ParentProcess在job中,那么子进程(我们的分叉)也将被放置在这个job中。这里可能有问题
第一个作业可以限制作业中的进程计数。如果说作业有此限制-作业中不超过1个进程-并且失败并出现错误状态\u配额\u超过
-结果返回给我们错误\u配额不足
。这是chrome.exe
案例-出于安全原因,一些chrome进程在作业中运行(限制为1个进程)(此进程也具有不受信任的强制级别,但与问题无关)
但是,即使作业在win8.1中没有活动进程计数限制(或者我们没有超过此限制),在作业属于另一个会话时,调用也会失败,状态为“访问被拒绝”。为什么会这样?这已经是内部的实现细节,现在(在windows 10中)它改变了-不再是这个错误-我们可以分叉进程,即使它在作业和另一个会话中。我们可以在第页中找到一些提示:
作业中的所有进程必须在与作业相同的会话中运行
工作
因此,这里有一些与作业对象和跨会话相关的窗口限制
如果有兴趣,如何在windows 8.1上重现/测试此错误?对于我来说,最简单的方法是-以会话0中运行的某些windows服务为例-此服务对于系统来说必须不是关键的(easy可以启动/停止它),并且具有自己的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 10中,另一张图片:
found dwProcessId=4d0
PssCaptureSnapshot=0
process in job now!
PssCaptureSnapshot=0
这是windows错误还是功能-很难说首先要检查的是您是否真的获得了您认为的特权。你是怎么做到的?但特权可能并不重要,相关进程的访问规则可能只允许访问本地系统帐户。@HarryJohnston关于特权,分配特权的函数(现在记不起名称)返回bool以确定是否成功分配特权。它总是返回真的。whoami/priv还显示特权现在已启用(尽管它仅显示特权的子集)。至于关于访问的问题,PSSession以完全相同的用户身份运行。@HarryJohnston我也忘了提出我的问题,但是当调用
PSCaptureSnapshot
失败且访问被拒绝时,我可以执行进程转储,而无需先克隆它。这很好,即使是在PSSession之外。这(也)让我相信访问权不是问题
found dwProcessId=4d0
PssCaptureSnapshot=0
process in job now!
PssCaptureSnapshot=0