Laden...

Forenbeiträge von niceGuy Ingesamt 8 Beiträge

09.01.2023 - 14:33 Uhr

// = Prepare callback
helper.AppLauncher.PROCESS_INFORMATION procInfo;

// = Prepare impersonation
helper.AppLauncher.ImpersonationInfo impersonationInfo = new helper.AppLauncher.ImpersonationInfo();

// = 2: Start a process as specified user
impersonationInfo.LogonType = 2;        // Service = 0, CurrentUser = 1, LogonUser = [2]
impersonationInfo.LogonName = "derLokaleBenutzermitAdminrechten";
impersonationInfo.LogonPassword = "meinGeheimesP@sswort";
helper.AppLauncher.StartProcessInCurrentUserSession("cmd.exe", null, true, impersonationInfo, out procInfo);

Wenn ich das so ausführe, dann erhalte ich eine gestartete CMD.exe aber diese kann nicht bedient werden:
--> Siehe Screenshot

09.01.2023 - 13:53 Uhr

Hallo zusammen,

Situation
Ein Windows Dienst läuft als SYSTEM im Hintergrund.
Der Dienst soll in einer aktiven Benutzersitzung eine Applikation starten.
Diese Applikation soll mit den Rechten eines ++dritten ++Benutzers gestartet werden.

Beteiligte
SYSTEM: Der Dienst ist standardmässig installiert ohne jegliche Spezialkonfiguration
Benutzer A: Angemeldet mit einer eigenen Windows Sitzung. Seine SessionID wird verwendet um darin eine Applikation unter dem Benutzer B zu starten.
Benutzer B: Wird mit

LogonUser

an Windows angemeldet. Sein Token wird dann für

CreateProcessAsUser

verwendet.

Aktueller Stand
Ich habe eine Funktion geschrieben welche eine Applikation in der Benutzersitzung starten kann.
Diese erwartet Parameter wie: applicationName, commandline und die impersonation Informationen.

Was läuft?
Der Start einer Applikation aus einem Dienst heraus in eine laufende Benutzersitzung. Die Applikation läuft unter dem SYSTEM Konto oder unter dem gleichen Konto wie der angemeldete Benutzer.

Was geht nicht?
Der Start einer Applikation aus einem Dienst heraus in eine laufende Benutzersitzung. Die Applikation läuft unter einem weiteren Benutzerkonto.

Der aktuelle Code liegt im Anhang.

Vielen Dank für Eure Hilfe!

01.05.2022 - 19:48 Uhr

Aber wie gesagt; Deine Grundvorgehen ist falsch, weil

bei einem Role-based Authorization Konzept, wie es Windows bzw. (Azure) Active Directory hat

Viele Dank für Deine Ausführungen.

Vermutlich schreiben wir aneinander vorbei:
Ich benötige den aktuellen Namen des lokalen Administrator Kontos.
--> Das Originale, echte welches Microsoft vorgesehen hat.
Kein zusätzlich in die lokale Administratorgruppe hinzugefügtes Benutzerkonto.

Das wäre in meinem Fall dieses Konto welches ebenfalls in der lokalen Admingruppe ist:
S-1-5-21-nnnnnnnnnn-nnnnnnnnnn-nnnnnnnnnn-1001
--> Diese SID (und weitere Mitglieder der lokalen Admingruppe) endet mit etwas anderem als -500

Ich orientiere mich dabei an folgendem devblog Eintrag und gehe davon aus, dass der Autor über die benötigten internen Informationen bei Microsoft verfügt:
https://devblogs.microsoft.com/scripting/how-can-i-determine-if-the-local-administrator-account-has-been-renamed-on-a-computer

Vermutlich wird es noch weitere Wege geben. Für den Moment habe ich eine Lösung die sprachenunabhängig und domänenunabhängig mir den lokalen Administrator nennt.

01.05.2022 - 19:13 Uhr

Da die SID des lokalen Administrator Accounts immer__ mit "S-1-5-21-" beginnt und mit "-500" endet, kann ich den Namen des Kontos hiermit lesen:


string sLocalAdministratorUser = "";

ManagementScope scope = new(@"\\.\root\CIMV2");
scope.Connect();

ObjectQuery query = new("SELECT Name from Win32_UserAccount WHERE SID LIKE 'S-1-5-21%-500'");
ManagementObjectSearcher searcher = new(scope, query);

ManagementObjectCollection results = searcher.Get();

foreach (var item in results)
{
	sLocalAdministratorUser = item["Name"].ToString();
	break;
}

Console.WriteLine("Local Administrator User=" + sLocalAdministratorUser);

Bezüglich der absoluten Aussage immer__:
How Can I Determine if the Local Administrator Account has been Renamed on a Computer?

Was ich noch nicht begriffen habe ist, wie ich direkt auf das erste und einzige item zugreifen kann, statt über eine abgebrochene foreach Schlaufe.

01.05.2022 - 17:51 Uhr

Es ist leider nicht ersichtlich, von was von einem Service Du sprichst (Registrierter Windows Service? IIS? ...?);
...
aber eigentlich kannst Du an allen Stellen einen Benutzer konfigurieren, in dessen Context die App ausgeführt wird.

Ein registrierter Windows Dienst der ganz normal mit SYSTEM Rechten laufen soll

  
sLocalAdministratorUser = sLocalAdministratorUser.Substring(sLocalAdministratorUser.IndexOf('\\') + 1);  
  

Ist übrigens auch nicht 100% safe, denn es gibt zwei potentielle Formate:

  • Domain\User
  • User@Domain

Das muss ich anschauen, wenn ich den Dienst auf einem Domänenmitglied laufen lasse.

PS: string statt String ist die sicherere Schreibweise (gilt auch für die anderen Varianten wie Int32 etc..).
Im Gegensatz zu Früher ist die klare Empfehlung nur noch die aliase (also die type keywords) zu verwenden.

Oh, Danke, das werde ich beherzigen!

Zurück zu meinem Anliegen:
Es muss doch möglich sein, den Namen des lokalen Administrator Kontos in Erfahrung zu bringen?

01.05.2022 - 15:46 Uhr

Wenn ich es mit null versuche:


String sLocalAdministratorUser = new SecurityIdentifier(WellKnownSidType.AccountAdministratorSid, null).Translate(typeof(NTAccount)).Value;
sLocalAdministratorUser = sLocalAdministratorUser.Substring(sLocalAdministratorUser.IndexOf('\\') + 1);
Console.WriteLine("Local Administrator User=" + sLocalAdministratorUser);

Ergibt dies als Resultat:> Fehlermeldung:

The domainSid parameter must be specified for creating well-known SID of type AccountAdministratorSid. (Parameter 'domainSid')

Und das verwirrt mich, denn ich möchte ja den lokalen Administrator Account. Also ohne Domäne.

01.05.2022 - 14:30 Uhr

Hallo Th69,

Darüber bin ich auch schon gestolpert.

AccountAdministratorSid, sollte gemäss Beschreibung die SID der Gruppe sein.
BuiltinAdministratorsSid, sollte gemäss Beschreibung die SID des Benutzers sein.

Mit meinem Code, den ich gepostet habe, passiert aber das genaue Gegenteil!

01.05.2022 - 13:35 Uhr

Hallo Community,

Ich kann mit diesem Code den Namen der lokalen Administratorgruppe herauslesen:


using System.Security.Principal;

String sGroupAdministrators = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null).Translate(typeof(NTAccount)).Value;
sGroupAdministrators = sGroupAdministrators.Substring(sGroupAdministrators.IndexOf('\\') + 1);

Console.WriteLine("Local Administrator Group=" + sGroupAdministrators);

Nun möchte ich den Namen des lokalen Administrators herauslesen. Mit folgendem Code funktioniert das als Applikation, nicht aber, wenn ich ihn als Dienst ausführe:


using System.Security.Principal;

String sLocalAdministratorUser = new SecurityIdentifier(WellKnownSidType.AccountAdministratorSid, WindowsIdentity.GetCurrent().User.AccountDomainSid).Translate(typeof(NTAccount)).Value;
sLocalAdministratorUser = sLocalAdministratorUser.Substring(sLocalAdministratorUser.IndexOf('\\') + 1);

Console.WriteLine("Local Administrator User=" + sLocalAdministratorUser);

Das Problem für mich ist, wie bekomme ich benötigte domainSID für "SecurityIdentifier" heraus, wenn ich den Code als Dienst laufen lasse?

Hat jemand eine Idee?