web-dev-qa-db-ja.com

Windows Vista / Windows 7特権:SeDebugPrivilege&OpenProcess

自分のニーズに合った適切な特権にエスカレーションすることについて私が見つけたすべてのことは、私の現在の方法に同意していますが、問題は存在します。誰かがWindowsVista/Windows 7の内部エクスペリエンスを持っていて、暗闇しかない場所で光を当てることができるといいのですが。これは長くなると思いますが、ご容赦ください。

環境

現在のマシン上の他のプロセスのメモリにアクセスする必要があるアプリケーションに取り組んでいます。これには、明らかに管理者権限が必要です。また、SeDebugPrivilege(いいえ、SetDebugPrivilegeのスペルミスではありません)も必要です。これは、より多くの特権が必要ないかどうか、したがって、私の問題。これまでのところ、コードはWindows XPのすべてのバージョン、およびテスト用のVista32ビット環境とWindows764ビット環境で正常に機能しています。

処理する

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

問題:

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

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

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

キッカー

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

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

ノート

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

呼び出し元が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
   /////////////////////////////////////////////////////////
}




ありがとう!

上記の条件下で、WindowsVistaおよびWindows7で別のプロセスを正しく開くために(実行可能ファイルが適切に「管理者として実行」されていると仮定して)不足している可能性のあるアクセス許可、特権、権限などについて誰かが洞察を持っている場合、よろしくお願いします。

絶対に困惑していなければここにはいませんでしたが、グループの経験と知識が再び輝いてくれることを願っています。このテキストの壁をお読みいただき、ありがとうございます。 Stack Overflowをすべての人に役立つタイプの人にしてくれてありがとう、善意だけでもありがたいです。

25
KevenK

そのため、多くのデバッグを行い、多くの人に情報を求めた後、ようやくRunWithDebugEnabledアプリケーションを作成した人を追跡し、その動作の概要を把握することができました。

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


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

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

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



この問題のデバッグと解決にご協力いただき、ありがとうございました。本当にありがたいです!

13
KevenK