COM+ Security Christof Sprenger Partner Group Microsoft GmbH [email protected] Agenda 1. 2. 3. 4. Security Grundlagen Windows Security Architektur COM+ Security Architektur Do’s & Don’ts.
Download ReportTranscript COM+ Security Christof Sprenger Partner Group Microsoft GmbH [email protected] Agenda 1. 2. 3. 4. Security Grundlagen Windows Security Architektur COM+ Security Architektur Do’s & Don’ts.
COM+ Security Christof Sprenger Partner Group Microsoft GmbH [email protected] Agenda 1. 2. 3. 4. Security Grundlagen Windows Security Architektur COM+ Security Architektur Do’s & Don’ts 2 Abschnitt 1 Security Grundlagen 3 „Definition“ Security ist: „Definieren und Durchsetzen von Grenzen des Vertrauens “ (defining and enforcing boundaries of trust) 4 „Definition“ Kurze Definition von Security: • • • wer (identity Authentifizierung) tut was (Zweck/Absicht) mit wem oder was (Privilege Authorisation) 5 Security Grundlagen: Begriffe „Principal“ Eine Identität (Sie oder Ihr PC) „Credentials“ Daten um Identität zu beweisen „Trust“ Den Credentials vertrauten „Authority“ Der, der für Principals bürgt „Privilege“ Das Recht etwas zu tun 6 Abschnitt 2 Windows Security Architektur 8 Windows Security Architektur Authentifizierung • • • Access Token Security Identifier Logon Session Authorisation • • • Privileges / User Rights Access Control List (ACL) Security Descriptors (SD) 9 Authentifizierung 1/2 Die Frage ist: “Wer bist du?” „Credentials“ werden beim Logon überprüft • Credentials sind: User/Password oder Smartcard Erfolgreiches Logon erzeugt ein • • eine Logon Session und ein Access-Token Access Token dient als Zutrittsausweis 10 Authentifizierung 2/2 Logging on... Logon Process (winlogon.exe) Win32 Subsystem (system) Security Subsystem (LSA) (lsass.exe) Authentication package Run Check Create process Validate Create user Shell CTRL-ALT-DEL Credentials With access token Add Access group token info (explorer.exe) (USER/PASS) Security Account Manager DB (SAM) 11 Access Token Bestandteile User SID Group SIDs Privileges Default für neue Objekte (z.B. Dateien, Pipes, Shared Memory ....) Logon Session ID ... 12 Logon-Sessions 5 Arten von logon-session SYSTEM Enthält alle Prozesse, die Teil des OS sind INTERACTIVE Für den interaktiv angemeldeten Benutzer NETWORK Entsteht durch authentifizierten Zugriff auf den Rechner über das Netzwerk SERVICE Für NT Dienste, die mit einem bestimmten Benutzerkonto konfiguriert wurden BATCH Für Prozesse die durch die COM Runtime getartet wurden 14 Logon Sessions Beispiel AlicesMachine JoesMachine Bob‘s network logon session Bob‘s Service logon session Alice‘s interactive logon session Teds‘s network logon session Alice‘s network logon session TedsMachine Alice‘s network logon session Teds‘s interactive logon session 16 Impersonation Ein (Server-)Prozess verrichtet oft Arbeit für verschiedene Benutzer Daher kann jedem Thread eine eigenes Access Token zugeordnet werden Es gibt also zwei Arten von Access Token • • Primary Token (für Prozesse) Impersonation Token (für Threads) 17 Impersonation im Bild server.exe Joe client.exe Alice Alice client.exe Bob Bob 18 Authorization Frage ist: “Was darfst du tun?” Auch: Access Check oder Access Control Wird bestimmt durch: • • • Art des gewünschten Zugriffs Access-Token (des aktuellen Threads) Access Control List (ACL) aus dem Security Descriptor des Objekts 19 Access Control Lists DACL ACE Everyone Read ACE „chrispre“Full Control ACE SYSTEM Full Control ACE Administrators Full Control 20 Security Descriptor Owner SID Group SID (POSIX) SACL DACL • • Permitted users Permissions 21 Authorisation im Bild Access-Token Access? Process/Thread OpenSomeObject() OK! Token SRM Check! (SecurityReferenceMonitor) Security-Descriptor SomeObject DACL SD ACE DACL User SID „chrispre” Group SIDs Privileges „chrispre“: Full 22 Netzwerk Authentifizierung Wie entsteht auf einem entfernten Rechner eine Logon Session, die den Benutzer repräsentiert, der über das Netzwerk zugreift? Das Kennwort darf nicht einfach über das Netzwerk versendet werden Die Bits und Bytes, die das Access Token bilden dürfen ebenfalls nicht versendet werden 23 NTLM mit Local Accounts Client Server lsass.exe 4. 5. client.exe 1. Negotiate 2. Challenge 3. Response server.exe 24 NTLM mit Domain Accounts Authority 0. 5. 6. Client Server lsass.exe 4. 7. 1-3 client.exe server.exe 25 NTLM über Domänengrenzen Domain A Authority A Domain B Authority B Client Server lsass.exe client.exe server.exe 26 Kerberos Authority 1. 2. Server Client 3. 27 Abschnitt 3 COM(+) und Security 28 COM Security Konzepte Authentifizierung: Wer ist der Client? • RPC und damit COM erlaubt dem Client den Grad der Authentifizierung einzustellen Access Control: Darf dieser Client dies tun? • Programmatisch vs. Deklarativ Identity: Welche Identity nimmt der Client an? Mit welcher Identity läuft der Server? • COM erlaubt es dem Client eine Identity auszuwählen • COM startet die Server automatisch und erlaubt es die Identity des Servers auszuwählen 29 Abschnitt 3.1 Authentifizerung 30 Auswahl des SSP in COM Jeder Server-Prozess registriert Security Support Provider (SSP) mit Hilfe von CoInitializeSecurity • Runtime sorgt dafür, daß Proxies automatisch den passenden SSP verwenden COM ruft CoInitializeSecurity implizit auf falls “vergessen” • • • Beim ersten Marshal oder Unmarshal Wählt default SSPs des Rechners Defaultwerte sagen: Security ist an 31 CoInitializeSecurity HRESULT CoInitializeSecurity( SECURITY_DESCRIPTOR* pSD, DWORD cAuthSvc, SOLE_AUTHENTICATION_SERVICE* prgAuthSvc, void* pvReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void* pvReserved2, DWORD dwCapabilities, void* pvReserved3 ); 32 Authentication Level Mit CoInitializeSecurity wird ein „Authentication Level“ gewählt Dies legt fest wann und/oder wie oft Authentifiziert wird und ob die Daten verschlüsselt werden 33 RPC_C_AUTHN_LEVEL RPC_C_AUTHN_LEVEL_NONE Keine Authentifizierung RPC_C_AUTHN_LEVEL_CONNECT Authentifizierung beim ersten “Kontakt” RPC_C_AUTHN_LEVEL_CALL Authentifizierung für das erste Packet eines jeden Aufrufs RPC_C_AUTHN_LEVEL_PACKET Authentifizierung für jedes Packet RPC_C_AUTHN_LEVEL_PKT_INTEGRITY PACKET + Signatur RPC_C_AUTHN_LEVEL_PKT_PRIVACY INTEGRITY + Verschlüsselung 34 Authentication Level Für den Server ist dies die „low watermark“ für eingehende Aufrufe Unterhalb dieses Levels werden Aufrufe abgelehnt • Alle exportierten Interface Pointer bekommen diese „low watermark“ als Hinweis mit COM Runtime wählt dann den höchsten von • • „low watermark“ des Servers Level der bei Aufruf von CoInitializeSecurity im Client angegeben wurde 35 Proxy und Security CoInitializeSecurity legt nur den „default authentication level“ für jeden Proxy fest Die Einstellungen können dann für jeden Proxy angepasst werden. Dies geht bei dem Standard-Proxy über IClientSecurity • IClientSecurity wird vom „proxy manager“ implementiert 36 Proxy & Stubs (Interceptors) Client Server ProxyManager IClientSecurity IFoo IFoo Proxy Object Stub IBaz IBaz Proxy Stub 37 IClientSecurity interface IClientSecurity : Iunknown { HRESULT QueryBlanket( IUnknown* pProxy, DWORD* pAuthnSvc,DWORD* pAuthzSvc, OLECHAR** pServerPrincName, DWORD* pAuthnLevel, DWORD* pImpLevel, void** ppAuthInfo, DWORD* pdwCapabilites ); HRESULT SetBlanket( IUnknown* pProxy, DWORD AuthnSvc, DWORD AuthzSvc, OLECHAR* pServerPrincName, DWORD AuthnLevel, DWORD ImpLevel, void* pAuthInfo, DWORD dwCapabilities ); HRESULT CopyProxy( IUnknown* pProxy, IUnknown** ppCopy ); } 38 Anpassen des Authn Level HRESULT MakePrivateCall( IBank* pib ) { IClientSecurity* pics = 0; pib->QueryInterface( IID_IClientSecurity, (void**)&pics ); DWORD nAuthnSvc, nImpLevel; pics->QueryBlanket( pib, &nAuthnSvc, 0, 0, 0, &nImpLevel, 0, 0 ); pics->SetBlanket( pib, nAuthnSvc, 0, 0, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, nImpLevel, 0, 0 ); pics->Release(); pib->SetCreditCardInfo( g_pszCardNum ); pib->Release(); } 39 Authn Level bei Aktivierung In COM gibt es einige Aufrufe zur Aktivierung von COM Objekten • • • CoCreateInstance(Ex) CoGetClassObject CoGetInstanceFromFile Der Default Authn Level wird durch CoInitializeSecurity bestimmt Wie kann der Client den Authn Level festlegen? (Es gibt noch kein IClientSecurity) Hierzu dient COSERVERINFO und COAUTHINFO 40 COAUTHINFO struct COSERVERINFO { DWORD dwReserved1; WCHAR* pszHostName; COAUTHINFO* pAuthInfo; DWORD dwReserved2; }; struct COAUTHINFO { DWORD DWORD WCHAR* DWORD DWORD COAUTHIDENTITY* DWORD }; // mbz // mbz dwAuthnSvc; dwAuthzSvc; pszServerPrincipalName; dwAuthnLevel; dwImpLevel; pAuthIdentityData; dwCapabilities; 41 „Normales“ Vorgehen Server setzt die „low watermark“ auf CONNECT or NONE (Effizienz) Ein Servers, der den Client identifizieren muss, setzt mindestens CONNECT • Z.B. muss ein Server, der nur bestimmte Clients zulässt diese auch unterscheiden können Server, die anonymen Zugriff erlauben müssen NONE verwenden. Clients setzen den Authn Level für bestimmte Operationen rauf. 42 Überprüfen des Authn Level Ein Server fordert manchmal einen höheren Authentication Level als sonst • Z.B. um eine PIN oder Kreditkartennummer zu übetragen Clients können den Level erhöhen Server können dies dann überprüfen IServerSecurity bietet die Möglichkeit den Kontext des Aufrufs nach dem Authn Level zu fragen • Hierzu ist auch CoGetCallContext nötig 43 IServerSecurity HRESULT CoGetCallContext( REFIID iid, void** ppv ); interface IServerSecurity : IUnknown { HRESULT QueryBlanket( DWORD* pAuthnSvc, DWORD* pAuthzSvc, OLECHAR** pServerPrincName, DWORD* pAuthnLevel, DWORD* pImpLevel, void** pPrivs, DWORD* pCapabilites ); // weitere Methoden ... } 44 Beispiel QueryBlanket HRESULT CoBank::SetCreditCardInfo( BSTR pszCardNum ) { // verlange PRIVACY DWORD nAuthnLevel HRESULT hr = CoQueryClientBlanket( 0, 0, 0, &nAuthnLevel, 0, 0, 0 ); // nicht authentifiziert if ( FAILED( hr ) ) return E_ACCESSDENIED; if ( nAuthnLevel < RPC_C_AUTHN_LEVEL_PRIVACY ) return E_ACCESSDENIED; // ... } 45 Abschnitt 3.2 Access Control 46 Zwei Arten von Authorisation COM bietet zwei Arten von Zugriffskontrolle Beide arbeiten auf Prozessebene Access Permissions • Welcher Benutzer darf in den Server Aufrufe absetzen Launch Permissions • Welcher Benutzer kann den Prozess in Folge eines Aktivierungsaufrufes starten Es ist möglich, dies feiner abgestuft im Programmcode zu machen 47 Access Permissions Werden über CoInitializeSecurity gesetzt Der erste Parameter kann in verschiedenen Arten verwendet werden. • • • • NULL für unbeschränkten Zugriff Ein Interface Pointer vom Typ IAccessControl Ein Security Descriptor Eine AppID dwCapabilities (8. Parameter) bestimmt was im Ersten steht 48 CoInitializeSecurity HRESULT CoInitializeSecurity( SECURITY_DESCRIPTOR* pSD, DWORD cAuthSvc, SOLE_AUTHENTICATION_SERVICE* prgAuthSvc, void* pvReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void* pvReserved2, DWORD dwCapabilities, void* pvReserved3 ); 49 Registry Wenn in CoInitializeSecurity eine AppID verwendet wird, wird die Registry verwendet. Pro Applikation bzw. AppID • • HKCR/AppID/{appid} AccessPermission=“01 00 04 80 ..." Falls dieser Key fehlt • • HCLM/Software/Microsoft/Ole DefaultAccessPermission=“01 00 04 80 ..." DCOMCNFG kann die Einträge setzen 50 Launch Permissions Wer darf einen COM Server starten? CoInitializeSecurity kann nicht verwendet werden, da der Prozess ja noch nicht läuft Hierfür ist die Registry da • • Falls dieser Key nicht existiert wird ein Default benutzt • • HKCR/AppID/{appid} LaunchPermission=“01 00 04 80 ...” HCLM/Software/Microsoft/Ole DefaultLaunchPermission=“01 00 04 80 ...” Mit Hilfe von DCOMCNFG können diese Werte editiert werden 51 Abschnitt 3.3 Role based security 52 Access Control in COM ist grob Launch Permissions pro Applikation Access Permissions pro Prozess Was, wenn man es genauer/feiner haben möchte? • • • Access Control pro Klasse Access Control pro Interface Access Control pro Methode Ist möglich, erfordert jedoch viel Code 53 Feinere Zugriffscontrolle Wie kann dies programmatisch gemacht werden? Authn Level ausreichend wählen Jede Methode macht folgendes • • • Lade das aktuelle Access Token • Dies geht in COM über IServerSecurity::ImpersonateClient() und IServerSecurity::RevertToSelf() Lade einen Security Descriptor für diese spezielle Methode aus einer DB Rufe die API AccessCheck auf und gib einen Fehler zurück das Ergebnis False ist 54 Impersonation Aufruf interface IServerSecurity : IUnknown { HRESULT QueryBlanket( ... ); HRESULT ImpersonateClient(); HRESULT RevertToSelf(); BOOL IsImpersonating(); } HRESULT CoGetCallContext( REFIID iid, void** ppv ); oder HRESULT CoImpersonateClient(); HRESULT CoRevertToSelf(); 55 Deklarative Access Control Das gleiche kann in COM+ deklarativ gemacht werden Der Code dazu ist im sogenannten Interceptor Die nötige Information (DACL) dazu steht im COM Catalog Problem: • • • Zur Designzeit stehen die Benutzer nicht fest Der Administrator kennt zur Installationszeit die Semantik der Methoden nicht. Wer soll also den COM Catalog „füllen“? Lösung: eine zusätzliche Indirektionsstufe 56 COM+ Roles 57 Abschnitt 3.4 Identity 58 Client Identity Per Default benutzt der Client das Token des Prozesses für alle ausgehenden Aufrufe. Thread (impersonation) Tokens werden nicht verwendet Aber das Verhalten kann man ändern. 59 Impersonation im Bild server.exe Joe client.exe Alice Alice client.exe Bob Bob 60 Per-Proxy Client Identity Die Identity kann für jeden Proxy verändert werden interface IClientSecurity : Iunknown { HRESULT QueryBlanket( ... ); HRESULT SetBlanket( IUnknown* pProxy, ..., void* pAuthInfo, DWORD dwCapabilities ); HRESULT CopyProxy( ... ); } 61 Explizit Die Identity kann explizit gesetzt werden • Für NTLM und Kerberos ist die folgende Struktur zu verwenden (für pAuthInfo in SetBlanket) struct SEC_WINNT_AUTH_IDENTITY_W { unsigned short* User; unsigned long UserLength; unsigned short* Domain; unsigned long DomainLength; unsigned short* Password; unsigned long PasswordLength; unsigned long Flags; }; 62 Cloaking (W2K) Eine andere Art ist das sogenannte Cloaking Cloaking inspiziert das aktuelle Thread Token und kopiert die Daten in den Proxy Aufrufen von IClientSecurity::SetBlanket mit entsprechendem Parameter für dwCapabilities • • EOAC_STATIC_CLOAKING EOAC_DYNAMIC_CLOAKING 63 Aktivierung Was tun die Aktivierungs-Aufrufe • • • Der COM SCM erzeugt die Objekte stellvertretend für den Aufrufer • CoCreateInstanceEx CoGetClassObject CoGetInstanceFromFile Impersoniert den Client Nutzt ebenfalls das Process Token Clients habe die Möglichkeit dies mit Hilfe von COAUTHINFO zu überschreiben 64 COAUTHINFO struct COAUTHINFO { DWORD DWORD WCHAR* DWORD DWORD COAUTHIDENTITY* DWORD }; dwAuthnSvc; dwAuthzSvc; pszServerPrincipalName; dwAuthnLevel; dwImpLevel; pAuthIdentityData; dwCapabilities; 65 Client Identity Zusammenfassung Jeder COM Aufruf nutzt das Process Token als Identität des Aufrufers Einzelne Interface Proxies können dies überschreiben • • Explizit durch Angabe der Credentials Über Cloaking (NT5) Aktivierung von COM Objekten ebenfalls mit expliziter Angabe einer anderen Identity möglich • COM SCM impersoniert 66 Server Identity COM SCM startet den COM Server Prozess via CreateProcessAsUser CreateProcessAsUser verlangt ein Token Drei Möglichkeiten für dieses Token Welche Möglichkeit verwendet wird steht in der Registry • • HKCR/AppID/{appid} RunAs=“…” 67 “As Activator” RunAs-Key ist nicht vorhanden COM SCM startet den Prozess mit dem Client Token Client muss dazu authentifiziert werden Jeder Client bekommt einen eigenen Server Prozess • Schlecht für die Performance • Nur sehr schwer möglich Resourcen gemeinsam zu nutzen Falls es sich um einen Remote Client handelt, hat der Server keine „network credentials“ • Kann mit Delegation in W2K umgangen werden • Wird allgemein als schlecht angesehen 68 “Interactive User” RunAs=“Interactive User” COM SCM startet den Prozess mit dem Token des momentan angemeldeten Benutzers Sehr nützlich fürs Debuggen • • Server hat „network credentials“ Ein Server Prozess für alle Clients Server ist in der Lage Fenster zu erzeugen • Z.B. für ASSERT oder MsgBox Nicht besonders nützlich für Release Version Ohne einen angemeldeten Benutzer schlagen alle Aktivierungsaufrufe fehl. Server Prozess muss mit allen möglichen Benutzern rechnen 69 “Distinguished Principal” RunAs=“Authority\Principal „ COM SCM ruft LogonUser auf um ein Token zu erzeugen. Ideal für Release Version • • • • Server hat „network credentials“ des ausgewählten Benutzers Ein Serverprozess für alle Clients Eindeutiger Account erlaubt es die Rechte/Privilegien genau zu kontrollieren Läuft auch im Hintergrund Nicht unbedingt für Debugging geeignet • CoRegisterClassObject macht evtl. Probleme Password wird als „LSA secret“ gespeichert • Dies muss von Hand aktualisiert werden 70 Impersonation Level Es ist möglich die Benutzung des so erhaltenen Tokens einzuschränken • • Anonymous wird nicht unterstützt Delegate geht nur mit Kerberos RPC_C_IMP_LEVEL_ANONYMOUS RPC_C_IMP_LEVEL_IDENTIFY RPC_C_IMP_LEVEL_IMPERSONATE RPC_C_IMP_LEVEL_DELEGATE 71 CoInitializeSecurity Der Client setzt den Default Impersonation Level mit CoInitializeSecurity HRESULT CoInitializeSecurity( SECURITY_DESCRIPTOR* pSD, DWORD cAuthSvc, SOLE_AUTHENTICATION_SERVICE *prgAuthSvc, void* pvReserved1, DWORD dwAuthnLevel, DWORD dwImpLevel, void* pvReserved2, DWORD dwCapabilities, void* pvReserved3 ); 72 IClientSecurity & Imp. Level Der Client kann die Einstellung für jeden Proxy ändern interface IClientSecurity : IUnknown { HRESULT QueryBlanket( IUnknown* pProxy, DWORD* pAuthnSvc, DWORD* pAuthzSvc, OLECHAR** pServerPrincName, DWORD* pAuthnLevel, DWORD* pImpLevel, void** ppAuthInfo, DWORD* pCapabilites ); HRESULT DWORD DWORD void* SetBlanket( IUnknown* pProxy, DWORD AuthnSvc, AuthzSvc, OLECHAR* pServerPrincName, AuthnLevel, DWORD ImpLevel, pAuthInfo, DWORD Capabilities ); HRESULT CopyProxy( IUnknown* pProxy, IUnknown** ppCopy ); } 73 Abschnitt 4 74 Do’s and Don’ts 1/3 Do • • • Sichern Sie Ihre Server ;-) Security während (vor) des Designs bedenken „Configure Security“ • • • Role Based Security spart Arbeit ‚Interactive user‘ fürs Debugging ‚This user‘ fürs Deployment 75 Do’s and Don’ts 2/3 Don´t • • • • Erfinden Sie kein eigenes “security system” Vergessen Sie nicht CoInitializeSecurity() aufzurufen Vorsicht bei der Verwendung von Impersonation • Skalierbarkeit Versuchen Sie CoInitializeSecurity() >= CONNECT zu vermeiden • Die Authentifizierung des Servers schlägt evtl. fehl 76 Do’s and Don’ts 3/3 Don´t • Versuchen Sie “callbacks” zum Client zu vermeiden (falls möglich) • Falls nötig: CoInitializeSecurity() mit Authn Level NONE ist die beste Wahl 77 Fragen? Fragen & Antworten Presentation Layer 78 Wo gibt’s weitere Info’s? MSDN online • http://www.microsoft.com/germany/msdn MSDN TechTalk-Newsgroup • msnews.microsoft.com microsoft.public.de.german.techtalk Web Seiten • • • COM Security in Practice • http://msdn.microsoft.com/library/techart/msdn_practicom.h tm KeithBrown COM Security FAQ • http://www.develop.com/kbrown COM Security FAQ • http://support.microsoft.com/ support/kb/articles/Q158/5/08.asp 79 Wo gibt’s weitere Info’s? Bücher • • • • Keith Brown: Programming Windows Security • http://www.develop.com/kbrown Don Box: Essential COM Solomon, Russinovich: Inside Windows 2000 • http://www.sysinternals.com Kaufman, Perlman, Spencier: Network Security 80