web-dev-qa-db-ja.com

リモートコンピューターでコマンドを実行し、ログオンしているユーザーにUIを表示する

オンラインで適切な解決策が見つからなかったので、ここで質問します。

プログラムを実行して、現在ログインしているユーザーにプログラムのGUIを表示したいコンピューターがたくさんあります。 AfaikこれはPowershellでは不可能であり(Windowsサービスの停止/開始は問題ありません)、PsExec.exeでこれを実行することができませんでした。

PsExecコマンドは次のようになります。タスクマネージャーにcalc.exeが表示されますが、GUIが表示されません。

C:\Users\Administrator.DEV\Desktop>PsExec.exe -i \\TEST-CLI-01 -u localUser -p userPassword -d calc.exe

セットアップの簡単な説明:サーバー:MS Server2012R2クライアント:Windows 8.1すべてのシステムはADドメインの一部です。

誰でも私がこれをどのように達成できるのか考えがありますか?

事前にたくさんThx :)

3
pinas

これは、不可能ではないにしても、非常に困難であることがわかります。簡単だと思うかもしれませんが、簡単ではありません。 Microsoftは、別のユーザーのセキュリティコンテキストでウィンドウマネージャーを操作できる場合に、一種のセキュリティ脆弱性(「シャッター」攻撃)を公開するため、意図的にこれを困難にしています。

Windows Vistaで導入された Session 0 Isolation 機能は、サービスプログラム(PsExecなど)がコンソールと対話することを困難にします。インタラクティブサービス検出サービスが実行されている場合、サービスがコンソールと対話しようとすると、ユーザーは安全なデスクトップに切り替えてサービスのGUIと対話するように求められます。

いくつかの Stackoverflowに関するディスカッション があり、アーキテクチャの詳細に少し触れます。

これを処理するより良い方法は、ユーザーに、ある種のプロセス間通信をリッスンし、それに応じて動作するプロセスを実行させることです。本当にハックしたい場合は、ユーザーがログオンし、ファイル/レジストリエントリを待っているときに、バックグラウンドで単純なVBScriptまたはPowershellスクリプトを実行します/ TCP connection/etcを実行してアクションを実行します。このようなものを一緒に概念実証としてすばやく作成できます。

2
Evan Anderson

あなたのためのヒントとヒント-私がしたことは次のとおりです

function startChromeRemotely($client) {
    $desktopSession = query user /server:$client | Select-String -Pattern Active
    $desktopSessionId = ($desktopSession -split '\s+')[3]
    .\PsExec.exe -i $desktopSessionId -d \\$client -u someuser-p somepassword "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
}

したがって、基本的には、最初にログイン(「アクティブ」)ユーザーのデスクトップセッションを取得し、その後chrome画面をユーザーセッションに直接「挿入」します。ドメイン管理者として実行した場合これは問題なく動作するようですが、どういうわけか奇妙で不安定な感じがします。

もう一度Thx :)

1
pinas

Evanが言ったように、これは悪意を持って悪用したり使用したりすることが非常に簡単であるため、意図的に実行することが困難になっています。

しかし、十分な献身があり、あなたの手を汚す気があれば、それを行うことができます。

実稼働環境のマシンで実行され、特定の条件下でログオンしたユーザーのセキュリティコンテキストでGUIアプリケーションを実行する、非常に堅牢で信頼性の高いWindowsサービスを作成しました。これにより、アプリケーションはユーザーの目の前に表示されます...要は、堅牢で信頼できる方法でそれを行うことが可能であるということです。

キーは CreateProcessAsUser Advapi32.dllのAPI関数 です。

また、その機能を使用するには、ログオンしたユーザーのプライマリアクセストークンを「盗む」ことができる必要があります。そしてそれを行うには、 WTSQueryUserToken AP​​I関数をWtsapi32.dllから を使用できます。

前述のAPIを使用する際の制限の1つは、ローカルシステムのセキュリティコンテキスト内からのみ呼び出すことができるということです。これがPsExec.exe -si 2 \\Test-CLI-01 calc.exeが機能する理由です。そこにある-sスイッチは、ローカルシステムとして実行するPsExec。

これは当然、WTSQueryUserTokenを使用する場合に必要になるため、Windowsサービスがローカルシステムとして実行される場合の1つです。ローカルシステムは、実行中のマシンに無制限にアクセスできるため、プログラムまたはサービスをローカルシステムとして実行することは、それ以外の場合は一般に悪い考えです。したがって、ハッカーがプログラムの欠陥を悪用した場合、ハッカーはローカルシステムのセキュリティコンテキストが付与するすべてのセキュリティ特権を使用して、コードに何らかのアクションを実行させるエクスプロイト。 (つまり、それらすべて

これは、これらのセキュリティトークンを破棄し、漏洩しないようにするのはユーザーの責任であるため、プログラマーが特に注意を払う必要がある場所でもあります。セキュリティトークンが適切に処理されない場合、悪質な目的でセキュリティトークンを使用する可能性があります。

私がしばらく前に書いたいくつかのC#から取ったいくつかの役立つ例:

ユーザーのプライマリアクセストークンの取得:

WTSQueryUserToken((uint)session.SessionId, out userPrimaryAccessToken) 

そのプライマリアクセストークンを使用して、そのユーザーとしてセッションでプロセスを開始します。

CreateProcessAsUser(userPrimaryAccessToken, null, cmdLine, ref saProcessAttributes, ref saThreadAttributes, false, 0, IntPtr.Zero, null, ref si, out pi)

これらは単なるWindows API呼び出しです...希望する任意の言語で複製できます。

1
Ryan Ries