Как я могу выдать себя за пользователя в ненадежных доменах? - PullRequest
0 голосов
/ 27 апреля 2018

Машина A и Машина B находятся в разных доменах. Машина A использует VPN для получения доступа к сети B * .

Я пытаюсь выдать себя за пользователя с целью использования Microsoft.Web.Adminstration для выполнения некоторых административных действий в IIS на Машина B .

Что я пробовал

  • Я попробовал решение здесь: https://forums.iis.net/t/1162205.aspx?Using+Microsoft+Web+Administration+on+a+remote+machine+not+in+the+domain. ReturnValue от LogonUser для меня ложно. Когда я начал писать это, я подумал, что, может быть, разница в том, что постер работал с машинами в двух разных, но надежных доменах, хотя теперь я вижу, что один из его компьютеров был только в рабочей группе. Я, честно говоря, не уверен, как этот сценарий сравнивается с моим ... Должен ли он быть фактически таким же или нет.

  • Я также попробовал другое решение, в котором использовались разные значения для типа входа в систему (NewCredential вместо Interactive) и другого поставщика входа в систему (WinNt50 вместо Default), поскольку он утверждал, что решает мою проблему с недоверяемыми доменами.

  • Также попытался объединить два решения, но пока ничего не получилось .

Дополнительная информация:

Я начал делать это в проекте asv.net mvc, но переключился на консольное приложение, когда первое решение потребовало от меня вызова CoInitializeSecurity, что, по-видимому, требует, чтобы оно не вызывалось заранее, и я этого не делал знать, как предотвратить это в проекте mvc (в консольном приложении мне просто нужно было отключить процесс размещения Visual Studio).

И я должен упомянуть, что я могу использовать класс NetworkCredential с классом NetworkConnection (https://gist.github.com/AlanBarber/92db36339a129b94b7dd) для подключения к целевому компьютеру и записи файлов. Поэтому я точно знаю, что пользователь / pass работать, и я могу использовать их с клиентского компьютера для доступа к файлам. Я просто не могу понять, как имитировать их.

Не думаю, что смогу сразу же назначить вознаграждение, но если кто-то сможет предложить решение, я добавлю вознаграждение, как только смогу, и передам его вам.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Возможно, это поможет, у меня есть решение, работающее с использованием аналогичного подхода.

Импорт

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();
        }

Надеюсь, тебя туда доставят!

0 голосов

Я не уверен, что вы пытаетесь сделать, я думаю, вы хотели бы выполнить некоторый код "как пользователь", который вы используете в туннеле 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. Код Sorce, содержащий пароли, как правило, «доступен» любому, у кого есть ILSpy
  3. Пароли, предоставленные разработчикам в исходном коде, были чем-то вроде проблема с Uber некоторое время назад

    Запуск от имени «столь же безопасен», как и предоставление учетных данных VPN кому-то одному ... вы можете предоставить «напоминание», если пользователь запускает приложение в своих собственных учетных данных, сравнивая пользователя с обращенными.

Другой вариант - использовать диспетчер учетных данных Windows (введите диспетчер учетных данных или откройте его из панели управления), и вы увидите что-то подобное. попробуйте и посмотрите, может ли ваша цель быть настроена с этим поставщиком учетных данных. Вы бы добавили что-то вроде этого, не забывайте порт, если вам нужен порт, в примере показано доверенное соединение на удаленном сервере Credentials Manager с сервером SQL. Если вы обнаружите, что это работает, то вы можете управлять пользователем с помощью API диспетчера учетных данных, как указано здесь . Я запрашивал у пользователя имя пользователя и пароль и сохранял их при сбое подключения.

...