AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD
Thema durchsuchen
Ansicht
Themen-Optionen

CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

Ein Thema von psyone · begonnen am 29. Sep 2009 · letzter Beitrag vom 3. Apr 2013
Antwort Antwort
Seite 1 von 2  1 2      
psyone

Registriert seit: 19. Okt 2007
5 Beiträge
 
RAD-Studio 2009 Arc
 
#1

CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 29. Sep 2009, 10:13
Hallo,

ich möchte mein Programm, dass per UAC Prompt Adminrechte erlangt hat, ein anderes Programm starten lassen, dass keine Adminrechte haben soll. Theoretisch müsste ich dafür einfach nur CreateProcessAsUser mit dem LinkedToken meiner Anwendung aufrufen, glaube ich.

Dazu gehe ich so vor:
- Token meiner Anwendung holen (OpenProcess, OpenProcessToken mit PROCESS_ALL_ACCESS, TOKEN_ALL_ACCESS)
- Umwandeln in PrimaryToken (DuplicateTokenEx mit TOKEN_ALL_ACCESS)
- LinkedToken holen (GetTokenInformation)
- CreateProcessAsUser mit dem LinkedToken

Klappt soweit auch alles, aber CreateProcessAsUser liefert den Fehler ERROR_PRIVILEGE_NOT_HELD.
MSDN sagt dazu "Typically, the process that calls the CreateProcessAsUser function must have the SE_INCREASE_QUOTA_NAME privilege and may require the SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable."
SE_INCREASE_QUOTA_NAME ist verfügbar und ich aktiviere es auch. SE_ASSIGNPRIMARYTOKEN_NAME ist nicht verfügbar und kann daher nicht aktiviert werden.

Meine Schlussfolgerung: das LinkedToken "is not assignable", denn wenn ich CreateProcessAsUser mit dem uneingeschränkten Token aufrufe klappt es ja auch. Daher die Frage: Wie mache ich mein LinkedToken assignable oder umgehe das Problem auf andere Weise?


Da ich den Nutzer nicht nach seinem Passwort fragen kann/will, kann ich auch nicht auf die diversen Logon Funktionen zurückgreifen. Das Token des eigentlich aktiven Benutzers werde ich vermutlich in meiner per UAC mit Adminrechten ausgestatteten Anwendung nicht bekommen. Einen Dienst, der sich um alles kümmert kann ich in diesem Fall nicht verwenden. Den Umweg über eine COM DLL, die statt meiner Anwendung die Adminrechte erhält, möchte ich möglichst vermeiden.

Ich habe mir auch die JWSCL angesehen. Damit kann ich das gleiche Ergebnis mit deutlich weniger Code erzielen, das Grundproblem bleibt jedoch bestehen. Hier könnte ich mir als Alternative vorstellen ein eingeschränktes Token komplett neu zu bauen und dieses statt dem LinkedToken zu verwenden. Leider weiß icht nicht welche SIDs ich dafür in die RestrictedSIDList eintragen muss.


Über den ein oder anderen Denkanstoß würde ich mich sehr freuen.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#2

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 29. Sep 2009, 10:42
Wenn ich mich nicht irre geht das leider nicht. Das LinkedToken kann wirklich nur mit dem TCB Privileg genutzt werden. Sonst liefert die GetTokenInformation ein Token zurück, dass man nur zur Identifikation nutzen kann und nicht für CPAU.

Du könntest mal versuchen das Token vom Explorer zu verwenden, um weniger Rechte zu haben.
Sonst könntest du das eingeschränkte Token auch selbst erstellen mit CreateRestrictedToken.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
psyone

Registriert seit: 19. Okt 2007
5 Beiträge
 
RAD-Studio 2009 Arc
 
#3

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 30. Sep 2009, 10:21
Ich habe mich mal an CreateRestrictedToken versucht. Dank JWSCL klappt das auch alles ganz einfach

Wenn ich damit Paint starte, darf ich nicht nach C:\Programme speichern. Daher gehe ich davon aus, dass der Rechteentzug klappt.

Eigentlich möchte ich aber den Internet Explorer (nicht den Standardbrowser) starten. Der startet auch kurz, schließt sich aber sofort wieder. Das ganze tritt auf bei Windows Vista Ultimate SP 2 + IE 8. Auf einem XP Pro SP3 + IE 8 gibt es das Problem nicht. Der XP Rechner führt den Code fehlerfrei aus. (TokenIntegrityLevelType natürlicht nicht, da auf XP nicht verfügbar)

Setze ich JwAdministratorsSID nicht auf die Liste der zu deaktivierenden SIDs, startet er normal. Aber dann hat er ja möglicherweise Adminrechte, oder?

Habe ich das RestrictedToken soweit richtig erstellt?


Delphi-Quellcode:
var
  lApp: String;
  lToken, lRestrictedToken: TJwSecurityToken;
  lSIDs: TJwSecurityIdList;
  lStartupInfo: TStartupInfo;
  lProcessInfo: TProcessInformation;

...

lSIDs := TJwSecurityIdList.Create(false);
lToken := TJwSecurityToken.CreateTokenEffective(TOKEN_ALL_ACCESS);

JwInitWellKnownSIDs;

lSIDs.Add(JwAdministratorsSID); // <-- IE schließt sich sofort wieder
lSIDs.Add(JwLocalSystemSID);
lSIDs.Add(JwNetworkServiceSID);
lSIDs.Add(JwLocalServiceSID);
lSIDs.Add(JwIntegrityLabelSID[iltMedium]);
lSIDs.Add(JwIntegrityLabelSID[iltHigh]);
lSIDs.Add(JwIntegrityLabelSID[iltSystem]);
lSIDs.Add(JwIntegrityLabelSID[iltProtected]);

lRestrictedToken := TJwSecurityToken.CreateRestrictedToken(lToken.TokenHandle, TOKEN_ALL_ACCESS, DISABLE_MAX_PRIVILEGE, lSIDs, nil, nil);
lRestrictedToken.TokenIntegrityLevelType := iltLow;

ZeroMemory(@lStartupInfo, SizeOf(lStartupInfo));
ZeroMemory(@lProcessInfo, SizeOf(lProcessInfo));
lStartupInfo.cb := SizeOf(lStartupInfo);

//lApp:= 'c:\program files\Internet Explorer\iexplore.exe';
lApp:= 'c:\windows\system32\mspaint.exe';

CreateProcessAsUser(lRestrictedToken.TokenHandle, PWideChar(lApp), nil, nil, nil, false, 0, nil, nil, lStartupInfo, lProcessInfo)
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#4

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 30. Sep 2009, 10:41
Also ich denke du solltest die Anwendung nicht mit Integrity Level low starten, sondern mit Normal.
Es gibt nur wirklich wenige Apps, die mit low funktionieren und der IE macht das auch noch selbstständig beim Starten.
Also versuch mal die SID IL Medium nicht zu deaktivieren (es wäre ja dann eine Deny Only SID) und das Integrity Level auf Medium zu lassen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
psyone

Registriert seit: 19. Okt 2007
5 Beiträge
 
RAD-Studio 2009 Arc
 
#5

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 30. Sep 2009, 11:02
Sobald ich dem IE die Administratoren-Gruppe wegnehme, schließt er sich immer sofort wieder.

Delphi-Quellcode:
lSIDs.Add(JwAdministratorsSID);
lRestrictedToken := TJwSecurityToken.CreateRestrictedToken(lToken.TokenHandle, TOKEN_ALL_ACCESS, DISABLE_MAX_PRIVILEGE, lSIDs, nil, nil);
Ich deaktiviere nur diese eine SID und stelle das IL nicht um. Auch ein explizites Setzen auf itlMedium bringt nichts.
Kann es sein, dass der IE für irgendwas eine Nutzergruppe an seinem access token braucht?
Hätte ich die SID einer Nutzergruppe mit eingeschränkten Rechten, könnte ich die dann meinem Token hinzufügen?

Setze ich das IL auf Low und lasse dem IE die Admingruppe, darf er gar nichts und startet normal. Das kann man wohl als Notlösung sehen.

Edit:
Anscheinend kann ich mit dem RestrictedToken C:\Programme nur lesen, nicht schreiben aber auch nicht ausführen.
Habe mir mit dem RestrictedToken cmd.exe gestartet. Da bekomme ich beim Versuch eine beliebige Anwendung unterhalb von C:\Programme zu starten die Meldung "Zugriff verweigert". Paint u.ä. geht nur weil es in C:\Windows liegt.

Wie bekomme ich jetzt am besten ein Token ohne Adminrechte, dass in C:\Programme Anwendungen ausführen darf?
Ich deaktiviere bisher nur die AdminsSID. Auf DISABLE_MAX_PRIVILEGE habe ich auch verzichet, so dass keine Privilegien entfernt werden.
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#6

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 30. Sep 2009, 23:20
Ich habe es mir nur krz angesehen. Das Problem ist das Admin deny only, welches den Zugriff verweigert.
Muss ich mir aber auch nochmal ansehen. Da ich gerade keine Zeit habe, kann ich es nicht machen.
Ich habe daher den Vorschlag:

1. Du benutzt des Aufgabenplaner (Task Scheduler), um eine Anwendung zu starten.
2. Du erstellst deinen eigenen Dienst, der die Aufgabe erledigt. Mein Prog Runassys startet auch einen eigenen Dienst mit einem Adminprozess.

Vllt hast du ja dann noch Lust das eigentliche Problem, warum man kein eigenens restriktives Token erstellen und gut nutzen kann, zu erforschen. Ein Artikel und Unterstützung durch den JEDI API Blog würde ich stellen.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
psyone

Registriert seit: 19. Okt 2007
5 Beiträge
 
RAD-Studio 2009 Arc
 
#7

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 2. Okt 2009, 09:11
Ich habe mir das ganze nochmal durch den Kopf gehen lassen. In meinem Fall nützt mir auch ein eingeschränktes Admin Token nichts, denn das Programm muss mit dem Token des eigentlich angemeldeten Benutzers laufen. Den Task Scheduler kann man deaktivieren, daher fällt er für mich als potentielle Lösung schon aus. Ein Dienst ist vermutlich Overkill für meinen speziellen Fall.

Ich habe daher auf einen deiner ersten Vorschläge zurück gegriffen: Mit OpenProcessToken das Token einer Anwendung beschaffen, die mit Nutzerrechten läuft. Dabei bin ich wieder auf mein ursprüngliches Problem gestoßen (CreateProcessAsUser schlägt mit ERROR_PRIVILEGE_NOT_HELD fehl) und kann dieses wohl jetzt zumindest erklären.

Zitat von http://msdn.microsoft.com/en-us/library/ms682429(VS.85).aspx:
Typically, the process that calls the CreateProcessAsUser function must have the SE_INCREASE_QUOTA_NAME privilege and may require the SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable.

If hToken is a restricted version of the caller's primary token, the SE_ASSIGNPRIMARYTOKEN_NAME privilege is not required. If the necessary privileges are not already enabled, CreateProcessAsUser enables them for the duration of the call.
Siehe dazu auch diese Diskussion.

Standardmäßig besitzen Admins das SE_ASSIGNPRIMARYTOKEN_NAME Privileg nicht, Dienste hingegen schon. Benötigt wird dieses Privileg nur dann nicht, wenn man mit CreateRestrictedToken ein eingeschränktes Token aus dem Token das aktuellen Prozesses baut. Daher kann man das LinkedToken und auch fremde Token als (normaler) Admin nicht mit CreateProcessAsUser nutzen. Da SE_ASSIGNPRIMARYTOKEN_NAME gar nicht vorhanden ist, kann es auch nicht automatisch durch CreateProcessAsUser aktiviert werden.

Ich versuche das ganze jetzt über CreateProcessWithTokenW zum laufen zu bringen.

Edit: Es klappt, manchmal.
Windows Vista Ultimate SP2, Ich bin als Admin angemeldet, UAC ist an. Mein Programm hat ein requireAdministrator Manifest. Beim Programmstart muss ich bestätigen, dass das Programm Adminrechte bekommt. Alles geht. Das von mir gestartete Programm läuft ohne Adminrechte.

Selbes System, ich bin als normaler Nutzer angemeldet, starte mein Programm, logge mich per UAC als Admin ein. Jetzt bekomme ich bei CreateTokenByProcessId (genauer bei OpenProcessToken) "Zugriff verweigert". Darf ich als Admin nicht auf Prozesse fremder User zugreifen oder gibt es da einen tollen Trick?

Die PID schreibe ich zur Zeit per Hand in den Code, nachdem ich sie per Taskmanager ausgelesen habe. Ja ich habe die Nummer richtig übertragen und entsprechend angepasst für den normalen Benutzer.

Delphi-Quellcode:
var
  lToken, lToken2: TJwSecurityToken;
  lStartupInfo: PStartupInfoW;
  lProcessInfo: PProcessInformation;

...

  lToken := TJwSecurityToken.CreateTokenByProcessId('1234', MAXIMUM_ALLOWED); // hier nicht TOKEN_ALL_ACCESS
  lToken2 := TJwSecurityToken.CreateDuplicateExistingToken(lToken, TOKEN_ALL_ACCESS);
  lToken2.ConvertToPrimaryToken(TOKEN_ALL_ACCESS);

  GetMem(lStartupInfo2, SizeOf(TStartupInfoW));
  GetMem(lProcessInfo2, SizeOf(TProcessInformation));
  ZeroMemory(lStartupInfo2, SizeOf(TStartupInfoW));
  ZeroMemory(lProcessInfo2, SizeOf(TProcessInformation));
  lStartupInfo2^.cb := SizeOf(TStartupInfoW);

  CreateProcessWithTokenW(lToken2.TokenHandle, 0, PWideChar('...'), nil, 0, nil, nil, lStartupInfo, lProcessInfo);
Edit2: DOH! Es kann so einfach sein. Der faule Programmierer schreibt natürlich TOKEN_ALL_ACCESS, damit er nicht suchen muss welche Rechte tatsächlich benötigt werden. MAXIMUM_ALLOWED ist ähnlich faul, funktioniert aber. Das Problem ist damit für mich zufriedenstellend gelöst. Habe den Code entsprechend angepasst.

Kleine Anmerkung: CreateProcessWithTokenW gibt es erst seit Vista/Server 2003. Das spielt bei mir keine Rolle, da ich den Code nur verwende, wenn die UAC an ist. Trotzdem muss man JWApi dynamisch linken damit das Programm auch unter <= XP startet.

Danke für deine Unterstützung und vor allem DANKE für die JWSCL
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#8

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 2. Okt 2009, 12:52
Ich werde mir das bei Gelegenheit ansehen. Deine Infos werden aber sicherlich helfen.

Nur zur Info:
CreateProcessWithTokenW wird von dem "Sekundären Anmeldedienst" implementiert. Wenn dieser deaktiviet wird, dann funktioniert das nicht mehr. Der Dienst muss deaktiviert sein und nichte einfach gestoppt.
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
Dezipaitor

Registriert seit: 14. Apr 2003
Ort: Stuttgart
1.701 Beiträge
 
Delphi 7 Professional
 
#9

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 10. Okt 2009, 23:18
Ich hab doch glatt Kays Senf übersehen

http://kay-bruns.de/wp/2007/03/01/runasloggedonuser
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation?
Goto: JEDI API LIB & Windows Security Code Library (JWSCL)
  Mit Zitat antworten Zitat
psyone

Registriert seit: 19. Okt 2007
5 Beiträge
 
RAD-Studio 2009 Arc
 
#10

Re: CreateProcessAsUser ERROR_PRIVILEGE_NOT_HELD

  Alt 12. Okt 2009, 09:43
Interessant. In den Comments findet sich ein Link zu DropMyRights, wo gezeigt wird wie einem Admin Token die Rechte genommen werden können.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz