Jak się podszywać in.NET?

Czy istnieje prosty sposób na podszywanie się pod użytkownika w. NET?

Do tej pory używałem tej klasy z code project dla wszystkich moich wymagań dotyczących podszywania się.

Czy jest lepszy sposób, aby to zrobić używając. NET Framework?

Mam zestaw poświadczeń użytkownika (nazwa użytkownika, Hasło, Nazwa domeny), który reprezentuje tożsamość, pod którą muszę się podszywać.

Author: Ralph Willgoss, 2008-09-24

7 answers

Oto dobry przegląd koncepcji podszywania się pod. NET.

Zasadniczo będziesz korzystał z tych klas, które są nieaktywne w. NET framework:

Kod często może być długi, choć i dlatego widzisz wiele przykładów, takich jak ten, do którego się odwołujesz, które próbują uprościć ten proces.

 55
Author: Eric Schoonover,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-08 09:52:38

"Podszywanie się" w przestrzeni. NET zazwyczaj oznacza uruchamianie kodu pod określonym kontem użytkownika. Jest to nieco osobna koncepcja niż uzyskanie dostępu do tego konta użytkownika za pomocą nazwy użytkownika i hasła, chociaż te dwa pomysły często łączą się w pary. Opiszę je obie, a następnie wyjaśnię, jak korzystać z mojej biblioteki SimpleImpersonation , która używa ich wewnętrznie.

Podszywanie się

W związku z tym, że nie jest to możliwe, nie jest to możliwe. net. net. net. net. net. net. net. net. net. net. net. net. net. net. net. net.]} przestrzeń nazw:
  • Nowszy kod (. NET 4.6+,. Net Core itp.) powinny ogólnie używać WindowsIdentity.RunImpersonated, który akceptuje uchwyt do tokena konta użytkownika, a następnie Action lub {[9] } dla kodu do wykonania.

    WindowsIdentity.RunImpersonated(tokenHandle, () =>
    {
        // do whatever you want as this user.
    });
    

    Lub

    var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
    {
        // do whatever you want as this user.
        return result;
    });
    
  • Starszy kod używał WindowsIdentity.Impersonate metoda pobierania obiektu WindowsImpersonationContext. Obiekt ten implementuje IDisposable, więc generalnie powinien być wywoływany z bloku using.

    using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
    {
        // do whatever you want as this user.
    }
    

    Podczas gdy ten API nadal istnieje w . NET Framework, generalnie należy go unikać i nie jest dostępny w. Net Core lub. Net Standard.

Dostęp do konta użytkownika

API do używania nazwy użytkownika i hasła w celu uzyskania dostępu do konta użytkownika w systemie Windows jest LogonUser - który jest natywnym API Win32. Nie ma obecnie wbudowanego API. NET do wywołania go, więc trzeba uciekać się do P / Invoke.

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);

Jest to podstawowa definicja wywołania, jednak jest o wiele więcej do rozważenia w rzeczywistości używa go w produkcji:

  • uzyskanie uchwytu z" bezpiecznym " wzorcem dostępu.
  • odpowiednie zamykanie uchwytów natywnych
  • [28]}poziomy zaufania Code access security (CAS) (tylko w. NET Framework)
  • przechodząc SecureString, kiedy można bezpiecznie zebrać jedną za pomocą naciśnięć klawiszy użytkownika.

Ilość kodu do napisania, aby zilustrować to wszystko, przekracza to, co powinno być w odpowiedzi StackOverflow, IMHO.

A połączone i łatwiejsze Podejście

Zamiast pisać to wszystko samemu, rozważ użycie mojej biblioteki SimpleImpersonation , która łączy podszywanie się i dostęp do użytkownika w jednym API. Działa dobrze zarówno w nowoczesnych, jak i starszych bazach kodu, z tym samym prostym API: {]}

var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
    // do whatever you want as this user.
}); 

Lub

var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
    // do whatever you want as this user.
    return something;
});

Zauważ, że jest bardzo podobny do API WindowsIdentity.RunImpersonated, ale nie wymaga wiedzy o uchwytach tokenów.

To jest API od wersji 3.0.0. Zobacz projekt readme po więcej szczegóły. Należy również zauważyć, że poprzednia wersja biblioteki używała API ze wzorem IDisposable, podobnym do WindowsIdentity.Impersonate. Nowsza wersja jest znacznie bezpieczniejsza i obie są nadal używane wewnętrznie.

 251
Author: Matt Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-12 19:05:41

To jest prawdopodobnie to, czego chcesz:

using System.Security.Principal;
using(WindowsIdentity.GetCurrent().Impersonate())
{
     //your code goes here
}
Ale naprawdę potrzebuję więcej szczegółów, żeby Ci pomóc. Możesz zrobić podszywanie się za pomocą pliku konfiguracyjnego (jeśli próbujesz to zrobić na stronie internetowej) lub poprzez dekoratory metod (atrybuty), jeśli jest to usługa WCF, lub przez... rozumiesz.

Ponadto, jeśli mówimy o podszywaniu się pod klienta, który wywołał konkretną usługę (lub aplikację internetową), musisz poprawnie skonfigurować klienta, aby przeszedł odpowiednie żetony.

Wreszcie, jeśli to, co naprawdę chcesz zrobić, to Delegacja, musisz również poprawnie skonfigurować reklamę, aby użytkownicy i maszyny były zaufane do delegacji.

Edit:
Zobacz też proszę. aby dowiedzieć się, jak podszywać się pod innego użytkownika i uzyskać dalszą dokumentację.

 18
Author: Esteban Araya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 04:10:24

Oto mój vb.net port odpowiedzi Matta Johnsona. Dodałem enum dla typów logowania. LOGON32_LOGON_INTERACTIVE była pierwszą wartością enum, która działała dla sql server. Mój sznurek połączeniowy był po prostu zaufany. Brak nazwy użytkownika / hasła w łańcuchu połączeń.

  <PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
  Public Class Impersonation
    Implements IDisposable

    Public Enum LogonTypes
      ''' <summary>
      ''' This logon type is intended for users who will be interactively using the computer, such as a user being logged on  
      ''' by a terminal server, remote shell, or similar process.
      ''' This logon type has the additional expense of caching logon information for disconnected operations; 
      ''' therefore, it is inappropriate for some client/server applications,
      ''' such as a mail server.
      ''' </summary>
      LOGON32_LOGON_INTERACTIVE = 2

      ''' <summary>
      ''' This logon type is intended for high performance servers to authenticate plaintext passwords.
      ''' The LogonUser function does not cache credentials for this logon type.
      ''' </summary>
      LOGON32_LOGON_NETWORK = 3

      ''' <summary>
      ''' This logon type is intended for batch servers, where processes may be executing on behalf of a user without 
      ''' their direct intervention. This type is also for higher performance servers that process many plaintext
      ''' authentication attempts at a time, such as mail or Web servers. 
      ''' The LogonUser function does not cache credentials for this logon type.
      ''' </summary>
      LOGON32_LOGON_BATCH = 4

      ''' <summary>
      ''' Indicates a service-type logon. The account provided must have the service privilege enabled. 
      ''' </summary>
      LOGON32_LOGON_SERVICE = 5

      ''' <summary>
      ''' This logon type is for GINA DLLs that log on users who will be interactively using the computer. 
      ''' This logon type can generate a unique audit record that shows when the workstation was unlocked. 
      ''' </summary>
      LOGON32_LOGON_UNLOCK = 7

      ''' <summary>
      ''' This logon type preserves the name and password in the authentication package, which allows the server to make 
      ''' connections to other network servers while impersonating the client. A server can accept plaintext credentials 
      ''' from a client, call LogonUser, verify that the user can access the system across the network, and still 
      ''' communicate with other servers.
      ''' NOTE: Windows NT:  This value is not supported. 
      ''' </summary>
      LOGON32_LOGON_NETWORK_CLEARTEXT = 8

      ''' <summary>
      ''' This logon type allows the caller to clone its current token and specify new credentials for outbound connections.
      ''' The new logon session has the same local identifier but uses different credentials for other network connections. 
      ''' NOTE: This logon type is supported only by the LOGON32_PROVIDER_WINNT50 logon provider.
      ''' NOTE: Windows NT:  This value is not supported. 
      ''' </summary>
      LOGON32_LOGON_NEW_CREDENTIALS = 9
    End Enum

    <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Private Shared Function LogonUser(lpszUsername As [String], lpszDomain As [String], lpszPassword As [String], dwLogonType As Integer, dwLogonProvider As Integer, ByRef phToken As SafeTokenHandle) As Boolean
    End Function

    Public Sub New(Domain As String, UserName As String, Password As String, Optional LogonType As LogonTypes = LogonTypes.LOGON32_LOGON_INTERACTIVE)
      Dim ok = LogonUser(UserName, Domain, Password, LogonType, 0, _SafeTokenHandle)
      If Not ok Then
        Dim errorCode = Marshal.GetLastWin32Error()
        Throw New ApplicationException(String.Format("Could not impersonate the elevated user.  LogonUser returned error code {0}.", errorCode))
      End If

      WindowsImpersonationContext = WindowsIdentity.Impersonate(_SafeTokenHandle.DangerousGetHandle())
    End Sub

    Private ReadOnly _SafeTokenHandle As New SafeTokenHandle
    Private ReadOnly WindowsImpersonationContext As WindowsImpersonationContext

    Public Sub Dispose() Implements System.IDisposable.Dispose
      Me.WindowsImpersonationContext.Dispose()
      Me._SafeTokenHandle.Dispose()
    End Sub

    Public NotInheritable Class SafeTokenHandle
      Inherits SafeHandleZeroOrMinusOneIsInvalid

      <DllImport("kernel32.dll")> _
      <ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)> _
      <SuppressUnmanagedCodeSecurity()> _
      Private Shared Function CloseHandle(handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
      End Function

      Public Sub New()
        MyBase.New(True)
      End Sub

      Protected Overrides Function ReleaseHandle() As Boolean
        Return CloseHandle(handle)
      End Function
    End Class

  End Class

Musisz użyć instrukcji Using, aby zawierała jakiś kod do uruchomienia.

 7
Author: toddmo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-22 19:24:19

Zobacz więcej szczegółów z mojej poprzedniej odpowiedzi Stworzyłem pakiet nuget Nuget

Code on Github

Próbka: możesz użyć:

           string login = "";
           string domain = "";
           string password = "";

           using (UserImpersonation user = new UserImpersonation(login, domain, password))
           {
               if (user.ImpersonateValidUser())
               {
                   File.WriteAllText("test.txt", "your text");
                   Console.WriteLine("File writed");
               }
               else
               {
                   Console.WriteLine("User not connected");
               }
           }

Zobacz pełny kod:

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


/// <summary>
/// Object to change the user authticated
/// </summary>
public class UserImpersonation : IDisposable
{
    /// <summary>
    /// Logon method (check athetification) from advapi32.dll
    /// </summary>
    /// <param name="lpszUserName"></param>
    /// <param name="lpszDomain"></param>
    /// <param name="lpszPassword"></param>
    /// <param name="dwLogonType"></param>
    /// <param name="dwLogonProvider"></param>
    /// <param name="phToken"></param>
    /// <returns></returns>
    [DllImport("advapi32.dll")]
    private static extern bool LogonUser(String lpszUserName,
        String lpszDomain,
        String lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);

    /// <summary>
    /// Close
    /// </summary>
    /// <param name="handle"></param>
    /// <returns></returns>
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public static extern bool CloseHandle(IntPtr handle);

    private WindowsImpersonationContext _windowsImpersonationContext;
    private IntPtr _tokenHandle;
    private string _userName;
    private string _domain;
    private string _passWord;

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

    /// <summary>
    /// Initialize a UserImpersonation
    /// </summary>
    /// <param name="userName"></param>
    /// <param name="domain"></param>
    /// <param name="passWord"></param>
    public UserImpersonation(string userName, string domain, string passWord)
    {
        _userName = userName;
        _domain = domain;
        _passWord = passWord;
    }

    /// <summary>
    /// Valiate the user inforamtion
    /// </summary>
    /// <returns></returns>
    public bool ImpersonateValidUser()
    {
        bool returnValue = LogonUser(_userName, _domain, _passWord,
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                ref _tokenHandle);

        if (false == returnValue)
        {
            return false;
        }

        WindowsIdentity newId = new WindowsIdentity(_tokenHandle);
        _windowsImpersonationContext = newId.Impersonate();
        return true;
    }

    #region IDisposable Members

    /// <summary>
    /// Dispose the UserImpersonation connection
    /// </summary>
    public void Dispose()
    {
        if (_windowsImpersonationContext != null)
            _windowsImpersonationContext.Undo();
        if (_tokenHandle != IntPtr.Zero)
            CloseHandle(_tokenHandle);
    }

    #endregion
}
 2
Author: Cedric Michel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-16 07:51:40

Wiem, że jestem dość spóźniony na przyjęcie, ale uważam, że biblioteka z Phillip Allan-Harding , jest najlepsza do tej sprawy i podobnych.

Potrzebujesz tylko małego kawałka kodu, takiego jak ten:

private const string LOGIN = "mamy";
private const string DOMAIN = "mongo";
private const string PASSWORD = "HelloMongo2017";

private void DBConnection()
{
    using (Impersonator user = new Impersonator(LOGIN, DOMAIN, PASSWORD, LogonType.LOGON32_LOGON_NEW_CREDENTIALS, LogonProvider.LOGON32_PROVIDER_WINNT50))
    {
    }
}

I dodać jego klasę:

. Net (C#) Podszywanie się pod dane uwierzytelniające sieci

Mój przykład może być użyty, jeśli chcesz, aby podszyty logon miał poświadczenia sieciowe, ale ma więcej opcji.

 2
Author: Federico Navarrete,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-08 12:50:43

Możesz użyć tego rozwiązania. (Użyj pakietu nuget) Kod źródłowy jest dostępny na: Github: https://github.com/michelcedric/UserImpersonation

Więcej Szczegółów https://michelcedric.wordpress.com/2015/09/03/usurpation-didentite-dun-user-c-user-impersonation/

 0
Author: Cedric Michel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-04 09:19:08