Berechtigungen von Diensten in Windows über die Kommandozeile ändern
Ein Windows-Dienst ist ein sicherungsfähiges Objekt. Wer ihn starten, beenden oder umkonfigurieren darf, entscheidet eine eigene Zugriffsliste und nicht die Gruppenmitgliedschaft. Berechtigungen von Diensten ändern heißt deshalb: diese Liste bearbeiten, und die ganze Schwierigkeit liegt darin, dass sie in Zugriffsmasken geschrieben ist und nicht in Verben.
Was in einem Dienst-DACL steht
Jeder Dienst und jeder Kerneltreiber, der beim Dienststeuerungs-Manager registriert ist, trägt einen Sicherheitsdeskriptor: einen Besitzer, eine Gruppe, eine Überwachungsliste und die diskretionäre Zugriffsliste, die entscheidet, wer was darf. Nur letztere ist gemeint, wenn von Dienstrechten die Rede ist.
Der Standarddeskriptor ist bewusst eng. Administratoren haben Vollzugriff. Hauptbenutzer dürfen, wo diese Gruppe noch existiert, starten und beenden. „Jeder" hält eine kleine Lesemaske, damit gewöhnlicher Code überhaupt feststellen kann, ob ein Dienst läuft. Kein Eintrag erlaubt einem normalen Konto das Starten: der häufigste Grund, überhaupt eine Zugriffsliste anzufassen.
Drei Situationen wiederholen sich. Ein Dienst soll nur bei Bedarf laufen, und die Personen, die ihn brauchen, sind keine Administratoren. Ein Programm im Benutzermodus muss einen bestimmten Gerätetreiber laden oder entladen. Oder eine Anwendung installiert einen Hilfsdienst und erwartet, dass unprivilegierter Code ihn steuert. Alle drei löst eine genaue Maske für eine bestimmte Gruppe, und alle drei verschlimmert es, stattdessen Vollzugriff zu vergeben, weil das schneller ging.
Deskriptor auf einen Blick
- Gespeichert unter
HKLM\SYSTEM\CurrentControlSet\Services\<Name>- Standardbesitzer
- NT-AUTORITÄT\SYSTEM
- Deskriptor lesen
sc sdshow <Dienst>- Deskriptor schreiben
sc sdset <Dienst> <SDDL>- Flottenweit
- Sicherheitsrichtlinie, Knoten „Systemdienste"
- Wirksam
- bei jedem Dienststart, für neue Zugriffsprüfungen sofort
Die Zugriffsmaske, Buchstabe für Buchstabe
Die Maske ist der Teil, der sich dem Auswendiglernen entzieht: ein Dienst hat zwölf
sinnvolle Rechte und vier gebräuchliche Zusammenfassungen davon. Am kompaktesten hat das
scacl.exe dokumentiert, ein kleines Freeware-Werkzeug für Windows NT, das jedem
Recht einen Buchstaben gab und sie zu einer Zeichenfolge zusammensetzen ließ. Diese
Buchstaben sind bis heute eine brauchbare Lernnotation, weil jeder genau einer
Win32-Konstante und einem SDDL-Kürzel entspricht, mit dem aktuelle Werkzeuge arbeiten.
Ein Sammelrecht unten auswählen zeigt, welche Einzelrechte es enthält und wie die entstehende Vergabe aussieht. Die vier Zusammenfassungen sind keine Bequemlichkeits-Erfindung des Werkzeugs, sondern die Gruppierungen, die die Win32-Dienstschnittstelle selbst definiert, weshalb sie in der Herstellerdokumentation immer wieder auftauchen.
Kein Sammelrecht gewählt — die zwölf Einzelrechte stehen unten alle einzeln.
R = CHLIQ — Alles, was nur liest: die Konfiguration, den Status, die Abhängigkeiten, die Zugriffssteuerungsliste und das Abfragen, das den Dienst selbst zur Meldung auffordert.
X = CPSEU — Den Dienst bedienen, ohne ihn umkonfigurieren zu können — die Maske, die ein Bedienkonto wirklich braucht.
W = CG — Die Konfiguration ändern, aber nicht den Sicherheitsdeskriptor. Bewusst vergeben: der Binärpfad gehört dazu.
F = HGQLSEPIUDCO — Jedes Recht darüber, einschließlich Löschen des Dienstes und Neuschreiben seiner Zugriffssteuerungsliste.
| Buchstabe | Erlaubt | Details |
|---|---|---|
H | Konfig lesen | Die Dienstkonfiguration lesen — Binärpfad, Starttyp, Abhängigkeiten, Anmeldekonto. |
G | Konfig ändern | Die Dienstkonfiguration ändern. Dieses Recht erlaubt es, den Binärpfad umzubiegen — praktisch Codeausführung unter dem Dienstkonto. |
Q | Status lesen | Den Dienststatus beim Dienststeuerungs-Manager abfragen — läuft, beendet, Start ausstehend. |
L | Abhängige | Die Dienste auflisten, die von diesem abhängen. |
S | Starten | Den Dienst starten. |
E | Beenden | Den Dienst beenden. |
P | Pausieren | Den Dienst anhalten und fortsetzen, sofern er das unterstützt. |
I | Abfragen | Den Dienst selbst auffordern, seinen Status sofort zu melden, statt den zwischengespeicherten Wert zu lesen. |
U | Eigener Code | Einen benutzerdefinierten Steuercode (128 bis 255) senden, den der Dienst selbst behandelt. |
D | Löschen | Die Dienstregistrierung löschen. |
C | Rechte lesen | Den Sicherheitsdeskriptor lesen — das Recht, die Zugriffssteuerungsliste überhaupt zu sehen. |
O | Rechte ändern | Die Zugriffssteuerungsliste selbst ändern. Wer dieses Recht hält, kann sich alles andere selbst gewähren. |
Lesen, bevor man in Windows etwas ändert
Der erste Befehl auf einem Dienst sollte ein Lesevorgang sein. Ein Deskriptor mit aufgelösten Sicherheitskennungen zeigt beides: wer aktuell was hält, und ob die Einträge auf diesem Rechner überhaupt auflösbar sind. Die alte Ausgabe nannte den Besitzer und dann jeden Eintrag mit seiner Maske in Klammern:
C:\> scacl \\AMARETTO tcpip /S
Security settings of service tcpip on \\AMARETTO:
Owner: NT-AUTHORITY\SYSTEM (S-1-5-18)
DACL:
00: [RIU] \World (S-1-1-0)
01: [XR] (null)\(null) (S-1-5-32-547)
02: [F] BUILTIN\Administrators (S-1-5-32-544)
04: [XR] NT-AUTHORITY\SYSTEM (S-1-5-18)
Zwei Details lohnen den Blick. Eintrag 01 hat keinen Namen, weil die Gruppe der
Hauptbenutzer auf dem ausgebenden Rechner nicht existiert. Der Eintrag gilt trotzdem und
vergibt eine Maske. Und „Jeder" hält RIU statt nichts, weshalb unprivilegierter
Code normalerweise feststellen kann, dass ein Dienst existiert.
Der heutige Lesevorgang heißt sc sdshow tcpip und liefert dieselbe Information
als eine SDDL-Zeichenfolge. Sie ist dichter und schlechter vorlesbar, aber genau das Format,
das sc sdset zurück erwartet: ein Lesen-Ändern-Schreiben-Zyklus muss also
nicht zwischen zwei Notationen übersetzen.
Rechte über die Kommandozeile vergeben und verweigern
Gefährlich ist beim Bearbeiten einer Zugriffsliste nicht die Maske, sondern der Unterschied
zwischen Ändern und Ersetzen. Ein ersetzender Aufruf schreibt genau die genannten Einträge
und verwirft alles andere, auch den Eintrag, der Ihnen das Bearbeiten erlaubt. Sowohl das
alte Werkzeug als auch sc sdset ersetzen im Zweifel, weshalb der Ändern-Schalter
wichtiger ist als jedes einzelne Recht.
C:\> scacl \\AMARETTO tcpip /E /G BUILTIN\Users:SE /D Tom:SE
Do you really want to apply the new security settings [Yes/No]: y
Successfully applied new security settings to service tcpip Diese Zeile gibt der Gruppe „Benutzer" Starten und Beenden und verweigert dieselben zwei Rechte einem Konto. Verweigernde Einträge werden immer zuerst geprüft, unabhängig von ihrer Position in der Liste. Die Verweigerung gewinnt also gegen die Gruppenvergabe. In der Ausgabe ist sie durch ein vorangestelltes Minus gekennzeichnet:
00: -[SE] BISTRO\Tom (S-1-5-21-859451957-1360023216-1846434929-1003)
01: [RIU] \World (S-1-1-0)
06: [SE] BUILTIN\USERS (S-1-5-32-545) Auswertungsreihenfolge
Die Schalter wirken nicht in der Reihenfolge, in der sie getippt werden. Die Folge unten ist die des älteren Werkzeugs und gilt genauso für jeden korrekten Lesen-Ändern-Schreiben-Zyklus, weil Besitzübernahme und Standardwiederherstellung alles Vorherige verwerfen.
- Ohne Rückfrage
- unterdrückt die Bestätigung für alle folgenden Schritte
- Besitz übernehmen
- die lokale Administratorengruppe wird neuer Besitzer
- Standard herstellen
- der bei der Installation geschriebene Deskriptor wird Grundlage für alles Folgende
- Ändern
- nachfolgende Änderungen bearbeiten die bestehende Liste statt sie zu ersetzen
- Ausführlich
- gibt die entstehende Liste aus
- Entfernen, ersetzen, geben, verweigern
- zuletzt, in dieser Reihenfolge
Dasselbe heute mit sc sdset
Berechtigungen von Diensten haben das Werkzeug überlebt, das sie zuerst lesbar gemacht hat. Am Objektmodell hat sich nichts geändert, die Überlegung überträgt sich also direkt. Geändert hat sich die Notation: statt Buchstaben zu kombinieren, setzt man eine SDDL-Zeichenfolge zusammen und übergibt den vollständigen Deskriptor. Eine Vergabe von Starten, Beenden und Statusabfrage an die Gruppe „Benutzer", an den Standarddeskriptor angehängt, sieht so aus.
C:\> sc sdshow Spooler
D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)...
C:\> sc sdset Spooler "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWRPWPLORC;;;BU)..." Der eingefügte Eintrag ist ein Erlauben-Eintrag ohne Vererbungsflags mit den Rechten Konfiguration lesen, Status lesen, Abhängige auflisten, Starten, Beenden, Abfragen und Rechte lesen, für die integrierte Gruppe „Benutzer". Der Vergleich mit dem Raster oben ist der schnellste Weg, eine fremde SDDL-Zeichenfolge zu prüfen: jedes Zwei-Buchstaben-Kürzel im Maskenteil ist eine Zeile dieser Tabelle.
Eine praktische Warnung zu sc sdset: der Befehl nimmt den übergebenen
Deskriptor wörtlich und führt nichts zusammen. Aktuelle Zeichenfolge lesen, den eigenen
Eintrag einfügen, das Ganze zurückschreiben. Nur den eigenen Eintrag zu schreiben ist die
moderne Schreibweise für „den Ändern-Schalter vergessen": mit derselben Folge.
Wozu die alte Notation weiterhin taugt
Zwei praktische Gründe. Erstens ist sie lesbar: /G BUILTIN\Users:SE versteht
auch jemand, der über den Tisch schaut, was für eine vierzig Zeichen lange
SDDL-Zeichenfolge nicht gilt. Zweitens ist ein großer Teil der noch existierenden
Dokumentation, Forenantworten und internen Handbücher in ihr geschrieben, und wer
Berechtigungen von Diensten ändern muss, erbt diesen Textbestand. Zu wissen, dass
X „steuern, aber nicht umkonfigurieren" bedeutet, entscheidet, ob eine
fünfzehn Jahre alte Antwort übernommen werden darf.
Die Werkzeuge selbst sind Zeitdokumente. scacl.exe erschien als Freeware für
Windows NT und Windows 2000 und wird nicht gepflegt; auf einem aktuellen System sind
sc, PowerShell oder eine Sicherheitsrichtlinie der unterstützte Weg. Ein
Detail hält viele auf, bevor sie überhaupt beim Deskriptor ankommen: sc
erwartet den Schlüsselnamen des Dienstes, nicht den Anzeigenamen aus der Konsole.
sc sdshow Spooler funktioniert, sc sdshow "Druckwarteschlange"
nicht, und die Meldung sagt, der Dienst existiere nicht, statt dass von zwei Namen der
falsche gewählt wurde.
Fragen zu Berechtigungen von Diensten
Welches Recht genügt, damit ein normales Konto einen Dienst starten darf?
SERVICE_START (0x0010, SDDL RP) allein reicht technisch zum Starten. Wer nur starten darf, kann den Status aber nicht lesen, weshalb die meisten Werkzeuge dann trotzdem einen Fehler melden. Praktisch brauchbar ist die Kombination aus Starten, Beenden und Statusabfrage, in der Buchstabennotation SEQ. Nahe am Sammelrecht X, aber nicht dasselbe: X enthält Rechte lesen, Starten, Beenden, Pausieren und den eigenen Steuercode, die Statusabfrage aber nicht.
Warum ist „Konfiguration ändern" faktisch Codeausführung?
Weil der Binärpfad Teil der Konfiguration ist. Wer ImagePath überschreiben darf, kann den Dienst auf eine beliebige ausführbare Datei zeigen lassen, und der Dienststeuerungs-Manager startet diese Datei dann unter dem Dienstkonto: häufig LocalSystem. Deshalb gehört dieses Recht in die administrative und nicht in die operative Kategorie.
Was passiert bei einer leeren Zugriffsliste?
Eine leere Liste ist nicht dasselbe wie keine Liste. Leer bedeutet, dass jede Zugriffsprüfung scheitert, auch die des Dienststeuerungs-Managers. Der Dienst ist dann nicht mehr verwaltbar, bis jemand den Besitz übernimmt. Fehlt die Liste dagegen ganz, ist alles erlaubt.
Wie komme ich zurück, wenn ich mich selbst ausgesperrt habe?
Besitz übernehmen und den Standarddeskriptor wiederherstellen. Das ältere Werkzeug schrieb das als scacl.exe \\HOST dienst /T /I; heute setzt man den Deskriptor mit sc sdset auf eine bekannte SDDL-Zeichenfolge zurück, wofür WRITE_OWNER oder lokale Administratorrechte nötig sind.
Sind die SDDL-Kürzel bei Diensten dieselben wie bei Dateien?
Nein. SDDL verwendet einen Satz Abkürzungen für alle Objektarten und löst sie über den Zahlenwert auf. Dasselbe Kürzel bedeutet je nach Objekt etwas anderes. Bei einem Dienst ist RP gleich SERVICE_START, bei einem Verzeichnisobjekt dagegen ein Leserecht auf ein Attribut. Einen Dienstdeskriptor mit Dateisemantik zu lesen ist der häufigste Fehler in diesem Bereich.
Übersteht die Änderung einen Neustart?
Ja. Der Deskriptor liegt bei der Dienstregistrierung unter HKLM\SYSTEM\CurrentControlSet\Services und wird bei jedem Start angewandt. Er übersteht nicht, dass ein Setup den Dienst löscht und neu anlegt. Der übliche Grund, warum eine sorgfältig gesetzte Berechtigung nach einem Update verschwunden ist.
Geht das auch per Gruppenrichtlinie?
Ja, und für mehr als eine Handvoll Rechner sollte es so laufen. Der Knoten „Systemdienste" einer Sicherheitsrichtlinie schreibt denselben Deskriptor auf jeden Rechner im Geltungsbereich und setzt ihn bei jeder Aktualisierung erneut, womit auch das Neuinstallations-Problem gelöst ist. Für einen einzelnen Rechner bleibt die Kommandozeile schneller.
Warum zeigte das alte Werkzeug Konten als (null)\(null)?
Weil einige der integrierten Konten, die im Standarddeskriptor stehen, nicht auf jedem Rechner existieren, und eine nicht auflösbare Sicherheitskennung keinen Namen hat. S-1-5-32-547 ist die Gruppe der Hauptbenutzer, auf einem Domänencontroller nicht vorhanden; S-1-5-32-549 sind die Server-Operatoren, die nur dort existieren. Die Einträge sind trotzdem gültig und wirksam.
Was unterscheidet „abfragen" von „Status lesen"?
Status lesen liefert den Zustand, den der Dienststeuerungs-Manager bereits kennt. Abfragen fordert den Dienst selbst zur Antwort auf. Was einen laufenden, aber hängenden Prozess sichtbar macht, während der zwischengespeicherte Status weiterhin „läuft" meldet.
Wann ist ein benutzerdefinierter Steuercode sinnvoll?
Nur wenn der Dienst einen dokumentiert. Die Codes 128 bis 255 behandelt der Dienst vollständig selbst, das Recht bedeutet also „darf diesem Dienst seine eigenen Kommandos schicken" und sonst nichts. Bei einem Dienst, der keine implementiert, hat es keine Wirkung.