2015-11-06 18 views
15

È System.Security.Principal.WindowsIdentityragionevolmente al sicuro da essere violato in modo tale che un caso mi da Thread.CurrentPrincipal s' Identity o WindowsIdentity.GetCurrent() che ha true per IsAuthenticated dà il mio assemblaggio informazioni di identità falsa? Nulla, naturalmente, è completamente a prova di manomissione, ma dato l'impegno e la dipendenza di Microsoft da parte di .Net, mi aspetterei che API critiche come questa siano Locked Down Hard e difficili da manomettere. È un'ipotesi valida da parte mia?Questo uso di System.Security.Principal.WindowsIdentity è ragionevolmente sicuro?

Il mio obiettivo qui è quello di fornire un SSO ragionevole delle best-practice nel mio assieme. Se Windows è compromesso, questo è fuori dal mio controllo, ma se (per esempio) è una questione semplice per un'app che si collega al mio assembly per fornirmi informazioni false, sarebbe su di me per non aver fatto la dovuta diligenza. Questa è una grande area di ignoranza per me.

Per essere chiari, sto cercando informazioni difficili, non opinioni off-the-polsino. Quindi, exploit pubblicati, o uso dimostrativo di un costruttore WindowsIdentity in un modo che potrebbe ingannare il mio codice, ecc. O sul lato "questo è un presupposto valido", articoli solidi che lo supportano, usi noti che fanno affidamento su di esso, ecc. Ho avuto molta fortuna a trovarli, ma ho incluso quello che ho trovato finora sotto il divisorio.

Ecco come ho intenzione di usare 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 
    } 
} 

Questo è in un assembly DLL   — purtroppo siamo bloccati su .Net 3.5   — che fornisce un'API pubblica per le risorse che possono essere limitata dalla diritti utente. Potrebbe essere utilizzato nelle app desktop o in un'app di IIS di ASP.Net con autenticazione di Windows (ASP.Net imposta un'istanza WindowsIdentity su Thread.CurrentPrincipal.Identity quando si utilizza l'autenticazione di Windows, non supportiamo attualmente altri tipi di autenticazione di IIS).

Posso fidarmi ragionevolmente di un SID da un'istanza WindowsIdentity da quelle fonti che affermano di essere autenticati in questo modo?

E non si è verificato a me a chiedermi se andava più che bene (doh!) fino a quando nel this question utente lc. sollevato una preoccupazione che l'assemblea sarebbe suscettibile di essere ingannato da un'applicazione dannosa che collegava con esso e " falsificato "quell'informazione. Non aveva alcuna prova specifica per indicare perché potrebbe essere una preoccupazione significativa, però, quindi questa domanda.


Cosa (poco) che ho trovato finora:

  • This answer fa l'affermazione

    ci si può fidare che l'attuale WindowsIdentity è che si dice che è, nella misura in cui dato che puoi fidarti di qualsiasi dato dato nella tua applicazione.

  • Il libro sostiene che Hacking the Code ASP.Net richiede un WindowsIdentity essere associato a una richiesta quando si fa il controllo del file AUTORIZZO, che, se vero sembra una base abbastanza solida per dire Microsoft, almeno, lo considera abbastanza buono .

  • Sono in grado di trovare molti esempi di persone che utilizzano felicemente le informazioni WindowsIdentity nel loro codice, ma la maggior parte di esse non pone la domanda se sono sicuri. C'è un implicazione, ma ...

+0

In che contesto stai chiedendo questo? Stai parlando di entrambe le app ASP.NET e desktop. Può essere ovvio, ma [quando si esegue un sistema "pwned", tutte le scommesse sono disattivate - un utente malintenzionato può iniettare e modificare il processo nel modo desiderato) (http://stackoverflow.com/questions/8357469/ how-can-i-miei-privati-funcs protezione-contro-riflessione-executing). – CodeCaster

+0

@CodeCaster: se Windows è correttamente compromesso, è fuori dal mio controllo. Ma se (per esempio) un'app può semplicemente creare un'istanza di 'WindowsIdentity', assegnarla al thread corrente e quindi chiamare il mio assembly e ingannarmi facendogli credere che sono qualcuno che non sono, che sarebbe su di me in mancanza a causa diligenza. Fondamentalmente, sto cercando di ottenere un SSO ragionevole. Non mi chiedevo se potevo fidarmi delle API sopra menzionate fino a quando quell'utente non l'ha segnalato sull'altra mia domanda (potrebbe essere solo un paranoico), e poi mi sono preoccupato di ciò che non so, che in quest'area è un sacco. :-) –

risposta

10

Non ti puoi fidare l'uno da Thread.CurrentPrincipal, n. Non c'è niente che impedisca al codice di funzionare con piena fiducia dallo spoofing.

sono stato in grado di falsificare nel mio ambiente come questo:

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

... prima di richiamare il codice. Sulla mia macchina, l'oggetto WindowsIdentity creato ha IsAuthenticated come true e IsAnonymous falso, e così, ovviamente, il codice estrae il SID dell'amministratore del mio dominio.

che non funziona in tutti gli ambienti, ma questo dovrebbe, a condizione che il codice in esecuzione ha autorizzazioni sufficienti per utilizzare riflessione: (. Ancora una volta, fatto prima di chiamare il codice)

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); 


Fondamentalmente, non c'è nulla per impedire che due pezzi di codice in esecuzione in Full Trust all'interno dello stesso processo si mentano l'uno sull'altro.

+0

@Damien_The_Unbeliever: Il riflesso lo fa, nel mio ambiente non di dominio e nel mio ambiente AD appropriato. ** Wow è spaventoso. ** Dopo aver impostato il campo 'm_user', non solo' .User' restituisce l'utente che abbiamo impostato, ma '.Name' restituisce il loro nome utente di dominio; quindi 'WindowsIdentifier' sembra essere stato correttamente hackerato, in un modo insignificante. Grazie per il tuo tempo e aiuto. –

+0

@Damien_The_Unbeliever: ** Tuttavia **, 'nuovo WindowsIdentity (identityFromThread.Token)' ** rivela lo spoof ** (e funziona correttamente nei miei due casi di utilizzo non dannoso, almeno nei test iniziali). Penso che questa risposta sia giusta per la mia domanda reale (le domande non possono essere obiettivi in ​​movimento!), Perché ho incluso il codice che hai ingannato con successo. Naturalmente, sono sicuro di scoprire se anche questo può essere ingannato ... –

+0

... e quindi abbiamo [questa domanda] (http://stackoverflow.com/questions/33573773/is-it- possibile-a-trick-questo-WindowsIdentity-code-in-con-il-male-utente). :-) –

Problemi correlati