25

必要に応じて適切な特権にエスカレートすることについて私が見つけたものはすべて、私の現在の方法と一致していますが、問題は存在します。誰かが Windows Vista/Windows 7 の内部の経験を持ち、暗闇しかないところに光を当てることができることを願っています。長くなると思いますが、ご了承ください。

環境

現在のマシン上の他のプロセスのメモリにアクセスする必要があるアプリケーションに取り組んでいます。これには、明らかに管理者権限が必要です。また、必要SeDebugPrivilegeです (いいえ、スペルミスではありませんSetDebugPrivilege)。これは正しく取得していると思いますが、これ以上の特権が必要ないのか、それが問題の原因なのか疑問に思います。これまでのところ、コードは Windows XP のすべてのバージョン、および私のテスト用の Vista 32 ビット環境と Windows 7 64 ビット環境で正常に動作しています。

プロセス

  • プログラムは常に管理者権限で実行されます。これは、この投稿全体で想定できます。
  • Access Token現在のプロセスのインクルードSeDebugPrivilege権をエスカレートしています。
  • EnumProcessesシステム上の現在の PID のリストを作成するために使用する
  • アクセス権を使用OpenProcessしてハンドルを開くPROCESS_ALL_ACCESS
  • ReadProcessMemory他のプロセスのメモリを読み取るために使用します。

問題:

開発中および個人的なテスト中 (Windows XP 32 & 64、Windows Vista 32、および Windows 7 x64 を含む) はすべて正常に動作しています。ただし、同僚の Windows Vista (32 ビット) と Windows 7 (64 ビット) の両方のマシンへのテスト展開中に、一般的なエラーでOpenProcess失敗する特権/権利の問題があるようです。Access Deniedこれは、制限付きユーザーとして実行している場合 (予想どおり) と、管理者として明示的に実行している場合 (右クリック →管理者として実行、および管理者レベルのコマンド プロンプトから実行した場合) の両方で発生します。

ただし、この問題は、私のテスト環境では再現できませんでした。私は問題を直接目撃したので、問題が存在すると信じています。実際の環境とテスト環境で識別できる唯一の違いは、UAC プロンプトでドメイン管理者アカウントを使用すると実際のエラーが発生するのに対し、私のテスト (エラーなしで動作) ではローカル管理者アカウントを使用することです。 UAC プロンプト。

OpenProcess使用されている資格情報により、UAC は「管理者として実行」できますが、プロセスは別のプロセスで実行できる正しい権限をまだ取得していないようです。私は、Vista/Windows 7 の内部構造に精通していないため、これが何であるかを知ることができません。誰かが原因を突き止めてくれることを願っています。

キッカー

RunWithDebugEnabledこのエラーを報告した人で、その環境で定期的にこのバグを再現できる人は、自分の権限をエスカレートし、渡された実行可能ファイルを起動するように見える小さなブートストラップ プログラムに沿って名前が付けられた小さなアプリケーションを持っていますエスカレートされた特権)。UAC プロンプトで同じドメイン管理者の資格情報を使用してこのプログラムを実行すると、プログラムは正常に動作し、意図したとおりに正常に呼び出しOpenProcessて動作することができます。

したがって、これは間違いなく正しい権限を取得する際の問題であり、ドメイン管理者アカウント正しい権限にアクセスできるはずの管理者アカウントであることがわかっています。(もちろん、このソース コードを入手できれば素晴らしいことですが、それが可能であれば私はここにいません)。

ノート

前述のとおり、失敗したOpenProcess試行によって報告されるエラーは次のとおりAccess Deniedです。のMSDNドキュメントによるとOpenProcess

呼び出し元が SeDebugPrivilege 特権を有効にしている場合、セキュリティ記述子の内容に関係なく、要求されたアクセスが許可されます。

これにより、これらの条件下では、(1) 取得SeDebugPrivilegesまたは (2) MSDN ドキュメントで言及されていない他の権限の要求のいずれかで問題が発生し、ドメイン管理者アカウントとローカル管理者の間で異なる可能性があると思われます。アカウント

サンプルコード:

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
   /////////////////////////////////////////////////////////
}



ありがとう!

上記の条件下でWindows VistaおよびWindows 7で別のプロセスを正しく開くために欠落している可能性のある許可、特権、権利などについて誰かが洞察を持っている場合(実行可能ファイルが適切に「管理者として実行」されていると仮定) 、それは非常に高く評価されます。

完全に困惑していなければ、私はここにいないでしょうが、グループの経験と知識が再び輝きを放つことを願っています. この長い文章を読んでいただき、ありがとうございます。善意だけでもありがたいです。スタック オーバーフローをすべての人にとって便利なものにしてくれていることに感謝します。

4

1 に答える 1

13

そのため、多くのデバッグを行い、多くの人に情報を求めて迷惑をかけた後、最終的にRunWithDebugEnabledアプリケーションを書いた人物を突き止め、その動作の概要を知ることができました。

この場合の問題はDebug programs、ドメイン管理者のローカル ポリシーの特権が削除されたため、SeDebugPrivilegeトークンがプロセスのアクセス トークンに存在しなかったことです。まったく存在しない場合は有効にすることはできず、既存のアクセストークンに特権を追加する方法はまだわかっていません.


現在の魔法のしくみ:
したがって、RunWithDebugEnabled魔法のアプリケーションは、その管理者権限を使用してサービスとして自身をインストールし、それ自体を開始するためSYSTEM、ドメイン管理者ではなくユーザー アカウントで実行されます。特権を使用SYSTEMすると、アプリは管理者トークンと同一の新しいアクセス トークンを作成しますが、SeDebugPrivilegeトークンが存在する場合のみです。この新しいトークンは、以前に欠落CreateProcessAsUser()していた新しく有効化されたプログラムを実行するために使用されます。SeDebugPrivilege

私は実際、この「解決策」が気に入らず、この特権を取得する「よりクリーンな」方法を探し続けています。これをSOの別の質問として投稿します。他の人がフォローできるように、また将来の参考のために、ここにもリンクすることを忘れないようにします。

編集: 管理者アカウントからSYSTEM(または同等のもの)になりすます



この問題のデバッグと解決に時間と労力を割いてくださったことに感謝します。本当にありがたいです!

于 2010-06-07T16:27:31.120 に答える