C++ Windows Vista/Windows 7 权限:SeDebugPrivilege 和 OpenProcess

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2932461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:32:18  来源:igfitidea点击:

Windows Vista/Windows 7 privilege: SeDebugPrivilege & OpenProcess

c++windowsuacprivilegesopenprocess

提问by KevenK

Everything I've been able to find about escalating to the appropriate privileges for my needs has agreed with my current methods, but the problem exists. I'm hoping maybe someone has some Windows Vista/Windows 7 internals experience that might shine some light where there is only darkness. I'm sure this will get long, but please bear with me.

我所能找到的关于根据我的需要升级到适当权限的所有内容都与我当前的方法一致,但问题仍然存在。我希望也许有人有一些 Windows Vista/Windows 7 内部体验,可能会在只有黑暗的地方发光。我相信这会持续很长时间,但请耐心等待。

Context

语境

I'm working on an application that requires accessing the memory of other processes on the current machine. This, obviously, requires administrator rights. It also requires SeDebugPrivilege(no, it is not a misspelling of SetDebugPrivilege), which I believe myself to be acquiring correctly, although I question if more privileges aren't necessary and thus the cause of my problems. Code has so far worked successfully on all versions of Windows XP, and on my test Vista 32 bit and Windows 7 64 bit environments.

我正在开发一个需要访问当前机器上其他进程的内存的应用程序。显然,这需要管理员权限。它还需要SeDebugPrivilege(不,这不是拼写错误SetDebugPrivilege),我相信自己是正确获得的,尽管我质疑是否不需要更多特权,从而导致我的问题。到目前为止,代码已在所有版本的 Windows XP 以及我的测试 Vista 32 位和 Windows 7 64 位环境上成功运行。

Process

过程

  • Program will Alwaysbe run with Administrator Rights. This can be assumed throughout this post.
  • Escalating the current process's Access Tokento include SeDebugPrivilegerights.
  • Using EnumProcessesto create a list of current PIDs on the system
  • Opening a handle using OpenProcesswith PROCESS_ALL_ACCESSaccess rights
  • Using ReadProcessMemoryto read the memory of the other process.
  • 程序将始终以管理员权限运行。这可以在整个帖子中假设。
  • 升级当前流程Access Token以包含SeDebugPrivilege权限。
  • 使用EnumProcesses该系统上创建当前PID列表
  • 使用打开手柄OpenProcessPROCESS_ALL_ACCESS访问权限
  • 使用ReadProcessMemory读取其他进程的内存。

Problem:

问题:

Everything has been working fine during development and my personal testing (including Windows XP 32 & 64, Windows Vista 32, and Windows 7 x64). However, during a test deployment onto both Windows Vista (32-bit) and Windows 7 (64-bit) machines of a colleague, there seems to be a privilege/rights problem with OpenProcessfailing with a generic Access Deniederror. This occurs both when running as a limited User (as would be expected) and also when run explicitly as Administrator (Right-click → Run as Administratorand when run from an Administrator level command prompt).

在开发和我的个人测试(包括 Windows XP 32 和 64、Windows Vista 32 和 Windows 7 x64)期间,一切都运行良好。但是,在同事的 Windows Vista(32 位)和 Windows 7(64 位)计算机上进行测试部署期间,似乎存在特权/权限问题,OpenProcess失败并出现一般Access Denied错误。以受限用户身份运行时(如预期的那样)和明确以管理员身份运行时(右键单击 →以管理员身份运行以及从管理员级别命令提示符运行时)都会发生这种情况。

However, this problem has been unreproducible for myself in my test environment. I have witnessed the problem first hand, so I trust that the problem exists. The only difference that I can discern between the actual environment and my test environment is that the actualerror is occurring when using a Domain Administrator account at the UAC prompt, whereas my tests (which work with no errors) use a local administrator account at the UAC prompt.

然而,这个问题在我的测试环境中已经无法重现。我亲眼目睹了这个问题,所以我相信这个问题是存在的。我可以辨别实际环境和我的测试环境之间的唯一区别是在 UAC 提示下使用域管理员帐户时发生了实际错误,而我的测试(没有错误)在UAC 提示。

It appears that although the credentials being used allow UAC to 'run as administrator', the process is still not obtaining the correct rights to be able to OpenProcesson another process. I am not familiar enough with the internals of Vista/Windows 7 to know what this might be, and I am hoping someone has an idea of what could be the cause.

看起来虽然使用的凭据允许 UAC“以管理员身份运行”,但该进程仍未获得能够OpenProcess在另一个进程上运行的正确权限。我对 Vista/Windows 7 的内部结构不够熟悉,不知道这可能是什么,我希望有人知道可能是什么原因。

The Kicker

踢球者

The person who has reported this error, and who's environment can regularly reproduce this bug, has a small application named along the lines of RunWithDebugEnabledwhich is a small bootstrap program which appears to escalate its own privileges and then launch the executable passed to it (thus inheriting the escalated privileges). When run with this program, using the same Domain Administrator credentials at UAC prompt, the program works correctly and is able to successfully call OpenProcessand operates as intended.

报告这个错误的人,以及谁的环境可以定期重现这个错误,有一个小应用程序,RunWithDebugEnabled它是一个小引导程序,它似乎提升自己的权限,然后启动传递给它的可执行文件(因此继承升级的特权)。使用此程序运行时,在 UAC 提示下使用相同的域管理员凭据,该程序可以正常运行,并且能够OpenProcess按预期成功调用和运行。

So this is definitely a problem with acquiring the correct privileges, and it is known that the Domain Administrator account isan administrator account that should be able to access the correct rights. (Obviously obtaining this source code would be great, but I wouldn't be here if that were possible).

所以这肯定是获取正确权限的问题,众所周知,Domain Administrator账号应该能够访问正确权限的管理员账号。(显然,获得此源代码会很棒,但如果可能的话,我不会在这里)。

Notes

笔记

As noted, the errors reported by the failed OpenProcessattempts are Access Denied. According to MSDN documentation of OpenProcess:

如前所述,失败的OpenProcess尝试报告的错误是Access Denied. 根据 MSDN 文档OpenProcess

If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.

如果调用者启用了 SeDebugPrivilege 权限,则无论安全描述符的内容如何,​​都会授予请求的访问权限。

This leads me to believe that perhaps there is a problem under these conditions either with (1) Obtaining SeDebugPrivilegesor (2) Requiring other privileges which have not been mentioned in any MSDN documentation, and which might differ between a Domain Administrator account and a Local Administrator account

这让我相信,在这些条件下可能存在问题,可能是 (1) 获取SeDebugPrivileges或 (2) 需要任何 MSDN 文档中未提及的其他权限,并且域管理员帐户和本地管理员帐户之间可能有所不同帐户

Sample Code:

示例代码:

void sample()
{
   /////////////////////////////////////////////////////////
   //   Note: Enabling SeDebugPrivilege adapted from sample
   //     MSDN @ http://msdn.microsoft.com/en-us/library/aa446619%28VS.85%29.aspx
   // Enable SeDebugPrivilege
   HANDLE hToken = NULL;
   TOKEN_PRIVILEGES tokenPriv;
   LUID luidDebug;
   if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE)
   {
      if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
      {
         tokenPriv.PrivilegeCount           = 1;
         tokenPriv.Privileges[0].Luid       = luidDebug;
         tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
         if(AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, 0, NULL, NULL) != FALSE)
         {
            // Always successful, even in the cases which lead to OpenProcess failure
            cout << "SUCCESSFULLY CHANGED TOKEN PRIVILEGES" << endl;
         }
         else
         {
            cout << "FAILED TO CHANGE TOKEN PRIVILEGES, CODE: " << GetLastError() << endl;
         }
      }
   }
   CloseHandle(hToken);
   // Enable SeDebugPrivilege
   /////////////////////////////////////////////////////////

   vector<DWORD> pidList = getPIDs();  // Method that simply enumerates all current process IDs

   /////////////////////////////////////////////////////////
   // Attempt to open processes
   for(int i = 0; i < pidList.size(); ++i)
   {
      HANDLE hProcess = NULL;
      hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pidList[i]);
      if(hProcess == NULL)
      {
         // Error is occurring here under the given conditions
         cout << "Error opening process PID(" << pidList[i] << "): " << GetLastError() << endl;
      }
      CloseHandle(hProcess);
   }
   // Attempt to open processes
   /////////////////////////////////////////////////////////
}







Thanks!

谢谢!

If anyone has some insight into what possible permissions, privileges, rights, etc. that I may be missing to correctly open another process (assuming the executable has been properly "Run as Administrator"ed) on Windows Vista and Windows 7 under the above conditions, it would be most greatly appreciated.

如果有人对在上述条件下在 Windows Vista 和 Windows 7 上正确打开另一个进程(假设可执行文件已正确“以管理员身份运行”)有所了解,我可能缺少哪些可能的权限、特权、权利等,将不胜感激。

I wouldn't be here if I weren't absolutely stumped, but I'm hopeful that once again the experience and knowledge of the group shines bright. I thank you for taking the time to read this wall of text. The good intentions alone are appreciated, thanks for being the type of person that makes Stack Overflow so useful to all!

如果我不是完全被难住了,我就不会在这里,但我希望团队的经验和知识再次闪耀。我感谢您花时间阅读这堵文字墙。感谢您的善意,感谢您成为使 Stack Overflow 对所有人如此有用的人!

采纳答案by KevenK

So after a lot of debugging and bothering a lot of people for information, I was finally able to track down the guy who wrote the RunWithDebugEnabledapplication and get a rundown of how it operates.

因此,在经过大量调试和打扰很多人获取信息之后,我终于能够找到编写RunWithDebugEnabled应用程序的人并了解其运行方式。

The problem, in this case, is that Debug programsprivilege in the local policy for the domain administrator had been removed, and thus the SeDebugPrivilegetoken was not present in the process's access token. It can't be enabled if it's not present at all, and I still know of no way to add the privilege to an existing access token.

在这种情况下,问题是Debug programs域管理员的本地策略中的特权已被删除,因此该SeDebugPrivilege令牌不存在于进程的访问令牌中。如果它根本不存在,则无法启用它,我仍然知道无法将特权添加到现有访问令牌。


How the current magic works:
So the RunWithDebugEnabledmagic application would use its Administrator rights to install itself as a service and start itself, thus running under the SYSTEMuser account rather than the Domain Administrator. With SYSTEMprivileges, the app then creates a new access token that is identical to the Administrator token, only with the SeDebugPrivilegetoken present. This new token is used to CreateProcessAsUser()and run the program with the newly enabled SeDebugPrivilegethat was missing before.


当前魔法的工作原理:
因此,RunWithDebugEnabled魔法应用程序将使用其管理员权限将自身安装为服务并启动自身,从而在SYSTEM用户帐户而不是域管理员下运行。使用SYSTEM特权,应用程序然后创建一个与管理员令牌相同的新访问令牌,只有SeDebugPrivilege令牌存在。此新令牌用于使用之前丢失CreateProcessAsUser()的新启用的令牌运行程序SeDebugPrivilege

I actually do not like this "solution" here, and have been continuing my search for a 'cleaner' way to obtain this privilege. I will be posting this as another question here on SO, which I will try to remember to link here as well to help others follow along and for future reference.

我实际上不喜欢这里的这种“解决方案”,并且一直在继续寻找一种“更清洁”的方式来获得这种特权。我将在 SO 上将此作为另一个问题发布在此处,我将尝试记住将其链接到此处,以帮助其他人跟进并供将来参考。

EDIT:Impersonate SYSTEM (or equivalent) from Administrator Account

编辑:从管理员帐户模拟系统(或等效)



I thank you all for your time and energies in helping to debug and solve this problem. It really is much appreciated!



感谢大家抽出时间和精力帮助调试和解决这个问题。真的很感激!