Microsoft ASP.NET で偽装されたユーザーのコンテキストで実行されるプロセスを生成する
この記事では、偽装されたユーザーのコンテキストで実行されるプロセスを生成する方法について説明します。
元の製品バージョン: ASP.NET
元の KB 番号: 889251
概要
この詳細な記事では、偽装されたユーザーのコンテキストで実行されるプロセスを ASP.NET ページで生成する方法について説明します。 偽装されたユーザーのコンテキストで実行されるプロセスを生成するには、 メソッドを System.Diagnostics.Process.Start
使用できません。 これは、ASP.NET では、偽装はプロセス レベルではなくスレッド レベルで実行されるためです。 そのため、ASP.NET から生成するすべてのプロセスは、偽装されたコンテキストではなく、ASP.NET ワーカー プロセスのコンテキストで実行されます。
手法の説明
この問題を回避するには、次の Win32 API に対してプラットフォーム呼び出し (P/Invoke) を呼び出す必要があります。
関数は
CreateProcessAsUser
、いずれかのパラメーターで指定されたセキュリティ トークンの ID の下にプロセスを作成します。 ただし、関数の呼び出しにはCreateProcessAsUser
プライマリ トークンが必要です。 そのため、偽装されたトークンをプライマリ トークンに変換する必要があります。関数は
DuplicateTokenEx
、偽装されたトークンをプライマリ トークンに変換します。 関数の呼び出しでは、CreateProcessAsUser
このプライマリ トークンが使用されます。
注:
関数の呼び出しを CreateProcessAsUser
機能させるには、偽装されたユーザーに次のセキュリティ ユーザー権限を割り当てる必要があります。
- Windows を実行しているコンピューターで、[ プロセス レベルのトークンを置き換える ] ユーザー権利と [ クォータの増加 ] ユーザー権限を偽装ユーザーに割り当てます。
- Windows Server または Windows XP を実行しているコンピューターで、偽装されたユーザーに プロセス レベルトークンを置き換える 権限を割り当てます。
プロセスを生成する手順
Microsoft は、例示のみを目的としてプログラミング例を提供しており、明示または黙示にかかわらず、いかなる責任も負わないものとします。 これには、市販性または特定の目的との適合性についての黙示の保証も含まれますが、これに限定はされません。 この記事は、説明されているプログラミング言語、手順を作成およびデバッグするために使用されているツールに読者が精通していることを前提にしています。 マイクロソフト サポート窓口では、特定のプロシージャの機能説明に関するご質問に対して支援いたしますが、本例を特定の目的を満たすために機能を追加したり、プロシージャを構築することは行いません。 偽装されたユーザーのコンテキストで実行されるプロセスを生成するには、次の手順に従います。
Visual Studio .NET で、新しい Visual C# ASP.NET Web アプリケーションを作成し、アプリケーションにQ889251という名前を付けます。
コード ビューでWebForm1.aspx ファイルを開きます。
WebForm1.aspx ファイルで、using コード ブロックに次のステートメントを追加します。
using System.Runtime.InteropServices; using System.Security.Principal;
次のコード行のようなコード行を見つけます。
public class WebForm1 : System.Web.UI.Page
手順 4 で識別されたコード行の後に、次のコードを追加します。
[StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO { public int cb; public String lpReserved; public String lpDesktop; public String lpTitle; public uint dwX; public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars; public uint dwYCountChars; public uint dwFillAttribute; public uint dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId; } [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int Length; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; } [DllImport("kernel32.dll", EntryPoint="CloseHandle", SetLastError=true, CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] public extern static bool CloseHandle(IntPtr handle); [DllImport("advapi32.dll", EntryPoint="CreateProcessAsUser", SetLastError=true, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)] public extern static bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("advapi32.dll", EntryPoint="DuplicateTokenEx")] public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
ソリューション エクスプローラーで、[WebForm1.aspx] を右クリックし、[開く] をクリックします。 Web フォームが デザイン ビューで開きます。
[ 表示 ] メニューの [ HTML ソース] をクリックします。
[HTML ソース] ウィンドウ内のすべての既存のコードを次のコードに置き換えます。
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Q889251.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body> <form id="Form1" method="post" runat="server"> <P> </P> <P> Enter Path of process to be run (with relevant parameters) <asp:TextBox id="TextBox1" runat="server"></asp:TextBox> </P> <P> <asp:Button id="Button1" runat="server" Text="CreateProcess"></asp:Button> </P> <P> <asp:Label id="Label1" runat="server">Status:</asp:Label> </P> <P> <asp:Label id="Label2" runat="server">Impersonated Identity:</asp:Label> </P> </form> </body> </HTML>
[ 表示 ] メニューの [ デザイン] をクリックします。
[CreateProcess] をダブルクリックします。
Button1_Click
メソッドがコードに挿入され、コードがコンテンツ ウィンドウに表示されます。既存
Button1_Click
のメソッドを次のコードに置き換えます。private void Button1_Click(object sender, System.EventArgs e) { IntPtr Token = new IntPtr(0); IntPtr DupedToken = new IntPtr(0); bool ret; Label2.Text+=WindowsIdentity.GetCurrent().Name.ToString(); SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.bInheritHandle = false; sa.Length = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = (IntPtr)0; Token = WindowsIdentity.GetCurrent().Token; const uint GENERIC_ALL = 0x10000000; const int SecurityImpersonation = 2; const int TokenType = 1; ret = DuplicateTokenEx(Token, GENERIC_ALL, ref sa, SecurityImpersonation, TokenType, ref DupedToken); if (ret == false) { Label1.Text +="DuplicateTokenEx failed with " + Marshal.GetLastWin32Error(); } else { Label1.Text+= "DuplicateTokenEx SUCCESS"; STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = ""; string commandLinePath; commandLinePath = TextBox1.Text; PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); ret = CreateProcessAsUser(DupedToken,null,commandLinePath, ref sa, ref sa, false, 0, (IntPtr)0, "c:\\", ref si, out pi); if (ret == false) { Label1.Text +="CreateProcessAsUser failed with " + Marshal.GetLastWin32Error(); } else { Label1.Text +="CreateProcessAsUser SUCCESS. The child PID is" + pi.dwProcessId; CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } ret = CloseHandle(DupedToken); if (ret == false) { Label1.Text+=Marshal.GetLastWin32Error(); } else { Label1.Text+="CloseHandle SUCCESS"; } } }
[ ビルド] メニューで、[ ソリューションのビルド] をクリックします。
[ デバッグ ] メニューの [ 開始] をクリックします。
[WebForm1] ページで、開始するプロセスのパスを入力します。 たとえば、「」と入力します
SystemDriver \Windows\Notepad.exe
。[ CreateProcess] をクリックします。
関連情報
フィードバック
https://aka.ms/ContentUserFeedback。
近日公開予定: 2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub イシューを段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、以下を参照してください:フィードバックの送信と表示