Laden...

Prozess als bestimmter Benutzer von SystemDienst aus starten

Erstellt von HexEdit vor 4 Jahren Letzter Beitrag vor 4 Jahren 3.805 Views
H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren
Prozess als bestimmter Benutzer von SystemDienst aus starten

Folgendes Problem ich habe ein WindowsDienst der als SYSTEM ausgeführt wird und möchte von diesem Dienst ein Programm auf einem bestimmten Benutzerkonto X starten.


            Process.Start(new ProcessStartInfo
            {
                FileName = "regedit.exe",  //zb regedit
               //Arguments = "...",
            }).WaitForExit();

So wird regedit zwar gestartet aber auf dem SYSTEM-Konto

Das ich btw. nur erreichen kann wenn ich mittels System Dienst die GUI(explorer.exe) auf dem SystemKonto starte. und meine GUI Prozesse kille.
was ja nicht das Ziel ist...


            Process.Start(new ProcessStartInfo
            {
                FileName = "regedit.exe",  //zb regedit
               //Arguments = "...",
               User = "Username",
               Domain = "Computername"
            }).WaitForExit();

Das geht auch nicht.

Hat irgendjemand eine Iddee, würde mich freuen.

4.931 Beiträge seit 2008
vor 4 Jahren

Suche mal mit dem Stichwort "Impersonation" im Forum oder in Internet danach.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Meinst du so:


         WindowsIdentity impersonatedIdentity = new WindowsIdentity(hToken);
            WindowsImpersonationContext myImpersonation = impersonatedIdentity.Impersonate();
            //Prozess starten
            myImpersonation.Undo();

Weist du zufällig wie ich den UserToken bekomme - warscheinlich mit nem DLLImport - oder müsste ich da mal das Internet durchwühlen.

16.806 Beiträge seit 2008
vor 4 Jahren

HexEdit Dein Code sieht aus, dass Du ihn 1:1 von der Microsoft Doku kopiert hast.
So wird das nichts werden....

Wenn Du nach "c# windowsidentity impersonation" suchst - zB nur zwei Minuten - dann findest Du Samples wie

[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);

Im Endeffekt bist Du damit also schneller bei der Zielfindung.

Es gibt aber verschiedene Wege der Impersonation.
Welche Du brauchst, das ist aus diesem Thread nicht ersichtlich.

4.931 Beiträge seit 2008
vor 4 Jahren

Probiere mal den ImpersonateManager (bzw. ProcessImpersonator) von Impersonation with C#. Das müsste deine Anforderungen bzgl. Anmelden über "Domain", "User" (und "Passwort") erfüllen.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Warumm sollte ich nicht den Code der ms Doku verwenden. 😄 Aber egal.


[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);

Das geht ja nicht da das Programm das Passwort des Benutzers nicht kennt.
Gibt es noch eine andere Möglichkeit ohne Passwort?
Im Prinzip sollte es ja gehen das das Programm Systemrechte hat oder sehe ich falsch?

Und

Es gibt aber verschiedene Wege der Impersonation.
Welche Du brauchst, das ist aus diesem Thread nicht ersichtlich.

Kenne mich überhaupt nicht mit aus, hab das Thema noch nie angefasst.
Werde aber gleich mal Googlen welche "Formen" es da gibt.

16.806 Beiträge seit 2008
vor 4 Jahren

Warumm sollte ich nicht den Code der ms Doku verwenden. 😄 Aber egal.

Naja, das eine ist den Code aus der Doku nehmen und verstehen, das andere blind kopieren.
Die Doku verweist ja auch auf die Quelle von hToken.

Gibt es noch eine andere Möglichkeit ohne Passwort?

Das wäre ein Sicherheitsleck.

Erklär, was Du tun willst.
Dann kann man Dir sagen, ob der Weg überhaupt aus Sicherheitsaspekten so valide ist.

Aber etwas auszuführen im Namen des Users, wenn Du dessen Credentials nicht kennst: nicht valide.
Und in Unternehmen auch in 99% der Fälle nicht legal (vor allem nicht mit Betriebsräten).

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Ich will ein Tool erstellen das unter anderem die Funktionalitäten von psexec hat.
Und da bei psexec das Passwort nicht erforderlich ist habe ich jetzt angenommen das das ohne Passwort möglich ist.

Und in Unternehmen auch in 99% der Fälle nicht legal (vor allem nicht mit Betriebsräten).

Bin noch in der Schule und hab sowas btw auch nicht mit Schul-PCs vor 😄

16.806 Beiträge seit 2008
vor 4 Jahren

Auch psExec wird nicht wahllos irgendein User impersonaten können.
Das wäre eine Windows-Lücke.

Und soweit ich weiß, funktioniert das Impersonate in PsExec durchaus mit Passwort - und fragt diese auch beim User Parameter ab.
Der -Credentials Parameter funktioniert mit gecachten Credentials; auch dort ist also eine Eingabe dieser notwendig.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

So nach ein bisschen googlen habe ich einen DLLImport (CreateProcessAsUser) erstellt und obwohl der Dienst SYSTEM rechte hat hab ich den ErrorCode für Zugriff verweigert erhalten, weiß jemand warum?

Dann ist mir aufgefallen das der import eig. nichts anderes macht als einen Prozess mit diesen Optionen in der ProcessStartInfo zu starten. (Hätte ich auch früher darauf kommen können 😄)


UseShellExecute = false,
Domain = "computername",
UserName = "username",
PasswordInClearText = "password" //oder Password

Problem ist das da hier (logischerweise wenn CreateProcessAsUser auch einen Fehler zurückgibt) auch Folgende Exception geworfen wird: "Access denied"

Weiß jemand warum?

16.806 Beiträge seit 2008
vor 4 Jahren

Anhand dieser Informationen kann man sagen: weil Du keine Rechte hast.
Zumindest ist wurde nicht mit der Gabe des Hellsehens versehen 😉

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Anhand der Fehlermeldung ist das das Naheliegenste aber der Prozess ist zu 100% als "Local System" gestartet, jedenfals sagt Regedit und Services das.

16.806 Beiträge seit 2008
vor 4 Jahren

Das heisst aber noch lange nicht, dass Du dazu genügend Rechte hast.
"LocalSystem" kann auch nicht irgendwas einfach so im Namen anderer Ausführen - und das ist gut so.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Kann ich dem Dienst irgendwie die Rechte dazu geben?

16.806 Beiträge seit 2008
vor 4 Jahren

Wozu? Es ist absolut nicht ersichtlich, was Du tust oder vor hast.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Mein Problem liegt darin: von einem Windows Dienst aus ein Programm in einem anderen Benutzer auszuführen.

16.806 Beiträge seit 2008
vor 4 Jahren

Was heisst "in einem anderen Benutzer"? In einer anderen aktiven Anmeldung? Oder als einen anderen Benutzer?
Ohne Credentials (Username+Password oder bereits den User Token) ist das in Windows nicht möglich.

Da Du aber weiterhin nicht sagen willst, was dieses andere Programm (wirklich ein Programm mit einer Instanz, wenn ja was für eine Art von Instanz? Shell, UI, Service, Call? oder nur ein Code Snippet?) ist, kann man Dir auch nicht genau helfen.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Ja in der GUI des anderen Benutzers und das Problem mit dem Passwort hab ich mittlerweite auch verstanden dh.
Ein Programm im betreffenden Konto führt den folgenden cmd Command aus "sc start Dienstname -rp -userName:userName -password:(Vom Benutzer eingegebenes Passwort) -path:regedit.exe -args:regeditArgs"

der Dienst:


class Dienst : ServiceBase
{
override OnStart(string[] args)
{
ArgumentParser parser = ArgumentParser .Parse(args);
StartProzessAlsBenutzer(parser.accountName, parser.password, parser.Path, parser.args);
}

void StartProzessAlsBenutzer(string userName, string passwd, string appPath, string[] args)
{
//Wie oben beschrieben
}
}

16.806 Beiträge seit 2008
vor 4 Jahren

Sorry, für mich hört sich das Vorhaben sehr dubios an.

Was ist der wirkliche Sinn dahinter? Wieso installierst Du den Service nicht einfach und hinterlegst bei der Registrierung die Credentials?

Danach kannst Du einfach eine Impersonation mit CurrentUser arbeiten.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Was soll daran Dubios sein bräuchte ich auch "Fremden" Rechnern SystemRechte würde ich A: PsExcec herunterladen oder B: von einem Linux USB-Stick booten und gewisse Systemdateien durch cmd austauschen(zb Utilman.exe die in logonUI.exe startbar ist)...

Der Sinn dahinter ist: Gewisse Aktionen in Windows erfordern Systemrechte(manchmal aleine das lesen von bestimmten Dateien oder Ordnern)

Und deswegen benötigt mein Programm Systemrechte und da ich denke dass so ein Dienst mit wenigen Zeilen Code geschrieben ist will ich nicht unbedingt auf ein externes Programm wie PsExec ausweichen.

16.806 Beiträge seit 2008
vor 4 Jahren

Wenn Du Credentials sicher und korrekt behandeln willst, dann kannst Du von mir beschrieben Weg verwenden:

Wieso installierst Du den Service nicht einfach und hinterlegst bei der Registrierung die Credentials?

Danach kannst Du einfach eine Impersonation mit CurrentUser arbeiten.

Das ist in Windows bereits eingebaut.
Utilman ist ein Hack - kein Tool für produktive Umgebungen.

"Einfach so" braucht man niemals auf fremden Rechnern Systemrechte.
Das ist einer der ersten Punkte, die man bei einer Systemhärtung entfernt.

Das Missbrauchspotential solcher Dinge ist hoch.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Den Dienst installiere ich ja und die Credentials werden auch übergebendas Problem ist immer noch die Exception "access denied" obwohl Credentials stimmen.

Hab auch mal mein PW entfernt und es funktioniert wie folgt immer noch nicht dh Exception

Wird bei "OnStart" aufgerufen mit StartProcess("cmd.exe", "@Echo Test")


        private static void StartProcess(string path, string args)
        {
            Process.Start(new ProcessStartInfo
            {
                FileName = path,
                Arguments = args,
                UseShellExecute = false,
                Domain = "COMPUTER",
                UserName = "Admin",
                PasswordInClearText = ""
            }).WaitForExit();
        }

Und ich kann dir versichern das ich es nur für Private Zwecke benötige.
Für was "Illegales" soll man den sonst so ein Programm verwenden ->

  • Für die möglichen Dinge gibt es bereits Programme.
16.806 Beiträge seit 2008
vor 4 Jahren

Naja, wenn ich hier "Admin" sehe, dann bin ich mir hier sehr sicher, dass Du jeden empfohlenen Sicherheitsaspekt einer Anwendung bzw. eines Systems missachtest.
Aber das lass ich an dieser Stelle mal Dein Problem sein.

Access Denied kann hier viele Ursachen haben
... keine Rechte auf die Exe
... keine Rechte auf ein Pfad
... keine Rechte auf eine Dependency
... falsche Credentials
... Du versuchst einen Domain User gegen Local System zu authN
... Du versuchst eine Anwendung zu starten, die eine UI / Shell hat.
... das Vorgehen matched mit einer Virenscanner Heuristik und der Virenscanner knallt Dir Dein Zeug weg
... much more...

Den Dienst installiere ich ja und die Credentials

Und wieso zeigt Dein Code dann erneut Plaintext Credentials statt einer Impersionation?

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Velleicht hab ich das mit den Credentials falsch verstanden aber der Dienst bekommt als Start- Argument den Benutzernamen und das Password des Kontos auf dem das Programm ausgeführt wird mit übergeben.

Die dann an die ProcessStartInfo übergeben werden

Und installiert werden, muss der Dienst ja mit SystemRechten sonst hat das Programm ja nur Nutzerrechte.

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Und Plaintext nur zur "lesbarkeit"


        private static void StartProcess(string domain, string userName, string passwd, string path, string args)
        {
            System.IO.File.WriteAllText("C:\\Output.txt", path + "|" + args);

            Process.Start(new ProcessStartInfo
            {
                FileName = path,
                Arguments = args,
                UseShellExecute = false,
                Domain = domain,
                UserName = userName,
                PasswordInClearText = passwd
            }).WaitForExit();
        }

H
HexEdit Themenstarter:in
38 Beiträge seit 2019
vor 4 Jahren

Start Meth.


protected override void OnStart(string[] args)
        {
            try
            {
                StartProcess(args[0], args[1], args[2], args[3], args[4]);
            }
            catch (Exception ex)
            {
                pipe.WriteStr(ex.Message);
            }
.....
....