web-dev-qa-db-ja.com

C#からのWindowsの偽装

LocalSystemとして実行されているC#プログラムは、一時的に別のユーザーのログインIDを偽装できますか?大まかに言って、LocalSystemとして実行したいWindowsサービスがありますが、ユーザーXYZに偽装することがあります(Windows統合セキュリティを使用してデータベースに接続する場合)。

すべての最も重要な:他のユーザーのパスワードを知らなくてもこれを行う方法はありますか?

注:パスワードが必須の場合、パスワードを安全に保管するための推奨戦略があります(c#またはvbscript、あるいはその両方)。

30
user53794

可能ですが、多くのコードを実行する必要があります。 NtCreateToken および CreateToken を参照してください。 SeCreateTokenPrivilegeが必要ですが、NT AUTHORITY\SYSTEMで実行しているので問題にはなりません。作成したトークンを使用して、スレッド内で偽装することができます。

18
wj32

短い答え:ユーザーパスワードまたはユーザーがCOMを介してサービスを呼び出すことなくしてはなりません。

プロセスで別のユーザーに成り代わるには、 ImpersonateLoggedOnUser を呼び出す必要があります。 ImpersonateLoggedOnUserにはトークンハンドルが必要です。トークンハンドルを取得するには、いくつかの方法があります。

  • LogonUser を使用してユーザーとしてログオンします。ただし、これにはユーザーのパスワードを知っている必要があります。
  • CreateRestrictedTokenDuplicateToken 、または DuplicateTokenEx を使用して既存のトークンを複製する。
  • OpenProcessToken または OpenThreadToken を使用して、すでにユーザーとしてログオンしている別のプロセスまたはスレッドからトークンを開く
11
Franci Penov

パスワードを保存する部分については、最近聞いた この質問 をご覧ください。

これは私の答えでした:

[〜#〜] dpapi [〜#〜] 、ストレージの暗号化を提供する Data Protection API を使用できます/使用する必要があります。
この種の問題のためだけに存在します。

ストレージの暗号化は、次のいずれかに基づいています。

  • ユーザーアカウント。ログインしたユーザーのみがデータにアクセスできます。これにより、まったく同じユーザー資格情報を持つ別のPCにデータを転送できるようになります。
  • マシン。その特定のマシン設定でのみデータにアクセスでき、別のPCには転送できません。

これを実装するために何が必要かを正確に示す Karl FranklinによるdnrTVショー と他の暗号化機能があります。
番組のソースコードもページで入手できます。

もちろん、そのテーマについては 他の記事 がたくさんあります。

5
Renaud Bompuis