7

机器 A机器 B位于不同的域中。机器 A使用 VPN 访问机器 B 的网络。

我试图冒充用户,以便在Machine BMicrosoft.Web.Adminstration上的 IIS 中执行一些管理操作。

我试过的

  • 我在这里尝试了解决方案:https://forums.iis.net/t/1162205.aspx?Using+Microsoft+Web+Administration+on+a+remote+machine+not+in+the+domain。LogonUser 的 returnValue 对我来说是错误的。当我开始写这篇文章时,我想可能不同之处在于发布者正在使用两个不同但受信任的域中的机器,尽管现在我看到他的一台机器只是在一个工作组中。老实说,我不确定这种情况与我的情况相比如何……它是否应该有效地相同。

  • 我还尝试了另一种解决方案,该解决方案使用不同的登录类型值(NewCredential 而不是 Interactive)和不同的登录提供程序(WinNt50 而不是 Default),因为它声称它解决了我的域不受信任的问题。

  • 还尝试将这两种解决方案结合起来,但到目前为止没有任何效果

额外信息:

我开始在 asp.net mvc 项目中执行此操作,但是当第一个解决方案需要我调用时切换到控制台应用程序CoInitializeSecurity,显然,它要求它没有被事先调用并且我不知道如何防止它一个 mvc 项目(在控制台应用程序中,我只需要禁用 Visual Studio 托管进程)。

我应该提一下,我可以使用NetworkCredential该类和NetworkConnection类(https://gist.github.com/AlanBarber/92db36339a129b94b7dd)连接到目标机器并写入文件。所以我绝对知道用户/密码可以工作,我可以从客户端机器上使用它们来访问文件。我只是不知道如何模仿他们。

我不认为我可以立即为此提供赏金,但如果有人能够提供解决方案,我会尽快添加赏金并将其提供给您。

4

2 回答 2

2

我不确定您要做什么,我猜您想以“用户”身份执行一些您在 VPN 隧道中使用的代码,而不是您曾经登录的用户,对吗?

如果是这样,您需要“模拟”,您是否可以尝试使用“运行方式”执行您的应用程序,然后执行您的代码,应该在 VPN 域上的用户处执行(如果在您的电脑上授权)

然后,您可以继续使用“运行方式”方法或查看:

[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
[DllImport("advapi32.DLL")]
public static extern bool RevertToSelf();

void SomeMethod()
{
   IntPtr phToken = IntPtr.Zero;
   ImpersonateLoggedOnUser(phToken);
   //... some code
   RevertToSelf();
}

关于硬编码用户名的遗憾是

  1. 用户有时(需要)更改密码
  2. 任何拥有 ILSpy 的人通常都可以“利用”包含密码的源代码
  3. 在源代码中提供给开发人员的密码是 Uber 前一段时间的一个问题

    运行方式与向某人提供 VPN 凭据“一样安全”......如果用户通过将用户与恢复的用户进行比较,以自己的凭据启动应用程序,您可以提供“提醒”。

另一种选择是使用 Windows 凭据管理器(键入凭据管理器或从控制面板打开它),您将看到类似这样的内容。继续尝试看看您的目标是否可以使用此凭据提供程序进行配置。您将添加类似这样的内容,如果您需要端口,请不要忘记端口,该示例显示远程服务器凭证管理器上到 SQL 服务器的受信任连接。如果您发现这可行,那么您可以通过这里回答的凭证管理器 API管理用户。我会提示用户输入用户名和密码,并在连接失败时存储它们。

于 2018-05-07T16:13:03.163 回答
1

也许这会有所帮助,我有一个使用类似方法的解决方案。

进口

using System.Security.Principal;
using System.Runtime.InteropServices;

private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;

static WindowsImpersonationContext impersonationContext;

[DllImport("advapi32.dll")]
public static extern int LogonUserA(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);

方法:

static private bool impersonateValidUser(string userName, string domain, string password)
        {
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            if (RevertToSelf())
            {
                if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        impersonationContext = tempWindowsIdentity.Impersonate();
                        if (impersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }
                }
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
            return false;
        }

        static private void undoImpersonation()
        {
            impersonationContext.Undo();
        }

我希望这能让你到达那里!

于 2018-05-09T20:30:22.767 回答