自分のニーズに合った適切な特権にエスカレーションすることについて私が見つけたすべてのことは、私の現在の方法に同意していますが、問題は存在します。誰かがWindowsVista/Windows 7の内部エクスペリエンスを持っていて、暗闇しかない場所で光を当てることができるといいのですが。これは長くなると思いますが、ご容赦ください。
現在のマシン上の他のプロセスのメモリにアクセスする必要があるアプリケーションに取り組んでいます。これには、明らかに管理者権限が必要です。また、SeDebugPrivilege
(いいえ、SetDebugPrivilege
のスペルミスではありません)も必要です。これは、より多くの特権が必要ないかどうか、したがって、私の問題。これまでのところ、コードはWindows XPのすべてのバージョン、およびテスト用のVista32ビット環境とWindows764ビット環境で正常に機能しています。
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プロンプトでローカル管理者アカウントを使用します。
使用されている資格情報により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をすべての人に役立つタイプの人にしてくれてありがとう、善意だけでもありがたいです。
そのため、多くのデバッグを行い、多くの人に情報を求めた後、ようやくRunWithDebugEnabled
アプリケーションを作成した人を追跡し、その動作の概要を把握することができました。
この場合の問題は、ドメイン管理者のローカルポリシーの_Debug programs
_特権が削除されたため、プロセスのアクセストークンにSeDebugPrivilege
トークンが存在しなかったことです。まったく存在しない場合は有効にできません。また、既存のアクセストークンに特権を追加する方法がまだわかりません。
現在の魔法のしくみ:
したがって、RunWithDebugEnabled
マジックアプリケーションは、管理者権限を使用して自分自身をサービスとしてインストールし、自分自身を起動するため、ドメイン管理者ではなくSYSTEM
ユーザーアカウントで実行されます。 SYSTEM
権限を使用すると、アプリは管理者トークンと同じ新しいアクセストークンを作成しますが、SeDebugPrivilege
トークンのみが存在します。この新しいトークンは、CreateProcessAsUser()
に使用され、以前は欠落していた新しく有効にされたSeDebugPrivilege
でプログラムを実行します。
私は実際、ここでのこの「解決策」が好きではなく、この特権を取得するための「よりクリーンな」方法を探し続けています。これを別の質問としてSOに投稿します。他の人がフォローし、将来参照できるように、ここにもリンクすることを忘れないようにします。
編集:管理者アカウントからシステム(または同等のもの)になりすます
この問題のデバッグと解決にご協力いただき、ありがとうございました。本当にありがたいです!