PssCreateSnapshot - 访问被拒绝的奇怪情况
PssCreateSnapshot - access denied odd situation
我创建了一些代码,用于使用 PssCaptureSnapshot
执行进程克隆,然后执行克隆的小型转储。
但是,在某些进程中,当 运行ning PssCaptureSnapshot
(运行ning 已提升)时,我的访问被拒绝。这根本不是问题,事实上,我无法执行克隆的进程也无法使用 ProcDump(来自 SysInternals 的工具)进行克隆。
然而,奇怪的是,如果我打开 PowerShell PSSession
到本地主机并从那里 运行 我的应用程序...创建克隆没有问题!
现在我的脑海里立刻浮现出……特权。所以我检查了 PSSession
内部的权限与外部的权限,然后......宾果游戏! PSSession 几乎拥有人类已知的所有特权,而在 PSSession 之外我只有少数特权。
没什么大不了的,我想...我会开始为自己分配权限,一次一个,中间调用 PssCaptureSnapshot
。当我停止访问被拒绝时,我知道我需要哪种权限!
这个计划是万无一失的。也就是说...直到我 运行 没有权限分配并且我仍然被拒绝访问...
所以现在我真的很抓狂:为什么它在 PSSession 内部工作而不是外部,当所有特权(理论上)都相同时?我该如何进一步解决这个问题?
如有任何帮助,我们将不胜感激。
PS:如果您认为有帮助,我很乐意 post 编写代码。但请记住,我的访问被拒绝,事实上它在 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.
内部 PS会话:
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.
在对 cogumel0 进行了相对较长的研究后,我们找到了问题的确切根源。
首先我们发现了 PssCaptureSnapshot
can failed when and only when it called with PSS_CAPTURE_VA_CLONE
标志 - 用于捕获进程中所有可克隆页面的快照。
尽管我们有进程句柄和所有必需的进程访问权限(比如 PROCESS_ALL_ACCESS
)- 对于某些进程 PssCaptureSnapshot
return 错误。为什么?
我注意到错误是 仅当进程在某些作业运行中。 (为了确定这一点,我们可以使用 IsProcessInJob
)并且 PssCaptureSnapshot
在这种情况下可以 return 2 不同错误:
ERROR_NOT_ENOUGH_QUOTA
- 我在 win8.1 和 win10 中查看 - 它
returned 说一些 chrome.exe
进程(不是全部)
ERROR_ACCESS_DENIED
- 此错误仅在我们处理的过程中发生
想要 snap - 运行 在另一个 session (比较我们的过程)和这个
仅在 win8.1 - 在 win10 中没有这个错误,即使处理在
作业和另一个会话中。
为了理解为什么会发生这种情况 - 需要查看 PssCaptureSnapshot
内部如何实现 PSS_CAPTURE_VA_CLONE
语义。它通过分叉目标进程(是的,在 windows 下分叉)来完成。对于此任务,使用了未记录的 ZwCreateProcessEx
api。当 SectionHandle == 0 (win32 CreateProcess
总是在此处传递在 exe 文件上创建的部分 (if say full true now CreateProcess
use another api, this was early)) ZwCreateProcessEx
clone (fork) process (ParentProcess) 而不是创建新的一个基于 SectionHandle(基于某些 exe 文件)
但是如果 ParentProcess 在工作中 - 子进程(我们的分叉)也将被放置在这个工作中。这可能是问题。
第一个作业可以限制作业中的进程数。如果说作业有此限制 - 作业中不超过 1 个进程 - ZwCreateProcessEx
并因错误 STATUS_QUOTA_EXCEEDED
而失败 - 结果 PssCaptureSnapshot
return 给我们 ERROR_NOT_ENOUGH_QUOTA
。这是 chrome.exe
案例 - 出于安全原因,一些 chrome 进程 运行 在工作中(限制在 1 个进程中)(此进程也有 不受信任的强制级别 但这与问题无关)
但即使作业在 win8.1 中没有活动进程数限制(或者我们没有超过此限制)- 作业属于另一个会话- 调用失败 STATUS_ACCESS_DENIED
。为什么这个 ?这已经是内部实现细节,现在(在 windows 10 中)它发生了变化——不再有这个错误——我们可以分叉进程,即使它在工作和另一个会话中。一些提示为什么我们可以在 AssignProcessToJobObject
page:
All processes within a job must run within the same session as the
job.
所以这里有一些 windows 与作业对象和跨会话相关的限制。
如何 reproduce/test windows 8.1 上的这个错误是否有趣?对于我来说最简单的方法 - 在会话 0 中使用一些 windows 服务 运行ning - 此服务必须对系统不重要(容易 start/stop 它)并且有自己的 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 错误还是功能 - 很难说
我创建了一些代码,用于使用 PssCaptureSnapshot
执行进程克隆,然后执行克隆的小型转储。
但是,在某些进程中,当 运行ning PssCaptureSnapshot
(运行ning 已提升)时,我的访问被拒绝。这根本不是问题,事实上,我无法执行克隆的进程也无法使用 ProcDump(来自 SysInternals 的工具)进行克隆。
然而,奇怪的是,如果我打开 PowerShell PSSession
到本地主机并从那里 运行 我的应用程序...创建克隆没有问题!
现在我的脑海里立刻浮现出……特权。所以我检查了 PSSession
内部的权限与外部的权限,然后......宾果游戏! PSSession 几乎拥有人类已知的所有特权,而在 PSSession 之外我只有少数特权。
没什么大不了的,我想...我会开始为自己分配权限,一次一个,中间调用 PssCaptureSnapshot
。当我停止访问被拒绝时,我知道我需要哪种权限!
这个计划是万无一失的。也就是说...直到我 运行 没有权限分配并且我仍然被拒绝访问...
所以现在我真的很抓狂:为什么它在 PSSession 内部工作而不是外部,当所有特权(理论上)都相同时?我该如何进一步解决这个问题?
如有任何帮助,我们将不胜感激。
PS:如果您认为有帮助,我很乐意 post 编写代码。但请记住,我的访问被拒绝,事实上它在 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.
内部 PS会话:
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.
在对 cogumel0 进行了相对较长的研究后,我们找到了问题的确切根源。
首先我们发现了 PssCaptureSnapshot
can failed when and only when it called with PSS_CAPTURE_VA_CLONE
标志 - 用于捕获进程中所有可克隆页面的快照。
尽管我们有进程句柄和所有必需的进程访问权限(比如 PROCESS_ALL_ACCESS
)- 对于某些进程 PssCaptureSnapshot
return 错误。为什么?
我注意到错误是 仅当进程在某些作业运行中。 (为了确定这一点,我们可以使用 IsProcessInJob
)并且 PssCaptureSnapshot
在这种情况下可以 return 2 不同错误:
ERROR_NOT_ENOUGH_QUOTA
- 我在 win8.1 和 win10 中查看 - 它 returned 说一些chrome.exe
进程(不是全部)ERROR_ACCESS_DENIED
- 此错误仅在我们处理的过程中发生 想要 snap - 运行 在另一个 session (比较我们的过程)和这个 仅在 win8.1 - 在 win10 中没有这个错误,即使处理在 作业和另一个会话中。
为了理解为什么会发生这种情况 - 需要查看 PssCaptureSnapshot
内部如何实现 PSS_CAPTURE_VA_CLONE
语义。它通过分叉目标进程(是的,在 windows 下分叉)来完成。对于此任务,使用了未记录的 ZwCreateProcessEx
api。当 SectionHandle == 0 (win32 CreateProcess
总是在此处传递在 exe 文件上创建的部分 (if say full true now CreateProcess
use another api, this was early)) ZwCreateProcessEx
clone (fork) process (ParentProcess) 而不是创建新的一个基于 SectionHandle(基于某些 exe 文件)
但是如果 ParentProcess 在工作中 - 子进程(我们的分叉)也将被放置在这个工作中。这可能是问题。
第一个作业可以限制作业中的进程数。如果说作业有此限制 - 作业中不超过 1 个进程 - ZwCreateProcessEx
并因错误 STATUS_QUOTA_EXCEEDED
而失败 - 结果 PssCaptureSnapshot
return 给我们 ERROR_NOT_ENOUGH_QUOTA
。这是 chrome.exe
案例 - 出于安全原因,一些 chrome 进程 运行 在工作中(限制在 1 个进程中)(此进程也有 不受信任的强制级别 但这与问题无关)
但即使作业在 win8.1 中没有活动进程数限制(或者我们没有超过此限制)- 作业属于另一个会话- 调用失败 STATUS_ACCESS_DENIED
。为什么这个 ?这已经是内部实现细节,现在(在 windows 10 中)它发生了变化——不再有这个错误——我们可以分叉进程,即使它在工作和另一个会话中。一些提示为什么我们可以在 AssignProcessToJobObject
page:
All processes within a job must run within the same session as the job.
所以这里有一些 windows 与作业对象和跨会话相关的限制。
如何 reproduce/test windows 8.1 上的这个错误是否有趣?对于我来说最简单的方法 - 在会话 0 中使用一些 windows 服务 运行ning - 此服务必须对系统不重要(容易 start/stop 它)并且有自己的 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 错误还是功能 - 很难说