• No results found

Methods of Linux Kernel Hacking

N/A
N/A
Protected

Academic year: 2021

Share "Methods of Linux Kernel Hacking"

Copied!
74
0
0

Loading.... (view fulltext now)

Full text

(1)

VYSOK ´

E U ˇ

CEN´I TECHNICK ´

E V BRN ˇ

E

BRNO UNIVERSITY OF TECHNOLOGY

FAKULTA INFORMA ˇ

CN´ICH TECHNOLOGI´I

´

USTAV INTELIGENTN´ICH SYST ´

EM ˚

U

FACULTY OF INFORMATION TECHNOLOGY DEPARTMENT OF INTELLIGENT SYSTEMS

METODY ´

UTOK ˚

U NA OPERA ˇ

CN´I SYST ´

EM LINUX

BAKAL ´

A ˇ

RSK ´

A PR ´

ACE

BACHELOR’S THESIS

AUTOR PR ´

ACE

BORIS PROCH ´

AZKA

AUTHOR

(2)

VYSOK ´

E U ˇ

CEN´I TECHNICK ´

E V BRN ˇ

E

BRNO UNIVERSITY OF TECHNOLOGY

FAKULTA INFORMA ˇ

CN´ICH TECHNOLOGI´I

´

USTAV INTELIGENTN´ICH SYST ´

EM ˚

U

FACULTY OF INFORMATION TECHNOLOGY DEPARTMENT OF INTELLIGENT SYSTEMS

METODY ´

UTOK ˚

U NA OPERA ˇ

CN´I SYST ´

EM LINUX

METHODS OF LINUX KERNEL HACKING

BAKAL ´

A ˇ

RSK ´

A PR ´

ACE

BACHELOR’S THESIS

AUTOR PR ´

ACE

BORIS PROCH ´

AZKA

AUTHOR

VEDOUC´I PR ´

ACE

Doc. Ing. TOM ´

A ˇ

S VOJNAR, Ph.D.

SUPERVISOR

(3)
(4)
(5)

Abstrakt

Tato bakal´aˇrsk´a pr´ace se zamˇeˇruje na bezpeˇcnost Linuxov´eho j´adra z ´utoˇcn´ıkova po-hledu. Snaˇz´ı se identifikovat a zmapovat veˇsker´e charakteristick´e rysy a metody pouˇz´ıvan´e dneˇsn´ımi poˇc´ıtaˇcov´ymi pir´aty. Jedn´ım z c´ıl˚u t´eto pr´ace je poskytnout komplexn´ı pohled na danou problematiku. Ve v´ysledku tak m˚uˇze slouˇzit jako mal´a referenˇcn´ı pˇr´ıruˇcka komukoliv, kdo m´a z´ajem o rozˇs´ıˇren´ı znalost´ı z oblasti jadern´e bezpeˇcnosti.

Pr´ace se skl´ad´a ze ˇctyˇr ˇc´ast´ı. Prvn´ı opakuje a definuje nejz´akladnˇejˇs´ı pojmy a ˇclenˇen´ı z oblasti operaˇcn´ıch syst´em˚u. Druh´a a tˇret´ı ˇc´ast tvoˇr´ı j´adro pr´ace. Zahrnuj´ı principy a metody pouˇz´ıvan´e pro skryt´ı proces˚u, soubor˚u, spojen´ı apod. Posledn´ı kapitola je vˇenov´ana dopro-vodn´ym t´emat˚um. Pˇr´ılohou k t´eto bakal´aˇrsk´e pr´aci je skupina jadern´ym modul˚u, kter´e demonstruj´ı diskutovan´e probl´emy, a tabulky, porovn´avaj´ıc´ı souˇcasn´e rootkity.

Kl´ıˇ

cov´

a slova

poˇc´ıtaˇcov´a bezpeˇcnost, Linuxov´e j´adro, rootkit, operaˇcn´ı syst´em, syst´emov´e vol´an´ı, virtu´aln´ı souborov´y syst´em, metody naruˇsen´ı j´adra, IA-32, i386

Abstract

This bachelor thesis focuses on the Linux kernel security from the attacker perspective. It tries to identify and map all key features and methods used by nowadays cyber-terrorists. One of its aims is to give a comprehensive overview of this topic. At final, it can serve as a small reference for everybody who wants to broaden his knowledge of Linux kernel security. The work consists of four parts. The first part repeats and defines basic notions and taxonomy of operation systems. The second and third part form the core. They cover principles and methods used to hide processes, files, connections, etc. The last chaper is devoted to related issues. A supplement of this bachelor thesis is a set of demonstrating modules, which implement discussed problems involved, and tables, where can be found a comparison of nowadays rootkits.

Keywords

computer security, Linux kernel, rootkit, operating system, system call, virtual filesys-tem, methods of kernel intrusion , IA-32, i386

Citace

Boris Proch´azka: Metody ´utok˚u na operaˇcn´ı syst´em Linux, bakal´aˇrsk´a pr´ace, Brno, FIT VUT v Brnˇe, 2008

(6)

Metody ´

utok˚

u na operaˇ

cn´ı syst´

em Linux

Prohl´

sen´ı

Prohlaˇsuji, ˇze jsem tuto bakal´aˇrskou pr´aci vypracoval samostatnˇe pod veden´ım pana doc. Ing. Tom´aˇse Vojnara Ph.D. Uvedl jsem vˇsechny liter´arn´ı prameny a publikace, ze kter´ych jsem ˇcerpal.

. . . . Boris Proch´azka

9. kvˇetna 2008

Podˇ

ekov´

an´ı

T´ımto bych r´ad podˇekoval panu doc. Ing. Tom´aˇsi Vojnarovi Ph.D. za peˇclivou kont-rolu m´ych text˚u, odborn´e konzultace a v neposledn´ı ˇradˇe vstˇr´ıcnost pˇri v´ybˇeru t´ematu m´e bakal´aˇrsk´e pr´ace.

c

Boris Proch´azka, 2008.

Tato pr´ace vznikla jako ˇskoln´ı d´ılo na Vysok´em uˇcen´ı technick´em v Brnˇe, Fakultˇe in-formaˇcn´ıch technologi´ı. Pr´ace je chr´anˇena autorsk´ym z´akonem a jej´ı uˇzit´ı bez udˇelen´ı opr´avnˇen´ı autorem je nez´akonn´e, s v´yjimkou z´akonem definovan´ych pˇr´ıpad˚u.

(7)

Obsah

´ Uvod 3 1 Operaˇcn´ı syst´em 5 1.1 Z´akladn´ı pojmy . . . 5 1.2 Linux . . . 8

1.2.1 Pouˇzit´a architektura a verze j´adra . . . 9

1.2.2 Uˇzivatelsk´y pamˇet’ov´y prostor . . . 9

1.2.3 Rozhran´ı syst´emov´ych vol´an´ı . . . 10

1.2.4 Jadern´y pamˇet’ov´y prostor . . . 10

1.3 Programov´an´ı v j´adˇre . . . 13

2 Principy ´utok˚u na Linux 16 Doprovodn´e programy . . . 16

Moˇznosti obrany a detekce . . . 18

2.1 Ran´a ´era . . . 18

2.1.1 Nahrazov´an´ı utilit . . . 18

2.1.2 Nahrazov´an´ı knihoven – preload . . . 18

2.2 Modern´ı ´era . . . 19

2.2.1 Napaden´ı rozhran´ı syst´emov´ych vol´an´ı . . . 19

2.2.2 Napaden´ı virtu´aln´ıho souborov´eho syst´emu . . . 26

3 Metody skr´yv´an´ı prostˇredk˚u, zdroj˚u a z´ısk´av´an´ı informac´ı o syst´emu 30 3.1 Skr´yv´an´ı proces˚u . . . 30

3.1.1 Syst´emov´e vol´an´ı sys getdents{64} . . . 30

3.1.2 Souborov´a operace vfs readdir . . . 31

3.1.3 Pl´anovaˇc . . . 32

3.2 Skr´yv´an´ı adres´aˇr˚u a soubor˚u . . . 33

3.2.1 Syst´emov´e vol´an´ı sys getdents{64} . . . 33

3.2.2 Souborov´a operace vfs readdir . . . 34

3.3 Skr´yv´an´ı z´aznam˚u v souborech . . . 34

3.3.1 Syst´emov´e vol´an´ı sys read . . . 34

3.3.2 Souborov´a operace vfs read . . . 35

3.4 Skr´yv´an´ı spojen´ı . . . 36

3.4.1 Adres´aˇr /proc/net . . . 36

3.4.2 Alternativy . . . 36

3.5 Pˇresmˇerov´an´ı spouˇstˇen´eho programu . . . 37

3.5.1 Syst´emov´e vol´an´ı sys execve . . . 37

(8)

3.5.3 Funkce open exec . . . 37

3.5.4 Funkce load binary . . . 38

3.6 Odposlech . . . 38

3.6.1 Odposlech stisknut´ych kl´aves (keylogging) . . . 39

3.6.2 Odposlech syst´emov´ych funkc´ı sys read/write() . . . 41

4 Infiltrace a pˇretrv´an´ı v OS 42 4.1 Infiltrace j´adra . . . 42

4.1.1 Moduly . . . 42

4.1.2 Obraz pamˇeti – soubory /dev/{k}mem . . . 44

4.1.3 Pˇrilinkov´an´ı k jadern´emu souboru . . . 45

4.2 Znovuspuˇstˇen´ı . . . 46

4.3 Komunikaˇcn´ı rozhran´ı s jadern´ym prostorem . . . 48

Z´avˇer 50

Seznam pouˇzit´ych zdroj˚u 54

Seznam pouˇzit´ych zkratek a symbol˚u 55

Seznam pˇr´ıloh 56

A V´ystupy demonstraˇcn´ıch program˚u 57

B Rejstˇr´ık symbol˚u 64

(9)

´

Uvod

Linux je od sv´eho poˇc´atku povaˇzov´an za jeden z nejprogresivnˇejˇs´ıch pˇredstavitel˚u z ˇrady existuj´ıc´ıch operaˇcn´ıch syst´em˚u. Je zn´am svoj´ı vysokou kvalitou n´avrhu, flexibilitou v´yvoje a velkou program´atorskou z´akladnou. Za dobu sv´e existence si naˇsel cestu t´emˇeˇr do vˇsech zaˇr´ızen´ı, kter´e lze nazvat v´ypoˇcetn´ım prostˇredkem.

D´ıky sv´e politice otevˇren´eho zdrojov´eho k´odu nab´ız´ı kaˇzd´emu moˇznost j´adro mˇenit, vylepˇsovat a experimentovat s n´ım. Ty nejlepˇs´ı ´upravy pak proch´azej´ı schvalovac´ım proce-sem zaˇclenˇen´ı do ofici´aln´ı verze j´adra. Strukturu j´adra ale m˚uˇzeme povaˇzovat i za jakousi d˚uvˇernou informaci, kter´a je vˇsak kaˇzd´emu pˇr´ıstupn´a. Pro ´utoˇcn´ıka maj´ı jadern´e k´ody po-dobnou v´ahu jako stavebn´ı pl´any banky pro bankovn´ıho zlodˇeje. Naˇs´ım

”stavebn´ım pl´anem“ tedy budou zdrojov´e k´ody j´adra a naˇs´ım c´ılem bude identifikace zraniteln´ych m´ıst

” velko-lep´e stavby“ – j´adra.

Pr´ace se skl´ad´a ze ˇctyˇr kapitol. Prvn´ı definuje z´akladn´ı pojmy, s kter´ymi budeme po zbytek pr´ace pracovat a pˇrin´aˇs´ı zasazen´ı diskutovan´e problematiky do ˇsirˇs´ıho kontextu. Popisuje architektonickou strukturu Linuxov´eho j´adra, kterou ˇclen´ı na pˇet samostatn´ych podsyst´em˚u, a vysvˇetluje rozd´ıl mezi uˇzivatelsk´ym a jadern´ym prostorem. Z´avˇer prvn´ı kapitoly je vˇenov´an zp˚usobu psan´ı jadern´ych program˚u.

Druh´a a tˇret´ı kapitola tvoˇr´ı j´adro bakal´aˇrsk´e pr´ace. Pˇri vytv´aˇren´ı vlastn´ı klasifikace jsem se rozhodl oddˇelit princip ´utoku (jak´ym zp˚usobem je ´utok veden) od c´ıle ´utoku (jak´a sluˇzba je ´utokem zasaˇzena). Vznik´a tak unik´atn´ı kategorizace princip˚u, kter´a je zachycena v druh´e kapitole. Kaˇzd´a kategorie obsahuje demonstraˇcn´ı program, kter´y byl navrhnut speci´alnˇe pro ovˇeˇren´ı platnosti kaˇzd´eho z princip˚u. D´ıky podrobn´emu studiu rozhran´ı syst´emov´ych vol´an´ı byl objeven i princip nov´y. Souˇc´ast´ı kapitoly je pr˚ubˇeˇzn´a diskuze z´akladn´ıch v´yhod a nev´yhod jednotliv´ych pˇr´ıstup˚u vˇcetnˇe zp˚usob˚u detekce a obrany.

Tˇret´ı kapitola pokr´yv´a ´utoky na samostatn´e syst´emov´e sluˇzby. Jedn´a se o ´utoky na proces, adres´aˇre a soubory, spojen´ı, aplikace a odposlech. U kaˇzd´eho ´utoku jsou vysvˇetleny alternativy a probl´em je implementov´an jedn´ım z princip˚u kapitoly dvˇe. Vznik´a tak dalˇs´ı skupina experiment´aln´ıch program˚u. Kapitola pokraˇcuje v diskuzi siln´ych a slab´ych str´anek jednotliv´ych pˇr´ıstup˚u.

Posledn´ı kapitola pokr´yv´a t´emata, kter´a m˚uˇzeme oznaˇcit jako doprovodn´a. Obsahuje zp˚usoby zav´adˇen´ı k´odu do j´adra a ˇreˇsen´ı probl´em˚u spojen´ych s restartov´an´ım napaden´eho syst´emu. ˇC´ast prostoru je vˇenov´ano komunikaˇcn´ım rozhran´ım rootkit˚u. Kapitola obsahuje ˇ

ctyˇri doprovodn´e programy.

Ve v´ysledku vznikla sada tˇriceti vlastn´ıch demonstraˇcn´ıch program˚u (z toho dvacet osm jadern´ych modul˚u), kter´e jsou naprogramov´any uniformn´ım zp˚usobem. Podporuj´ı pocho-pen´ı prob´ıran´eho textu a mohou slouˇzit jako v´ychodisko pro dalˇs´ı v´yvojovou etapu. Jejich seznam je souˇc´ast´ı pˇr´ılohy A, na kterou se text na ˇradˇe m´ıst odvol´av´a.

Pˇri studiu a tvorbˇe t´eto pr´ace mi byly neoceniteln´ym pomocn´ıkem pˇredevˇs´ım publi-kace [1, 2, 3] a zdrojov´e k´ody Linuxov´eho j´adra. Pro snazˇs´ı orientaci v jadern´em k´odu byl

(10)

vytvoˇren podrobn´y rejstˇr´ık symbol˚u, kter´y se nach´az´ı v pˇr´ıloze B. Usnadˇnuje vyhled´av´an´ı definic jadern´ych funkc´ı a struktur, kter´e jsou v pr´aci pouˇzity.

Jednou z motivac´ı pr´ace bylo porovnat vlastnosti a kvalitu veˇrejnˇe dostupn´ych rootkit˚u. V´ysledky tohoto ´ukolu lze nal´ezt v tabulk´ach pˇr´ılohy C. Tabulky jsou navrˇzeny tak, aby reflektovaly poˇrad´ı znalost´ı z´ıskan´ych pˇri ˇcetbˇe t´eto bakal´aˇrsk´e pr´ace. Lze je tedy studovat i pr˚ubˇeˇznˇe.

(11)

Kapitola 1

Operaˇ

cn´ı syst´

em

´

Uvodn´ı kapitola je rozˇclenˇena na tˇri podkapitoly. Prvn´ı definuje a opakuje z´akladn´ı pojmy z oblasti operaˇcn´ıch syst´em˚u. Druh´a podkapitola se vˇenuje struktuˇre Linuxov´eho j´adra. ˇClen´ı ho na pˇet podsyst´em˚u a kaˇzd´y ve struˇcnosti charakterizuje. Podrobnˇe se zab´yv´a rozd´ılem mezi uˇzivatelsk´ym a jadern´ym reˇzimem. Posledn´ı podkapitola shrnuje pravidla pro psan´ı program˚u, bˇeˇz´ıc´ıch v jadern´em adresov´em prostoru.

1.1

akladn´ı pojmy

Operaˇcn´ı syst´em m´a v z´akladn´ı hierarchii kaˇzd´eho v´ypoˇcetn´ıho syst´emu v´yraznou a niˇc´ım nenahraditelnou roli. Ze sv´e pozice (obr. 1.1) m´a za ´ukol vytvoˇrit spojuj´ıc´ı vrstvu mezi hardware poˇc´ıtaˇce a uˇzivatelsk´ymi aplikaˇcn´ımi programy. M˚uˇze b´yt ch´ap´an v uˇzˇs´ım a ˇsirˇs´ım slova smyslu – od samotn´eho j´adra aˇz po kolekci program˚u nutn´ych pro bezprobl´emov´y provoz cel´eho syst´emu. Z pohledu t´eto pr´ace se n´am hod´ı definice ˇsirˇs´ı, nebot’ naˇs´ım c´ılem je identifikovat zraniteln´a m´ısta syst´emu jako celku.

uživatel

aplikační prog.

operační systém

hardware

Obr´azek 1.1: Z´akladn´ı hierarchie v´ypoˇcetn´ıho syst´emu

J´adro, jakoˇzto stˇeˇzejn´ı prvek, je zavedeno pˇri spuˇstˇen´ı prvn´ı1 a bˇeˇz´ı po celou dobu bˇehu v´ypoˇcetn´ıho syst´emu. Reˇzie zp˚usoben´a bˇeˇz´ıc´ım j´adrem je n´am kompenzov´ana n´asleduj´ıc´ımi sluˇzbami [4]:

• spr´avce prostˇredk˚u – dovoluje prostˇredky (procesory, pamˇet’ a ostatn´ı periferie) sd´ılet efektivnˇe a t´ım maxim´alnˇe vyuˇz´ıvat poˇc´ıtaˇcov´e zdroje. D˚uleˇzitou roli hraje i v bezpeˇcnostn´ı politice cel´eho syst´emu, nebot’ j´adro mus´ı z d˚uvodu pˇr´ım´e komunikace s hardware bˇeˇzet v privilegovan´em reˇzimu (kap. 1.2.3).

1

(12)

• tv˚urce prostˇred´ı – vytv´aˇr´ı standardn´ı rozhran´ı pro uˇzivatelsk´e aplikaˇcn´ı programy. Podporuje t´ım pˇrenositelnost aplikac´ı napˇr´ıˇc r˚uzn´ymi operaˇcn´ımi syst´emy. Z´aroveˇn vytv´aˇr´ı z´akladn´ı abstrakce jako je proces, soubor nebo virtu´aln´ı pamˇet’.

Proces je v odborn´ych publikac´ıch typicky definov´an jako

”an instance of a program in execution“ [2] , coˇz volnˇe znamen´a bˇeˇz´ıc´ı program. ˇCasto je tak´e oznaˇcov´an jako ´uloha. Z naˇseho pohledu bude ch´ap´an jako kolekce datov´ych struktur, kter´e popisuj´ı aktu´aln´ı stav spuˇstˇen´eho programu.

K tomu, aby mohl proces bˇeˇzet, potˇrebuje ˇcas od ˇcasu obsadit centr´aln´ı v´ypoˇcetn´ı jednotku. Ta se m˚uˇze nach´azet pr´avˇe v jednom z n´asleduj´ıc´ıch stav˚u:

• CPU bˇeˇz´ıc´ı v uˇzivatelsk´em prostoru,

• CPU bˇeˇz´ıc´ı v jadern´em prostoru po syst´emov´em vol´an´ı, • CPU bˇeˇz´ıc´ı v jadern´em prostoru po pˇreruˇsen´ı.

Zat´ımco prvn´ı dva pˇr´ıpady jsou ´uzce sv´az´any s pr´avˇe prob´ıhaj´ıc´ım procesem, u po-sledn´ıho tomu tak vˇetˇsinou nen´ı.

V´ıce´ulohov´y operaˇcn´ı syst´em umoˇzˇnuje prov´adˇet nˇekolik ´uloh souˇcasnˇe. Tato schopnost je anglicky naz´yv´ana jako multitasking. Multitasking m˚uˇze b´yt realizov´an dvˇema z´akladn´ımi zp˚usoby [5]:

1. zd´anliv´y – vytv´aˇr´ı se pouze dojem souˇcasn´eho bˇehu rychl´ym pˇrep´ın´an´ım ´uloh. Vych´az´ı ze skuteˇcnosti, ˇze pouze jedna ´uloha m˚uˇze v dan´y okamˇzik obsadit procesor. Podle zp˚usobu pˇridˇelov´an´ı a odeb´ır´an´ı ˇcasov´ych kvant d´ale rozliˇsujeme:

(a) kooperativn´ı (nepreemptivn´ı) – vyˇzaduje aktivn´ı spolupr´aci pr´avˇe bˇeˇz´ıc´ıch ´

uloh. Kaˇzd´a ´uloha mus´ı dostateˇcnˇe ˇcasto pˇred´avat ˇr´ızen´ı zpˇet operaˇcn´ımu syst´ e-mu, aby mohl rozhodnout o dalˇs´ım pˇridˇelen´ı v´ypoˇcetn´ıch prostˇredk˚u. Z´asadn´ı nev´yhoda tohoto pˇr´ıstupnu spoˇc´ıv´a v moˇznosti zastaven´ı syst´emu ˇspatnˇe napro-gramovanou ´ulohou2.

(b) preemptivn´ı – pˇridˇelov´an´ı a odeb´ır´an´ı procesoru m´a plnˇe v kompetenci operaˇcn´ı syst´em a dˇeje se tak v pravideln´ych intervalech na z´akladˇe pˇredem definovan´eho algoritmu. I v tomto pˇr´ıpadˇe se m˚uˇze pr´avˇe prov´adˇen´a ´uloha dobrovolnˇe vzd´at pˇridˇelen´eho v´ypoˇcetn´ıho ˇcasu – typicky ˇcek´an´ım na dokonˇcen´ı vstup-v´ystupn´ı operace. Oproti nepreemptivn´ı variantˇe je sloˇzitˇejˇs´ı na implementaci a vyˇzaduje v´yraznˇejˇs´ı hardwarovou podporu.

2. skuteˇcn´y – vyˇzaduje plnou hardwarovou podporu (v´ıce procesor˚u).

Soubor je pojmenovan´a uspoˇr´adan´a kolekce dat uloˇzen´a na datov´em nosiˇci. Mezi charak-teristick´e atributy patˇr´ı typ, d´elka, ˇcasov´e a vlastnick´e ´udaje, uˇzivatelsk´a opr´avnˇen´ı apod. Kolekci soubor˚u pak naz´yv´ame adres´aˇr. O jejich fyzickou reprezentaci na datov´em nosiˇci se star´a podsyst´em operaˇcn´ıho syst´emu – syst´em soubor˚u (kap. 1.2.4).

2

Bohat´e vyuˇzit´ı vˇsak nach´az´ı ve spojen´ı s vestavˇen´ymi syst´emy, kde jsou ´ulohy podrobeny komplexn´ı anal´yze.

(13)

Virtu´aln´ı pamˇet’ je zp˚usob spr´avy pamˇeti poˇc´ıtaˇce za ´uˇcelem vyuˇzit´ı v´ıce vnitˇrn´ı pamˇeti, neˇz je skuteˇcnˇe k dispozici. V modern´ıch operaˇcn´ıch syst´emech tvoˇr´ı nejd˚uleˇzitˇejˇs´ı pod-syst´em – spr´ava pamˇeti (kap. 1.2.4).

V´ıceuˇzivatelsk´y operaˇcn´ı syst´em m´a prostˇredky pro vytvoˇren´ı pracovn´ıho prostˇred´ı pro v´ıce jak jednoho uˇzivatele. Mus´ı obsahovat autentizaˇcn´ı mechanizmy pro ovˇeˇren´ı identity uˇzivatele a udrˇzet je v bezpeˇc´ı pˇred neˇz´adouc´ımi vlivy uˇzivatel˚u ostatn´ıch – od naruˇsen´ı soukrom´ı aˇz po neadekv´atn´ı vyuˇz´ıv´an´ı v´ypoˇcetn´ıch prostˇredk˚u.

Druhy jader rozliˇsujeme podle mnoˇzstv´ı k´odu vykon´avan´eho v jadern´em adresov´em pro-storu (obr. 1.2) a mnoˇzstv´ı sluˇzeb a abstrakc´ı, kter´e n´am poskytuje. Nejbˇeˇznˇejˇs´ı ˇclenˇen´ı [4, 5] je na:

• Monolitick´a j´adra. Veˇsker´y k´od bˇeˇz´ı v jadern´em adresov´em prostoru a nab´ız´ı vy-soko´urovˇnov´e rozhran´ı s velk´ym mnoˇzstv´ım sluˇzeb a abstrakc´ı. Podsyst´emy j´adra jsou ´

uzce propojeny, coˇz umoˇzˇnuje maxim´aln´ı moˇznou efektivitu bˇehu j´adra. Na druhou stranu chyba jedin´eho podsyst´emu m˚uˇze ohrozit bezpeˇcnost a stabilitu syst´emu jako celku. Aby bylo moˇzn´e rozˇsiˇrovat j´adro za bˇehu bez nutnosti restartu, vˇetˇsina mo-nolitick´ych jader podporuje dynamick´e nahr´av´an´ı modul˚u. Jakmile je modul jednou zaveden, st´av´a se plnohodnotnou souˇc´ast´ı j´adra a m˚uˇze k j´adru pˇristupovat libovoln´ym zp˚usobem. Tato vlastnost m˚uˇze b´yt velice snadnou cestou k modifikaci bˇeˇz´ıc´ıho j´adra (kap. 4.1.1).

• Mikroj´adra. Snaˇz´ı se minimalizovat mnoˇzstv´ı k´odu bˇeˇz´ıc´ıho v jadern´em adresov´em prostoru a poskytuje pouze z´akladn´ı rozhran´ı, sluˇzby a abstrakce. Vˇse ostatn´ı je pˇresunuto do uˇzivatelsk´eho pamˇet’ov´eho prostoru do tzv. server˚u. Koncept mikro-jader nar´aˇz´ı pˇredevˇs´ım na nutnost vyˇsˇs´ı reˇzie z d˚uvod˚u ˇcastˇejˇs´ıch syst´emov´ych vol´an´ı a t´ım spojen´ych zmˇen kontext˚u. Pˇrin´aˇs´ı vˇsak lepˇs´ı n´avrh a je bezpeˇcnˇejˇs´ı.

• Hybridn´ı j´adra. Jsou kombinac´ı pˇredeˇsl´ych dvou variant jader. Hlavn´ı nev´yhodu mikrojader se snaˇz´ı eliminovat pˇresunut´ım nˇekter´ych sluˇzeb v podobˇe server˚u (napˇr. souborov´y syst´em) do jadern´eho adresov´eho prostoru.

• Experiment´aln´ı j´adra. Jsou zastoupeny pico, nano ˇci exoj´adry. Vˇetˇsinou se snaˇz´ı zd˚uraznit nˇekter´y z rys˚u mikrojader.

jádro software modul software jádro software servery jádro softwaresoftware servery monolitické

s modulární strukturou mikrojádro hybridní

(14)

1.2

Linux

Koˇreny j´adra spadaj´ı do roku 1991, kdy finsk´y student helsinsk´e univerzity Linus Tor-valds zveˇrejnil prvn´ı verzi sv´eho Linuxu. Vych´azel pˇri tom z Minixu3, coˇz je operaˇcn´ı syst´em Unixov´eho typu urˇcen´y pro podporu v´yuky. Od t´e doby se na v´yvoji Linuxu pod´ılelo tis´ıce v´yvoj´aˇr˚u a j´adro bylo zaˇrazeno do projektu GNU. Zjednoduˇsen´e sch´ema architektury operaˇcn´ıho syst´emu Linux lze zhl´ednout na obr´azku 1.3 a bude diskutov´ano v n´asleduj´ıc´ıch odd´ılech.

Aplikace 1 Aplikace 2

Knihovny

Rozhraní systémových volání

Správa 

procesů Správa paměti souborůSystém  zařízeníSpráva  Síťování

Souběžné  zpracování úloh

Správce  paměti

Virtuální paměť souborový Virtuální  systém Síťové spojení Přístup k  zařízením Ovladače  rozhraní HW závislý  kód Bloková  zařízení Znaková  zařízení Typy  souborových  systémů Síťový  podsystém Charakteristická  vlastnost Podsystém Programová  podpora Jaderný  prostor Uživatelský  prostor Hardware

Procesor Paměť Disk, CD, ... Konzole, ... Síťové  rozhraní

Obr´azek 1.3: Zjednoduˇsen´a architektura operaˇcn´ıho syst´emu Linux

V dneˇsn´ı dobˇe m˚uˇzeme Linux klasifikovat jako typick´eho pˇredstavitele monolitick´ych ja-der s modul´arn´ı podporou. Jedn´a se o v´ıce´ulohov´y a v´ıceuˇzivatelsk´y operaˇcn´ı syst´em s vyni-kaj´ıc´ı souborovou, s´ıt’ovou a v´ıceprocesorovou podporou. Nen´ı proto divu, ˇze sv´e uplatnˇen´ı

3

(15)

nach´azel pˇredevˇs´ım v serverov´ych syst´emech. Moˇznost pˇreruˇsen´ı v jadern´em adresov´em pro-storu4, kter´a byla implementov´ana od verze 2.6, podporuje nasazen´ı tohoto syst´emu i na klasick´e stoln´ı poˇc´ıtaˇce. Hlavn´ı pˇr´ınos spoˇc´ıv´a v rychlejˇs´ıch odezv´ach na uˇzivatelsk´e akce i pˇri vysok´em zat´ıˇzen´ı pracovn´ı stanice.

1.2.1 Pouˇzit´a architektura a verze j´adra

V dalˇs´ım textu budeme pˇredpokl´adat architekturu IA-32, dˇr´ıve oznaˇcovanou jako i386. Jedn´a se o 32bitovou, registrovou architekturu s CISCovou instrukˇcn´ı sadou. Vˇetˇsina do-provodn´ych k´od˚u v tomto textu postr´ad´a z d˚uvod˚u lepˇs´ı ˇcitelnosti typov´e a jin´e kontroly. Implementaˇcn´ı podrobnosti lze nal´ezt ve zdrojov´ych textech jednotliv´ych pˇr´ıklad˚u, kter´e jsou ned´ılnou souˇc´ast´ı t´eto pr´ace. Orientaˇcn´ı v´ystup tˇechto modul˚u je moˇzn´e zhl´ednout v pˇr´ıloze A. Pro z´ajemce o hlubˇs´ı studium obsahuje pˇr´ıloha B tabulku pouˇzit´ych sym-bol˚u a jejich odkaz do zdrojov´ych k´od˚u j´adra. D´ale pˇredpokl´ad´ame pouze jednoproceso-rov´y v´ypoˇcetn´ı prostˇredek. Pouˇzit´e j´adro bylo 2.6.16.59. Pˇres veˇskerou snahu o zachov´an´ı maxim´aln´ı pˇrenositelnosti je nutn´e si uvˇedomit, ˇze nˇekter´e metody a techniky vyuˇz´ıvaj´ı unik´atn´ıch vlastnost´ı t´eto architektury popˇr. verze pouˇzit´eho j´adra. Autor nenese ˇz´adnou zodpovˇednost za pˇr´ıpadn´e ˇskody vznikl´e pˇri experimentov´an´ım s tˇemito jadern´ymi moduly.

1.2.2 Uˇzivatelsk´y pamˇet’ov´y prostor

Uˇzivatelsk´y pamˇet’ov´y prostor se nach´az´ı od adresy 0x00000000 po adresu 0xC00000005a vyplˇnuje prostor o velikosti 3GB. Jedn´a se o virtu´aln´ı adresov´y prostor, kter´y patˇr´ı aplikaci. Aplikace m˚uˇze pouˇz´ıvat pouze tu ˇc´ast virtu´aln´ıho adresov´eho prostoru, kterou si dopˇredu za-alokuje. V pˇr´ıpadˇe, ˇze se pokus´ı zapsat do nealokovan´e pamˇeti, dojde k n´asiln´emu ukonˇcen´ı programu. Kódová oblast Datová oblast BSS Hromada Knihovny Mapované soubory Zásobník Systémová oblast Data 0x C 00 00 00 0 0x FF FF FF FF 0x 08 04 80 00 0x 00 00 00 00 1GB Jaderný paměťový prostor Uživatelský paměťový prostor3GB

Obr´azek 1.4: Mapa pamˇeti

Kaˇzd´y program se skl´ad´a z nˇekolika sekc´ı, kter´e se pˇri zav´adˇen´ı do hlavn´ı operaˇcn´ı pamˇeti mapuj´ı na vhodn´e adresov´e pozice (obr. 1.4). Tyto sekce dˇel´ıme [7, 2] na:

• K´odov´a oblast. Obsahuje spustiteln´y k´od v podobˇe instrukc´ı pro danou architek-turu.

• Datov´a oblast. Obsahuje glob´aln´ı promˇenn´e, kter´e se dˇel´ı podle poˇc´ateˇcn´ı hodnoty na:

4

Takov´e j´adro naz´yv´ame angl. reentrant kernel. 5Hodnotu hraniˇcn´ı adresy urˇcuje symbol

(16)

* BSS. Neinicializovan´e glob´aln´ı promˇenn´e.

* Data. Inicializovan´e glob´aln´ı promˇenn´e. Jsou souˇc´ast´ı spustiteln´eho souboru. • Hromada. Alokovan´a pamˇet’ vznikl´a za chodu programu. Pˇr´ıstup k n´ı je moˇzn´y pouze

pˇres ukazatele a je plnˇe v reˇzii program´atora.

• Knihovny. Jsou skupinou modul˚u, kter´e zajiˇst’uj´ı bˇeˇz´ıc´ım aplikac´ım nejbˇeˇznˇejˇs´ı sluˇzby a snazˇs´ı komunikaci s operaˇcn´ım syst´emem. Jedn´a se pˇredevˇs´ım o vstup-v´ystupn´ı, ˇretˇezcov´e, matematick´e a ˇcasov´e funkce. D´ale pak funkce dynamick´e alokace pamˇeti. • Z´asobn´ık. Obsahuje lok´aln´ı promˇenn´e, parametry funkc´ı a n´avratov´e adresy.

1.2.3 Rozhran´ı syst´emov´ych vol´an´ı

K tomu, aby mohl operaˇcn´ı syst´em Linux vytvoˇrit dostateˇcnˇe bezpeˇcn´e prostˇred´ı pro aplikace a hardware, potˇrebuje ke sv´emu bˇehu procesor s podporou alespoˇn dvou r˚uzn´ych ´

urovn´ı bˇehu. Kdyˇz procesor zpracov´av´a proces, kter´y bˇeˇz´ı v uˇzivatelsk´em pamˇet’ov´em pro-storu, bˇeˇz´ı v tzv. uˇzivatelsk´em reˇzimu. V tomto stavu nem˚uˇze pouˇz´ıvat veˇsker´e instrukce a t´ım m´a regulovan´y pˇr´ıstup k hardware a do pamˇeti. V opaˇcn´em pˇr´ıpadˇe se procesor nach´az´ı v jadern´em pamˇet’ov´em prostoru a bˇeˇz´ı v tzv. jadern´em reˇzimu, kdy m´a dovoleny veˇsker´e operace. K pˇrepnut´ı mezi m´ody m˚uˇze probˇehnout pouze pˇres tzv. syst´emovou br´anu6. Ta je vyvol´ana programem v pˇr´ıpadˇe, ˇze potˇrebuje prov´est operaci, na kterou v uˇzivatelsk´em m´odu nem´a opr´avnˇen´ı (typicky pˇristoupit k hardware).

Hardware Rozhraní hardware Jádro Rozhraní systémových volání Knihovny Rozhraní knihovny Aplikace

Obr´azek 1.5: Hierarchie rozhran´ı

Sluˇzby bˇeˇz´ıc´ı v jadern´em reˇzimu jsou aplikac´ım dostupn´e v´yhradnˇe pˇres rozhran´ı sy-st´emov´ych vol´an´ı. Z obr´azku 1.5 je patrn´e, ˇze toto rozhran´ı tvoˇr´ı z´akladn´ı vrstvu mezi aplikacemi a operaˇcn´ım syst´emem. M˚uˇze b´yt vyvol´ana dvˇema zp˚usoby [4]:

1. pˇr´ımo – z aplikace pˇres specializovanou instrukci (napˇr. softwarov´e pˇreruˇsen´ı) 2. nepˇr´ımo – prostˇrednictv´ım knihovny.

1.2.4 Jadern´y pamˇet’ov´y prostor

Jadern´y pamˇet’ov´y prostor vyplˇnuje zb´yvaj´ıc´ı 1GB pamˇeti od adresy 0xC00000000 po 0xFFFFFFFF (obr. 1.4). Tato pamˇet’ je pˇr´ıstupn´a pouze z tzv. supervizor m´odu7 a aplikace

6

Typ deskriptoru pˇreruˇsen´ı, kter´e m˚uˇze b´yt vyvol´ano z uˇzivatelsk´eho reˇzimu. Jedn´a se o instrukce into, bound a int $0x80.

7´

(17)

ji nemohou pouˇz´ıvat. Nach´az´ı se v n´ı fyzick´a reprezentace cel´eho j´adra. J´adro si m˚uˇzeme rozdˇelit na pˇet z´akladn´ıch podsyst´em˚u podle obr´azku 1.3. Jsou to [3]:

1. Spr´ava proces˚u. M´a za ´ukol vytv´aˇret, spravovat a ruˇsit jednotliv´e procesy. Ty jsou reprezentov´any datov´ymi strukturami, tzv. proces deskriptory (task struct), kter´e jsou prov´az´any pomoc´ı obousmˇernˇe v´azan´eho seznamu. D´ale zajiˇst’uje komunikaci proces˚u s okol´ım a mezi sebou navz´ajem vˇcetnˇe pˇr´ıbuzensk´ych vztah˚u. V´yraznou roli zde zast´av´a O(1) pl´anovaˇc, kter´y urˇcuje, jak´y proces bude bˇeˇzet v n´asleduj´ıc´ı chv´ıli. Rychl´ym stˇr´ıd´an´ım proces˚u vytv´aˇr´ı iluzi souˇcasn´eho bˇehu v´ıce ´uloh. V Linuxu se jedn´a o preemptivn´ı variantu.

2. Spr´ava pamˇeti. Jedn´a se pravdˇepodobnˇe o nejsloˇzitˇejˇs´ı podsyst´em. Jeho hlavn´ım ´

ukolem je pˇreklad logick´e adresy, se kterou pracuje procesor, na adresu fyzickou, kter´a se nach´az´ı v operaˇcn´ı pamˇeti. Jelikoˇz se jedn´a o ˇcastou a sloˇzitou operaci, je ˇc´ast cel´eho pˇrekladov´eho procesu implementov´ana za podpory hardware – MMU8.

Architektura x86 [2, 4, 8, 9, 10] pouˇz´ıv´a segmentaci, kter´a je povinn´a, a str´ankov´an´ı, kter´e je voliteln´e. Syst´em Linux str´ankov´an´ı pouˇz´ıv´a a pˇreklad je tedy prov´adˇen ve dvou kroc´ıch (obr. 1.6):

(a) Pˇrevod logick´e adresy na line´arn´ı za pouˇzit´ı segmentace. Jelikoˇz segmentace nem˚uˇze b´yt u t´eto architektury vynech´ana, zav´ad´ı j´adro jen ty nejnutnˇejˇs´ı seg-menty - k´odov´y a datov´y segment pro jadern´y reˇzim a k´odov´y a datov´y segment pro uˇzivatelsk´y reˇzim. K´odov´y segment je urˇcen pro ˇcten´ı a spouˇstˇen´ı, datov´y segment pak pro ˇcten´ı a z´apis. Vzhledem k tomu, ˇze se k´odov´y i datov´y seg-ment na operaˇcn´ım syst´emu Linux plnˇe pˇrekr´yvaj´ı, jsou data adresov´ana pouze offsetem, at’ uˇz se jedn´a o jak´ykoliv segment. Doch´az´ı tak k splynut´ı logick´e a line´arn´ı adresy a k disjunkci vˇsech operac´ı, kter´e maj´ı segmenty nastaveny. Rozd´ıl ´urovn´ı opr´avnˇen´ı

”jadern´ych“ a ”uˇzivatelsk´ych“ segment˚u vˇsak z˚ust´av´a nad´ale zachov´an. Pˇr´ıstup je moˇzn´y pouze tehdy, pokud ´uroveˇn opr´avnˇen´ı nen´ı menˇs´ı neˇz ´uroveˇn opr´avnˇen´ı dan´eho segmentu.

(b) Pˇrevod line´arn´ı adresy na fyzickou neboli str´anku na r´amec za pouˇzit´ı str´ankov´an´ı. K pˇrekladu slouˇz´ı horn´ıch 20 bit˚u, kter´e jsou rozdˇeleny na dvˇe ˇc´asti po 10 bitech9–indexy do dvoj´urovˇnov´eho str´ankovac´ıho mechanizmu. Doln´ıch 12 bit˚u10 je zachov´ano a tvoˇr´ı posunut´ı ve str´ance/r´amci. Poloˇzka tabulky str´anek obsahuje krom ˇc´ısla r´amce jeˇstˇe dalˇs´ı reˇzijn´ı informace. Jedn´a se napˇr. o pr´avo k z´apisu, je-li str´anka v operaˇcn´ı pamˇeti, z´akladn´ı kontrola pˇr´ıstupu atd. Chyb´ı moˇznost zak´azat spuˇstˇen´ı instrukc´ı. Z v´yˇse uveden´eho vypl´yv´a, ˇze cel´y virtu´aln´ı adresn´ı prostor je pˇr´ıstupn´y pro ˇcten´ı a spouˇstˇen´ı. ˇC´ast pak i s moˇznost´ı z´apisu. Pˇredevˇs´ım d´ıky str´ankov´an´ı m˚uˇze operaˇcn´ı syst´em vyuˇz´ıvat svoji operaˇcn´ı pamˇet’ velice efektivnˇe. Umoˇzˇnuje totiˇz spustit nˇekolik proces˚u soubˇeˇznˇe a nahr´at pouze ty str´anky, kter´e jsou opravdu potˇreba. D´ıky tomu je moˇzn´e spustit i aplikace, kter´e vyˇzaduj´ı v´ıce pamˇeti, neˇz je skuteˇcnˇe k dispozici. Str´anky je moˇzn´e jednoduˇse sd´ılet, coˇz se vyuˇz´ıv´a pˇri mapov´an´ı knihoven a rychl´e meziprocesov´e komunikaci. Z´aroveˇn podporuje pˇrenositelnost, nebot’ procesy se ˇz´adn´ym zp˚usobem nestaraj´ı o fyzickou organizaci v pamˇeti.

8MMU je zkr. Memory management unit. 9

Adres´aˇr nebo tabulka str´anek jsou pole s 1024 z´aznamy. 10

(18)

Rámce stránek

+

+

RÁMEC OFFSET

+

ADRESÁŘ STRÁNKA OFFSET

0 11 12 21 22 31 0 11 12 21 22 31 Lineární/Virtuální adresa Fyzická adresa Fyzický adresový prostor Tabulka stránek Adresář stránek OFFSET 0 0 31 15 Logická adresa SELEKTOR gdtr/ldtr CPU registr Tabulka deskriptorů

+

cr3 CPU registr S eg m en ta ce S trá nk ov án í

Obr´azek 1.6: Pˇreklad adres

3. Syst´em soubor˚u. Vych´az´ı ze z´akladn´ı myˇslenky Unixu reprezentovat vˇse11jako sou-bor. Vytv´aˇr´ı t´ım hierarchii abstrakc´ı, tzv. virtu´aln´ı souborov´y syst´em, nad hardware, nebot’ mus´ı odst´ınit r˚uzn´e zp˚usoby pˇr´ıstupu k zaˇr´ızen´ım a zohlednit jejich soubo-rov´y syst´em. V´ysledkem je transparentn´ı pˇr´ıstup pˇres unifikovan´e syst´emov´e rozhran´ı. Jemu podˇr´ızen´e souborov´e syst´emy m˚uˇzeme rozdˇelit [2, 3] na tˇri kategorie (obr. 2.3):

11

(19)

• Diskov´y – spravuje disky a zaˇr´ızen´ı emuluj´ıc´ı jejich chov´an´ı. Mezi nejtypiˇctˇejˇs´ı souborov´e syst´emy tohoto typu patˇr´ı: Ext2, Ext3, ReiserFS (Unix/Linux), FAT, NTFS (Windows), ISO9660, UDF (CD/DVD).

• S´ıt’ov´y – umoˇzˇnuje pˇr´ıstup k soubor˚um uloˇzen´ym na jin´em s´ıt’ov´em poˇc´ıtaˇci. Z´astupci: NFS, Coda, AFS (Unix/Linux), CIFS, Samba (Windows), NCP (No-vell).

• Speci´aln´ı – zajiˇst’uje pˇr´ıstup k datov´ym struktur´am j´adra pomoc´ı obyˇcejn´ych soubor˚u.

4. Spr´ava zaˇr´ızen´ı. Je do znaˇcn´e m´ıry prov´az´ana se souborov´ym podsyst´emem. M´a za ´ukol mapov´an´ı syst´emov´ych operac´ı na hardwarov´e periferie pomoc´ı specifick´eho k´odu – ovladaˇce zaˇr´ızen´ı. Ten se skl´ad´a z datov´ych struktur a funkc´ı, kter´e zaˇr´ızen´ı ovl´adaj´ı a kontroluj´ı. Mapov´an´ı vˇetˇsinou prob´ıh´a pomoc´ı jedn´e z dvojice tabulek podle znakov´e resp. blokov´e povahy zaˇr´ızen´ı. Plat´ı, ˇze kaˇzd´e zaˇr´ızen´ı m´a sv˚uj ovladaˇc. 5. S´ıt’ov´an´ı. Tvoˇr´ı spojovac´ı vrstvu pro pˇrenos dat mezi programy a s´ıt’ovou kartou.

S´ıt’ov´e operace jsou dostupn´e pomoc´ı tzv. popisovaˇce soubor˚u (angl. file descriptor) a jeho souborov´ych operac´ı. Souborovou reprezentaci s´ıt’ov´eho spojen´ı ale na disku nenajdeme - tvoˇr´ı samostatnou kategorii. Dalˇs´ım rozd´ılem od klasick´ych soubor˚u je, ˇze pˇr´ıchod paket˚u je asynchronn´ı ud´alost, kterou j´adro nem˚uˇze v ˇz´adn´em pˇr´ıpadˇe ovlivnit. Cel´y podsyst´em s´ıt’ov´an´ı je navrˇzen dostateˇcnˇe obecnˇe a je nez´avisl´y na pouˇzit´em protokolu. V jeden okamˇzik se zpracov´av´a pouze jeden paket. Podpora smˇerov´an´ı je samozˇrejmost´ı.

1.3

Programov´

an´ı v j´

adˇ

re

Programov´an´ı v jadern´em pamˇet’ov´em prostoru s sebou nese m´ırnˇe odliˇsn´y styl pro-gramov´an´ı, neˇz na jak´y je vˇetˇsina program´ator˚u zvykl´a z prostoru uˇzivatelsk´eho. Jedn´a se pˇredevˇs´ım o omezen´ı, kter´a vypl´yvaj´ı z architektury j´adra a pˇr´ıpadnˇe samotn´e hardwarov´e platformy (podrobnˇeji v [1]):

• J´adro nem´a pˇr´ıstup k standardn´ı C knihovnˇe z d˚uvod˚u optimalizace rychlosti a velikosti sv´eho k´odu. Nejbˇeˇznˇejˇs´ı a nejd˚uleˇzitˇejˇs´ı knihovn´ı funkce reimplementuje do knihovny vlastn´ı, kter´a je souˇc´ast´ı zdrojov´ych k´od˚u j´adra.

• Je naps´ano v GNU C a ISO C99, coˇz jsou rozˇs´ıˇren´ı klasick´eho ANSI C. Zat´ımco ISO C99 je ofici´aln´ı revize jazyka C, GNU C dovoluje z´apisy, kter´e umoˇzˇnuj´ı l´epe ovlivnit optimalizaci generovan´eho k´odu. Mezi nejzaj´ımavˇejˇs´ı patˇr´ı:

* Inline funkce. Tyto funkce vkl´adaj´ı k´od funkce do m´ısta, kde by byla funkce vol´ana. Odstraˇnuje reˇzii zp˚usobenou vol´an´ım funkce a umoˇzˇnuje lepˇs´ı optimali-zaci. Nev´yhodou je nar˚ustaj´ıc´ı mnoˇzstv´ı vygenerovan´eho k´odu, nebot’ do kaˇzd´eho m´ısta volan´ı je zkop´ırov´ana cel´a funkce. Pouˇzit´ı je tedy pˇredurˇceno pro mal´e a ˇcasovˇe kritick´e funkce. Oproti makr˚um nab´ız´ı i komfort typov´e kontroly.

* Inline assembler. Umoˇzˇnuje vkl´adat assemblerovsk´e instrukce pˇr´ımo do funkc´ı jazyku C pˇres direktivu asm(). Pouˇz´ıv´a se pouze u platformovˇe z´avisl´ych ˇc´ast´ı zdrojov´ych k´od˚u a zprostˇredkov´av´a kontakt s hardware dan´e architektury.

(20)

* Direktiva podm´ınˇen´eho vˇetven´ı pomoc´ı z´apis˚u likely() a unlikely(). Z´apis

if (likely(a)) { ... }

znaˇc´ı, ˇze a bude t´emˇeˇr vˇzdy nenulov´e. Naopak z´apis if (unlikely(a)) { ... }

znamen´a, ˇze a bude nulov´e t´emˇe vˇzdy. Tyto z´apisy zrychluj´ı prov´adˇen´ı pˇreloˇzen´eho k´odu v pˇr´ıpadˇe, ˇze je naˇse pˇredpovˇed’ na podm´ınku spr´avn´a. V opaˇcn´em pˇr´ıpadˇe k´od zpomal´ı.

• Neexistuj´ıc´ı ochrana pamˇeti jadern´eho prostoru klade mnohem vyˇsˇs´ı n´aroky na program´atorsk´e schopnosti a v pˇr´ıpadˇe detekce chyby vy´ust´ı v tzv. oops12 a zasta-ven´ı syst´emu. Pamˇet’ je str´ankov´ana, ale k odkl´ad´an´ı na disk t´emˇeˇr nedoch´az´ı13. Pro-gram´ator v j´adˇre si mus´ı uvˇedomit, ˇze kaˇzd´y spotˇrebovan´y byte znamen´a o byte m´enˇe v cel´e fyzick´e pamˇeti.

• J´adro pˇri sv´e pr´aci m˚uˇze jen obt´ıˇznˇe pouˇz´ıvat aritmetiku plovouc´ı ˇr´adov´e ˇc´arky. D˚uvodem je nemoˇznost odchycen´ı v´yjimky a n´asledn´e automatick´e pˇrepnut´ı z celoˇc´ıseln´e aritmetiky do aritmetiky plovouc´ı ˇr´adov´e ˇc´arky. Pˇr´ıpadn´e uˇzit´ı j´adrem je tak degradov´ano na manu´aln´ı uloˇzen´ı a n´aslednou obnovu vˇsech pouˇzit´ych registr˚u. • K dispozici je pouze mal´y statick´y z´asobn´ık. Z tohoto d˚uvodu na nˇem nen´ı moˇzn´e

alokovat pˇr´ıliˇs velk´e mnoˇzstv´ı promˇenn´ych. V pˇr´ıpadˇe, ˇze potˇrebujeme pracovat se sloˇzitˇejˇs´ımi datov´ymi strukturami, mus´ıme poˇz´adat j´adro o pˇridˇelen´ı pamˇeti pomoc´ı funkce kmalloc()14. Na konci sv´e pr´ace pamˇet’ uvoln´ıme pˇres kfree(). Z´asobn´ık m´a na architektuˇre x86 historickou velikost dvou str´anek bezprostˇrednˇe za sebou, tedy 8KB. Prvn´ım d˚uvodem byl fakt, ˇze struktura popisuj´ıc´ı aktu´aln´ı proces task struct byla na spodn´ı stranˇe jadern´eho z´asobn´ıku15. Druh´ym, ˇze hardwarov´e pˇreruˇsen´ı po-uˇz´ıvalo stejn´y z´asobn´ık jako pr´avˇe bˇeˇz´ıc´ı proces. Probl´emy pˇri hled´an´ı dvou str´anek bezprostˇrednˇe za sebou na dlouho bˇeˇz´ıc´ım syst´emu pˇrimˇely v´yvoj´aˇre vˇetve 2.6 k ˇradˇe zmˇen. Nejd˚uleˇzitˇejˇs´ı jsou um´ıstˇen´ı jednoduˇsˇs´ı struktury thread info na z´asobn´ıku a z n´ı vych´azej´ıc´ı ukazatel na task struct a vlastn´ı jadern´y z´asobn´ık pro hardwarov´e pˇreruˇsen´ı. D´ıky tomu se testuje i pouˇzit´ı str´anky jedin´e.

• N´achylnost j´adra k synchronizaˇcn´ım probl´em˚um jakoˇzto d˚usledek sd´ılen´ı zdroj˚u operaˇcn´ıho syst´emu. Tento probl´em prohlubuje v´ıce´ulohov´a a v´ıceprocesorov´a pod-pora. Svoji roli hraje i pˇreruˇsen´ı at’ uˇz v uˇzivatelsk´em nebo novˇe v jadern´em prostoru.

ˇ

Reˇsen´ım tˇechto probl´em˚u jsou semafory a aktivn´ı ˇcek´an´ı (angl. spinlock). Nutnost´ı je i pˇredch´azet uv´aznut´ı (angl. deadlock).

12

Nen´ı ˇz´adnou zkratkou n´ybrˇz citoslovce.

13Hlavn´ı motivac´ı je rychlost syst´emu. Odloˇziteln´e jsou pouze nˇekter´e pˇredem definovan´e ˇasti j´adra jako napˇr. z´asobn´ık jadern´ych vl´aken.

14Jedn´a se o analogii funkce malloc(). Nav´ıc obsahuje parametr urˇcuj´ıc´ı d˚uleˇzitost poˇzadavku. 15

Architektura x86 bohuˇzel nem´a registr nav´ıc, kter´y by mohla obˇetovat na ukazatel na tuto ˇcasto pouˇz´ıvanou strukturu. Tento nedostatek se kompenzuje um´ıstˇen´ım struktury na konec z´asobn´ıku.

(21)

• Jednou z d˚uleˇzit´ych vlastnost´ı operaˇcn´ıch syst´em˚u je jejich pˇrenositelnost. Linux d˚uslednˇe oddˇeluje ˇc´ast k´odu, kter´y je platformovˇe z´avisl´y16 a ˇc´ast k´odu, kter´y je platformovˇe nez´avisl´y. Pro program´atory platformovˇe nez´avisl´ych ˇc´ast´ı to znamen´a nepˇredpokl´adat ˇz´adnou konkr´etn´ı architekturu pˇri psan´ı programov´eho k´odu.

• Nemoˇznost pouˇzit´ı konvenˇcn´ıch lad´ıc´ıch n´astroj˚u.

16

(22)

Kapitola 2

Principy ´

utok˚

u na Linux

Kapitola je rozdˇelena do dvou celk˚u s n´azvy ran´a ´era a modern´ı ´era. Prvn´ı zachycuje historick´e metody ´utok˚u na uˇzivatelsk´y prostor, druh´y souˇcasn´e zp˚usoby ovl´adnut´ı prostoru jadern´eho. Kapitola modern´ı ´era pˇrin´aˇs´ı vlastn´ı klasifikaci ´utok˚u v chronologick´em poˇrad´ı tak, jak se objevovaly v komunitn´ıch ˇcl´anc´ıch [11, 12, 13, 14, 15, 16] ˇci zdrojov´ych k´odech zkouman´ych rootkit˚u [17, 18, 19, 20, 21, 22]. Pˇri studiu byl objeven nov´y princip ´utoku na rozhran´ı syst´emov´ych vol´an´ı, kter´y jsem pojmenoval jako CPU registr idtr (viz kap. 2.2.1 princip ˇc. 5). Vˇedomosti nabyt´e v t´eto kapitole budou uplatnˇeny v kapitole ˇc. 3, kde budou pouˇzity pro ´unos syst´emov´ych sluˇzeb.

Doprovodn´

e programy

Jako praktick´a ˇc´ast t´eto bakal´aˇrsk´e pr´ace byla navrˇzena sada tˇriceti vlastn´ıch dopro-vodn´ych program˚u (z toho dvacet osm jadern´ych modul˚u, jeden skript a jedna aplikace). Vznikla tak uniformn´ı mnoˇzina experiment˚u, kter´e jsou rozprostˇreny v n´asleduj´ıc´ım textu. Je na nˇe pr˚ubˇeˇznˇe odkazov´ano v jednotliv´ych pododd´ılech a jejich kompletn´ı v´yˇcet lze nal´ezt v pˇr´ıloze A. Zdrojov´e k´ody vˇsech doprovodn´ych program˚u lze nal´ezt na pˇriloˇzen´em datov´em nosiˇci. Pˇri ˇcten´ı t´eto bakal´aˇrsk´e pr´ace je vhodn´a jejich studie, nebot’ k´ody jednotliv´ych pododd´ıl˚u vystihuj´ı pouze hlavn´ı myˇslenku diskutovan´eho probl´emu. Zasadit problematiku do funkˇcn´ıho celku je c´ılem pr´avˇe tˇechto doprovodn´ych program˚u.

Pˇriloˇzen´e moduly maj´ı uniformn´ı strukturu zn´azornˇenou na str´ance 17. Kaˇzd´y modul m´a informativn´ı hlaviˇcku. N´asleduj´ıc´ı pouˇzit´e hlaviˇckov´e soubory a pˇr´ıkazy pro preproce-sor. Pˇr´ıkaz MODULE_LICENSE("Dual BSD/GPL") je nutn´y pro bezprobl´emov´e zaveden´ı mo-dulu do pamˇeti. Samotn´y k´od je ale v´az´an licenˇcn´ı smlouvou bakal´aˇrsk´e pr´ace. Makro #define MODULE_NAME "demo_name" pˇriˇrazuje modulu unik´atn´ı n´azev, kter´y se odr´aˇz´ı i v pojmenov´an´ı vstupn´ı, v´ykonn´e a v´ystupn´ı funkci. V´ykonn´a (stˇeˇzejn´ı) funkce je pojmenov´ana stejnˇe jako modul a obsahuje pˇr´ıkazy prov´adˇej´ıc´ı demonstraˇcn´ı k´od. Na konci kaˇzd´eho modulu je nutn´e vstupn´ı a v´ystupn´ı funkci zaregistrovat pomoc´ı module_init(fce) a module_exit(fce). Podrobn´e informace o zp˚usobu zav´adˇen´ı modul˚u do j´adra lze nal´ezt v kap. 4.1.1.

Z informativn´ı hlaviˇcky vzorov´eho modulu je patrn´e, ˇze nutnou podm´ınkou pro ´uspˇeˇsn´y bˇeh modulu je architektura IA-32 a Linuxov´e j´adro 2.6.16.59. Pomoc s instalac´ı tohoto j´adra pˇrin´aˇs´ı soubor readme.txt, nach´azej´ıc´ı se v koˇrenov´em adres´aˇri na pˇriloˇzen´em do-provodn´em nosiˇci. V pˇr´ıpadˇe pouˇzit´ı jin´eho j´adra1 ˇci architektury nem˚uˇze b´yt oˇcek´avan´y v´ysledek garantov´an.

1

(23)

/**

* soubor: jmeno.c

* autor: Boris Proch´azka (xproch63@stud.fit.vutbr.cz)

* projekt: bakal´aˇrsk´a pr´ace ’Metody ´utok˚u na operaˇcn´ı syst´em Linux’

* VUTBR-FIT: ISP, IBP, ISZ

* datum: zima 2007/8, l´eto 2007/8 * k´odov´an´ı: iso 8859-2

* pˇreloˇzeno: IA-32 (i386), kernel 2.6.16.59, gcc 4.0.3 * licence: Dle licenˇcn´ı smlouvy bakal´aˇrsk´e pr´ace

* popis: Struˇcn´y popis funkce. **/

#include <hlavicky.h>

MODULE_LICENSE("Dual BSD/GPL");

MODULE_DESCRIPTION("Strucny popis funkce");

MODULE_AUTHOR("Boris Prochazka (xproch63@stud.fit.vutbr.cz)"); #define MODULE_NAME "demo_name"

/** V´ykonn´y k´od. */

static void demo_name(void) {

//--> k´od demonstruj´ıc´ı princip nebo metodu <--}

/** Vstupn´ı funkce modulu. */ static int demo_name_init(void) {

printk(KERN_INFO "Modul "MODULE_NAME" se zavadi do jadra.\n"); demo_name();

printk(KERN_INFO "Modul "MODULE_NAME" zaveden.\n"); return 0;

}

/** V´ystupn´ı funkce modulu. */ static void demo_name_exit(void) {

printk(KERN_INFO "Modul "MODULE_NAME" byl uspesne odstranen z jadra.\n"); return;

}

/** Definice vstupn´ıch/v´ystupn´ıch funkc´ı. */ module_init(demo_name_init);

module_exit(demo_name_exit);

(24)

Moˇ

znosti obrany a detekce

Souˇc´ast´ı kaˇzd´eho pododd´ılu je odstavec nesouc´ı n´azev moˇznosti obrany a detekce. Jeho ´

uˇcelem je prov´est kr´atk´e shrnut´ı a diskuzi pr´avˇe nabyt´ych poznatk˚u. Zamˇeˇruje se pˇri tom na zp˚usoby odhalen´ı ´utoku a moˇznosti prevence jejich vzniku. Informace z odstavce moˇznosti obrany a detekce maj´ı inkrement´aln´ı charakter a jsou v pr˚ubˇehu textu doplˇnov´any s rozˇsiˇruj´ıc´ımi se vˇedomostmi. V z´avˇeru pr´ace jsou ty nejd˚uleˇzitˇejˇs´ı struˇcnˇe shrnuty.

2.1

Ran´

a ´

era

Prvn´ı pokusy o nezvan´e

”vylepˇsen´ı“ operaˇcn´ıho syst´emu spadaj´ı do poˇc´atku 90. let 20. stolet´ı. V t´eto dobˇe doch´az´ı ke vzniku z´akladn´ıch pojm˚u jako je rootkit, p˚uvodnˇe znaˇc´ıc´ı sadu upraven´ych administr´atorsk´ych n´astroj˚u. Dnes t´ımto pojmem oznaˇcujeme pˇredevˇs´ım programy, kter´e dok´aˇz´ı modifikovat j´adro za bˇehu. N´azev rootkit je odvozen od z´akladn´ı schopnosti pˇridˇelit opr´avnˇen´ı uˇzivatele root, tedy maxim´aln´ı moˇzn´e opr´avnˇen´ı. Tato podka-pitola dotv´aˇr´ı pohled na bezpeˇcnost operaˇcn´ıch syst´em˚u jako celku a vzhledem k jej´ı dneˇsn´ı neaktu´alnosti j´ı bude vˇenov´ano pouze minimum prostoru.

2.1.1 Nahrazov´an´ı utilit

Nahrazov´an´ı utilit je povaˇzov´ano za nejprimitivnˇejˇs´ı zp˚usob ovl´adnut´ı syst´emu. V pˇ r´ıpa-dˇe, ˇze ´utoˇcn´ık nahrad´ı veˇsker´e administr´atorsk´e programy (ls, ps, top, w, ...) vlastn´ımi, m˚uˇze v jejich v´ypisech potlaˇcit hl´aˇsen´ı o sv´ych aktivit´ach. ´Utoˇcn´ık m´a typicky pˇripraven´e sady pˇredkompilovan´ych n´astroj˚u, spustiteln´ych na konkr´etn´ı verzi operaˇcn´ıho syst´emu.

Moˇznosti obrany a detekce

Pro spr´avce syst´emu je nutn´e pouˇz´ıvat n´astroje produkuj´ıc´ı nezkreslen´e v´ysledky. Na jejich ochranu m˚uˇze pouˇz´ıt kontroln´ı souˇcty, kter´e se budou pˇred jejich pouˇzit´ım porovn´avat2. Dalˇs´ı moˇznost´ı je m´ıt kopii tˇechto n´astroj˚u na m´ıstˇe urˇcen´em pouze pro ˇcten´ı (napˇr. CD).

2.1.2 Nahrazov´an´ı knihoven – preload

Nahrazov´an´ı jednotliv´ych utilit je ne´umˇernˇe pracn´e. Nav´ıc se m˚uˇze st´at, ˇze na nˇekter´e d˚uleˇzit´e zapomeneme. M˚uˇzeme se tedy pokusit zamˇeˇrit na spoleˇcn´y programov´y k´od, j´ımˇz jsou knihovny. Vˇetˇsina syst´emov´ych sluˇzeb je totiˇz vol´ana nepˇr´ımo (viz kap. 1.5). Zmˇenou v knihovnˇe tak m˚uˇzeme ovlivnit chod vˇsech aplikac´ı, kter´e tuto knihovnu pouˇz´ıvaj´ı3. Z po-hledu ´utoˇcn´ıka jsme tedy poˇr´ad

”na p˚ul cesty“, nebot’ nemus´ıme postihnout cel´y syst´em. Moˇznosti obrany a detekce

Odhalit parazitn´ı knihovnu m˚uˇzeme studiem namapovan´ych oblast´ı v souboru /proc/pid/ maps ˇci v´ypisem slinkovan´ych souˇc´ast´ı programem ldd program. Obranou mohou b´yt i staticky zkompilovan´e programy (obsahuj´ı knihovnu vlastn´ı), pouˇzit´ı pˇr´ım´eho vol´an´ı j´adra (bez asistence knihovny) nebo opˇet kontroln´ı souˇcty.

2Bezpeˇcnost syst´emu pak z´avis´ı na zabezpeˇcen´ı kontroln´ıch souˇct˚u. 3

(25)

2.2

Modern´ı ´

era

S postupem ˇcasu bylo nutn´e vym´yˇslet nov´e praktiky, kter´e by ´utoˇcn´ık˚um zajistily delˇs´ı setrv´an´ı v napaden´em syst´emu. Logick´ym postupem byl pˇresun stˇredu z´ajm˚u do jadern´eho prostoru. Proˇc modifikovat celou ˇradu objekt˚u na disku, kdyˇz stejnou pr´aci m˚uˇze vykonat samotn´e j´adro? Staˇc´ı pouze vhodnˇe modifikovat jeho struktury a funkce tak, aby ´utoˇcn´ıkovi zajistily poˇzadovan´e vlastnosti. Vzhledem k tomu, ˇze veˇsker´e ´upravy prob´ıhaj´ı v operaˇcn´ı pamˇeti, moˇznosti detekce jsou ˇr´adovˇe komplikovanˇejˇs´ı. Nev´yhodou tohoto typu ´utok˚u je n´achylnost k chyb´am typu race condition4, kter´e mohou v nˇekter´ych pˇr´ıpadech v´est aˇz k nekontrolovateln´emu p´adu cel´eho syst´emu.

2.2.1 Napaden´ı rozhran´ı syst´emov´ych vol´an´ı

Zamˇeˇrme se nyn´ı na pr˚ubˇeh syst´emov´eho vol´an´ı. Jiˇz v´ıme, ˇze je vyvol´ano z uˇzivatelsk´eho prostoru pˇri potˇrebˇe aplikace ˇci knihovny komunikovat se syst´emem (kap. 1.2.3). Syst´emov´a vol´an´ı jsou rozliˇsov´ana ˇc´ısly a jejich kompletn´ı v´yˇcet lze nal´ezt v souboru unistd.h5. Pr˚ubˇeh vol´an´ı zn´azorˇnuje obr´azek 2.1, kde ˇsipky znamenaj´ı pˇred´av´an´ı ˇr´ızen´ı mezi funkcemi. Apli-kace je tak v podstatˇe odk´az´ana na informace, kter´e j´ı operaˇcn´ı syst´em prostˇrednictv´ım sv´ych syst´emov´ych vol´an´ı zpˇr´ıstupn´ı. V pˇr´ıpadˇe, ˇze z nich ´utoˇcn´ık odfiltruje z´aznamy o sv´ych aktivit´ach, st´av´a se z pohledu uˇzivatele prakticky neodhaliteln´y.

read() wrapper call read() Aplikace Knihovna Uživatelský prostor sys_read() system_call() Rutina systémového volání Obslužná rutina Jaderný prostor

Obr´azek 2.1: Diagram syst´emov´eho vol´an´ı

Cesta do hlubin j´adra zaˇc´ın´a (na architektuˇre IA-32 v Linuxu) vyvol´an´ım softwarov´eho pˇreruˇsen´ı int $0x80. Ta zp˚usob´ı v´yjimku a n´asledn´e pˇrepnut´ı syst´emu do jadern´eho pro-storu. Z tabulky pˇreruˇsen´ı, jej´ıˇz zaˇc´atek urˇcuje procesorov´y registr idtr, je zavol´ana jadern´a funkce. Ta m´a v naˇsem pˇr´ıpadˇe ˇc´ıslo 0x80–rutina syst´emov´eho vol´an´ı6. Pro identifikaci konkr´etn´ı obsluˇzn´e rutiny slouˇz´ı registr eax. Rutina syst´emov´eho vol´an´ı zkontroluje plat-nost pˇredan´e hodnoty v registru eax a v pˇr´ıpadˇe ´uspˇechu vyvol´a konkr´etn´ı obsluˇznou rutinu, kterou touto hodnotou v tabulce syst´emov´ych vol´an´ı identifikuje. Pˇred´av´an´ı parametr˚u je zajiˇstˇeno pˇres ostatn´ı procesorov´e registry7ebx, ecx, edx, esi, edi a ebp. V pˇr´ıpadˇe vyˇsˇs´ıch n´arok˚u na mnoˇzstv´ı parametr˚u je moˇzn´e jeden z registr˚u pouˇz´ıt jako ukazatel na sloˇzitˇejˇs´ı

4

Je synchronizaˇcn´ı probl´em naz´yvan´y jako soubˇeh. Nast´av´a pˇri nekontrolovan´em pˇr´ıstupu ke sd´ılen´ym prostˇredk˚um.

5

Zdrojov´e k´ody j´adra include/asm/unistd.h.

6Od procesoru Intel Pentium II se v instrukˇcn´ı sadˇe nach´az´ı nov´a instrukce sysentr. Jedn´a se o instrukci urychluj´ıc´ı proces vyvol´an´ı syst´emov´e rutiny. V j´adˇre je podporov´ana od verze 2.6.

7red´av´an´ı pˇres z´asobn´ık nen´ı z d˚uvod˚u zmˇeny z uˇzivatelsk´eho na jadern´y z´asobn´ık moˇzn´e. Z´aroveˇn je pˇred´av´an´ı pˇres registry nejrychlejˇs´ı.

(26)

datovou strukturu. K pˇrepnut´ı zpˇet do uˇzivatelsk´eho prostoru se provede instrukc´ı iret8. N´avratov´a hodnota je vˇzdy vr´acena v registru eax. Kompletn´ı sch´ema pr˚ubˇehu syst´emov´e vol´an´ı zachycuje obr´azek 2.2.

Tabulka přerušení divide_error debug ... system_call 0x80 … 0x01 0x00 Tabulka systémových volání sys_restart_syscall sys_exit sys_fork sys_read 3 2 1 0 sys_write 4 ... ... ... mov    $0x3,%eax int $0x80 ... Aplikace/ Knihovna system_call: pushl %eax SAVE_ALL … cmpl $(nr_syscalls), %eax jae syscall_badsys … call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) … RESTORE_REGS addl $4, %esp iret  Rutina systémového volání asmlinkage ssize_t sys_read (unsigned int fd, char __user * buf, size_t count) {         struct file *file;         ssize_t ret = ­EBADF; …         return ret; } Obslužná rutina idtr CPU registr

Obr´azek 2.2: Sch´ema pr˚ubˇehu syst´emov´eho vol´an´ı

Na tomto m´ıstˇe je nutn´e zd˚uraznit, ˇze doˇslo k pˇrepnut´ı z uˇzivatelsk´eho prostoru do jadern´eho a naopak (kap. 1.2.3). Kontextov´a z´avislost na procesu vˇsak z˚ustala po celou dobu zachov´ana9.

Pˇredt´ım, neˇz se pust´ıme do samotn´ych ´utok˚u, mus´ıme si zvolit syst´emovou sluˇzbu, proti kter´e budeme ´utoky testovat. Za jednoho z nejvhodnˇejˇs´ıch kandid´at˚u m˚uˇzeme povaˇzovat syst´emov´e vol´an´ı sys setuid(), kter´e nastavuje efektivn´ı ID bˇeˇz´ıc´ıho procesu. Jedn´a se o jednoduchou funkci s minimem postrann´ıch efekt˚u. Jej´ı nejd˚uleˇzitˇejˇs´ı ˇc´ast shrnuje n´ asle-duj´ıc´ı k´od:

asmlinkage long sys_setuid(uid_t uid) {

int old_ruid, old_suid, new_ruid, new_suid; ..

if (capable(CAP_SETUID)) { //M´ame pr´avo zmˇenit ´uroveˇn opr´avnˇen´ı procesu? ..

new_suid = uid; //Nov´e opr´avnˇen´ı }

current->suid = new_suid; //Nastaven´ı nov´eho opr´avnˇen´ı bˇeˇz´ıc´ıho procesu }

8

Nebo komplement´arn´ı instrukc´ı k sysentr instrukc´ı sysexit. 9

(27)

Current je makro, kter´e je pˇrekladem nahrazeno funkc´ı get current(). Ta vrac´ı uka-zatel na strukturu task struct, kter´a popisuje pr´avˇe bˇeˇz´ıc´ı proces. Naˇs´ım c´ılem bude tuto funkci modifikovat tak, aby po vyvol´an´ı naˇs´ım programem s vhodn´ym parametrem uid, pˇredala tomuto procesu nejvyˇsˇs´ı moˇzn´a pr´ava. Budeme k tomu pouˇz´ıvat program uveden´y jako ˇc´ıslo i v pˇr´ıloze A, kter´y tuto sluˇzbu pˇr´ımo vyvol´av´a.

Nyn´ı se pokus´ıme identifikovat zraniteln´a m´ısta. Poˇrad´ı je chronologicky uspoˇr´adan´e. 1. Tabulka syst´emov´ych vol´an´ı

Nejjednoduˇsˇs´ı a po dlouhou dobu nejpouˇz´ıvanˇejˇs´ı zp˚usob ´utoku byla ´uprava z´aznamu v tabulce syst´emov´ych vol´an´ı. Jedn´a se v podstatˇe pouze o vloˇzen´ı vlastn´ı funkce pˇred obsluˇznou rutinu popˇr. jej´ı kompletn´ı nahrazen´ı. V dneˇsn´ı dobˇe je situace m´ırnˇe zkom-plikov´ana snahou jadern´ych v´yvoj´aˇr˚u proˇcistit jadern´e rozhran´ı a z toho d˚uvodu jiˇz symbol sys call table veˇrejnˇe neexportuj´ı. To n´am vˇsak nebr´an´ı si adresu zaˇc´atku tabulky v pamˇeti nal´ezt sv´epomoc´ı. M˚uˇzeme k tomu pouˇz´ıt nˇekter´y z n´ıˇze uveden´ych zp˚usob˚u:

• System.map

K tomu, aby se j´adro dalo pˇri ladˇen´ı analyzovat, mus´ı nˇekde udrˇzovat seznam sv´ych symbol˚u, tzv. syst´emovou mapu. Ta obsahuje seznam funkc´ı a promˇenn´ych spolu s jejich adresami. Pro ´utoˇcn´ıka se jedn´a o nesm´ırnˇe cenn´y materi´al a z to-hoto d˚uvodu ho administr´atoˇri na produkˇcn´ıch stanic´ıch typicky nepouˇz´ıvaj´ı. Demonstraˇcn´ı skript, kter´y se pokus´ı vyhledat adresu symbolu sys call table v souboru System.map, je pod ˇc´ıslem ii v pˇr´ıloze A.

• Heuristika

Dalˇs´ı moˇznost´ı je vyhled´an´ı tabulky syst´emov´ych vol´an´ı v datov´e oblasti j´adra. Pro spolehlivou identifikaci budeme potˇrebovat zn´at adresy funkc´ı jej´ıch poloˇzek. V d˚usledku jiˇz zmiˇnovan´ych zmˇen v rozhran´ı je nyn´ı exportov´an pouze sym-bol sys close(), jehoˇz pouˇzit´ı d´av´a nejednoznaˇcn´e v´ysledky. J´adro naˇstˇest´ı z d˚uvod˚u snazˇs´ıho ladˇen´ı poskytuje soubor /proc/kallsyms10, kter´y obsahuje i symboly, kter´e nejsou v jadern´em prostoru exportov´any. Jejich anal´yzou a n´asledn´em pˇredan´ı modulu ˇc. iii (pˇr´ıloha A) v podobˇe parametr˚u jiˇz dost´av´ame uspokojuj´ıc´ı v´ysledek. Pr˚uchod pˇres datovou ˇc´ast jadern´eho prostoru a n´asledn´y test na v´yskyt tabulky zn´azorˇnuje n´asleduj´ıc´ı k´od:

for (inspected_address = ((init_mm.end_code + 4) & 0xfffffffc); inspected_address < init_mm.end_data;

inspected_address += sizeof(void *)) {

if (sys_call_table_hit(inspected_address)) { NALEZENO! } }

• Trasov´an´ı

Posledn´ı metoda vyuˇz´ıv´a znalosti c´ılov´e architektury a implementace rozhran´ı syst´emov´ych vol´an´ı v j´adˇre. Zavol´an´ım instrukce sidt11 zjist´ıme um´ıstˇen´ı ta-bulky pˇreruˇsen´ı. V n´ı pomoc´ı indexu 0x80 nalezneme pˇr´ısluˇsn´y z´aznam, kter´y jiˇz obsahuje adresu rutiny syst´emov´eho vol´an´ı. Adresa rutiny syst´emov´eho vol´an´ı se nach´az´ı v promˇenn´e system call po vykon´an´ı tohoto k´odu:

10adro mus´ı b´yt s touto podporou (CONFIG KALLSYMS) zkompilov´ano. 11

(28)

asm ("sidt %0" : "=m" (idtr)); //Zisk adresy tabulky pˇreruˇsen´ı idt_system_call = &((struct idt_descriptor *)idtr.idt_table)[0x80]; system_call = ((idt_system_call->offset31_16 << 16) |

(idt_system_call->offset15_00)); //Zisk adresy rutiny sys. vol´an´ı Pro nalezen´ı adresy tabulky syst´emov´ych vol´an´ı mus´ıme opˇet pouˇz´ıt heuristick´e metody. Vyuˇzijeme znalosti, ˇze rutina syst´emov´eho vol´an´ı obsahuje pouze jedin´e funkˇcn´ı vol´an´ı call *sys call table(,%eax,4), v kter´em je hledan´a adresa obsaˇzena. V hexadecim´aln´ım strojov´em z´aznamu se jedn´a o ˇretˇezec tvaru 0xff 0x14 0x85 0x[sys call table], kter´y mus´ı funkce obsahovat. Zb´yv´a n´am tedy pouze identifikovan´y vzor vyhledat. K´od proch´azej´ıc´ı rutinu syst´emov´eho vol´an´ı za ´uˇcelem vyhled´an´ı tabulky syst´emov´ych vol´an´ı m˚uˇze vypadat takto:

unsigned char *walker = (char *)system_call; //Adresa rutiny while(limit--) { //maxim´aln´ı moˇzn´a hloubka zanoˇren´ı, limit=1000

if (walker[0] == 0xff && walker[1] == 0x14 && walker[2] == 0x85)

return (unsigned long**)(&walker[3]); //Adresa sys_call_table walker++; //Zkouman´a pozice v rutinˇe syst´emov´eho vol´an´ı }

Funkˇcn´ı demonstrace se nach´az´ı pod ˇc´ıslem iv pˇr´ılohy A. Jelikoˇz se jedn´a o dopo-sud nejrychlejˇs´ı a nejspolehlivˇejˇs´ı metodu, bude pouˇz´ıv´ana i v dalˇs´ıch pˇr´ıkladov´ych modulech.

V pˇr´ıpadˇe, ˇze zn´ame adresu sys call table, n´am jiˇz nic nebr´an´ı prov´est naˇse prvn´ı pˇresmˇerov´an´ı. Metody budeme testovat proti jiˇz zm´ınˇen´emu syst´emov´emu vol´an´ı setuid(), kter´e umoˇzˇnuje zmˇenu ´urovnˇe opr´avnˇen´ı aktu´alnˇe bˇeˇz´ıc´ıho procesu. Tuto sluˇzbu nahrad´ıme vlastn´ı verz´ı new sys setuid, kter´a n´am, v pˇr´ıpadˇe pˇred´an´ı vhodnˇe zvolen´eho parametru, pˇridˇel´ı maxim´aln´ı moˇzn´a pr´ava. Funkce new sys setuid() bude vypadat n´asledovnˇe:

asmlinkage long new_sys_setuid(uid_t uid) {

if (uid == MAGIC_NUMBER) { //#define MAGIC_NUMBER 12345

current->uid=0; //V pˇr´ıpadˇe vyvol´an´ı funkce s parametrem current->gid=0; //12345 z´ısk´a proces maxim´aln´ı pr´ava }

return old_sys_setuid(uid);//Zachov´an´ı p˚uvodn´ı funkce sys_setuid() }

Zb´yv´a jen prov´est z´amˇenu v tabulce syst´emov´ych vol´an´ı. Tu demonstruje modul ˇc. v v pˇr´ıloze A. K´od, kdy zamˇen´ıme poloˇzku v tabulce syst´emov´ych vol´an´ı, vypad´a n´asledovnˇe:

(29)

old_sys_setuid = sys_call_table[__NR_setuid];//P˚uvodn´ı fce. sys_setuid() sys_call_table[__NR_setuid] = new_sys_setuid;//Nov´a fce. sys_setuid()

2. Obsluˇzn´a rutina

Syst´emov´ı administr´atoˇri brzy zaˇcali tabulku syst´emov´ych vol´an´ı kontrolovat. Jednalo se o test shody s hodnotami, kter´e mˇela tabulka pˇri prvn´ım zaveden´ı syst´emu. Tedy v dobˇe, kdy jeˇstˇe nemohla b´yt nijak pozmˇenˇena. Nutnost´ı ´utoˇcn´ıka je zachovat tabulku v nezmˇenˇen´em stavu. Prvn´ı moˇznost je zamˇeˇrit se na zmˇenu toku ˇr´ızen´ı po vyvol´an´ı obsluˇzn´e rutiny. Toho m˚uˇzeme dos´ahnout absolutn´ım skokem jmp um´ıstˇen´ym ihned po zaˇc´atku funkce. Konkr´etnˇe m˚uˇze j´ıt o k´od

movl $0,%eax --> po pˇreloˇzen´ı "\xb8\x00\x00\x00\x00" jmp *%eax --> po pˇreloˇzen´ı "\xff\xe0"

kter´y po pˇreloˇzen´ı do strojov´eho k´odu d´a v´ysledek "0xb8 0x[sys hack] 0xff 0xe0". Jedn´a se o prvn´ıch 7B obsluˇzn´e rutiny, kter´e si mus´ıme pˇred pˇreps´an´ım skokem zapa-matovat, abychom je mohli v pˇr´ıpadˇe potˇreby obnovit. Cel´y proces v´ymˇeny prvn´ıch 7B u funkce sys setuid() vypad´a n´asledovnˇe:

static char old_code[7]; //P˚uvodn´ıch 7B funkce sys_setuid() static char new_code[7] = //Nov´ych 7B (jmp) funkce sys_setuid() "\xb8\x00\x00\x00\x00" //Na m´ısto &new_code[1] mus´ıme pˇred "\xff\xe0"; //pouˇzit´ım dosadit adresu volan´e funkce &new_code[1] = new_sys_setuid; //Dosazen´ı volan´e fce. new_sys_setuid() _memcpy(old_code,sys_call_table[__NR_setuid],sizeof(old_code));

_memcpy(sys_call_table[__NR_setuid],new_code,sizeof(new_code));

Velmi ˇcasto vˇsak potˇrebujeme n´ami upravenou obsluˇznou rutinu sami volat a jej´ı n´avratovou hodnotu vyuˇz´ıt. K tomuto ´uˇcelu si m˚uˇzeme na kr´atk´y okamˇzik rutinu opravit a po navr´acen´ı jej´ıho v´ysledku ji opˇet zmˇenit do jej´ı p˚uvodn´ı skokov´e podoby: _memcpy(sys_call_table[__NR_setuid],old_code,sizeof(old_code));//Oprava ret=((long (*)(uid_t uid))sys_call_table[__NR_setuid])(uid); //Vol´an´ı _memcpy(sys_call_table[__NR_setuid],new_code,sizeof(new_code));//Zmˇena Funkˇcn´ı doprovodn´y program se nach´az´ı v pˇr´ıloze A pod ˇc´ıslem vi.

3. Rutina syst´emov´eho vol´an´ı

Dalˇs´ı moˇznost´ı je pˇrestat origin´aln´ı tabulku syst´emov´ych vol´an´ı pouˇz´ıvat. Znamen´a to pro n´as vytvoˇrit si vlastn´ı priv´atn´ı kopii tabulky. V takto vznikl´e tabulce jiˇz m˚uˇzeme prov´adˇet zmˇeny relativnˇe beztrestnˇe12, protoˇze syst´em o ni nevede ˇadn´y z´aznam. new_sys_call_table=kmalloc(sizeof(unsig long*)*NR_syscalls,GFP_KERNEL); _memcpy(new_sys_call_table, old_sys_call_table, //Kop´ırov´an´ı tabulky sizeof(unsigned long*)*NR_syscalls); //syst´emov´ych vol´an´ı new_sys_call_table[__NR_setuid] = new_sys_setuid; //Nov´a sys_setuid() 12

(30)

Zb´yv´a jiˇz pˇrepsat odkaz v rutinˇe syst´emov´eho vol´an´ı tak, aby zaˇcala n´ami vytvoˇrenou tabulku pouˇz´ıvat. Prostudujeme-li zp˚usob, jak´ym z´ısk´av´ame adresu tabulky syst´ e-mov´ych vol´an´ı pomoci trasov´an´ı (kap. 2.2.1), zjist´ıme, ˇze adresu jiˇz dobˇre zn´ame. P˚uvodnˇe jsme ji pouˇz´ıvali pro zisk odkazu na tabulku syst´emov´ych vol´an´ı. Nyn´ı pˇrep´ıˇseme samotn´y odkaz, aby ukazoval na naˇs´ı novou tabulku new sys call table. Demonstraˇcn´ı program lze nal´ezt pod ˇc. vii pˇr´ıloha A.

V pˇr´ıpadˇe, ˇze naˇse architektura podporuje rozˇs´ıˇren´ı o sysentr (poz. 6), jsme vˇsak jeˇstˇe neskonˇcili. Je velmi pravdˇepodobn´e, ˇze mnoho program˚u bude z d˚uvod˚u vyˇsˇs´ı efektivity vykon´av´an´ı k´odu instrukci sysentr upˇrednostˇnovat pˇred pouˇzit´ı pˇreruˇsen´ı int $0x80. Nezb´yv´a neˇz nal´ezt k´od i t´eto rutiny. Studiem souboru entry.S13 dospˇ e-jeme k z´avˇeru, ˇze obsluˇzn´a funkce je z naˇseho pohledu t´emˇeˇr identick´a a nach´az´ı se nˇekde tˇesnˇe nad funkc´ı rutiny syst´emov´eho vol´an´ı. Vyuˇzit´ım jiˇz dobˇre zn´am´eho heuris-tick´eho zp˚usobu, nyn´ı vˇsak opaˇcn´ym smˇerem neˇz v prv´em pˇr´ıpadˇe (m´ısto walker++ je walker--), nalezneme i jej´ı odkaz do tabulky syst´emov´ych vol´an´ı. Pro kontrolu spr´avnosti vyhled´av´an´ı n´am poslouˇz´ı fakt, ˇze obˇe rutiny pouˇz´ıvaj´ı stejnou tabulku. V´ysledky um´ıstˇen´ı tabulky tedy mus´ı b´yt totoˇzn´e. Rozˇs´ıˇren´ı pˇredeˇsl´eho programu ˇc. vii, kdy zmˇen´ıme odkaz na tabulku syst´emov´ych vol´an´ı i v rutinˇe vyvolan´e in-strukc´ı sysentr, lze nal´ezt pod ˇc. viii v pˇr´ıloze A.

4. Tabulka pˇreruˇsen´ı

Jinou, pro ´utoˇcn´ıka nem´enˇe zaj´ımavou destinac´ı, je tabulka pˇreruˇsen´ı. I kdyˇz by se mohlo na prvn´ı pohled zd´at, ˇze se jedn´a v podstatˇe o to sam´e jako v pˇr´ıpadˇe tabulky syst´emov´ych vol´an´ı, nen´ı to tak ´uplnˇe pravda. Cel´y tento podsyst´em je mnohem ´uˇzeji sv´az´an s konkr´etn´ı architekturou a operaˇcn´ım syst´emem. V drtiv´e vˇetˇsinˇe je naps´an v assembleru.

Naˇs´ım c´ılem bude pˇredˇradit rutinˇe syst´emov´eho vol´an´ı rutinu vlastn´ı. V n´ı budeme testovat pˇred´avan´e hodnoty a v pˇr´ıpadˇe vol´an´ı funkce sys setuid() s paramet-rem uid == 12345 pˇridˇel´ıme pr´avˇe bˇeˇz´ıc´ımu procesu maxim´aln´ı pr´ava. Cel´y ´ukol rozdˇel´ıme na dvˇe ˇc´asti:

(a) Meziˇcl´anek v assembleru – m´a za ´ukol vytvoˇrit z´akladn´ı prostˇred´ı pro vyˇsˇs´ı programovac´ı jazyk. Jedn´a se pˇredevˇs´ım o ´uschovu a obnovu programovac´ıho modelu spolu s pˇred´an´ım parametr˚u funkci napsan´e v jazyku C.

new_int:

pushl %%es \

pushl %%ds |

pushl %%eax +-- ´uschova prog. modelu

... |

pushl %%ebx /

pushl %%esp //Promˇenn´a ’regs’ ve funkci pre_system_call() call *hijack //Zavol´an´ı funkce pre_system_call()

popl %%esp

popl %%ebx \

... |

popl %%eax +-- obnova prog. modelu

popl %%ds |

13

(31)

popl %%es /

jmp *old_int //Pokraˇcuj na p˚uvodn´ı rutinˇe syst´emov´eho vol´an´ı

(b) Funkce v C – mus´ı z registrov´ych parametr˚u, kter´e se nyn´ı nach´azej´ı na z´asobn´ıku v jasnˇe definovan´em poˇrad´ı, identifikovat pˇr´ıpady, kdy m´a doj´ıt k pozmˇenˇen´ı v´ypoˇctu. K parametr˚um pˇristupuje pˇres strukturu struct pt regs * regs, napˇr. regs->eax.

asmlinkage void pre_system_call(struct pt_regs * regs) {

switch(regs->eax) //Zjisti, o jak´e syst´emov´e vol´an´ı se jedn´a {

case __NR_setuid: //Sys. vol´an´ı sys_setuid()

if (regs->ebx == 12345) { //Parametr uid == 12345 current->uid=0; //Zmˇeˇn pr´ava prob´ıhaj´ıc´ıho current->gid=0; //procesu na maxim´aln´ı } break; default: break; } }

Nyn´ı jiˇz staˇc´ı doplnit adresy funkc´ı namapovan´ych v pamˇeti do funkce new int() a zmˇenit pˇr´ısluˇsn´y deskriptor v tabulce pˇreruˇsen´ı:

old_int = get_descriptor_offset(idt_system_call);//P˚uvodn´ı r.sys.vol´an´ı

hijack = pre_system_call; //Naˇse "Funkce v C"

set_descriptor_offset(idt_system_call, new_int); //Nov´a r.sys.vol´an´ı Uk´azkov´y modul se nach´az´ı pod ˇc. ix v dodatku A.

5. CPU registr idtr

Moˇznost´ı modifikovat pˇr´ımo procesorov´y registr idtr se zat´ım ˇz´adn´y ˇcl´anek ani root-kit nezab´yval. M˚uˇzeme t´ım dos´ahnout pˇresmˇerov´an´ı jiˇz v samotn´em z´arodku pˇreruˇsen´ı a dostat pod kontrolu veˇsker´e n´asledn´e dˇen´ı. Prvn´ım pˇredpokladem je vytvoˇrit si vlastn´ı tabulku pˇreruˇsen´ı a v n´ı pak prov´est potˇrebn´e modifikace. Vlastn´ı kopii ta-bulky pˇreruˇsen´ı z´ısk´ame n´asledovnˇe:

old_idt_table = get_idt_table(); //P˚uvodn´ı tabulka pˇreruˇsen´ı new_idt_table = (unsigned long*) //Alokace prostoru pro novou

kmalloc(sizeof(struct idt_descriptor)*IDT_SIZE, GFP_KERNEL); _memcpy(new_idt_table,old_idt_table, //Nov´a tabulka pˇreruˇsen´ı

sizeof(struct idt_descriptor)*IDT_SIZE);

Zmˇeny v n´ami okop´ırovan´e tabulce prov´ad´ıme ´uplnˇe stejnˇe jako v pˇredeˇsl´e metodˇe, kdy jsme ´utoˇcili na origin´aln´ı tabulku pˇreruˇsen´ı:

(32)

idt_system_call = get_idt_descriptor(new_idt_table, SYSTEM_CALL_NUMBER); old_int = get_descriptor_offset(idt_system_call); //P˚uvodn´ı r.sys.vol´an´ı

hijack = pre_system_call; //Naˇse "Funkce v C"

set_descriptor_offset(idt_system_call, new_int); //Nov´a r.sys.vol´an´ı

Posledn´ım ´ukolem je zmˇenit odkaz v registru idtr z origin´aln´ı tabulky na tabulku naˇsi, modifikovanou. To provedeme pˇres instrukci lidt14:

asm volatile("sidt %0" : "=m" (idtr)); //Zisk adresy tabulky pˇreruˇsen´ı idtr.idt_table = new_idt_table; //Modifikace adresy tab. pˇreruˇsen´ı asm volatile("lidt %0" :: "m" (idtr)); //Uloˇzen´ı adresy tab. pˇreruˇsen´ı Uk´azku lze nal´ezt v pˇr´ıloze A pod ˇc. x.

Nejˇcastˇeji pouˇz´ıvan´y zp˚usob ´utoku na rozhran´ı syst´emov´ych vol´an´ı je ´utok na tabulku syst´emov´ych vol´an´ı nebo na rutinu syst´emov´eho vol´an´ı. Obl´ıbenost tˇechto zp˚usob˚u tkv´ı v jejich jednoduchosti a nenesou s sebou ˇz´adn´a omezen´ı. Metoda zmˇeny prvn´ıch 7B v ob-sluˇzn´e rutinˇe je pouˇziteln´a na libovolnou funkci. Jej´ı nejvˇetˇs´ı nev´yhodou je fakt, ˇze jej´ı k´od nemohou vykon´avat dva procesy z´aroveˇn (z d˚uvodu ukl´ad´an´ı a obnovov´an´ı onˇech ´uvodn´ıch 7B). Tuto kritickou sekci mus´ı chr´anit napˇr. spinlock. Princip pojmenovan´y jako tabulka pˇreruˇsen´ı patˇr´ı ke zp˚usob˚um pokroˇcil´ym, vyˇzaduj´ıc´ı ˇc´ast implementace v assembleru. Jeho rozˇs´ıˇren´ım jsme objevili zp˚usob nov´y, pojmenovan´y jako CPU registr idtr. Ten je ze vˇsech zp˚usob˚u nejsloˇzitˇejˇs´ı a v praxi zat´ım nebyl pouˇzit ani diskutov´an.

Moˇznosti obrany a detekce

Nejobvyklejˇs´ı zp˚usobem ochrany pˇred podobn´ym typem ´utok˚u je kontrola vˇsech hodnot, kter´e m˚uˇze ´utoˇcn´ık zmˇenit. Pˇri tom se doporuˇcuje ˇc´ıst hodnoty po bytech, nebot’ ´utoˇcn´ık m˚uˇze ´upravou syst´emov´eho vol´an´ı read() maskovat svoji pˇr´ıtomnost v syst´emu. Zaj´ımavou myˇslenkou m˚uˇze b´yt i poˇc´ıt´an´ı dlouhodob´eho pr˚umˇeru vykonan´ych instrukc´ı15. Vych´az´ı z faktu, ˇze jak´akoliv modifikace pˇrid´av´a v´ykonn´y k´od a t´ım p´adem zpomaluje cel´y syst´em. Uˇz z podstaty se jedn´a o jakousi fuzzy metodu, kterou je tˇreba podpoˇrit dalˇs´ımi mˇeˇren´ımi.

2.2.2 Napaden´ı virtu´aln´ıho souborov´eho syst´emu

Jak plyne z kapitoly 1.2.4, nach´az´ı se virtu´aln´ı souborov´y syst´em na niˇzˇs´ı vrstvˇe neˇz rozhran´ı syst´emov´ych vol´an´ı. Tvoˇr´ı spojuj´ıc´ı vrstvu mezi abstraktn´ım syst´emov´ym vol´an´ım a skuteˇcnou implementac´ı souborov´eho syst´emu (obr. 2.3). V´ysledkem je, ˇze uˇzivatel je od souborov´eho syst´emu kompletnˇe odst´ınˇen a pˇr´ıstup k nˇemu prov´ad´ı v´yhradnˇe a jen pˇres syst´emov´a vol´an´ı. Ty pak na z´akladˇe um´ıstˇen´ı souboru v souborov´em syst´emu vyberou konkr´etn´ı metodu pro pˇr´ıstup k fyzick´emu m´ediu.

Virtu´aln´ı souborov´y syst´em rozliˇsuje tyto ˇctyˇri druhy struktur:

1. superblok – informace o souborov´em syst´emu (filesystem metadata), 2. i-uzel – informace a identifikace souboru (file metadata),

14Instrukce lidt napln´ı registru idtr sv´ym 5 slabikov´ym operandem. 15

References

Related documents

As demonstrated above, the National Green Building Standard is clearly equivalent to LEED NC when individual green categories are compared, and far more stringent than LEED NC

a valuable tool for identifying mercury species in gypsum samples obtained in WFGD plants in 263 .. In particular, the results obtained from the analysis of the different gypsum

 The relation between action and desire: because user’s actions are mainly determined by his desire and the current context values, and there is only one active user during a

Relatively few outsiders had direct contact with these remote and closed societies, and little real knowledge needed obstruct the creative fantasy of elite ideologues, but

(2001) considers both the elderly population and welfare participants in Quebec, Canada and find that demand for essential drugs reacts less to the introduction of prescription

The throttle screw D4 on the solenoid valve S3 is used to adjust the deceleration from nominal speed to precision lowering speed. The following applies:. Turn inward =

These key recommendations are: (1) investigation of barriers into green practices based on the findings in this thesis, and into solutions to those barriers; (2) more

Ultraviolet and optical stellar spectra of the HgMn slowly rotat- ing star HD 175640, observed with both HST-STIS and UVES instruments, were used to extend and discuss the atomic