首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用其他用户的凭据启动进程

使用其他用户的凭据启动进程
EN

Stack Overflow用户
提问于 2011-06-20 15:46:17
回答 3查看 49.7K关注 0票数 5

我想使用另一个用户名的凭据启动一个进程。这就是我现在所拥有的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        /// <summary>
        /// Do actions under another username's credentials
        /// </summary>
        /// <param name="username">Username to inpersonate</param>
        /// <param name="domain">Domain/Machine</param>
        /// <param name="password">Password </param>
        public static void Action(string username,string domain, string password )
        {
            try
            {
                if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref hToken))
                {
                    if (DuplicateToken(hToken, 2, ref hTokenDuplicate))
                    {

                        WindowsIdentity windowsIdentity = new WindowsIdentity(hTokenDuplicate);

                        WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate();

                        // Check the identity but it could do any other action under given username credentials
                      try
                        {
                            ProcessStartInfo info = new ProcessStartInfo("cmd.exe");
                            info.UseShellExecute = false;
                            info.RedirectStandardInput = true;
                            info.RedirectStandardError = true;
                            info.RedirectStandardOutput = true;
                            info.UserName = "dummy"; // see the link mentioned at the top
                            // Define the string value to assign to a new secure string.
                            char[] chars = { 'p', 'a', 's', 's','1','2','3','4','/' };
                            // Instantiate the secure string.
                            SecureString testString = new SecureString();
                            // Assign the character array to the secure string.
                            foreach (char ch in chars)
                                testString.AppendChar(ch);

                            info.Password = testString;

                            Process.Start(info);

                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Exception Occurred :{0},{1}",ex.Message, ex.StackTrace.ToString());
                        }

                        // Stop impersonating the user
                        impersonationContext.Undo();
                    }
                }
                // Free the tokens
                if (hToken != IntPtr.Zero) 
                    CloseHandle(hToken);
                if (hTokenDuplicate != IntPtr.Zero)
                    CloseHandle(hTokenDuplicate);

        }catch(Exception ex)
         {
             Console.WriteLine("Exception occurred. " + ex);
          }

它似乎不工作,我得到一个“访问被拒绝”。你有什么办法吗?如果我们请求凭据,我们就得到了正确的凭据,所以它应该在该凭据下执行任何程序。即:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
               if (DuplicateToken(hToken, 2, ref hTokenDuplicate))
                    {

                        WindowsIdentity windowsIdentity = new WindowsIdentity(hTokenDuplicate);                      
                        WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate();

                        // Check the identity but it could do any other action under given username credentials
                        Console.WriteLine("After impersonation: {0}", WindowsIdentity.GetCurrent().Name);

                        // Stop impersonating the user
                        impersonationContext.Undo();
                    }

答案是正确的,我们得到了“哑巴”。

我们可以让它变得更简单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 public static void Run()
        {
            try
            {
                const string file = "cmd.exe";

                var sspw = new SecureString();

                foreach (var c in "pass1234/")
                    sspw.AppendChar(c);

                var proc = new Process();

                proc.StartInfo.UseShellExecute = false;

                proc.StartInfo.WorkingDirectory = Path.GetDirectoryName(file);

                proc.StartInfo.FileName = Path.GetFileName(file);

                proc.StartInfo.Domain = "WIN08";
                proc.StartInfo.Arguments = "";
                proc.StartInfo.UserName = "dummy";
                proc.StartInfo.Password = sspw;
                proc.StartInfo.LoadUserProfile = false;
                proc.Start();
            }catch(Exception e)
            {
                Console.WriteLine(e);
             }

但是,我还是有例外的.

EN

回答 3

Stack Overflow用户

发布于 2011-06-21 09:17:54

这可能对某些人来说很奇怪,我很抱歉,我是Linux开发人员…测试结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /// <summary>
    /// Class that deals with another username credentials
    /// </summary>
    class Credentials
    {
        /// <summary>
        /// Constructor of SecureString password, to be used by RunAs
        /// </summary>
        /// <param name="text">Plain password</param>
        /// <returns>SecureString password</returns>
        private static SecureString MakeSecureString(string text)
        {
            SecureString secure = new SecureString();
            foreach (char c in text)
            {
                secure.AppendChar(c);
            }

            return secure;
        }

        /// <summary>
        /// Run an application under another user credentials.
        /// Working directory set to C:\Windows\System32
        /// </summary>
        /// <param name="path">Full path to the executable file</param>
        /// <param name="username">Username of desired credentials</param>
        /// <param name="password">Password of desired credentials</param>
        public static void RunAs(string path, string username, string password)
        {
            try
            {
                ProcessStartInfo myProcess = new ProcessStartInfo(path);
                myProcess.UserName = username;
                myProcess.Password = MakeSecureString(password);
                myProcess.WorkingDirectory = @"C:\Windows\System32";
                myProcess.UseShellExecute = false;
                Process.Start(myProcess);
            }
            catch (Win32Exception w32E)
            {
                // The process didn't start.
                Console.WriteLine(w32E);
            }
        }

    }
票数 7
EN

Stack Overflow用户

发布于 2011-06-20 15:50:38

我不认为您需要登录用户并复制句柄。您所需要做的就是在ProcessStartInfo对象中设置用户名、域和密码。如果我没记错的话,这是从.NET 3.0开始提供的。

编辑:

另外,对于更多信息,这是当您将用户名/域/密码提供给ProcessStartInfo:http://support.microsoft.com/kb/165194时实际发生的情况。拒绝访问的原因可能是您无权访问用户的桌面或窗口工作站。仅仅调用LoginUser是不够的。

票数 6
EN

Stack Overflow用户

发布于 2013-12-17 09:35:43

可能是你忘了设置只读安全字符串?我的方法对我来说很好:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Process proc = new Process
        {
            StartInfo =
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardInput = true,
                FileName = "cmd.exe",
                UserName = "user",
                Domain = "myDomain",
                Password = GetSecureString("Password"),
                Arguments = "/c ipconfig"                   
            }
        };
        proc.Start(); 

GetSecureString()函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static SecureString GetSecureString(string str)
    {
        SecureString secureString = new SecureString();
        foreach (char ch in str)
        {
            secureString.AppendChar(ch);
        }
        secureString.MakeReadOnly();
        return secureString;
    }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6413900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文