示例#1
0
        /// <summary>コンストラクタ</summary>
        public SecurityEventLog()
        {
            bool   ret    = false;
            IntPtr hToken = IntPtr.Zero;

            // アクセス権を希望
            ret = SecurityWin32.OpenProcessToken(
                Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref hToken);
            // 2つの特権を有効にする(特権名を指定して)
            EnablePrivilege(hToken, SE_SECURITY_NAME);
            EnablePrivilege(hToken, SE_AUDIT_NAME);
        }
示例#2
0
        /// <summary>特権を有効にする。</summary>
        /// <param name="hToken">トークン</param>
        /// <param name="name"></param>
        private void EnablePrivilege(IntPtr hToken, string name)
        {
            long LUID = 0;
            bool ret  = false;

            // 特権のLUIDを取得
            ret = SecurityWin32.LookupPrivilegeValue(null, name, ref LUID);

            // 特権情報構造体
            SecurityWin32.TOKEN_PRIVILEGES tp = new SecurityWin32.TOKEN_PRIVILEGES();
            // 特権のLUID属性を設定
            tp.Privileges            = new SecurityWin32.LUID_AND_ATTRIBUTES();
            tp.Privileges.Luid       = LUID;
            tp.Privileges.Attributes = SE_PRIVILEGE_ENABLED;

            // 特権を有効にする。
            ret = SecurityWin32.AdjustTokenPrivileges(hToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
        }
        /// <summary>
        /// ASP.NET で偽装ユーザーのコンテキストで実行されるプロセスを生成する
        /// http://support.microsoft.com/kb/889251/ja
        /// </summary>
        /// <param name="commandLinePath">コマンドライン</param>
        /// <param name="currentDirectory">カレント・ディレクトリ</param>
        /// <param name="impersonationLevel">偽装レベル</param>
        /// <param name="errorInfo">エラー情報</param>
        /// <returns>
        /// ・true:成功
        /// ・false:失敗
        /// </returns>
        public static bool CreateProcessAsImpersonationUser(
            string commandLinePath, string currentDirectory,
            SecurityWin32.SECURITY_IMPERSONATION_LEVEL impersonationLevel, out string errorInfo)
        {
            // エラー情報の初期化
            errorInfo = "";

            // 失敗するので初期化
            if (string.IsNullOrEmpty(currentDirectory))
            {
                currentDirectory =
                    Environment.GetEnvironmentVariable(
                        "SystemRoot", EnvironmentVariableTarget.Process);
            }

            // トークン
            IntPtr token = IntPtr.Zero;
            // 継承可能にする。
            IntPtr tokenDuplicate = IntPtr.Zero;

            // 戻り値
            bool ret;

            // 偽装ユーザのアカウント・トークン
            token = WindowsIdentity.GetCurrent().Token;

            // SECURITY_ATTRIBUTES構造体
            SecurityWin32.SECURITY_ATTRIBUTES sa
                = new SecurityWin32.SECURITY_ATTRIBUTES();

            // Security Descriptor
            sa.lpSecurityDescriptor = IntPtr.Zero; // = (IntPtr)0;
            // Security Descriptorのハンドルは継承不可能
            sa.bInheritHandle = false;
            // サイズ
            sa.Length = Marshal.SizeOf(sa);

            try
            {
                // 偽装アクセストークンハンドルは、
                // CreateProcessAsUserに指定できないため、
                // DuplicateTokenExでプライマリ・トークンに変換する
                ret = SecurityWin32.DuplicateTokenEx(
                    token, (uint)SecurityWin32.ACCESS_MASK.GENERIC_ALL, ref sa,
                    (int)impersonationLevel, (int)SecurityWin32.TOKEN_TYPE.TokenPrimary, ref tokenDuplicate);

                // 戻り値判定
                if (ret)
                {
                    // true(成功)

                    // STARTUPINFO構造体
                    ProcessWin32.STARTUPINFO si = new ProcessWin32.STARTUPINFO();
                    // デスクトップ名
                    si.lpDesktop = "";
                    // サイズ
                    si.cb = Marshal.SizeOf(si);

                    // PROCESS_INFORMATION構造体
                    ProcessWin32.PROCESS_INFORMATION pi = new ProcessWin32.PROCESS_INFORMATION();

                    // 偽装可能にしたトークンを指定してプロセス起動
                    ret = ProcessWin32.CreateProcessAsUser(
                        tokenDuplicate, null, commandLinePath, ref sa, ref sa, false,
                        0, IntPtr.Zero, currentDirectory, ref si, out pi);

                    // 戻り値判定
                    if (ret)
                    {
                        // true(成功)

                        CmnWin32.CloseHandle(pi.hProcess);
                        CmnWin32.CloseHandle(pi.hThread);

                        // 偽装可能にしたトークンのハンドラを閉じる
                        ret = CmnWin32.CloseHandle(tokenDuplicate);
                    }
                    else
                    {
                        // asp.net - Running cscript.exe from C# .ashx does not execute code in vbscript file - Stack Overflow
                        // http://stackoverflow.com/questions/3842020/running-cscript-exe-from-c-sharp-ashx-does-not-execute-code-in-vbscript-file

                        // false(失敗)
                        errorInfo = "CreateProcessAsUser failed with " + Marshal.GetLastWin32Error()
                                    + ": if 1314, make sure user is a member 'Replace a process level token' Control Panel -> Administrative Tools -> Local Security Settings.";
                    }
                }
                else
                {
                    // false(失敗)
                    errorInfo = "DuplicateTokenEx failed with " + Marshal.GetLastWin32Error();
                }
            }
            finally
            {
                // 失敗(例外発生)時など。

                // トークンハンドル、
                // 偽装アクセストークンハンドルをクローズ
                if (token != IntPtr.Zero)
                {
                    CmnWin32.CloseHandle(token);
                }
                if (tokenDuplicate != IntPtr.Zero)
                {
                    CmnWin32.CloseHandle(tokenDuplicate);
                }
            }

            // false(失敗)
            return(false);
        }
        /// <summary>
        /// ユーザ名・ドメイン・パスワードで偽装する。
        /// </summary>
        /// <param name="userName">ユーザ名</param>
        /// <param name="domain">ドメイン</param>
        /// <param name="password">パスワード</param>
        /// <param name="impersonationLevel">偽装レベル</param>
        /// <param name="errorInfo">エラー情報</param>
        /// <returns>
        /// ・true:成功
        /// ・false:失敗
        /// </returns>
        public bool ImpersonateValidUser(
            string userName, string domain, string password,
            SecurityWin32.SECURITY_IMPERSONATION_LEVEL impersonationLevel, out string errorInfo)
        {
            // エラー情報の初期化
            errorInfo = "";

            // ワーク
            WindowsIdentity tempWindowsIdentity;

            // トークンのハンドラ
            IntPtr token          = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            try
            {
                // クライアントアプリケーションによる偽装を終了。
                if (SecurityWin32.RevertToSelf())
                {
                    // RevertToSelf成功

                    // 偽装する。

                    // トークンハンドルを取得
                    if (SecurityWin32.LogonUserA(userName, domain, password,
                                                 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                    {
                        // LogonUserA成功

                        // 偽装アクセストークンハンドルを作成
                        if (SecurityWin32.DuplicateToken(token, impersonationLevel, ref tokenDuplicate) != 0)
                        {
                            // DuplicateToken成功

                            // 偽装アクセストークンを使用して偽装する。
                            tempWindowsIdentity       = new WindowsIdentity(tokenDuplicate);
                            this.impersonationContext = tempWindowsIdentity.Impersonate();
                            if (this.impersonationContext != null)
                            {
                                // Impersonate成功
                                // 正常終了
                                return(true);
                            }
                            else
                            {
                                // Impersonate失敗
                                errorInfo = "Impersonate failed";
                            }
                        }
                        else
                        {
                            // DuplicateToken失敗
                            errorInfo = "DuplicateToken failed with " + Marshal.GetLastWin32Error();
                        }
                    }
                    else
                    {
                        // LogonUserA失敗
                        errorInfo = "LogonUserA failed with " + Marshal.GetLastWin32Error();
                    }
                }
                else
                {
                    // RevertToSelf失敗
                    errorInfo = "RevertToSelf failed with " + Marshal.GetLastWin32Error();
                }
            }
            finally
            {
                // 失敗(例外発生)時など。

                // トークンハンドル、
                // 偽装アクセストークンハンドルをクローズ
                if (token != IntPtr.Zero)
                {
                    CmnWin32.CloseHandle(token);
                }
                if (tokenDuplicate != IntPtr.Zero)
                {
                    CmnWin32.CloseHandle(tokenDuplicate);
                }
            }

            // 異常終了
            return(false);
        }