Geschrieben von: Christoph Wille
Kategorie: Sicherheit
This printed page brought to you by AlphaSierraPapa
Geschützte Bereiche auf einer Website kann man auf viele Arten implementieren. Will man aber daß Seiten im geschützen Bereich unter dem Account des eingeloggten Benutzers laufen (Impersonation), dann helfen nur noch Windows Accounts. Anwendungen der Impersonation gibt es unzählige, aber sie wird immer dort notwendig, wo der normale Account des Webservers nicht mehr genug Rechte hat: zB anlegen von Usern im Active Directory, managen von DNS Servern via WMI, oder auch so einfache Dinge wie das Auslesen von mit NTFS Rechten geschützten Dateien.
Die Übungsannahme für heute ist daher wie folgt: wir haben eine Datei namens secure.txt, auf die nur der lokale Administrator Vollzugriff hat (und sonst niemand irgendwelche Rechte). Unsere Scripts sollen diese Datei auslesen und an den Browser schicken. Wie macht man das? (die im ersten Absatz angesprochenen Anwendungsfälle funktionieren analog)
Unter ASP ist die Sache sehr einfach - da die Datei secure.txt nur NTFS Rechte für den Administrator gesetzt hat, machen wir das gleiche mit dem ASP Script, das die secure.txt ausliest:
Im Script selbst passiert nichts magisches (highprivtest.asp), es dient nur dazu nachzuweisen, daß eine Aktion ausgeführt wird, die einen spezifischen User Account verlangt (in diesem Fall den Administrator):
<% Option Explicit Dim strDateiname, strInhalt, objFs, objTextStream strDateiname = Server.MapPath("secure.txt") Set objFs = Server.CreateObject("Scripting.FileSystemObject") Set objTextStream = objFs.OpenTextFile(strDateiname, 1) ' fsForReading strInhalt = objTextStream.ReadAll objTextStream.Close Set objTextStream = Nothing Set objFs = Nothing Response.Write strInhalt %>
Durch die Absicherung von highprivtest.asp mit einem NTFS ACL werden wir im Browser nach Benutzernamen und Passwort gefragt:
Und danach läuft das Script unter dem eingegebenen Account ("Impersonation"), und kann somit ohne Probleme auf secure.txt zugreifen. Piece of cake - Impersonation mit ASP ist leicht.
Eigentlich ist diese Überschrift eine Gemeinheit gegenüber ASP.NET, aber im ersten Gedanken ist erhöhte Sicherheit - wie sie dankenswerterweise in ASP.NET enhalten ist - einfach nur lästig, weil man auf mehr Dinge Rücksicht nehmen muß.
Um so richtig zu verstehen, warum ASP.NET sich anders verhält, muß man sich die Architekturunterschiede von ASP und ASP.NET vor Auge halten. ASP läuft als ISAPI Anwendung direkt im IIS, und nimmt somit automatisch dessen Prozessidentität an. ASP.NET hingegen läuft in einem eigenen von IIS getrennten Prozess, dem ASP.NET Worker Prozess (als aspnet_wp.exe im Task Manager zu sehen). Und dieser läuft im Gegensatz zu IIS nicht als SYSTEM, sondern als korrekt niedrig privilegierter ASPNET Account, der standardmäßig keine Impersonation macht.
Da es hin und wieder nützlich sein kann, die Prozessidentität des ASP.NET Worker Prozesses zu ändern (und sei es nur auf einen Domain-Account), stelle ich jetzt die notwendigen Handgriffe vor. Schritt 1 ist die Datei machine.config ausfindig zu machen:
In dieser machine.config gibt es die processModel Sektion, in der man mit den Attributen userName und password die gewünschten Einstellungen treffen kann. Die reservierten Wörter machine (ASPNET Account) und System (SYSTEM Account) sind vor der Sektion nochmals ausführlich erklärt.
<processModel enable="true" timeout="Infinite" idleTimeout="Infinite" shutdownTimeout="0:00:05" requestLimit="Infinite" requestQueueLimit="5000" restartQueueLimit="10" memoryLimit="60" webGarden="false" cpuMask="0xffffffff" logLevel="Errors" clientConnectedCheck="0:00:05" comAuthenticationLevel="Connect" userName="machine" password="AutoGenerate" comImpersonationLevel="Impersonate" responseRestartDeadlockInterval="00:09:00" responseDeadlockInterval="00:03:00" maxWorkerThreads="25" maxIoThreads="25" />
Das Wissen um den ASPNET Account erspart einem später einige Zeit bei der Problemsuche. So zum Beispiel, wenn man auf folgende Idee kommt: was in ASP gegangen ist, geht auch in ASP.NET. Was meine ich damit? Nun, einfach auf highprivtest.aspx (Code folgt sogleich) den NTFS ACL nur für Administratoren zu setzen.
<% @Page Language="C#" %> <% @Import Namespace="System.IO" %> <% StreamReader stmReader = File.OpenText(Server.MapPath("secure.txt")); string strLine; while (null != (strLine = stmReader.ReadLine())) { strLine = Server.HtmlEncode(strLine); Response.Write(strLine +"<br>\r\n"); } stmReader.Close(); %>
Wenn man highprivtest.aspx so abgesichert nun aufruft, bekommt man folgenden Fehler (nach oftmaligen völlig richtigem Eintippen des Accounts mit Zugriffsberechtigung):
Was ist passiert? Nun, ASP.NET macht per Default keine Impersonation. Das heißt, obwohl ich Benutzername und Passwort brav eintippe, versucht der Worker Prozess mit dem ASPNET Account auf die Datei zuzugreifen - und das geht klarerweise schief, weil der Account keinen Zugriff nach NTFS Rechten hat.
Es folgt somit der nächste Streich: gut, dann geben wir einfach zusätzlich zum Administrator auch dem ASPNET Account die Leseberechtigung:
Nun, der Erfolg (?) ist ein anderer:
Was ist passiert? ASP.NET kann wieder als "anonymer Benutzer" auf die Datei zugreifen, und ignoriert den Adminstrator Account den der Client schickt. Es ist zum Verzweifeln - nur Administrator geht nicht, weil der Worker Prozess dann nicht zugreifen kann, gibt man den ASPNET Account dazu, wird der Zugriff wieder anonym. Wie kommen wir aus diesem Dilemma hinaus?
Mittels obigen NTFS Rechten und der immer nützlichen web.config! Diese Datei erlaubt es uns, ASP.NET zur Impersonation zu zwingen, alles was man braucht sind 2 Einträge - einer für die Art der Authentication, und einen zweiten zum Erzwingen der Impersonation:
<configuration> <system.web> <compilation debug="true" /> <authentication mode="Windows"/> <identity impersonate="true"/> </system.web> </configuration>
Damit haben wir es geschafft - der Administrator Account wird impersonisiert, um den Zugriff auf die Datei secure.txt zu erlangen.
Im Prinzip ist es nicht schwierig, sondern nur ungewohnt, daß die NTFS Permissions auch den ASPNET Account enthalten müssen, und man die web.config anpassen muß. Dieses Mehr an Arbeit sollte uns die erhöhte Sicherheit durch ASP.NET aber wert sein.
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20020123.zip
NT Account Management via ASP
http:/www.aspheute.com/artikel/20010402.htm
On Demand Zugriffsrechte für Web Sites vergeben
http:/www.aspheute.com/artikel/20011207.htm
Schritt-für-Schritt Debuggen von Sicherheitsproblemen
http:/www.aspheute.com/artikel/20011119.htm
Verzeichnissicherheit mit NTFS und IIS Authentifizierung
http:/www.aspheute.com/artikel/20001109.htm
.NET Security
http://msdn.microsoft.com/library/default.asp?url=/nhp/default.asp?contentid=28001369
.NET Security Mailingliste
http://www.dotnetgerman.com/listen/dotnetDEsecurity.asp
ASP.NET Denied Access to IIS Directories
http://www.asp.net/security.aspx
Security in the .NET Framework: An Overview
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/netframesecover.asp?frame=true
Version 1 Security Changes for the Microsoft .NET Framework
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/V1securitychanges.asp?frame=true
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.