2015-11-06 8 views
15

Ist System.Security.Principal.WindowsIdentityvernünftigerweise sicher vor solchen gehackt, dass eine Instanz I von Thread.CurrentPrincipal ‚s Identity oder WindowsIdentity.GetCurrent() erhalten, die true für IsAuthenticated hat meine Montage falsche Identitätsinformationen gibt? Nichts ist natürlich völlig manipulationssicher, aber angesichts Microsofts Engagement für und der Abhängigkeit von .Net würde ich erwarten, dass kritische APIs wie diese Locked Down Hard und schwer zu manipulieren sind. Ist das eine gültige Annahme von meiner Seite?Ist diese Verwendung von System.Security.Principal.WindowsIdentity einigermaßen sicher?

Mein Ziel ist es, angemessene Best Practices SSO in meiner Assembly bereitzustellen. Wenn Windows selbst kompromittiert ist, liegt das außerhalb meiner Kontrolle, aber wenn es zum Beispiel für eine App, die mit meiner Assembly verlinkt, einfach ist, mir falsche Informationen zu geben, wäre es für mich eine Fehleinschätzung. Dies ist ein großes Gebiet der Ignoranz für mich.

Um klar zu sein, ich bin auf der Suche nach harten Informationen, nicht aus der Manschette Meinungen. Also veröffentlichte Exploits oder demonstrierte die Verwendung eines WindowsIdentity Konstruktors in einer Weise, die meinen Code usw. tricksen würde. Oder auf der "das ist eine gültige Annahme" Seite, solide Artikel, die es sichern, bekannte Verwendungen, die darauf vertrauen, usw. Ich habe Ich hatte viel Glück dabei, sie zu finden, aber ich habe das, was ich bisher gefunden habe, unter dem Teiler eingefügt.

Hier ist, wie ich verwenden will WindowsIdentity:

using System.Security.Principal; 
using System.Threading; 
// ... 

// I only want Windows-authenticated users 
WindowsIdentity identity = Thread.CurrentPrincipal == null 
    ? null 
    : Thread.CurrentPrincipal.Identity as WindowsIdentity; 
SecurityIdentifier sid; 

// I can't imagine how an authenticated account would be anonymous, but... 
if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous) { 
    // SSO success from thread identity 
    sid = identity.User; 
    // ...check that that SID is allowed to use our system... 
} else { 
    identity = WindowsIdentity.GetCurrent(); 
    if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous) { 
     // SSO success from current Windows user 
     sid = identity.User; 
     // ...check that that SID is allowed to use our system... 
    } else { 
     // SSO fail 
    } 
} 

Dies ist in einer DLL-Baugruppe   — leider wir auf .Net 3.5   — stecken, die eine öffentliche API zu Ressourcen zur Verfügung stellt, die von beschränkt werden kann, Nutzerrechte. Es kann in Desktop-Apps oder in einer ASP.Net IIS-App mit Windows-Authentifizierung verwendet werden (ASP.Net setzt eine WindowsIdentity Instanz auf Thread.CurrentPrincipal.Identity, wenn Windows-Auth verwendet wird; andere Arten von IIS-Auth werden derzeit nicht unterstützt).

Kann ich vernünftigerweise einer SID von einer WindowsIdentity Instanz aus Quellen vertrauen, die behaupten, so authentifiziert zu sein? war in Ordnung

Es mir nicht, wenn das auftrat zu fragen (doh!) bis in this question Benutzern lc. Bedenken geäußert, dass die Anordnung von einem böswilligen App ausgetrickst, die mit ihm verbunden und "anfällig sein würde, gefälscht "diese Informationen. Er hatte keine konkreten Beweise dafür, warum das ein wichtiges Anliegen sein könnte, daher diese Frage.


Was (wenig) ich bisher gefunden habe:

  • This answer den

    macht Anspruch

    Sie können die aktuellen WindowsIdentity darauf vertrauen, dass, die es sagt, es ist, soweit weil Sie jedem Datenelement in Ihrer Anwendung vertrauen können.

  • Das Buch Hacking the Code behauptet, dass ASP.Net erfordert ein WindowsIdentity mit einer Anforderung zugeordnet werden, wenn die Datei authorizaton Prüfung zu tun, die, wenn sie wahr zu sagen Microsoft, zumindest wie eine ziemlich solide Basis scheint, es ist gut genug erachtet .

  • Ich kann viele Beispiele von Leuten finden, die glücklich die Informationen WindowsIdentity in ihrem Code verwenden, aber die meisten von ihnen stellen die Frage nicht, ob sie sicher sind. Es gibt eine Implikation, aber ...

+0

In welchem ​​Kontext fragen Sie das? Sie sprechen über ASP.NET- und Desktop-Apps. Es mag offensichtlich sein, aber [wenn man auf einem "pwned" -System läuft, sind alle Wetten aus - ein böswilliger Benutzer kann in seinen Prozess injizieren und modifizieren, wie er will] (http://stackoverflow.com/questions/8357469/ Wie kann ich-schützen-meine-private-Funktionen-gegen-Reflexion-Ausführung). – CodeCaster

+0

@CodeCaster: Wenn Windows selbst ist kompromittiert, das ist außerhalb meiner Kontrolle. Aber wenn (zum Beispiel) eine App einfach eine "WindowsIdentity" -Instanz erstellen kann, weise sie dem aktuellen Thread zu, und rufe dann meine Assembly an, um zu glauben, dass sie jemand ist, der sie nicht ist Sorgfalt. Im Grunde versuche ich vernünftige Best Practice SSO zu erreichen. Ich habe nicht in Frage gestellt, ob ich den obigen APIs vertrauen konnte, bis dieser Benutzer es bei meiner anderen Frage anzeigte (er könnte einfach paranoid sein), und dann machte ich mir Sorgen darüber, was ich nicht weiß, was in diesem Bereich ein ist Menge. :-) –

Antwort

10

Sie nicht derjenige von Thread.CurrentPrincipal vertrauen können, nicht. Es gibt nichts, was Code daran hindert, in vollem Vertrauen zu laufen, indem man es spoofiert.

konnte ich es in meiner Umgebung so fälschen:

var admin = new WindowsIdentity(@"Administrator"); 
var princ = new WindowsPrincipal(admin); 
System.Threading.Thread.CurrentPrincipal = princ; 

..., bevor Sie Ihren Code aufrufen. Auf meinem Computer hat das erstellte WindowsIdentity Objekt IsAuthenticated als true und IsAnonymous false, und so extrahiert natürlich Ihr Code die SID meines Domänenadministrators.

, dass in allen Umgebungen nicht funktioniert, aber dies sollte, vorausgesetzt, dass der laufende Code genügend Berechtigungen verwenden Reflexion hat: (. Auch hier getan, bevor Sie Ihren Code aufrufen)

var ident = WindowsIdentity.GetCurrent(); 
Thread.CurrentPrincipal = new WindowsPrincipal(ident); 
var userSid = ident.User; 

var fakeSid = new SecurityIdentifier("S-1-3-0"); 

typeof (WindowsIdentity).GetField("m_user", 
    BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ident, fakeSid); 


Im Grunde gibt es nichts zu stoppen zwei Teile des Codes unter voller Vertrauenswürdigkeit innerhalb des gleichen Prozesses von einander zu lügen.

+0

@Damien_The_Unbeliever: Die Reflexion macht man in meiner Nicht-Domänen-Umgebung und meiner eigenen AD-Umgebung. ** Wow, das ist gruselig. ** Nach dem Setzen dieses 'm_user'-Felds gibt' .User' nicht nur den von uns gesetzten Benutzer zurück, sondern '.Name' gibt ihren Domain-Benutzernamen zurück; so scheint "WindowsIdentifier" auf eine triviale Weise richtig gehackt worden zu sein. Danke für deine Zeit und Hilfe. –

+0

@Damien_The_Unbeliever: ** Allerdings **, 'neue WindowsIdentity (identityFromThread.Token)' ** enthüllt die Spoof ** (und funktioniert in meinen zwei nicht-bösartigen Anwendungsfällen, zumindest in den ersten Tests). Ich denke, diese Antwort ist richtig für meine eigentliche Frage (Fragen können keine beweglichen Ziele sein!), Weil ich Code einfügte, den Sie erfolgreich ausgetrickst haben. Ich bin natürlich dran, um herauszufinden, ob auch das ausgetrickst werden kann ... –

+0

... und so haben wir [diese Frage] (http://stackoverflow.com/questions/33573773/is-it-) Möglich-zu-Trick-diesen-Windowsidentitäts-Code-in-den-falschen-Benutzer-verwenden. :-) –

Verwandte Themen