CreateProcessAsUser von C # aufrufen

8

Ich habe versucht, einen neuen Prozess im Kontext eines bestimmten Benutzers mit der CreateProcessAsUser -Funktion der Windows-API zu erstellen, scheint aber in ein ziemlich unangenehmes Sicherheitsproblem zu geraten ...

Bevor ich weiter erläutere, hier ist der Code, den ich derzeit verwende, um den neuen Prozess zu starten (ein Konsolenprozess - PowerShell, um genau zu sein, obwohl es keine Rolle spielen sollte).

%Vor%

Um des Problems willen, ignoriere den Code, der sich mit den Umgebungsvariablen beschäftigt (Ich habe diesen Abschnitt unabhängig getestet und es scheint zu funktionieren.)

Nun, der Fehler, den ich bekomme, ist der folgende (geworfen an der Zeile nach dem Aufruf von CreateProcessAsUSer ):

  

"Eine erforderliche Berechtigung wird vom Client nicht gehalten" (Fehlercode 1314)

(Die Fehlermeldung wurde entdeckt, indem der Nachrichtenparameter aus dem Win32Exception-Konstruktor entfernt wurde. Zugegebenermaßen ist mein Fehlerbehandlungscode hier vielleicht nicht der beste, aber das ist eine ziemlich irrelevante Angelegenheit. Sie können das gerne kommentieren, wenn Sie möchten Allerdings.) Ich bin wirklich ziemlich verwirrt über die Ursache dieses vagen Fehlers in dieser Situation. Die MSDN-Dokumentation und verschiedene Forum-Threads haben mir nur so viel Ratschläge gegeben, und vor allem, da die Ursachen für solche Fehler sehr unterschiedlich zu sein scheinen, habe ich keine Ahnung, welchen Abschnitt des Codes ich modifizieren muss. Vielleicht ist es einfach ein einzelner Parameter, den ich ändern muss, aber ich könnte die falschen / nicht genug WinAPI-Aufrufe für alles, was ich weiß, machen. Was mich sehr verwirrt, ist, dass die vorherige Version des Codes, der die einfache CreateProcess -Funktion verwendet (äquivalent mit Ausnahme des Benutzer-Token-Parameters), vollkommen in Ordnung ist. Wie ich es verstehe, ist es nur notwendig, die Benutzerfunktion Logon aufzurufen, um das entsprechende Token-Handle zu erhalten und es dann zu duplizieren, damit es an CreateProcessAsUser übergeben werden kann.

Vorschläge für Änderungen am Code sowie Erklärungen sind sehr willkommen.

Notizen

Ich habe mich in erster Linie auf die MSDN-Dokumente (sowie auf PInvoke.net für die C # -Funktion / strut / enum-Deklarationen) bezogen. Insbesondere die folgenden Seiten scheinen eine Menge Informationen in den Hinweisen zu haben, von denen einige wichtig sein können und mir entgehen:

Bearbeiten

Ich habe gerade Mitchs Vorschlag ausprobiert, aber leider wurde der alte Fehler gerade durch einen neuen ersetzt: "Das System kann die angegebene Datei nicht finden." (Fehlercode 2)

Der vorherige Aufruf von CreateProcessAsUser wurde durch Folgendes ersetzt:

%Vor%

Beachten Sie, dass dieser Code nicht mehr das doppelte Token, sondern das Original verwendet, wie es in den MSDN-Dokumenten vorgeschlagen wird.

Und hier ist ein weiterer Versuch mit CreateProcessWithLogonW . Der Fehler ist diesmal "Anmeldefehler: unbekannter Benutzername oder falsches Passwort" (Fehlercode 1326)

%Vor%

Ich habe auch versucht, den Benutzernamen im UPN-Format ("Alex @ Alex-PC") anzugeben und die Domain unabhängig als zweites Argument zu übergeben, alles ohne Erfolg (identischer Fehler).

    
Noldorin 20.03.2009, 23:49
quelle

3 Antworten

7

Ahh ... scheint, als wäre ich von einem der größten Fehler in der WinAPI-Interop-Programmierung überrascht worden. Außerdem wäre es in diesem Fall eine kluge Idee gewesen, den Code für meine Funktionsdeklarationen zu schreiben.

Wie auch immer, alles, was ich tun musste, war, ein Argument zum DllImport-Attribut der Funktion hinzuzufügen, die CharSet = CharSet.Unicode spezifiziert. Dies hat den Trick für die Funktionen CreateProcessWithLogonW und CreateProcessWithTokenW bewirkt. Ich schätze es hat mich schließlich einfach getroffen, dass das W-Suffix der Funktionsnamen auf Unicode verweist und dass ich dies explizit in C # angeben musste! Hier sind die korrekten Funktionsdeklarationen, falls jemand interessiert ist:

%Vor%     
Noldorin 22.03.2009, 17:59
quelle
6

Von hier :

  

Normalerweise ruft der Prozess, der die   CreateProcessAsUser-Funktion muss haben   der SE_ASSIGNPRIMARYTOKEN_NAME und   SE_INCREASE_QUOTA_NAME-Berechtigungen. Ob   Diese Funktion schlägt mit fehl   ERROR_PRIVILEGE_NOT_HELD (1314), verwenden   die Funktion CreateProcessWithLogonW   stattdessen. CreateProcessWithLogonW   benötigt keine besonderen Privilegien, aber   das angegebene Benutzerkonto muss sein   darf sich interaktiv anmelden.   Im Allgemeinen ist es am besten zu verwenden   CreateProcessWithLogonW zum Erstellen eines   mit alternativen Anmeldeinformationen verarbeiten.

Sehen Sie sich diesen Blogbeitrag an How um CreateProcessWithLogonW & amp; CreateProcessAsUser in .NET

    
Mitch Wheat 20.03.2009 23:52
quelle
4

Jonathan Peppers hat diesen tollen Code zur Verfügung gestellt, der meine Probleme behoben hat

Ссылка

    
ermagana 03.12.2009 16:54
quelle