Mein Problem war ein Service, der eine Pipe als Interface zur Verfügung stellt, auf die von beliebigen PCs zugegriffen werden soll. Insbesondere eben auch von PCs außerhalb der Domäne in der der Service läuft der die Named Pipe zur Verfügung stellt. Die Clients melden sich über VPN an dem entsprechenden Server an, gehören aber eben selbst nicht zur Domäne.
Von einem Rechner, der nicht in der Domäne des Rechners liegt, auf eine Pipe eines Rechners in einer Domäne zuzugreifen war schon immer mit extra Vorkehrungen verbunden. Der Code für den anonymen Zugriff auf eine Pipe finden wir als KB Artikel http://support.microsoft.com/kb/813414/en-us. Über die Qualität dieses Beispiels möchte ich mich hier allerdings nicht auslassen.
Dieses Sample ist nett für alle die XP und Windows 2003 Server nutzen. Und interessanter Weise funktioniert es auch auf Windows Vista, Windows 7 oder Windows Server 2008. Aber nur weil dieses Beispiel die Pipe nur lesend benutzt.
Dieses Programm berücksichtigt nicht die neuen Sicherheitsfunktionen von Vista, Windows 7 oder Windows Server 2008. Es klappt genau dann nicht, wenn der Server eben auf einem Vista, Windows 7, oder Server 2008 läuft UND die Pipe für Lesen und Schreiben geöffnet wird. ERROR_ACCESS_DENIED (5) ist das was der Client dann bekommt, wenn die Pipe lesend und schreibend geöffnet werden soll.
Was ist das Problem
Das Problem liegt in einem Sicherheitsmechanismus, der sogenannten Windows Integrity.
Ich rate jedem die Literatur der nachfolgenden beiden Links:
- Windows Integrity Mechanism Design
http://msdn.microsoft.com/en-us/library/bb625963.aspx - Windows Vista for Developers – Part 4
http://weblogs.asp.net/kennykerr/archive/2006/09/29/windows-vista-for-developers-_1320_-part-4-_1320_-user-account-control.aspx
Kurzbeschreibung:
Prozessen oder auch anderen Systemobjekten wird ein Inegrity-Level zugeordnet.
Greift nun ein Prozess auf ein Systemobjekt zu, dann werden nicht nur die allgemeinen Rechte geprüft (z.B. Rechte für Anonymen Zugriff, oder die entsprechenden Gruppenrechte), sondern auch der Integrity Level dieses Prozesses wird mit dem der Ressource verglichen.
Liegt nun der Integrity Level des Clients niedriger als der Intergrity Level des Objektes, dann greift eine neue Policy, die dann festlegt was passiert. In den meisten Fällen bedeutet dies, dass der Lesezugriff zugelassen wird, aber der Schreibzugriff untersagt wird.
Übrigens passiert das gleiche, wenn man ein Addin für den IE8 auf Vista (und später hat). Der IE8 läuft im geschützten Modus und damit im Integrity Level Low. Normale Programme laufen im Integrity Level Medium.
Möchte nun das IE8 Addin eine Pipe oder einen Shared Memory Block eines Services oder eines “normalen” anderen Programmes, schreibend öffnen, dann passiert das gleiche. Der Zugriff wird reduziert auf nur lesen.
Und dieses Thema wird hauptsächlich in der Doku und im Netz diskutiert (und zum Teil, gelöst).
Ich will das jetzt hier nicht über die Maßen ausdehnen. Ich kann nur anraten, die entsprechenden Artikel wirklich einmal zu lesen.
Jetzt zurück zu dem was NICHT in diesen entsprechenden Artikeln und Forumbeiträgen steht.
1. Anonymen Zugriff wird automatisch der Integrity Level Untrusted zugewiesen. Die Doku zeigt in dem Beispiel nur die Vorgehensweise für den Integrity Level low.
Mein Fehler war es, die ganze Zeit SECURITY_MANDATORY_LOW_RID zu verwenden. Aber ich sagte es schon: Der Anonyme Zugriff erfolgt im Integrity Level Untrusted.
2. Ich arbeite mit SDDL String und auch dort in den Headern ist Low das niedrigste für das es im Netz und auch in der Doku (http://msdn.microsoft.com/en-us/library/bb625963.aspx) findet. Dort steht ziemlich weit unten ein Beispiel, um ein Objekt einem “Low”-Integrity-Prozess zugänglich zu machen. Und dort finden wir folgende SDDL Definition:
#define LOW_INTEGRITY_SDDL_SACL_W L"S:(ML;;NW;;;LW)"3. Anonymer Zugriff ist also Integrity Level Untrusted (ich weiß ich wiederhole mich).
Und nun wird es spaßig. Es gibt auch gar keinen SDDL Sid für untrusted, es gibt nur die folgenden Definitionen in den Headern:
// Integrity Labels #define SDDL_ML_LOW TEXT("LW") #define SDDL_ML_MEDIUM TEXT("ME") #define SDDL_ML_MEDIUM_PLUS TEXT("MP") #define SDDL_ML_HIGH TEXT("HI") #define SDDL_ML_SYSTEM TEXT("SI")
Alles das hat mich in die Irre geführt und 2 Tage Arbeit gekostet.
Als mir klar war, dass ich eine Regel für den Untrusted Intergity Level benötige, war die Lösung gefunden.
Bauen wir uns einen eigenen SID! Aus der Doku können wir die entsprechenden RIDs finden und uns nun folgenden SID konstruieren: “S-1-16-0″.
Und das bringt uns zu dem SDDL String für den Level untrusted:
#define UNTRUSTED_INTEGRITY_SDDL_SACL _T("S:(ML;;NW;;;S-1-16-0)")Ich habe das oben beschriebene Sample etwas modifiziert, dass man genau dieses Problem des anonymen Zugriffs auf eine Pipe testen kann. Das Beispiel kann man hier herunterladen.
Ich habe das Sample dazu etwas umgebaut:
- so dass lesender und schreibender Zugriff auch benutzt wird.
- dass SDDL verwendet wird, was den Code extrem simplifiziert.
- dass zumindest etwas an dem ekligem Code lesbarer wurde.
- dass ein paar Bugs raus sind.
Ich bitte dennoch dies nur als Sample zu betrachten und nicht als Beispiel Software, die meinem Anspruch an C/C++ Code genügt
PS: Eine entsprechende Diskussion über das Problem findet sich in nntp://microsoft.public.de.vc
http://groups.google.de/group/microsoft.public.de.vc/browse_thread/thread/3be20505999b8aab
Danke noch mal explizit an den Regular Andreas Heyer für seinen wertvollen Diskussionsbeitrag.
4 Kommentare zu “Windows Integrity Control: Schreibzugriff auf eine Named Pipe eines Services über anonymen Zugriff auf Vista, Windows 2008 Server und Windows 7”
Link für diesen Beitrag | RSS-Feed zu diesem Beitrag
Hinterlassen sie einen Kommentar:
Beachten sie bitte, dass Kommentare evtl. nicht sofort hier erscheinen. Die Kommentare werden zur Moderation an den Webmaster gesendet. Es kann also etwas dauern, bis Ihr Kommentar hier veröffentlicht wird!
on Mi 16 Dez 2009 um 15:19 #
Andreas Heyer
Hallo Martin,
es wäre schön, wenn du noch den Google-Groups-Link zu unserer Diskussion in mpdv einfügen würdest. Ein wenig “Knowledge-Reputation” kann jeder von uns gebrauchen.
MfG
Andreas
on Mi 16 Dez 2009 um 15:30 #
Martin Richter
Hi Andreas!
Siehe PS am Ende des Artikels. OK so
Gruß Martin
on Fr 27 Aug 2010 um 16:16 #
Martin Richter
Selten aber es kommt vor, dass Microsoft auf Quellen außerhalb Ihres eigenen Refugiums verweisen:
http://blogs.technet.com/b/nettracer/archive/2010/07/23/why-does-anonymous-pipe-access-fail-on-windows-vista-2008-windows-7-or-windows-2008-r2.aspx
on Mi 02 Mrz 2011 um 12:06 #
Hung Mai
Hi Martin,
It’s a pity that I cannot speak German. If I could, the only sentence I would like to say is: “Thank you, this is a perfect article!”.
Best regards,
Hung Mai.