Professional Documents
Culture Documents
KONZULENS
Tartalomjegyzk
sszefoglal .................................................................................................................5 Abstract ....................................................................................................................... 6 1 Bevezets ................................................................................................................... 7 1.1 Feladat rtelmezse .............................................................................................. 7 1.2 Tervezs clja ......................................................................................................7 1.3 Feladat indokoltsga ............................................................................................ 7 1.4 Szakdolgozat felptse ........................................................................................ 8 2 State-of-the-art feltrs ............................................................................................ 9 2.1 Proactive security ................................................................................................ 9 2.2 Tmadsi formk ............................................................................................... 10 2.2.1 NULL pointer dereferencia ......................................................................... 10 2.2.2 Buffer overflow .......................................................................................... 11 2.2.3 Format string tmadsok ............................................................................. 13 2.2.4 Return-oriented Programming (ROP) .......................................................... 14 2.2.5 Jump-oriented Programming (JOP) ............................................................. 14 2.3 Memriavdelmi megoldsok ............................................................................ 15 2.3.1 Memria rhatsgt s futtathatsgt korltoz megoldsok ..................... 15 2.3.2 Stack canary (SSP) ...................................................................................... 17 2.3.3 ASLR.......................................................................................................... 18 2.3.4 UDEREF .................................................................................................... 19 2.3.5 Segvguard ................................................................................................... 19 2.3.6 KERNEXEC ............................................................................................... 19 2.3.7 SMEP ......................................................................................................... 20 2.4 FreeBSD ............................................................................................................ 21 2.4.1 Felpts ..................................................................................................... 21 2.4.2 VM felpts ............................................................................................... 22 2.4.3 Trap ............................................................................................................ 25 2.4.4 Alacsony szint memriakezel rutinok ...................................................... 25 2.4.5 Sysctl interface............................................................................................ 26 2.4.6 Tunable interface ........................................................................................ 26 2.4.7 CPU inicializci ........................................................................................ 26
2.4.8 Kernel debug............................................................................................... 27 2.5 Intel x86-64 ....................................................................................................... 29 2.5.1 Architektra ................................................................................................ 29 2.5.2 Binris patchels nmdost kd ............................................................ 29 2.5.3 XD bit ......................................................................................................... 29 2.5.4 SMAP ......................................................................................................... 30 2.5.5 CPL ............................................................................................................ 30 3 Megvalsts ........................................................................................................... 31 3.1 SMAP implementlsa FreeBSD kernelben ....................................................... 31 3.1.1 ksp_kpatch futsidej binris patchels .................................................... 31 3.1.2 SMAP ......................................................................................................... 35 3.1.3 Szksges kernel mdostsok .................................................................... 38 3.1.4 Tesztek ....................................................................................................... 44 3.2 ASLR megvalstsa FreeBSD-ben ................................................................... 46 3.2.1 ASLR.......................................................................................................... 46 3.2.2 Szksges mdostsok ............................................................................... 46 3.2.3 Kezdeti belltsok ...................................................................................... 53 3.2.4 Buktatk ..................................................................................................... 55 3.2.5 Emulcis rtegek ....................................................................................... 55 4 rtkels ................................................................................................................. 56 4.1 SMAP................................................................................................................ 56 4.2 ASLR ................................................................................................................ 59 4.2.1 ASLR tesztesetek ........................................................................................ 59 4.3 FreeBSD helyzete .............................................................................................. 73 Ksznetnyilvnts................................................................................................... 77 Irodalomjegyzk ........................................................................................................ 78 brajegyzk ............................................................................................................... 82 Rvidtsek ................................................................................................................ 83 Fggelk ..................................................................................................................... 85
HALLGATI NYILATKOZAT
Alulrott Pintr Olivr, szigorl hallgat kijelentem, hogy ezt a szakdolgozatot meg nem engedett segtsg nlkl, sajt magam ksztettem, csak a megadott forrsokat (szakirodalom, eszkzk stb.) hasznltam fel. Minden olyan rszt, melyet sz szerint, vagy azonos rtelemben, de tfogalmazva ms forrsbl tvettem, egyrtelmen, a forrs megadsval megjelltem. Hozzjrulok, hogy a jelen munkm alapadatait (szerz(k), cm, angol s magyar nyelv tartalmi kivonat, kszts ve, konzulens(ek) neve) a BME VIK nyilvnosan hozzfrhet elektronikus formban, a munka teljes szvegt pedig az egyetem bels hlzatn keresztl (vagy hitelestett felhasznlk szmra) kzztegye. Kijelentem, hogy a benyjtott munka s annak elektronikus verzija megegyezik. Dkni engedllyel titkostott diplomatervek esetn a dolgozat szvege csak 3 v eltelte utn vlik hozzfrhetv. Kelt: Budapest, 2013. 05. 17.
sszefoglal
Napjainkban az informatika s informatikai szolgltatsok elterjedtek. Az let minden terletre beszivrogott, s az emberek napjainak szerves rszt kpezi. Reggel felkelnek, elveszik az oko stelefonjukat s kzssgi oldalakat nznek, a buszon hreket olvasnak, este ttermet vagy szrakozhelyeket keresnek az interneten. Ezt az informcihsget s terhelst ki kell szolglni. A legnagyobb rendelkezsre llssal rendelkez tartalomszolgltatk ltalban valamilyen szerver opercis rendszert hasznlnak. A Netcraft[46] felmrsei alapjn ezek tlnyom tbbsgben FreeBSD, Microsoft Windows Server 2008 s Linux rendszerek. A munkm sorn FreeBSD rendszerekkel foglalkozom, tbb okbl kifolylag. A FreeBSD a Linuxokhoz s Windowsokhoz kpest kevsb elterjedt rendszer, kisebb fejleszti bzissal rendelkezik, azonban bizonyos terleteken gy is versenykpes velk. Teljestmnyben sok helyen meg is elzi ket. A FreeBSD egy nylt forrs rendszer, mely fejlesztse sorn els szempont a teljestmny volt. A korltozott fejleszti kapacitsok miatt gy ms terletek httrbe szorultak. Az egyik ilyen terlet a biztonsg. A rendszer tartalmaz biztonsgi megoldsokat, amelyek magasabb szinten befolysoljk a rendszer mkdst. Ezek a teljessg ignye nlkl: jails, DAC, MAC, BSM s BSM-re pl megoldsok. Fejlesztsk a TrustedBSD projekt keretn bell kszlt el, melyet rszben a DARPA tmogatott. A rendszer azonban a mai napig szinte mentes az alacsony szint proac tive vdelmi megoldsoktl. A dolgozatomban ezek llapotnak felmrsvel foglalkoztam s egy (kett) lehetsges megolds kivlasztsa utn azt implementltam. A fontossga miatt vlasztsom az ASLR-re s jdonsga miatt az SMAP-ra esett.
Abstract
Today, information technology and information services are prevalent. Theyre present in all aspects of life and form an integral part of people's days. People get up in the morning and take their smart phones, browsing social networking sites and reading news on the bus, and at night they looking for restaurants or night clubs online. This hunger for information and load must to be served. The content providers that have the greatest availability generally have a server operating system in use. According to Netcraft's surveys, the overwhelming majority of them are, FreeBSD, Microsoft Windows Server 2008 and Linux systems. The topic of my thesis deals with the FreeBSD system for many reasons. FreeBSD is less commonly used than Linux or Windows, and has a smaller developer base; however, in some areas it is still competitive with them, and is leader in performance. FreeBSD is an open-source system, where the priority in development was performance. Due to the limited capacity of development in other areas are overshadowed. One such area was security. The system includes security solutions that affect the operation of the system at a higher level. These are without attempting to be comprehensive: jails, DAC, MAC, BSM and BSM solutions built on. Their development was completed within the TrustedBSD project which was partially supported by DARPA. However, the FreeBSD system still does not have a lot of proactive security solutions. My thesis deals with the assessment of their condition and after choosing one (two) possible solution that has been implemented. The choice fell on ASLR and SMAP.
1 Bevezets
1.1 Feladat rtelmezse
A feladat, megvizsglni, hogy a jelenlegi FreeBSD 10-CURRENT (a legfrissebb fejleszti vltozat, 2013. februr 2013. mjus) milyen vdelmi megoldsokat tartalmaz a lehetsges megoldsok kzl. Ezt kveten egy nem implementlt megoldst implementlok, s megvizsglom vals krlmnyek kztt, kitrve a teljestmnyre is, mivel a FreeBSD projekt szmra az elsk kztt van a teljestmny is.
tartalomszolgltatk, hlzati infrastruktra ksztk s IT biztonsgi cgek is. Emellett tervek fogalmazdtak meg bennem a FreeBSD opercis rendszerrel. A kzeljvben vagy FreeBSD commiter (olyan szemly, aki rendelkezik rsjoggal a hivatalos FreeBSD verzikvet rendszerhez) szeretnk lenni, vagy a FreeBSD opercis rendszer forkolsval kvnok ltrehozni egy biztonsgos s friss BSD varinst, mely annyira kveti a szl opercis rendszert, amennyire csak lehet.
rszegysgeirl adok egy ttekintst. A Intel x86-64 rszben az Intel x86-64 processzor pr tulajdonsgrl fogok rszletesebben rni, melyek kapcsoldnak a tmmhoz. Az ezt kvet rszekben (SMAP implementlsa FreeBSD kernelben s ASLR megvalstsa FreeBSD-ben) pedig a konkrt tervezsi s megvalstsi megoldsokat rom le, melyek ptenek az elz fejezetekre. Vgezetl az rtkels valamint a rszben bellk rtkelem leszrt s sszegzem a s
megoldsokat eredmnyeket.
tapasztalatokat
2 State-of-the-art feltrs
2.1 Proactive security
A klasszikus biztonsgi megoldsok s megvalstsok egy mr bekvetkezett tmads s/vagy kreset felkutatsval s utlagos vagy folyamatlagos kezelsvel foglalkoznak, ezt hvjuk ltalnosabban reactive security-nek is. Ilyen megoldsok a ma is forgalomban kaphat vrusirtk, tzfalak s forensics eszkzk , mivel tbbsgk egy, mr ismert minta vagy szignatra alapjn dolgozik. Termszetesen ezek az eszkzk is egyre nagyobb tudssal lesznek felvrtezve s mozdulnak el proactive irnyba. Ezzel szemben a proactive security megoldsok a hangslyt egy esetleg tmads megelzsre fektetik. A kszti s alkalmazi megprblnak mindig egy lpssel a tmad eltt lenni s megakadlyozni egy esetleges betrs sikeressgt vagy legalbb nagysgrendekkel megnehezteni azt. Ilyen megoldsok a '90-es vek vgtl kezdtek terjedni, leginkbb a PaX s az OpenWall kezdemnyezseknt. Az ltaluk kifejlesztett technolgikat ksbb nagyobb software cgek is tvettk, tbbek kztt a Microsoft is a Windows rendszerekhez.
Amikor a kernel vgrehajtja a read() hvst a char dev-en, akkor lefut a kf_ptr() fggvny, azonban a kf_ptr NULL-ra mutat, gy az aktulis process cmternek NULL cmn tallhat utastsait hajtja vgre a kernel. User space oldalrl pedig a kvetkez kdrszlet: 10
char shellcode[] = SHELLCODE helye; void bar(void) { int dev=0; char dummy[4096]; mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0); memcpy(NULL, shellcode, sizeof(shellcode)); dev = open(/dev/echo, O_RDWR); read(dev, dummy, PAGE_SIZE); }
Itt felmappeljk a NULL cmtl kezdd lapot, s elhelyezzk rajta a shellcodeot, ezt kveten meghvjuk rajta a srlkeny read() fggvnyt. Erre is szletett egy korltoz megolds, melynek lnyege, hogy mmap()-elni, csak egy bizonyos virtulis memria cm felett enged a rendszer, ez tipikusan egy lap mret vagy ennek kett hatvny szorosa. x86-64 rendszeren a lapmret 4096 byte, a minimlis VM cm FreeBSD esetben pedig 4 kbyte, ha a security.bsd.map_at_zero sysctl rtke 0. Vdekezs ellene: VM kezdcm megemelse, UDEREF, SMEP s SMAP.
11
2.2.2.2 stack buffer overflow (stack smashing) A problma oka ltalban a hinyz vagy tves hatr ellenrzs vagy integer over vagy underflow. Egy srlkeny kd a kvetkez:
#include <string.h> void foo (char *bar) { char buff[12]; strcpy(buff, bar); } int main (int argc, char **argv) { foo(argv[1]); }
Ha programot els paramterknt 12 karakternl hosszabb string -gel hvjuk meg, akkor a foo() fggvnyben tallhat buff tmbt elkezdjk rni, s mivel a strcpy() fggvny nem ellenriz hosszt, ezrt az rs nem fejezdik be a tmb vgnl, hanem a stack-en lev szenzitv adatokat is fellrjuk Egy megfelelen elksztett string esetn a program flow-t kontrolllni tudjuk. Vdekezs ellene ASLR-rel, NX stack-kel vagy SSP-vel trtnik. 2.2.2.3 heap overflow A heap overflow[27] ugyancsak a buffer overflow-k csaldjba tartozik. A stack overflow-nl komplexebb tmadst ignyel. A heap-en a memrit dinamikusan allokljuk. Ezen allokcik nyilvntartsa ltalban egy segd struktrval trtnik, melyek magukban foglaljk a memria rgikat is. A tmads clja ezeknek a struktrknak a fellrsa s a control flow eltrtse. Vdekezs ellene ASLR-rel s NX bittel trtnik.
12
kiolvashatunk a segtsgvel. Egy egyszer plda, mely format string tmadshoz vezethet:
... char buff[256]; scanf(%s, buff); printf(buff); ...
A baj pedig a printf() fggvnycsald termszetes mkdsbl fakad. A formtum string-knt megadott %-ot kvet paramtereknek megfelel rtkeket veszi le a stack-rl. Ha inputknt egy crafted inputot adunk, akkor annak megfelelen fogja vgigprgetni a stacket. Ez manapsg ltalnos esetben infoleak-hez j. Pldul, ha a %x %x %x %x format string-et adjuk be, akkor a stack-rl az els 4 integert olvashatjuk ki. Rgebben vagy specilis fordtsi direktvt hasznlva, a printf() fggvnnyel rni is lehet, nem csak olvasni a stack-rl. Ehhez %n formtumot kell alkalmazni, s paramterknt a printf() stack-jn a clcmet kell tartalmazni, ahova a %n-ig kirt byte-ok szma kerl.
... char *s=foo; int size; printf(%s%n, s, &size); ...
A kd lefutsa utn a size vltoz rtke 3 lesz, mivel az s pointer egy 3 hossz string-re mutat s a foo 3 karakterbl ll. Ha ez kombinljuk a lefelejtett format string-gel s mi tudjuk megadni, hogy mit, hol, hova s milyen mdon rjon ki a printf(), akkor szinte brmit mdostani tudunk a memriban. Vdekezs ellene ASLR-rel s NX bittel trtnik. 13
14
Ez a vdelem sok elny mellett htrnyokkal is jrhat, mivel az alkalmazs ksztk hanyagsgbl vagy lustasgbl nem megfelelen hasznljk az mmap() s mprotect() interface-t. Ez leginkbb a futs kzben generlt kdokra igaz, melyeket utna vgre akarunk hajtani (JIT, just in time framework-k). A FreeBSD nem tartalmaz PaX MPROTECT biztonsgi megoldst. 2.3.1.2 W^X A W^X[42] az OpenBSD software-s megoldsa az NX-re mely a PaX PAGEEXEC[50]-bl mert tleteket , olyan esetekben, amikor a hardware nem tartalmaz hozz kiegsztst. A megolds a klnbz ELF szekcikat sztszedi, s a vdelmi szintnek megfelelen jrarendezi, melyek vdett memria cmeken
helyezkednek el. Ez a mdszer x86 esetben rvnyes. A FreeBSD nem tartalmaz W^X biztonsgi megoldst.
15
2.3.1.3 XD Az XD (XD bit eXecute Disable) az Intel fejlesztse, mely segtsgvel lapokat tudunk nem futtathatnak jellni. A szolgltats rendelkezsre ll az XD kiterjesztst tartalmaz 32 bites processzorokban s 64-bites x86-64 processzorokban.
Az NX megltt a CPUID.80000001H:EDX.NX[bit20] alapjn tudjuk ellenrizni[9]. Lnyegben ez a hardware oldali megvalstsa a W^X-nek bizonyos korltozsokkal. nmagban nem jelent megoldst minden problmra, de elsegti ms technolgikkal egytt a hatkony vdekezst. FreeBSD alatt hasznlt vdelmi megolds.
16
17
2.3.3 ASLR
Az ASLR[10] Address Space Layout Randomization clja, hogy vletlenszersget vigyen a processzek cmterbe, ez ltal megneheztve az exploitok lefutst. Egy program cmtere tbb rszbl ll, mint pldul a text szegmens, a data szegmens, a bss, a stack s a program ltal hasznlt megosztott knyvtrak. Ezen fell a cmtrbe lehetnek mappelve file-ok s memria rgik sokasga az mmap() rendszerhvs segtsgvel. Az ASLR ezen szekcik kezdcmeit hivatott randomizlni. Ezen fell, a program belpsi pontja is randomizlhat. Itt ktfle futtathat file tpust klnbztetnk meg: ET_EXEC s ET_DYN. Az ET_EXEC esetn a program maga nincs felksztve relokcira, a benne tallhat szimblumok abszolt elrsek a program belpsi pontjtl szmtva, gy ebben az esetben a belpsi pont randomizcija nem trivilis. ET_DYN esetben mr maga a binris fel van ksztve a relokcira, gy ebben az esetben egyszerbb dolgunk van. A binrisokat az exec_loader tipikusan mmap() fggvnyhvs segtsgvel mappeli be a cmtrbe. A FreeBSD nem tartalmaz ASLR biztonsgi megoldst. 2.3.3.1 mmap randomizci Az mmap randomizci PaX Team ltal RANDMMAP[11] nven referlt megolds az mmap() rendszerhvst hivatott randomizlni. A randomizcit a cmen minden mmap() hvs esetn alkalmazzuk, kivve, ha a MAP_FIXED flag-gel jelezzk a kernelnek, hogy a megadott cmre szeretnnk krni az adott vm_address rgit. 2.3.3.2 stack randomizci Stack randomizci RANDUSTACK[12] esetn a stack kezdcmt randomizljuk. Itt ktfle megolds van. Az egyszerbb az gynevezett stack gap hasznlata, amikor az adott lapon bell eltoljuk a stacket N darab bittel. A bonyolultabb megolds pedig az elbbi megoldst is felhasznlva ezen fell mg a program indulsakor vletlen cmre mappeli a stack kezdett. Ltezik egy RANDKSTACK[13] is, mely a kernel stacket hivatott randomizlni.
18
2.3.4 UDEREF
Az UDEREF[14][15] megolds azt a clt tzte ki maga el, hogy biztostsa a kernel space user space hatrokat s hiba esetn a kernel ne dereferljon user space memrit, ha az explicit nincs engedlyezve. Ha nem engedlyezett dereferls trtnik, akkor a kernel Oops-ot vagy kernel panic()-ot dob az adatok sikeres kiolvassa helyett. Ez azrt fontos, mert gy a kernel exploitok egy nagy halmazt hatstalantani lehet. Ez azrt mkdhet, mivel eltte legitim mdon shell kdot kell a kernelbe injektlni, de az UDEREF miatt nem lehet egyszeren csak a user space memrit cm szerint dereferlni. Az UDEREF egy software-es megolds, x86-on hatkonyan implementlhat minimlis sebessgvesztssel szegmentci alkalmazsval. Az x86-64-es CPU azonban nem tartalmazza a szegmentcit, gy kerl megoldsokat kell alkalmazni. Az UDEREF a user space - kernel space tmenetnl unmappeli az eredeti user space cmteret s tmappeli egy msik cmtrre, ami non-exec/supervisor jogokkal br, gy ha a kernel innen prbl kdot futtatni, akkor Oops-ot vagy panic()-ot kapunk. A FreeBSD nem tartalmaz UDEREF biztonsgi megoldst.
2.3.5 Segvguard
Az ASLR srlkenysgt hivatott kijavtani. Az ASLR bruteforce
alkalmazsval kijtszhat. A servguard[16][17] nmagban nem egy memriavdelmi megolds. A megolds lnyege, hogy minden a kernel ltal terminlt program utn feljegyezzk a terminls idejt s okt. Ezen informcikat aggregljuk, s egy limitet lltunk be r: az adott id alatt tolerlhat hiba mennyisgt. A limit tlpse utn a kernel addig nem enged j folyamatot ltrehozni, ameddig a limit le nem telt. A FreeBSD nem tartalmaz Segvguard biztonsgi megoldst.
2.3.6 KERNEXEC
A KERNEXEC[48][49] a W^X esetben emltett PAGEEXEC s az MPROTECT kernel space beli megfelelje. Segt megakadlyozni, hogy kernel space kd kernel spaceben user space kdot lefuttasson. A FreeBSD nem tartalmaz KERNEXEC biztonsgi megoldst 19
2.3.7 SMEP
Az SMEP[44] (Supervisor-mode execution Prevention) ugyancsak az Intel ltal kifejlesztett technolgia, melynek clja, hogy a kernel space kd ne tudjon user space memrin elhelyezked kdot vgrehajtani. Ez lnyegben az elbb emltett KERNEXEC hardware oldali megfelelje. FreeBSD alatt hasznlt vdelmi megolds.
20
2.4 FreeBSD
2.4.1 Felpts
A FreeBSD kernel tervezsekor trekedtek az egyszersgre s tlthatsgra. A kd alapjban vve kt jl elklnl rszre oszthat [6]: gpfgg (machine-dependent, MD) s gp fggetlen (machine-independent, MI) kdokra. Ennek a szeparcinak a lnyege, hogy egy adott megoldst vagy driver-t csak egyszer kell megrni MI mdon, s ez az MI mdon megrt rteg nem tartalmaz semmilyen MD kdot, s az alsbb architektrnknt vltoz, de azonos interface-t nyjt MD rteget hasznlja. Az MI rsz tovbb oszthat, ezek a teljessg ignye nlkl a kvetkezk: basic kernel facilities alap kernel szolgltatsok: timer s rendszer id kezels, descriptor kezels s process kezels memory-management support memria menedzsment: lapozs s lapcsere generic system interfaces ltalnos rendszer interface-ek: I/O kontrol s prhuzamos mveletek descriptor-okon file system file rendszerek: file-ok, mappk, elrsi utak fordtsa, file zrols s I/O buffer kezels terminal-handling support terminl kezels: pseudo terminl interface s terminl felgyelet inter-process communication facilities folyamatok kztti
kommunikci: socket-ek networking hlzatkezels: kommunikcis protokollok s ltalnos hlzati erforrsok Ezek kzl jelenleg a memriakezelsre s a virtulis memrira fkuszlok.
21
2.4.2 VM felpts
2.4.2.1 Address space A sys/amd64/include/vmparams.h file-bl:
/* * Virtual addresses of things. Derived from the page directory and * page table indexes from pmap.h for precision. * * 0x0000000000000000 - 0x00007fffffffffff user map * 0x0000800000000000 - 0xffff7fffffffffff does not exist (hole) * 0xffff800000000000 - 0xffff804020100fff recursive page table (512GB slot) * 0xffff804020101000 - 0xfffffdffffffffff unused * 0xfffffe0000000000 - 0xfffffeffffffffff 1TB direct map * 0xffffff0000000000 - 0xffffff7fffffffff unused * 0xffffff8000000000 - 0xffffffffffffffff 512GB kernel map * * Within the kernel map: * * 0xffffffff80000000 KERNBASE */
Lthat a kvetkez brn, hogy a FreeBSD kernel mint a legtbb kernel a negatv cmtrben fut x86-64 architektrn. A user space memria pedig a pozitv cmtren helyezkedik el.
0xffffffffffffffff
kernel
hole
0x0000800000000000 0x00007fffffffffff
0x0000000000000000
22
Ezen bell is, a user space cmtr rdekel minket els sorban, az ASLR relcijban. 2.4.2.2 A vmspace A vmspace adatstruktra rja le a FreeBSD rendszerben egy process cmtert. Ez magban foglalja a virtulis memria llapott, az MI s az MD rteget vonatkozlag is. Minden egyes vm_map_entry egy mappelt cmet tartalmaz. Szmunka ezek a legfontosabbak jelen helyzetben, mivel ezeket fogom mdostani. A vmspace struktra ki lesz egsztve kt vltozval, melyeket a ksbbiekben mutatok be.
2.4.2.3 A stack X86-64 esetben a stack lefel terjeszkedik, ami annyit tesz, hogy kezdcme alaprtelmezetten 0x00007fffffffffff. Ahogy nvekszik a stack gy ez a cm cskken. A stacket hasznljuk AUX infk tadsra is, melyeket a run-time link-editor (rtld) hasznl. Ugyancsak itt adjuk t a futtatand programnak a paramtereit s a krnyezeti vltozkat is.
23
A stack-hez a vmspace struktrban egy vm_map_entry tartozik, mely lerja a tulajdonsgait. A stack-en stack frame-ek tallhatk, melyeket x86-64-en az rbp regiszter cmez meg. Egy ilyen stack frame lthat a Figure 3 brn. 2.4.2.4 Az mmap Az mmap()[25] egy UNIX rendszerhvs, mely segtsgvel memrit tudunk foglalni, file-okat vagy eszkzket tudunk a memriba mappelni. A fggvny szignatrja:
void * mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
Els paramtere void *addr egy cm, mely, ha nem NULL, akkor az egy javaslat a rendszer szmra, hogy hova krjk a mappelst, ha NULL, akkor a rendszer dnti el, hogy milyen cmre rakja (ASLR-rel ezt kvnjuk els sorban randomizlni). Msodik paramtere size_t len megadja, hogy mekkora a mappelend cmtr. Harmadik paramtere int prot megadja, hogy milyen jogokat adunk az adott memria rginak, ez lehet PROT_NONE, PROT_READ, PROT_WRITE, PROT_EXEC s ezek kombincija. mprotect() esetn ezekre tesznk megszortsokat. Negyedik paramtere int flags megadja a mappelt objektum tpust, opciit s tulajdonsgait. tdik int fd egy file descriptor, mely megadja a mappelend objektum descriptort. 24
Hatodik paramter off_t offset megadja, hogy az fd-ben milyen offset-tl kezdve mappeljk be a memriba a len paramter ltal megadott hossz rgit. Az mmap() rendszerhvst kernel oldalon a sys_mmap() fggvny valstja meg, amit az ASLR implementlsakor mdostani fogok.
2.4.3 Trap
A trap egy specilis CPU szolgltats, mely segtsgvel bizonyos esemnyek kvetkeztben a rendszer kernel mdba vlt. A trap kivltsnak hatsra a rendszer llapota elmentsre kerl. Egy rszt maga a CPU menti le, ms rszt a trap-et lekezel rutin. A trap a folyamatok szmra szinkron. Trap keletkezik zr osztsnl, laphibnl s egyb esemnyek bekvetkezsekor. Ez bvebben megtallhat az Intel SDM-ben[1]. Jelen m esetben a laphiba esetn dobott trap lesz a fontos, mint ahogy ez ksbb lthat lesz.
int
copyin_nofault(const void * __restrict udaddr, void * __restrict kaddr, size_t __nonnull(2); int
len)
__nonnull(1)
copyout(const void * __restrict kaddr, void * __restrict udaddr, size_t len) __nonnull(1) __nonnull(2);
25
int
copyout_nofault(const void * __restrict kaddr, void * __restrict udaddr, size_t __nonnull(2); /* Fetch User Type */ int fubyte(const void *base); long fuword(const void *base); int fuword16(void *base); int32_t fuword32(const void *base); int64_t fuword64(const void *base); /* Set User Type */ int subyte(void *base, int byte); int suword(void *base, long word); int suword16(void *base, int word); int suword32(void *base, int32_t word); int suword64(void *base, int64_t word);
len)
__nonnull(1)
/* Compare and Set User Type */ uint32_t casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval); u_long casuword(volatile u_long *p, u_long oldval, u_long newval);
Ksbb ezek a fggvnyek mg el fognak kerlni, ezrt soroltam itt fel ket.
26
FreeBSD esetben sincs ez mskpp. A CPU inicializci FreeBSD alatt a hammer_time(...) fggvny segtsgvel trtnik. A teljessg ignye nlkl pr funkci, amit ez a fggvny vgez: belltja a kernel stacket, belltja a descriptorokat, ltrehozza az 0-s process-t, amely a kernel-t rja le, inicializlja a kernel-t rint mutex-eket, identifiklja a processzort s inicializlja, ezt kveten engedlyezi processzor cache vonalakat, inicializlja a memrit s elindtja a 0-s process-t. Szmunkra a hammer_time(...) fggvny ltal hvott initializecpu() fggvny az rdekes, mivel ez vgzi a valdi CPU inicializcit. Ez a fggvny tovbbi rszfggvnyekre bomlik, mely fggvnyek CPUID alapjn funkcikat kapcsolnak be a processzorban, pldul XD bit tmogatst, az SMEP tmogatst, vagy az ltalam ksztett patch utn az SMAP tmogatst.
27
2.4.8.2 KGDB A FreeBSD rendszerekben a msik szlltott debugger a kgdb[22], mely a gdb egy kiterjesztse kernel debuggolshoz. Ezt az eszkzt leginkbb post-mortem esetekben hasznljuk, de on-line kernel is debuggolhat vele (on-line esetben kgdb /boot/kernel/kernel /dev/mem parancs futtatsa szksges). A gdb teljes funkcionalitst tartalmazza kiegsztve pr kernel specifikus kiegsztssel.
28
2.5.3 XD bit
Az jabb Intel s AMD processzorokban alkalmazott technolgia, mellyel lapokat nem futtathatnak lehet jellni. Az XD feloldsa eXecution Disable. AMD esetben az XD-t NX-nek nevezik, mely feloldsa Never eXecute.
29
2.5.4 SMAP
Az SMAP[2][3] az Intel egyik legjabb fejlesztse, mely egy biztonsgi kiegszts. Feloldsa a Supervisor Mode Access Prevention. A megolds lnyegben az UDEREF[15] hardware oldali[19] megoldsa. A technolgia megakadlyozza, hogy lapozs esetn supervisor privilgiumban fut kd user md kdhoz tartoz memriaterlethez frjen hozz. Ha ezt megszegi, akkor laphiba kivtel dobdik. Ezt a korltozst tmenetileg ki lehet kapcsolni az EFLAGS.AC flag ki vagy be billentsvel. Errl bvebben a dolgozat htralev rszben lesz sz.
2.5.5 CPL
Current privilege level, aktulis privilgium szint. Az Intel processzorokban klnbz privilgiumszintek vannak, ezeket hvjuk Ring-nek is. Ngy szint definilt. A 0, 1, 2 supervisor md hozzfrst biztost, 0 biztostja a legtbb jogot s nvekedve cskken a jogosultsgok kre. A Ring 3 pedig a user md hozzfrs. Az opercis rendszerek tipikusan csak a 0-s s a 3-as mdot implementljk.
30
3 Megvalsts
3.1 SMAP implementlsa FreeBSD kernelben
3.1.1 ksp_kpatch futsidej binris patchels
3.1.1.1 Ismertets Mivel a FreeBSD alapbl nem tmogatja framework-szeren a binris patchels folyamatt, gy nekem kellett implementlnom a szakdolgozat keretein bell. Az gy elksztett ksp_kpatch framework-t rszben a Linux kernelben tallhat
alternatives[18] framework inspirlta, rszben a jzan sz. A framework szksgessgt az indokolja, hogy szp s hatkony megoldst kerestem a forrsban elszrtan s vltoz szmban elfordul, futsidben bizonyos felttelek alapjn kicserlend assembly utastsok cserjre. Ezt a framework nlkl is meg lehetett volna oldani felttelek beiktatsval, de mint azt mr tbbszr is hangslyoztam, FreeBSD esetben az elsdleges szempontok kztt a teljestmny ll, gy egy rendszer mlyt rint s sokat hasznlt fgg vnycsaldot befolysol kiegsztsnek hatkonynak kell lennie. A nem hatkony megoldsok a kvetkezk lennnek: minden egyes felttelhez kttt utasts lefutsa eltt meg kellene vizsglni az adott felttelt s a felttelnek megfelelen az adott utastsr a ugrani. Ennek kltsge, mint lthat elg nagy, mivel tartalmaz egy felttelt s egy ugrst. A msik megolds esetben rszben nmdost kd van alkalmazva, amikor egy alternatv utastst megelz s kvet egy-egy ugrs. Mint lthat, ez sem egy hatkony megolds, tbb szempontbl sem; ha a cm, amire ugrani kell, nem egy lapon van azzal a cmmel, ahol a megelz utasts szerepelt, akkor laphiba keletkezhet s a lapot be kell hozni, ergo a kltsg hatalmas lesz. Ezen tnyezk miatt a futsidej binris patchels mellett dntttem. Ez azt takarja, hogy amikor a rendszer bootols kzben a CPU-t inicializlja, akkor bizonyos felttelek s egy specilis adatszerkezet segtsgvel megkeresi a kernel binrisban tallhat utastsokat s kicserli azokat msikra. Ennek a megoldsnak is vannak htrnyai, de jval kevesebb, mint az elzeknek. Ez a megvalsts NOP utastsokat hasznl az alternatv utastsok helynek biztostsra, melyeket a patchels sorn kicserlek a cl utastsokra. A NOP utasts nem csak 1 byte-os NOP lehet, 31
hanem gynevezett multi byte NOP is, melyeket az Intel SDM tartalmaz. A multi byte NOP utastsok lnyege, hogy maga az utasts tbb byte hossz, de atomian egy rajel alatt futnak le. A megvalsts tnzsben s finomtsban segtsget kaptam Konstantin Belousov FreeBSD fejleszttl is. A szksges ismeretek nagy rszt az Intel SDM tartalmazza, rszben pedig a GNU assembler dokumentcija. A megvalsts jelenleg csak a szksges funkcionalitst tartalmazza, azaz jelen formjban csak a kernel image patchelse lehetsges vele, a kernel modulok nem. Ez a fejleszti dnts azrt lett meghozva, mert nem kapcsoldik kzvetlenl a biztonsgi tmakrhz. Azonban szksg volt r, hogy az SMAP technolgira felksztett kernel kpes legyen felbootolni olyan rendszeren jrafordts nlkl is, amely CPU-ja nem tartalmaz SMAP technolgit. Konstantinnal ebbl egy kisebb vita alakult ki, hogy a hely fenntartsra szolgl NOP utastsok lasstjk a rendszert, gy az SMAP patchbl kt verzi kszlt el; egy, amely esetben csak fordts idben lehet az alternatv utastsokat a kernelbe fordtani s egy, amely a ksp_kpatch frameworkt hasznlja. 3.1.1.2 Adatstruktra A hasznlt specilis struktra a kvetkez - sys/amd64/include/ksp_kpatch.h:
struct ksp_kpatch { char *patchable_address; char *patch_address; u_int feature_bit; u_short feature_selector; u_char patchable_size; u_char patch_size; }; /* /* /* /* /* /* 64 64 32 16 8 8 bit bit bit bit bit bit */ */ */ */ */ */
Az els struktra elem char *patchable_address megadja a kernel imageben a lecserlend utastsok cmt. Az ezt kvet elem char *patch_address megadja a lecserl utastsok cmt. Az u_int feature_bit megadja, hogy az u_short feature_selector ltal kivlasztott sttusz byte melyik bitje alapjn kell lecserlni vagy nem lecserlni az adott utasts sorozatot. Az utols kt elem pedig megadja a patchelend s a patch utastssorozatok mrett. Erre a ksbbiekben lesz szksg, mivel ellenrzm, hogy a patch nem nagyobb-e, mint a patchelend. Ha igen, akkor hibt dobok konkrtan egy KASSERT van alkalmazva, gy hiba esetn kernel panic() lesz a vgeredmny. 32
3.1.1.3 ksp_kpatch ltrehozsa A kernel forrsban ksp_kpatch-et a kvetkez formban lehet ltrehozni:
#define _ksp_kpatch_clac 89071: .byte 0x0f,0x1f,0x00 ; /* patchable - nop */ 89072: .pushsection set_ksp_kpatch_set, "a" ; .quad 89071b ; /* &patchable */ .quad 89073f ; /* &patch */ .int CPUID_STDEXT_SMAP ; /* feature_bit*/ .word CPU_STDEXT_FEATURE ; .byte 89072b-89071b ; .byte 89074f-89073f ; .popsection ; .pushsection set_ksp_kpatch_patch_set, "ax" ; 89073: .byte 0x0f,0x01,0xca ; /* patch - clac */ 89074: .popsection \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
Mint ahogy az lthat, a munka javarszt a fordtval vgeztetem el. Az elbb bemutatott struktra mezi itt lesznek kitltve. Ehhez a GNU assembler .pushsection s .popsection kztt tallhat rszek msik szekciba kerlnek a binrison bell, gy a patch hasznlati helyen a binrisban csak a 89071 s 89072 cmkk kztti binris szekvencia fog szerepelni, a tbbi "meta adat" a kernel image ms rszben fog elhelyezkedni. A .set_ksp_kpatch_set szekciban tallhatk a ksp_kpatch struktra adatai, az egyetlen figyelemre mlt dolog itt a mret szmtsok, melyeket a cmkk egymsbl kivonsval kapjuk meg. A .set_ksp_kpatch_patch_set szekciban tallhatk a patch byte sorozatok. A szekcikat linkert bemutat rszben bvebben kifejtem. 3.1.1.4 linker script mdostsok A mdostand file a sys/conf/ldscript.amd64, mely a kernel binris linkelst rja le. A mdostst most patch formtumban szemlltetem (mi vltozott az elz verzihoz kpest).
diff --git a/sys/conf/ldscript.amd64 b/sys/conf/ldscript.amd64 index 9210a73..3f22e63 100644 --- a/sys/conf/ldscript.amd64 +++ b/sys/conf/ldscript.amd64 @@ -67,6 +67,18 @@ SECTIONS PROVIDE (__etext = .); PROVIDE (_etext = .); PROVIDE (etext = .);
33
+ + + + + + + + + + + +
set_ksp_kpatch_set : { PROVIDE ( __start_set_ksp_kpatch_set = . ); KEEP (*(set_ksp_kpatch_set)); PROVIDE ( __stop_set_ksp_kpatch_set = . ); } set_ksp_kpatch_patch_set : { PROVIDE ( __start_set_ksp_kpatch_patch_set = . ); KEEP (*(set_ksp_kpatch_patch_set)); PROVIDE ( __stop_set_ksp_kpatch_patch_set = . ); } .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } .eh_frame_hdr : { *(.eh_frame_hdr) }
Itt lthat, hogy a hozzadott szekcik mg kt specilis elemet tartalmaznak, a __start_set_ksp_kpatch_patch_set s __stop_set_ksp_kpatch_patch_set vltozkat, melyek segtsgvel C kdbl egyszeren meg tudom tallni az adott szekci ltal tartalmazott adatokat jelen esetben ez egy tmb a set_ksp_kpatch_set esetben s egy vltoz hosszsg tmb a set_ksp_kpatch_patch_set szekci esetn. 3.1.1.5 Boot idej patchels folyamata A megvalsts a sys/amd64/amd64/ksp_kpatch.c file-ban tallhat. Itt hrom fggvny tallhat:
static void ksp_pad_with_nops(void *_buffer, unsigned int len) { ... }
Ez a funkci abban az esetben van hasznlva, ha a patch mrete kisebb, mint a patchelend kd mrete. Ebben az esetben a ksp_pad_with_nops() funkci kivlasztja a megfelel padding NOP utastsokat. Ez alatt azt kell rteni, hogy a lehet legnagyobb atomi NOP utastsokkal tlti fel a patchelend res helyet, hogy a futst a lehet legkisebb mrtkben lasstsa.
void ksp_kpatch_apply(struct ksp_kpatch *patch) { ... }
A ksp_kpatch_apply() vgzi a valdi patchelst. A fent definilt struktrt ez a funkci hasznlja. Kivlasztja a megfelel sttusz byte-okat s ellenrzi a feature_bit alapjn, hogy szksges-e az adott kdrszlet kicserlsre. Ha szksg van r, akkor a
34
megfelel helyen fellrja az utastsokat. Termszetesen eltte ellenrzi, hogy a mretek megfelelek-e.
void ksp_kpatch(void) { ... }
A ksp_kpatch() keresi ki a binris image-bl a ksp_kpatch-eket tartalmaz rszt, s az ott tallhat meta adatok alapjn vgigiterl rajtuk. A megtallshoz itt hasznljuk fel a linker szekci lersban korbban emltett kt specilis vltozt (__start_set_ksp_kpatch_patch_set s __stop_set_ksp_kpatch_patch_set). 3.1.1.6 boot folyamatba beilleszts A ksp_kpatch() a sys/amd64/amd64/machdep.c file-ban tallhat
hammer_time() funkciban kap helyet. A hammer_time() fggvny felels felkszteni a CPU-t UNIX rendszer futtatsra.
@@ -1800,6 +1801,9 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) initializecpu(); /* Initialize CPU registers */ initializecpucache(); + + + /* patching kernel text for new instructions */ ksp_kpatch(); =
A patchels a CPU s CPU cache inicializci utn trtnik meg. A cache trlsvel nem kell foglalkozni[4][5].
3.1.2 SMAP
Az Intel 64 (X86-64) architektra eddig kt megoldst adott a lineris memribl utasts vgrehajts korltozsra: az eXecute Disable (XD, NX) bitet s az SMEP technolgit. A harmadik ilyen szablyoz technolgia az SMAP[2], mely az adathozzfrst hivatott szablyozni. Az SMAP feloldsa Supervisor Mode Access Prevention. Ha az SMAP be van kapcsolva, akkor a processzor elutastja a supervisor md adathozzfrst azon lapokhoz, melyek user mdn elrhetk. Az elutastott hozzfrs laphibt eredmnyez. Ez azonban nem minden esetben kvnatos, mivel a kernelnek 35
hozz kell frnie user lapokhoz pldul a korbban emltett copyin s copyout fggvnycsald tagjainak mivel ez a termszetes funkcionalitshoz hozz tartozik. Erre az esetre az SMAP architektra megengedi, hogy tmenetileg hozzfrjnk user space lapokhoz: engedlyezsre a stac, visszavonsra a clac utasts szolgl, melyekkel az EFLAGS.AC bitet tudjuk lltani. 3.1.2.1 A cpuid Az SMAP tmogats meglte a cpuid utastssal krhet le. Ha a processzor tmogatja, akkor CPUID.(EAX=07H,ECX=0H):EBX.SMAP[bit 20] = 1. Ezt kveten a CR4.SMAP[bit 21] bit belltsval tudjuk bekapcsolni a szolgltatst. A szolgltats kikapcsolt paging mdban is bekapcsolhat, azonban nincs hatssal a processzor ezen md mkdsre. 3.1.2.2 STAC SMAP vdelem alatt tmeneti user space hozzfrs engedlyezse. EFLAGS.AC bit belltsa, csak Ring 0-ban lehet hasznlni. gpi kdja: 0F 01 CB 3.1.2.3 CLAC SMAP vdelem alatt tmeneti user space hozzfrs visszavonsa. EFLAGS.AC bit trlse, csak Ring 0-ban lehet hasznlni. gpi kdja: 0F 01 CA 3.1.2.4 SMAP s a hozzfrsi jogok Adat olvass engedlyezett[2]: - Ha CR4.SMAP = 0, akkor adat olvashat minden lineris cmrl, amihez tartozik valid cmfordts - Ha a CR4.SMAP = 1, akkor a hozzfrsi jogok fggenek a CPL-tl s az EFLAGS.AC bittl: * ha CPL < 3 s EFLAGS.AC = 1: adat olvashat minden lineris cmrl, amihez tartozik valid cmfordts
36
ha CPL = 3 vagy EFLAGS.AC = 0, akkor adat olvashat minden olyan lineris cmrl, melyhez tartozik valid cmfordts mely esetben a U/S flag (bit 2) = 0 legalbb egy cmfordtst felgyel lapbejegyzsen
Adat rs engedlyezett: - Ha a CR0.WP = 0 s CR4.SMAP = 0, akkor adat rhat minden lineris cmre, amihez tartozik valid cmfordts - Ha a CR0.WP = 0 s CR4.SMAP = 1, akkor a hozzfrs fgg a CPLtl s EFLAGS.AC flag-tl. * Ha CPL < 3 s EFLAGS.AC = 1, akkor adat rhat minden lineris cmre, amihez tartozik valid cmfordts * Ha CPL = 0 vagy EFLAGS.AC = 0, akkor adat rhat minden olyan lineris cmen, amelyhez tartozik valid cmfordts mely esetben a U/S flag (bit 2) = 0 legalbb egy lapbejegyzsen - Ha a CR0.WP = 1 s CR4.SMAP = 0, akkor adat rhat minden olyan lineris cmre, amihez tartozik valid cmfordts mely esetben a R/W flag (bit 1) = 1 minden cmfordtst felgyel lapbejegyzsen
Ha a CR0.WP = 1 s CR4.SMAP = 1, akkor a hozzfrsi jogok fggenek a CPL-tl s az EFLAGS.AC flag-tl: - Ha a CPL < 3 s EFLAGS.AC = 1, akkor adat rhat minden olyan lineris cmre, amihez tartozik valid cmfordts mely esetben a R/W flag (bit 1) = 1 minden cmfordtst felgyel lapbejegyzsen - Ha a CPL = 3 vagy EFLAGS.AC = 0, akkor adat rhat minden olyan lineris cmre, melyhez tartozik valid cmfordts mely esetben a U/S flag (bit 2) = 0 legalbb egy cmfordtst felgyel lapbejegyzsen s a cmfordtst felgyel sszes lapbejegyzsen az R/W (bit 1) = 1
Az SMAP ltal nem engedlyezett adathozzfrsek laphibt eredmnyeznek. Az SMAP nincs hatssal az instruction fetch-re, a user md adat elrsre s a supervisor md adatelrsre csak supervisor lapokra.
37
3.1.2.5 SMAP ltal kivltott laphiba Az SMAP ltal kivltott kivtel laphiba s a hibakdja 1, ha olvassrl van sz, s 3, ha rsrl van sz.
3.1.3.2 pmap.c Az SMAP support-ot az initcpu helyett a pmap alrendszerben kapcsoljuk be, mivel a bootols korai szakaszban mg nincs r szksg s problmkat is okozhat. 38
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 1b1c86c..8fb223a 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -98,6 +98,7 @@ __FBSDID("$FreeBSD$"); * and to when physical maps must be made correct. */ +#include "opt_cpu.h" #include "opt_pmap.h" #include "opt_vm.h" @@ -665,6 +666,18 @@ pmap_bootstrap(vm_paddr_t *firstaddr) if (cpu_stdext_feature & CPUID_STDEXT_SMEP) load_cr4(rcr4() | CR4_SMEP); + +#ifdef + + + + +#else + + + +#endif + if (cpu_stdext_feature & CPUID_STDEXT_SMAP) INTEL_SMAP load_cr4(rcr4() | CR4_SMAP); else panic("The kernel compiled with \"options INTEL_SMAP\"," "but your CPU doesn't support SMAP!\n"); /* !INTEL_SMAP */ printf("Your CPU has support for SMAP security feature. " "You should recompile the kernel with " "\"options INTEL_SMAP\" to use them.\n"); /* INTEL_SMAP */ /* * Initialize the kernel pmap (which is statically allocated). */
sys/amd64/amd64/trap.c file-ban tallhat trap() fggvnyben. Ha az SMAP nincs bekapcsolva, akkor a laphibval SMAP rszrl nem foglalkozunk. Ha be van kapcsolva, akkor folytatjuk az ellenrzst: ha user mdban vagyunk vagy az EFLAGS.AC rtke 1, akkor ugyancsak nem foglalkozunk a laphibval SMAP rszrl, mert ekkor vagy nem vonatkozik rnk vagy engedlyezett. Minden ms esetben le kell kezelnnk a laphibt SMAP szempontjbl, azaz kernel panic() lesz a vgeredmny. Az elbbi felttelek ellenrzsre egy kln static fggvnyt vezettem be, mivel gy olvashatbb a kd.
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 6fcca81..0afc891 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -127,6 +127,9 @@ void dblfault_handler(struct trapframe *frame); static int trap_pfault(struct trapframe *, int); static void trap_fatal(struct trapframe *, vm_offset_t);
39
+#ifdef INTEL_SMAP +static bool smap_access_violation(struct trapframe *, int usermode); +#endif #define MAX_TRAP_MSG 33 static char *trap_msg[] = { diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 6fcca81..0afc891 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -127,6 +127,9 @@ void dblfault_handler(struct trapframe *frame); static static +#ifdef +static +#endif int trap_pfault(struct trapframe *, int); void trap_fatal(struct trapframe *, vm_offset_t); INTEL_SMAP bool smap_access_violation(struct trapframe *, int usermode);
#define MAX_TRAP_MSG 33 static char *trap_msg[] = { @@ -718,6 +721,14 @@ trap_pfault(frame, usermode) map = &vm->vm_map; +#ifdef INTEL_SMAP + if (__predict_false(smap_access_violation(frame, usermode))) { + trap_fatal(frame, eva); + return (-1); + } +#endif + /* * When accessing a usermode address, kernel must be * ready to accept the page fault, and provide a @@ -874,6 +884,20 @@ trap_fatal(frame, eva) panic("unknown/reserved trap"); } +#ifdef INTEL_SMAP +static bool +smap_access_violation(struct trapframe *frame, int usermode) +{ + if ((cpu_stdext_feature & CPUID_STDEXT_SMAP) == 0) + return (false); + + if (usermode || (frame->tf_rflags & PSL_AC) != 0) + return (false); + + return (true); +} +#endif + /* * Double fault handler. Called when a fault occurs while writing * a frame for a trap/exception onto the stack. This usually occurs
40
3.1.3.4 support.S A sys/amd64/amd64/support.S file-ban trtn mdostsok kivtel nlkl a user space memrit leglisan elr utastsok stac s clac utastsokkal val krlvtele. Ezzel tmenetileg kikapcsoljuk az SMAP-et, gy a kernel kpes hozzfrni user space memrihoz.
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 77dbf63..9c12087 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -35,6 +35,7 @@ #include <machine/asmacros.h> #include <machine/asmacros.h> #include <machine/intr_machdep.h> #include <machine/pmap.h> +#include <machine/smap_instr.h> #include "assym.s" @@ -244,12 +245,16 @@ ENTRY(copyout) shrq cld STAC rep movsq CLAC movb andb STAC rep movsb CLAC $3,%rcx
+ + +
%dl,%cl $7,%cl
done_copyout: xorl %eax,%eax @@ -290,12 +295,16 @@ ENTRY(copyin) movb %cl,%al shrq $3,%rcx cld + STAC rep movsq + CLAC movb %al,%cl andb $7,%cl + STAC rep movsb + CLAC
/* copy longword-wise */
Ez egy plda a sok fggvny kzl, melyet a support.S tartalmaz, a tbbi esetben is hasonl mdostsok vannak. Ezeken fell, ha valamilyen exception trtnne,
41
akkor abban az esetben a EFLAGS.AC flag-et trlni kell, hogy a control-flow-ban ne terjedjen random helyekre s ne okozzon nem kvnt srlkenysget. 3.1.3.5 exception.S Az elz alpont alatt emltett kivtelkezels esetn kezelend megvalsts. (Az EFLAGS rtke kivtel hatsra automatikusan a stack-re kerl.)
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index 89ad638..2956efc 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -42,6 +42,7 @@ #include <machine/asmacros.h> #include <machine/psl.h> #include <machine/trap.h> +#include <machine/smap_instr.h> #include <machine/specialreg.h> #include "assym.s" @@ -196,6 +197,7 @@ alltraps_pushregs_no_rdi: movq %r15,TF_R15(%rsp) movl $TF_HASSEGS,TF_FLAGS(%rsp) cld + CLAC FAKE_MCOUNT(TF_RIP(%rsp)) #ifdef KDTRACE_HOOKS /* @@ -276,6 +278,7 @@ IDTVEC(dblfault) movw %ds,TF_DS(%rsp) movl $TF_HASSEGS,TF_FLAGS(%rsp) cld + CLAC testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ jz 1f /* already running with kernel GS.base */ swapgs @@ -379,6 +382,7 @@ IDTVEC(fast_syscall) movq %r15,TF_R15(%rsp) /* C preserved */ movl $TF_HASSEGS,TF_FLAGS(%rsp) cld + CLAC FAKE_MCOUNT(TF_RIP(%rsp)) movq PCPU(CURTHREAD),%rdi movq %rsp,TD_FRAME(%rdi) @@ -474,6 +478,7 @@ IDTVEC(nmi) movw %ds,TF_DS(%rsp) movl $TF_HASSEGS,TF_FLAGS(%rsp) cld + CLAC xorl %ebx,%ebx testb $SEL_RPL_MASK,TF_CS(%rsp) jnz nmi_fromuserspace @@ -533,6 +538,7 @@ nmi_calltrap: shrq cld $3,%rcx /* trap frame size in long words */
42
/* copy trapframe */
3.1.3.6 asmacros.h Itt a PUSH_FRAME makrt egsztettem, ki a CLAC utastssal, hogy kivtel esetn trljk az EFLAGS.AC flag-et biztonsgi okokbl a trap kezelsekor. A helyrelltott task-ra nincs hatssal, mivel az EFLAGS-et mg a trls eltt elmenti a CPU a stack-re.
diff --git a/sys/amd64/include/asmacros.h b/sys/amd64/include/asmacros.h index 1fb592a..c985623 100644 --- a/sys/amd64/include/asmacros.h +++ b/sys/amd64/include/asmacros.h @@ -167,7 +167,8 @@ movw %es,TF_ES(%rsp) ; \ movw %ds,TF_DS(%rsp) ; \ movl $TF_HASSEGS,TF_FLAGS(%rsp) ; \ cld + cld ; \ + CLAC #define POP_FRAME movq TF_RDI(%rsp),%rdi ; \ \
43
3.1.4 Tesztek
Mivel az SMAP kpes CPU-k csak jniusban jelennek meg a piacon, gy tesztelni csak emultoron (Qemu 1.4 s jabbak tmogatjk bekapcsolt TCG esetn) tudtam. Jniusban hozzfrst kapok az Intel tmogatsval SMAP kpes gphez, s akkor teljestmnyteszteket is vgzek. Az SMAP technolgia igen egyszeren tesztelhet funkcionalits
szempontjbl. A scenario annyibl ll, hogy egy valid user space cmet kell dereferlnunk kernelbl, anlkl, hogy hozzfrst engedlyeztnk volna a kernelnek. Erre ksztettem[23] egy tesztesetet, mely egy FreeBSD char device-bl s egy user space programbl ll. A user space program a stack-jn ltrehoz egy tmbt, melynek kezdcmt belerja a char dev-be. Ezutn, amikor a char dev-re read rendszerhvs rkezik, akkor derefelja a kernel a user space processz memriaterlett. Ekkor bekapcsolt s mkd SMAP esetn a kernel panic()-ot dob.
44
Ha a teszteset olyan gpen van lefuttatva, amely nem SMAP kpes, akkor a user space memria tartalma mindenfle korltozs nlkl kiolvashat.
45
3.2.2.2 vm_map A sys/vm/vm_map.c file-ban tallhat vmspace_alloc() fggvnyben trtnt vltoztats a megfelel inicializcihoz kell, a vmspace struktrhoz hozzadott vltozkat pldnyostskor kinullzom.
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 933b0e1..8754aa8 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -65,6 +65,8 @@ #include <sys/cdefs.h>
46
__FBSDID("$FreeBSD$"); +#include "opt_pax.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -297,6 +299,10 @@ vmspace_alloc(min, max) vm->vm_taddr = 0; vm->vm_daddr = 0; vm->vm_maxsaddr = 0; +#ifdef PAX_ASLR + vm->vm_aslr_delta_mmap = 0; + vm->vm_aslr_delta_stack = 0; +#endif /* PAX_ASLR */ return (vm); }
3.2.2.3 vm_mmap A sys/vm/vm_mmap.c file-ban tallhat a sys_mmap() fggvny, mely az mmap() rendszerhvst valstja meg. Szmunka ez azrt fontos, mert ez a fggvny felels user space oldalrl a memriakezelsrt. Amikor amd64 rendszeren dinamikusan foglalunk memrit, akkor ez a fggvny ad neknk egy memria rgit. A sys_mmap() fggvnyen bell hvom meg a pax_aslr_mmap() fggvnyt, mely a cmen a randomizcit alkalmazza.
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index c17e9ce..9113fbb 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include "opt_compat.h" #include "opt_hwpmc_hooks.h" +#include "opt_pax.h" #include <sys/param.h> #include <sys/systm.h> @@ -89,6 +90,10 @@ __FBSDID("$FreeBSD$"); #include <sys/pmckern.h> #endif +#ifdef PAX_ASLR +#include <sys/pax.h> +#endif /* PAX_ASLR */ + int old_mlock = 0; SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RW &old_mlock, 0, "Do not apply RLIMIT_MEMLOCK on mlockall"); @@ -197,6 +202,9 @@ sys_mmap(td, uap) struct file *fp; struct vnode *vp; vm_offset_t addr;
CTLFLAG_TUN,
47
+#ifdef PAX_ASLR + vm_offset_t orig_addr; +#endif /* PAX_ASLR */ vm_size_t size, pageoff; vm_prot_t cap_maxprot, prot, maxprot; void *handle; @@ -207,6 +215,9 @@ sys_mmap(td, uap) cap_rights_t rights; addr = (vm_offset_t) uap->addr; +#ifdef PAX_ASLR + orig_addr = addr; +#endif /* PAX_ASLR */ size = uap->len; prot = uap->prot & VM_PROT_ALL; flags = uap->flags; @@ -389,6 +400,9 @@ sys_mmap(td, uap) map: td->td_fpop = fp; maxprot &= cap_maxprot; +#ifdef PAX_ASLR + pax_aslr_mmap(td, &addr, orig_addr, flags); +#endif /* PAX_ASLR */ error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, flags, handle_type, handle, pos); td->td_fpop = NULL;
3.2.2.4 kern_exec A sys/kern/kern_exec.c file-ban tallhat mdostsok tbb szempontbl is fontosak. A process/thread ltrehozsakor itt hvom meg az ASLR ltal hasznl vltozk inicializcijt elvgz pax_aslr_init() fggvnyt. Ugyancsak ebben a szekciban alkalmazzuk a stack-en a randomizcit a pax_aslr_stack()
fggvnyhvssal.
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 3890157..1a3ede0 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include "opt_hwpmc_hooks.h" #include "opt_kdtrace.h" #include "opt_ktrace.h" +#include "opt_pax.h" #include "opt_vm.h" #include <sys/param.h> @@ -95,6 +96,10 @@ __FBSDID("$FreeBSD$"); dtrace_execexit_func_t dtrace_fasttrap_exec; #endif +#ifdef PAX_ASLR +#include <sys/pax.h> +#endif /* PAX_ASLR */ + SDT_PROVIDER_DECLARE(proc);
48
SDT_PROBE_DEFINE(proc, kernel, , exec, exec); SDT_PROBE_ARGTYPE(proc, kernel, , exec, 0, "char *"); @@ -1044,6 +1049,10 @@ exec_new_vmspace(imgp, sv) map = &vmspace->vm_map; } +#ifdef PAX_ASLR + pax_aslr_init(curthread, imgp); +#endif /* PAX_ASLR */ + /* Map a shared page */ obj = sv->sv_shared_page_obj; if (obj != NULL) { @@ -1220,6 +1229,9 @@ exec_copyout_strings(imgp) int argc, envc; char **vectp; char *stringp, *destp; +#ifdef PAX_ASLR + char *orig_destp; +#endif /* PAX_ASLR */ register_t *stack_base; struct ps_strings *arginfo; struct proc *p; @@ -1248,6 +1260,10 @@ exec_copyout_strings(imgp) roundup(sizeof(canary), sizeof(char *)) roundup(szps, sizeof(char *)) roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *)); +#ifdef PAX_ASLR + orig_destp = destp; + pax_aslr_stack(curthread, &destp, orig_destp); +#endif /* PAX_ASLR */ /* * install sigcode
3.2.2.5 kern_pax A sys/kern/kern_pax.c file-ban tallhatk a sysctl handler-ek melyek segtsgvel futsidben lehet vltoztatni az ASLR tulajdonsgait - sokasga, a tunables defincik, az ASLR ltal hasznlt globlis vltozk, s a randomizcit vgz fggvnyek a natv kdokhoz s az emulcis rtegekhez. Els lpsben ltrehozok egy sajt node-ot a sysctl fban:
SYSCTL_NODE(_security, OID_AUTO, pax, CTLFLAG_RD, 0, "PaX (exploit mitigation) features.");
49
(A vlasztsom azrt esett erre a ktsz int kezdeti felptsre, mivel a kzeljvben foglalkozni szeretnk mg ezzel a projekttel s az ASLR-en kvl tbb biztonsgi funkcit is kvnok implementlni.) A kvetkez ltrehozand elem segtsgvel lehet lltani az ASLR hatskrt. Mint ahogy az lejjebb lthat, tbb szintet definiltam. 0 rtk esetn az ASLR ki van kapcsolva; 1 esetn az ASLR-t opcionlisan be lehet kapcsolni binrisonknt; 2 esetn globlisan be van kapcsolva az ASLR, de binrisonknt ki lehet kapcsolni; 3 esetn globlisan be van kapcsolva s nem lehet kikapcsolni. Jelenleg implementlva a 0-s s 3-as szint van. A kztes szintek implementlshoz a rendszeren lev ELF file-okat ki kell egszteni egy plusz szekcival vagy note-tal, amely tartalmazza a meg felel belltsokat. Ez kernel linker s run-time linker szinten is beavatkozst ignyel. A mdostshoz szksges kernel oldali kdok rszben megvalsultak, de nincsenek bekapcsolva. A kernel linker oldal mg megvalstsra vr.
SYSCTL_PROC(_security_pax_aslr, OID_AUTO, status, CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN, NULL, 0, sysctl_pax_aslr_status, "I", "Restrictions status. " "0 - disabled, " "1 - enabled, " "2 - global enabled, " "3 - force global enabled"); TUNABLE_INT("security.pax.aslr.status", &pax_aslr_status);
Az ezt kvet sysctl-ek s tunable-k az ASLR tulajdonsgait lltjk, hogy a randomizland cmbl hny bit legyen randomizlva. Egyet kiragadva kzlk:
SYSCTL_PROC(_security_pax_aslr, OID_AUTO, mmap_len, CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_TUN, NULL, 0, sysctl_pax_aslr_mmap, "I", "Number of bits randomized for mmap(2) calls. " "32 bit: [8,16] 64 bit: [16,32]"); TUNABLE_INT("security.pax.aslr.mmap", &pax_aslr_mmap_len);
50
int
val;
val = pax_aslr_mmap_len; err = sysctl_handle_int(oidp, &val, sizeof(int), req); if (err || !req->newptr) return (err); if (val < PAX_ASLR_DELTA_MMAP_MIN_LEN || val > PAX_ASLR_DELTA_MMAP_MAX_LEN) return (EINVAL); pax_aslr_mmap_len = val; return (0); }
A lnyegi megvalsts, amelyek az ASLR-t implementljk, a pax_aslr_init() fggvnyben s az ezt kvetekben tallhatk:
void pax_aslr_init(struct thread *td, struct image_params *imgp) { struct vmspace *vm; u_int sv_flags; if (imgp == NULL) { panic("[PaX ASLR] pax_aslr_init - imgp == NULL"); } if (!pax_aslr_active(td)) return; vm = imgp->proc->p_vmspace; sv_flags = imgp->proc->p_sysent->sv_flags; #ifndef COMPAT_FREEBSD32 vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_MMAP_LSB, pax_aslr_mmap_len); vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_STACK_LSB, pax_aslr_stack_len); vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); #else /* COMPAT_FREEBSD32 */ if ((sv_flags & SV_LP64) != 0) { vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_MMAP_LSB, pax_aslr_mmap_len); vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), PAX_ASLR_DELTA_STACK_LSB, pax_aslr_stack_len); vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); } else { vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(), PAX_ASLR_COMPAT_DELTA_MMAP_LSB, pax_aslr_compat_mmap_len); vm->vm_aslr_delta_stack = PAX_ASLR_DELTA(arc4random(), PAX_ASLR_COMPAT_DELTA_STACK_LSB, pax_aslr_compat_stack_len); vm->vm_aslr_delta_stack = ALIGN(vm->vm_aslr_delta_stack); } #endif /* !COMPAT_FREEBSD32 */ }
51
Ez a fggvny minden thread ltrehozsakor lefut s inicializlja az ASLR ltal hasznlt vltozkat, melyek alapjn megtrtnik a randomizci. A FreeBSD kernelt amd64 architektrn lehet fordtani kompatibilitsi rteggel s anlkl. Erre az esetre az init fggvny kvzi kt rszre van osztva sebessg optimalizls miatt. Ha nincs kompatibilitsi rteg, akkor csak a natv rsz inicializldik, ha van, akkor a kd tpusnak megfelel. Az mmap() randomizcit a pax_aslr_mmap() fggvny vgzi, a pax_aslt_init() ltal generlt random alapjn. A randomizcit csak bizonyos esetekben alkalmazzuk. Az egyik ilyen eset, ha nem MAP_FIXED flag-gel hvjuk meg az mmap()-ot s NULL kezdcm hintet adunk neki (azaz a kernelre bzzuk a cm kivlasztst), ha NULL-tl eltr, akkor nem randomizljuk, mivel ez rszben trn az mmap() alap funkcionalitst. A msik ilyen eset, ha mappels nem MAP_ANON, azaz nem tartozik hozz semmilyen file descriptor, hanem csak memria rgit krnk a kerneltl, ez utbbit impliklja a MAP_STACK is.
void pax_aslr_mmap(struct thread *td, vm_offset_t *addr, vm_offset_t orig_addr, int flags) { if (!pax_aslr_active(td)) return; if (!(flags & MAP_FIXED) && ((orig_addr == 0) || !(flags & MAP_ANON))) { #ifdef PAX_ASLR_DEBUG uprintf("[PaX ASLR] applying to %p orig_addr=%p f=%x\n", (void *)*addr, (void *)orig_addr, flags); #endif /* PAX_ASLR_DEBUG */ if (!(td->td_proc->p_vmspace->vm_map.flags & MAP_ENTRY_GROWS_DOWN)) *addr += td->td_proc->p_vmspace>vm_aslr_delta_mmap; else *addr -= td->td_proc->p_vmspace>vm_aslr_delta_mmap; #ifdef PAX_ASLR_DEBUG uprintf("[PaX ASLR] result %p\n", (void *)*addr); #endif /* PAX_ASLR_DEBUG */ } #ifdef PAX_ASLR_DEBUG else uprintf("[PaX ASLR] not applying to %p orig_addr=%p f=%x\n", (void *)*addr, (void *)orig_addr, flags); #endif /* PAX_ASLR_DEBUG */ }
A stack randomizci esetn jelenleg stack gap randomizci van megvalstva, ami annyit jelent, hogy a lapon bell van eltolva a stack kezdcme: 52
void pax_aslr_stack(struct thread *td, char **addr, char *orig_addr) { if (!pax_aslr_active(td)) return; *addr -= td->td_proc->p_vmspace->vm_aslr_delta_stack; #ifdef PAX_ASLR_DEBUG uprintf("[PaX ASLR] orig_addr=%p, addr=%p\n", (void *)orig_addr, (void *)*addr); #endif /* PAX_ASLR_DEBUG */ }
stack
randomizcit
sys/kern/kern_exec.c
file-ban
tallhat
exec_copyout_strings() fggvnyben hvom meg, mely sszelltja a program futtats linkerhez szksges adatstruktrt s belltja a user space stack kezdcmt. 3.2.2.6 Mdostsok sszegzse
git diff --stat 94108ee710c3afd3c9944ed40e129598dd242a00..54316e66bd3e82d9b02721bbc2c7c8a3 f7254e81 sys/compat/freebsd32/freebsd32_misc.c | 13 + sys/conf/files | 1 + sys/conf/options | 5 + sys/kern/kern_exec.c | 16 ++ sys/kern/kern_pax.c | 450 ++++++++++++++++++++++++++++++++++ sys/sys/pax.h | 161 ++++++++++++ sys/vm/vm_map.c | 6 + sys/vm/vm_map.h | 2 + sys/vm/vm_mmap.c | 14 ++ 9 files changed, 668 insertions(+)
max
((sizeof(void *) * NBBY) / 2) ((sizeof(void *) * NBBY) / 3) ((sizeof(void *) * NBBY) / 3)
Kompatibilitsi esetben a kpletek hasonlan alakulnak, azonban egy fontos klnbsg van: void * pointer mrete helyett az int mrete alapjn szmolom ki a randomizci hosszt.
53
max
((sizeof(int) * NBBY) / 2) ((sizeof(int) * NBBY) / 3) ((sizeof(int) * NBBY) / 3)
Az rtkek alakulsa: 64 bites rendszeren a sizeof(void *) rtke 8, 32 bites rendszeren pedig 4; az NBBY egy FreeBSD ltal architektrnknt definilt makr, amely megadja, hogy az adott CPU esetben egy byte hny bitet tartalmaz. Az osztk pedig slyok, amelyek megadnak egy elgsges als hatrt s egy fels hatrt, mely esetben mr hibk is lphetnek fel. Kompatibilitsi esetben a dnts azrt esett az int tpusra, mert a FreeBSD ltal tmogatott architektrkon az int rendre 32 bit hosszknt van rtelmezve, gy a sizeof(int) mindig 4-et fog visszaadni s neknk pont ez kell. Az konkrt rtkek pedig:
Szmtsi md ((sizeof(void *) * NBBY) / 2) ((sizeof(void *) * NBBY) / 3) ((sizeof(void *) * NBBY) / 4) ((sizeof(void *) * NBBY) / 5) ((sizeof(int) * NBBY) / 2) ((sizeof(int) * NBBY) / 3) ((sizeof(int) * NBBY) / 4) ((sizeof(int) * NBBY) / 5) rtk 32 21 16 12 16 10 8 6
Alaprtelmezetten a globlis ASLR belltsok a minimumra vannak lltva, mivel gy a legkisebb a valsznsge, hogy memriaignyes programok esetn hiba lpne fel, ezt a tulajdonsgot tbb mdon is megvltoztathatjuk. Az egyik megolds, ha a FreeBSD rendszerekben tallhat /etc/sysctl.conf file segtsgvel tlltjuk a kvnt rtkre a sysctl vltozkat. A msik megolds, ha a /boot/loader.conf file-ba rjuk bele a megfelel belltsokat, amelyeket aztn a tunable alrendszer boot idben bellt . Vgl a harmadik mdszer, hogy fordts idben lltjuk a legbiztonsgosabbra, melyet a PAX_ASLR_MAX_SEC opcival lehet belltani.
54
3.2.4 Buktatk
Ha az rtkeket tl magasra lltjuk, akkor bizonyos programok nem indulnak el rendesen, ha tl alacsonyra, akkor pedig srlkenyek lehetnek a tmadsokra nzve. Az ASLR nmagban nem megolds / workaround, mivel tbb mdszerrel is tmadhat[17][31], azonban mg gy is egy hatkony eszkz a vdelem oldalrl. Bizonyos srlkenysgeit hatkonyan lehet orvosolni a segvguard megoldssal, melyrl a bevezetben volt sz.
55
4 rtkels
4.1 SMAP
Az technolgia bevltotta a hozz fztt remnyeket, gy a nem engedlyezett user space memria hozzfrs esetn a kernel panic() fggvnyhvsba vgzdik. Ez biztonsgi szempontbl fontos elrelps, mivel gy a tmad nem kpes hozzfrni rzkeny adatokhoz. A technolgia htrnya, hogy a gp ezt kveten hasznlhatatlan lesz a kvetkez jraindtsig.
Mint ahogy az a (Figure 6: user space memria rsa, olvassa kernelbl SMAP nlkl) brn lthat, ha az SMAP vdelem nincs bekapcsolva, akkor a kernel kpes nem kontrolllt mdon is user space memrit olvasni. Ennek a kvetkezmnye slyos lehet egy esetleges srlkenysg kihasznlsnl, mivel a kernelbe nem kernel kd injektlhat.
56
Ha az SMAP vdelem be van kapcsolva, akkor az ahogy a Figure 7 brn lthat - olvass esetn s rs esetn - a Figure 8 brn lthat - kernel panic()-ot kapunk, ezltal megakadlyozva a kdinjektlst. A technolgia pozitv mellkhatsa, hogy a kernel kd minsge javulhat, mivel a nem megfelel memria hozzfrs esetn a kernel nem lesz funkcionlis s ki kell javtani a programozi hibkat. 57
Az elkszlt mdostsrl teljestmny tesztek egyelre nem kszltek, mivel olyan fizikai gphez mg nem frtem hozz, amely tmogatja az SMAP technolgit. A tesztek Qemu 1.4 alatt kszltek.
58
4.2 ASLR
Az ASLR egy kis kltsg, de hatkony technika, mely megnehezti a rendszerek exploitlst[35]. FreeBSD alatt az implementcit hatkonyan meg lehetett oldani, mivel rendelkezsre lltak a szksges framework-k, mint pldul a sysctl, tunables, arc4random(), stb.
Az ASLR be van kapcsolva, mivel a security.pax.aslr.status rtke 1 (implementlva jelenleg a 0 s 3 sttusz van jelenleg, de ami 0-tl eltr, az 3-as szintknt van rtelmezve, mint ahogy azt az implementcis rszben ki is fejtettem). A security.pax.aslr.compat sysctl node meglte miatt lthat, hogy a rendszer melyen a teszteket vgeztem - freebsd32 kompatibilitsi rteggel lett fordtva. A kvetkezkben a FreeBSD rendszer rszt kpez cat program address spacet fogom vizsglni a procstat[36] programmal. A cat programot elindtom a httrben, s a shell kirja a hozz tartoz PID-et. A procstat[36] man (a man parancs segtsgvel rjk el a manulokat) oldalbl erre van most szksgem:
-v Display virtual memory mappings for the process.
59
Ez alapjn a procstat -v parancs segtsgvel ki tudom ratni a process ltal mappelt memria rgikat. (Ez tbbek kztt potencilis infoleak).
Lthat a Figure 9 s Figure 10 brn, hogy kt futs kztt a memria cmek vltoztak. Ez vrhat volt, mivel ez az ASLR lnyege, azonban ahogy az feltnhet, a program belpsi pontja s a linker nem lett randomizlva.
60
A heap randomizlva lett, a betlttt megosztott fggvnyknyvtrak s a szegmensei is randomizlva lettek. Az utols eltti memria cm a stacket jelenti. Errl a kprl nem ltszik, de az is randomizlva lett a stack gap megoldssal, amit a ksbbiekben igazolni is fogok.
op@pandora-test ~> su Password: op@pandora-test op# sysctl security.pax.aslr.status=0 security.pax.aslr.status: 1 -> 0 op@pandora-test op# exit
61
A Figure 11 s Figure 12 brt megelzend parancsok segtsgvel kikapcsoltam az ASLR-t s megismteltem a fent lertakat. Ebben az esetben a kt futs kztt semmilyen klnbsg nem tapasztalhat a megvltozott PID-eken kvl. 4.2.1.2 ASLR randomizci ellenrzse paxtest-tel A kvetkez eszkz, amely segtsgvel az implementcit vizsgltam a paxtest[37], melyet tbb helyen is mdostanom kellett, hogy fordthat s futtathat legyen FreeBSD alatt is: ebbl lett a paxtest-freebsd[38]. A paxtest egy egsz sor ellenrzst vgez, klnbz szegmensek rhatsgval s futtathatsgval, a randomizcijval s egyb ellenrzsekkel. Az ASLR viszonylatban most enge m a randomizcit rint tesztek rdekeltek. A program kimenete bekapcsolt ASLR esetn a kvetkez:
op@pandora-test paxtest-freebsd# sysctl security.pax.aslr.status=1 security.pax.aslr.status: 0 -> 1 op@pandora-test paxtest-freebsd> ./paxtest kiddie PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@adamantix.org> Released under the GNU Public Licence version 2 or later Writing output to paxtest.log It may take a while for the tests to complete Test results:
62
PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@adamantix.org> Released under the GNU Public Licence version 2 or later Mode: kiddie FreeBSD pandora-test 10.0-CURRENT FreeBSD 10.0-CURRENT #80 r+70a9d86: Mon May 13 16:48:55 CEST 2013 op@pandoratest:/usr/obj/usr/home/op/git/freebsd-base.git.http/sys/OP amd64 Executable anonymous mapping : Executable bss : Executable data : Executable heap : Executable stack : Executable anonymous mapping (mprotect) : Executable bss (mprotect) : Executable data (mprotect) : Executable heap (mprotect) : Executable shared library bss (mprotect) : Executable shared library data (mprotect): Executable stack (mprotect) : Anonymous mapping randomisation test : Heap randomisation test (ET_EXEC) : Main executable randomisation (ET_EXEC) : Shared library randomisation test : Stack randomisation test (SEGMEXEC) : Stack randomisation test (PAGEEXEC) : Arg/env randomisation test (SEGMEXEC) : Arg/env randomisation test (PAGEEXEC) : Return to function (strcpy) : a NULL byte. Return to function (strcpy, PIE) : a NULL byte. Return to function (memcpy) : Return to function (memcpy, PIE) : Executable shared library bss : Executable shared library data : Writable text segments : Killed Killed Killed Killed Killed Vulnerable Vulnerable Vulnerable Vulnerable Vulnerable Vulnerable Vulnerable 16 bits (guessed) 7 bits (guessed) No randomisation 16 bits (guessed) 12 bits (guessed) 12 bits (guessed) 13 bits (guessed) 13 bits (guessed) paxtest: return address contains paxtest: return address contains Vulnerable Vulnerable Killed Killed Vulnerable
A vastaggal kiemelt rszen lthat a program ltal valsznstett randomizci, mely kzel egybecseng a belltott rtkekkel. Az mmap randomizci esetn 16 bit-es belltsok voltak, a stack randomizci esetn pedig 12 bit-es. Ezek szpen ltszanak a fenti kimenetbl is. A tesztet megismteltem kikapcsolt ASLR-rel is, melynek a kimenete ez:
op@pandora-test paxtest-freebsd> su Password: op@pandora-test paxtest-freebsd# sysctl security.pax.aslr.status=0 security.pax.aslr.status: 1 -> 0 op@pandora-test paxtest-freebsd# exit op@pandora-test paxtest-freebsd> ./paxtest kiddie PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@adamantix.org> Released under the GNU Public Licence version 2 or later Writing output to paxtest.log
63
It may take a while for the tests to complete Test results: PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@adamantix.org> Released under the GNU Public Licence version 2 or later Mode: kiddie FreeBSD pandora-test 10.0-CURRENT FreeBSD 10.0-CURRENT #80 r+70a9d86: Mon May 13 16:48:55 CEST 2013 op@pandoratest:/usr/obj/usr/home/op/git/freebsd-base.git.http/sys/OP amd64 Executable anonymous mapping : Executable bss : Executable data : Executable heap : Executable stack : Executable anonymous mapping (mprotect) : Executable bss (mprotect) : Executable data (mprotect) : Executable heap (mprotect) : Executable shared library bss (mprotect) : Executable shared library data (mprotect): Executable stack (mprotect) : Anonymous mapping randomisation test : Heap randomisation test (ET_EXEC) : Main executable randomisation (ET_EXEC) : Shared library randomisation test : Stack randomisation test (SEGMEXEC) : Stack randomisation test (PAGEEXEC) : Arg/env randomisation test (SEGMEXEC) : Arg/env randomisation test (PAGEEXEC) : Return to function (strcpy) : a NULL byte. Return to function (strcpy, PIE) : a NULL byte. Return to function (memcpy) : Return to function (memcpy, PIE) : Executable shared library bss : Executable shared library data : Writable text segments : Killed Killed Killed Killed Killed Vulnerable Vulnerable Vulnerable Vulnerable Vulnerable Vulnerable Vulnerable No randomisation No randomisation No randomisation No randomisation No randomisation No randomisation No randomisation No randomisation paxtest: return address contains paxtest: return address contains Vulnerable Vulnerable Killed Killed Vulnerable
Ugyancsak a vastaggal kiemelt rszeket rdemes figyelni. Ebben az esetben semmilyen randomizci nem trtnik, ahogy azt el is vrtuk. A jelenleg elksztett megolds mg nem tkletes s csak rszben implementlja a PaX Team ltal lert megoldsokat, de az implementci jelenlegi llapotval szemben tmasztott kvetelmnyeimet teljesti. A projektet egyetemen kvl is folytatni szeretnm, mert napi szinten hasznlok FreeBSD-t. 4.2.1.3 ASLR implementci vals krlmnyek kztt A patchet klnbz fzisaiban felraktam a sajt gpemre, melyen a fejlesztsek kszltek. Ez id alatt rendellenessget nem tapasztaltam. 64
A tipikus hasznlat az albbiakbl llt: Firefox s Opera bngsz hasznlata tbb tab-bal; Vim editor clang_complete plugin-nel tbb pldnyban hasznlata; FreeBSD build rendszer hasznlata nagyobb mdostsok utn, ez kzel 1.5 rs intenzv load, mely jelents szmtsi, disc mveletet eredmnyez, ezen fell szmos process s thread kerl ltrehozsra; FreeBSD build rendszer hasznlata kisebb mdostsok utn; linuxulator-ral Linuxra kszlt alkalmazsok futtatsa; vlc-vel HD vide nzse, mocp-vel zenehallgats; proxyzs s filterezs; Qemu alatt FreeBSD futtatsa.
Ezen fentebb felsorolt pontokat egyszerre prhuzamosan futattam. A gp egy 4 magos 64-bites Intel CPU-val rendelkezik, melynek tpusa Q9300, a gp 4 GB fizikai memrit tartalmaz, az alaplap Asus P5Q-E s a rendszer UFS file rendszeren van. Ezek az informcik a kvetkez pontban ismertetett unixbench esetben is relevnsak. 4.2.1.4 ASLR implemenci teljestmny tesztje unixbench programmal A teljestmny tesztekhez a unixbench[39] nev tesztet hasznltam, abbl is a 4.1-es verzit. A patch s a teszt amd64 architektrj FreeBSD 10-CURRENT alatt kszlt, r249952 revision alatt. A rendszer single user mdban lett elindtva, ezt kveten a filerendszerek fel lettek csatolva a mount -a parancs segtsgvel. A tesztek script parancs alatt futottak, melynek clja, hogy minden terminlra kerl outputot s inputot eltrol egy file-ban.
65
disabled aslr enabled aslr without aslr avg szoras avg szoras avg szoras C Compiler Throughput 1089.866667 2.615976554 1093.3 3.750999867 1092.5 3.174901573 Dc: sqrt(2) to 99 decimal places 83885.93333 214.9895424 83427 786.7425691 83637.5 104.4307905 Dhrystone 2 using register variables 19864723.33 23882.548 19698426.2 136015.0205 19228373.7 202126.5748 Double-Precision Whetstone 3259.933333 1.955334583 3245.466667 21.86603149 3261.033333 2.638812864 Execl Throughput 1262.533333 7.1988425 1260.733333 4.630694692 1270.666667 4.717343885 File Copy 1024 bufsize 2000 maxblocks 93897 1569.701883 94943.33333 192.2246949 94597.66667 434.1432175 File Copy 256 bufsize 500 maxblocks 26269.66667 647.5216856 26089 454.808751 26073 467.9882477 File Copy 4096 bufsize 8000 maxblocks 73755 77.48548251 72271.33333 1255.538663 73772.66667 28.14841618 File Read 1024 bufsize 2000 maxblocks 281040.3333 2438.549227 280970.6667 1000.484549 273580 193.1864384 File Read 256 bufsize 500 maxblocks 71493.33333 847.0385666 71552 435.1689327 70263.66667 106.2277428 File Read 4096 bufsize 8000 maxblocks 912792 3980.592795 907621.3333 3458.126998 886477 2924.608863 File Write 1024 bufsize 2000 maxblocks 151343.3333 420.9089371 154922 3107.584914 155800 3335.458139 File Write 256 bufsize 500 maxblocks 45039 670.5005593 45024 783.171118 45834.66667 738.9061736 File Write 4096 bufsize 8000 maxblocks 68977.33333 88.50047081 67631 1165.670193 68333.66667 1192.193077 Pipe Throughput 685209.3 3467.610213 685788.1 3643.923557 672573.9667 1877.654426 Pipe-based Context Switching 120032.7 2072.9011 122654.7667 1292.200764 119311.7667 2337.814044 Process Creation 3032.666667 55.55558778 3070.966667 77.27873791 3050.4 61.51349445 Recursion Test--Tower of Hanoi 189751.0333 264.2940849 189276.4 725.3452419 190272.0667 416.1870052 Shell Scripts (1 concurrent) 3707.966667 37.44520441 3690.266667 47.68021952 3727.3 40.42635279 Shell Scripts (16 concurrent) 490.9666667 1.517673658 487.2 3.551056181 493.1333333 1.4571662 Shell Scripts (8 concurrent) 941.4333333 8.256108849 938 11.17273467 947.7666667 11.24825912 System Call Overhead 536400.5333 912.0273369 534672.8 968.5840593 537497.4667 1931.36515
lpm lpm lps MWIPS lps KBps KBps KBps KBps KBps KBps KBps KBps KBps lps lps lps lps lpm lpm lpm lps
A fenti eredmnyeket a unixbench program hromszori futtatsval kaptam. A program a teszteseteit hromszor ismtli meg, gy sszesen minden teszteset 9 alkalommal futott le. A fenti tblzat ezen rtken tlagt s szrst tartalmazza. Az utols oszlopban pedig a dimenzik tallhatk. Jelentsk: lpm loop per minute, MWIPS - Millions of Whetstone Instructions Per Second, lps loop per sec. Az elkvetkez oldalakon pr fontosabb mrsi eredmnyt vizulisan is megmutatok.
66
A Figure 14: execl throughput (loops per sec) brn a msodpercenknt lefutott execl() fggvnyhvs szmt lthatjuk. Az execl() az aktulis process image-t cserli le az jra. Az elzetes vrakozsaimnak megfelelen ebben a tesztesetben a patch nlkli kernel volt a leggyorsabb. Ezt a megpatch-elt, de kikapcsolt ASLR-rel hasznlt kernel, mg a leglassabb az ASLR-rel hasznlt kernel volt. A jelensg eredete, hogy bekapcsolt ASLR esetben a kernel legenerlja a szksges randomokat, s ellenrzi a feltteleket, hogy melyik ASLR bellts rvnyes az adott process-re. Kikapcsolt ASLR esetben a randomok nem generldnak le, csak az ellenrzs kltsge tevdik hozz.
67
A Figure 15: process creation (loops per sec) brn a vrtakkal ellenttben a leggyorsabb a bekapcsolt ASLR-rel rendelkez kernel volt, azonban itt a mrsi eredmny bizonytalan, mint ahogy az a szrsokbl is ltszik. Msodik lett a patch nlkli kernel s harmadik a patchelt, de kikapcsolt ASLR-rel fut kernel.
68
A Figure 16: shell scripts (8 concurrent) (loops per sec) s Figure 17: shell scripts (16 concurrent) (loops per sec) brkon a Figure 14: execl throughput (loops per sec) brnl ltottakkal hasonl paprforma lthat.
69
A Figure 18: system call overhead (loops per sec) brn is a paprforma igazoldott be.
70
s a vgre egy rdekessg, a Figure 19: pipe throughput (loops per sec) brn lthat esetben mind kikapcsolt ASLR-rel, mind bekapcsolt ASLR-rel megnvekedett a rendszer pipe() megvalstsnak teresztkpessge. Erre magyarzatot mg nem talltam megrzs alapjn memoria alignment van a httrben tovbbi kutatst ignyel a pontos ok kidertse.
71
teszteset C Compiler Throughput Dc: sqrt(2) to 99 decimal places Dhrystone 2 using register variables Double-Precision Whetstone Execl Throughput File Copy 1024 bufsize 2000 maxblocks File Copy 256 bufsize 500 maxblocks File Copy 4096 bufsize 8000 maxblocks File Read 1024 bufsize 2000 maxblocks File Read 256 bufsize 500 maxblocks File Read 4096 bufsize 8000 maxblocks File Write 1024 bufsize 2000 maxblocks File Write 256 bufsize 500 maxblocks File Write 4096 bufsize 8000 maxblocks Pipe Throughput Pipe-based Context Switching Process Creation Recursion Test--Tower of Hanoi Shell Scripts (1 concurrent) Shell Scripts (16 concurrent) Shell Scripts (8 concurrent) System Call Overhead
disabled vs without 99.76% 100.30% 103.31% 99.97% 99.36% 99.26% 100.75% 99.98% 102.73% 101.75% 102.97% 97.14% 98.26% 100.94% 101.88% 100.60% 99.42% 99.73% 99.48% 99.56% 99.33% 99.80%
enabled vs without 100.07% 99.75% 102.44% 99.52% 99.22% 100.37% 100.06% 97.96% 102.70% 101.83% 102.39% 99.44% 98.23% 98.97% 101.96% 102.80% 100.67% 99.48% 99.01% 98.80% 98.97% 99.47%
A fenti tblzatban a kikapcsolt s a bekapcsolt ASLR viszonya lthat a patchet nem tartalmz kernelhez.
72
Ahogy a fenti tblzatbl is ltszik, a FreeBSD igen kevs memriavdelmi megoldst implementl, s amelyek implementlva vannak, azok tbbsge hardware meglthez vannak ktve. Ez annak a kvetkezmnye, hogy a FreeBSD projekt a teljestmnyt s a felhasznlhatsgot tzte a zszlajra, azonban e tny mellett az is kzrejtszik, hogy bizonyos feladatok elvgzsre mg gy is kevs a fejleszti kapacits. Bizonyos elremozduls azonban ltszik, mivel a fenti tblzatban tallhat megoldsok egy rsze az utbbi vek termse. Vgezetl lljon itt pr paxtest kimenet, mely egy jvkpet vzolhat fel. A kiemelseket clszer figyelni.
73
74
75
76
Ksznetnyilvnts
Ezton szeretnk ksznetet mondani technolgiai review-krt s tancsokrt: Hunger-nek <hunger@hunger.hu>, konzulensemnek Bencsth Boldizsrnak
<boldizsar.bencsath@crysys.hit.bme.hu>, Konstantin Belousov <kib@freebsd.org> FreeBSD fejlesznek, PaX Team-nek <pageexec@freemail.hu>. Tesztelsrt: Hiren Panchasara-nak <hiren.panchasara@gmail.com> Yahoo FreeBSD fejlesztnek, Fodor Zoltnnak <zoltan.fodor@intel.com>, Pawel Gepner <pawel.gepner@intel.com>. ltalnos review-krt s javtsokrt: Bords Katalinnak, Lgler Gergelynek, Lszl Blanknak s Morvai Boglrknak. Vgezetl, de nem utols sorban: desapmnak Pintr Sndornak, csaldomnak s bartaimnak a tmogatsrt.
77
Irodalomjegyzk
[1] Intel: Intel 64 and IA-32 Architectures Software Developer Manuals - Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B and 3C, Order Number: 325462-046US, March 2013, http://download.intel.com/products/processor/manual/325462.pdf Intel: Intel Architecture Instruction Set Extensions Programming Reference, 319433-014, AUGUST 2012, Chapter 9.3, http://software.intel.com/sites/default/files/319433-014.pdf Intel: Intel Architecture Instruction Set Extensions Programming Reference, 319433-014, AUGUST 2012, Chapter 9.6, table 9-13, table 9-14 http://software.intel.com/sites/default/files/319433-014.pdf Intel: Intel 64 and IA-32 Architectures Software Developer Manuals - Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B and 3C, Order Number: 325462-046US, March 2013, SDM vol.3 8.1.3, http://download.intel.com/products/processor/manual/325462.pdf Intel: Intel 64 and IA-32 Architectures Software Developer Manuals - Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B and 3C, Order Number: 325462-046US, March 2013, SDM vol.3 11.6, http://download.intel.com/products/processor/manual/325462.pdf Marshall Kirk McKusick, George V. Neville-Neil: The Design and Implementation of the FreeBSD Operating System, 2.2 Kernel Organization, http://books.google.hu/books/about/The_Design_and_Implementation_of_the_Fre .html?id=-RqMzqH__BMC&redir_esc=y FreeBSD: FreeBSD Man Pages sysctl(8). http://www.freebsd.org/cgi/man.cgi?query=sysctl&sektion=8 FreeBSD: FreeBSD Man Pages sysctl(3). http://www.freebsd.org/cgi/man.cgi?query=sysctl&sektion=3&apropos=0&manpa th=FreeBSD+9.1-RELEASE Intel: Intel 64 and IA-32 Architectures Software Developer Manuals - Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B and 3C, Order Number: 325462-046US, March 2013, SDM vol.3 4.1.4, http://download.intel.com/products/processor/manual/325462.pdf
[2]
[3]
[4]
[5]
[6]
[7] [8]
[9]
[10] PaX Team: Address Space Layout Randomization, http://pax.grsecurity.net/docs/aslr.txt [11] PaX Team: RANDMMAP, http://pax.grsecurity.net/docs/randmmap.txt [12] PaX Team: RANDUSTACK, http://pax.grsecurity.net/docs/randustack.txt [13] PaX Team: RANDKSTACK, http://pax.grsecurity.net/docs/randkstack.txt 78
[14] PaX Team: UDEREF, http://grsecurity.net/~spender/uderef.txt [15] PaX Team: UDEREF64, http://grsecurity.net/pipermail/grsecurity/2010April/001024.html [16] Nergal: The advanced return-into-lib(c) exploits: PaX case study, http://www.phrack.org/issues.html?issue=58&id=4&mode=txt [17] Tyler Durden: Bypassing PaX ASLR protection, http://www.theparticle.com/files/txt/hacking/phrack/p59-0x09.txt [18] LWN: SMP alternatives, http://lwn.net/Articles/164121/ [19] PaX Team: SMAP, http://forums.grsecurity.net/viewtopic.php?f=7&t=3046 [20] FreeBSD: FreeBSD Kernel Interface Manual, ddb, http://www.freebsd.org/cgi/man.cgi?query=ddb&sektion=4&apropos=0&manpath =FreeBSD+9.1-RELEASE [21] John H. Baldwin, Introduction to Debugging the FreeBSD Kernel, http://www.bsdcan.org/2008/schedule/attachments/45_article.pdf [22] FreeBSD: FreeBSD General Commands Manual, kgdb. http://www.freebsd.org/cgi/man.cgi?query=kgdb&apropos=0&sektion=0&manpat h=FreeBSD+9.1-RELEASE&arch=default&format=html [23] Pintr Olivr: SMAP tester, https://github.com/opntr/freebsd-smap-tester [24] Marshall Kirk McKusick, George V. Neville-Neil: The Design and Implementation of the FreeBSD Operating System, 5.2. Overview of the FreeBSD Virtual-Memory System, http://www.ico.aha.ru/h/The_Design_and_Implementation_of_the_FreeBSD_Ope rating_System/ch05lev1sec2.htm [25] FreeBSD System Calls Manual, mmap(2), http://www.freebsd.org/cgi/man.cgi?query=mmap&apropos=0&sektion=0&manp ath=FreeBSD+9.1-RELEASE&arch=default&format=html [26] Jan Hubicka, Andreas Jaeger, Mark Mitchell: System V Application Binary Interface, AMD64 Architecture Processor Supplement, http://people.freebsd.org/~obrien/amd64-elf-abi.pdf [27] Felix FX Lindner, A heap of risk, http://www.h-online.com/security/features/AHeap-of-Risk-747161.html [28] Ryan Roemer, Erik Buchanan, Hovav Shacham and Stefan Savage: ReturnOriented Programming: Systems, Languages, and Applications, http://cseweb.ucsd.edu/~hovav/dist/rop.pdf [29] Sebastian Krahmer: x86-64 buffer overflow exploits and the borrowed code chunks exploitation technique, http://users.suse.com/~krahmer/no-nx.pdf
79
[30] Tyler Bletsch, Xuxian Jiang, Vince W. Freeh, Zhenkai Liang: Jump-Oriented Programming: A New Class of Code-Reuse Attack, http://www.comp.nus.edu/~liangzk/papers/asiaccs11.pdf [31] Ralf Hund, Carsten Willems, Thorsten Holz: Practical Timing Side Channel Attacks Against Kernel Space ASLR, http://www.internetsociety.org/sites/default/files/Practical%20Timing%20Side%2 0Channel%20Attacks%20Against%20Kernel%20Space%20ASLR.pdf [32] OWASP: Format string attack, https://www.owasp.org/index.php/Format_string_attack [33] Gera, Riq: Advances in format string exploitation, http://www.phrack.org/issues.html?issue=59&id=7&mode=txt [34] FreeBSD: FreeBSD Man Pages sysctl(9), http://www.freebsd.org/cgi/man.cgi?query=sysctl&sektion=9&manpath=FreeBSD +9.1-RELEASE [35] Spender, PaX Team: KASLR KASLR: An Exercise in Cargo Cult Security, http://forums.grsecurity.net/viewtopic.php?f=7&t=3367 [36] FreeBSD: FreeBSD Man Pages procstat(1), http://www.freebsd.org/cgi/man.cgi?procstat [37] Spender:paxtest, http://grsecurity.net/~spender/paxtest-0.9.11.tar.gz [38] Oliver Pinter: paxtest-freebsd, https://github.com/opntr/paxtest-freebsd [39] Byte Magazine: unixbench, http://code.google.com/p/byte-unixbench/ [40] PaX Team: MPROTECT, http://pax.grsecurity.net/docs/mprotect.txt [41] Hiroaki Etoh: ProPolice, http://pacsec.jp/psj04/psj04-hiroaki-e.ppt [42] The de Raadt: Exploit Mitigation Techniques, http://www.openbsd.org/papers/ven05-deraadt/index.html [43] Spender: PaX -The Guaranteed End of Arbitrary Code Execution, http://grsecurity.net/PaX-presentation.ppt [44] Intel: Intel 64 and IA-32 Architectures Software Developer Manuals - Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B and 3C, Order Number: 325462-046US, March 2013, page 1767, http://download.intel.com/products/processor/manual/325462.pdf [45] Hunger: paxtest-freebsd9amd64.txt, http://hunger.hu/paxtest-freebsd9amd64.txt [46] Netcraft: Most Reliable Hosting Company Site in April 2013, http://news.netcraft.com/archives/2013/05/01/most-reliable-hosting-companysites-in-april-2013-2.html
80
[47] FreeBSD: FreeBSD problem reports, http://www.freebsd.org/cgi/querypr.cgi?pr=ports/177488 [48] WikiBooks: Grsecurity/Appendix/Grsecurity and PaX Configuration Options, http://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configur ation_Options [49] PaX Team: PaX - kernel self-protection, http://pax.grsecurity.net/docs/PaXTeamH2HC12-PaX-kernel-self-protection.pdf [50] PaX Team: pageexec, http://pax.grsecurity.net/docs/pageexec.txt
81
brajegyzk
Figure 1: XD bitek elfordulsa[1]................................................................... 16 Figure 2: vmspace struktra[24] ....................................................................... 23 Figure 3: Stack Frame Base Pointer-rel FreeBSD x86-64 alatt[26] ................... 24 Figure 4: SMAP akciban - mkd vdelem .................................................. 44 Figure 5: teszteset SMAP tmogats nlkl - a stack kiolvashat ..................... 45 Figure 6: user space memria rsa, olvassa kernelbl SMAP nlkl .............. 56 Figure 7: user space memria olvassa bekapcsolt SMAP vdelemmel ............ 57 Figure 8: user space memria rsa bekapcsolt SMAP vdelemmel .................. 57 Figure 9: cat memory mapping ASLR-rel ........................................................ 60 Figure 10: cat memory mapping ASLR-rel a kvetkez futskor ..................... 60 Figure 11: cat memory mapping ASLR nlkl ................................................. 61 Figure 12: cat memory mapping ASLR nlkl a kvetkez futtatskor ............ 62 Figure 13: unixbench program futsbl kapott vgeredmnyek ...................... 66 Figure 14: execl throughput (loops per sec) ...................................................... 67 Figure 15: process creation (loops per sec) ....................................................... 68 Figure 16: shell scripts (8 concurrent) (loops per sec)....................................... 69 Figure 17: shell scripts (16 concurrent) (loops per sec) ..................................... 69 Figure 18: system call overhead (loops per sec) ............................................... 70 Figure 19: pipe throughput (loops per sec) ....................................................... 71
82
Rvidtsek
ASLR BIOS BSD BSM CLAC CPL CPU DAC DARPA ELF ISP IT JIT JOP KASSERT lpm lps MAC MD MI MWIPS NBBY NOP Address Space Layout Randomization Basic Input/Output System Berkeley Software Distribution Basic Security Module CLear AC flag Current Privilege Level Central Processing Unit Discretionary Access Control Defense Advenced Research Projects Agency Executable and Linkable Format Internet Service Provider Information Technology Just-In-Time Jump-Oriented Programming Kernel Assert loops per minute loops per sec Mandatory Access Control Machine-Dependent Machine-Independent Millions of Whetstone Instructions Per Second Number of Bits per Byte No Operation
83
NX PIC PID PIE ROP RTLD SDM SMAP SMEP SSP STAC TCG TID UFS VM XD
Never eXecute, Position-Independent Code Process ID Position-Independent Executable Return-Oriented Programming Run-Time Link eDitor Software Developerss Manual Supervisor-Mode Access Prevention Supervisor-Mode Execution Prevention Stack Smash Protection SeT AC flag Tiny Code Generator Thread ID Unix File System Virtual Memory eXecute Disable
84
Fggelk
Az SMAP technolgia tesztelshez hasznlt emultor neve Qemu ez egy CPU emultor. A fejlesztsek kezdetekor az 1.4-es verzi mg nem volt bent a FreeBSD ports rendszerben, gy azt nekem kellett mkdsre brnom. Ebbl szletett pr FreeBSD-s bug report[47] s patch. Miutn mkdsre brtam az emultort , elkezddhetett a tesztels idkzben a FreeBSD ports-ban is frisslt az emultor 1.4es verzira. Ezen fell az emultort TCG (tiny code generator) tmogatssal kell fordtani, mivel ez emullja a host CPU ltal nem tmogatott utastsokat s szolgltatsokat, mint pldul az SMAP-ot. Az emultor rendkvl konfigurlhat s klnbz processzorcsaldokat tmogat:
op@pandora-test paxtest-freebsd# qemu-system-x86_64 -cpu \? x86 qemu64 QEMU Virtual CPU version 1.4.1 x86 phenom AMD Phenom(tm) 9550 Quad-Core Processor x86 core2duo Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz x86 kvm64 Common KVM processor x86 qemu32 QEMU Virtual CPU version 1.4.1 x86 kvm32 Common 32-bit KVM processor x86 coreduo Genuine Intel(R) CPU T2600 @ 2.16GHz x86 486 x86 pentium x86 pentium2 x86 pentium3 x86 athlon QEMU Virtual CPU version 1.4.1 x86 n270 Intel(R) Atom(TM) CPU N270 @ 1.60GHz x86 Conroe Intel Celeron_4x0 (Conroe/Merom Class Core 2) x86 Penryn Intel Core 2 Duo P9xxx (Penryn Class Core 2) x86 Nehalem Intel Core i7 9xx (Nehalem Class Core i7) x86 Westmere Westmere E56xx/L56xx/X56xx (Nehalem-C) x86 SandyBridge Intel Xeon E312xx (Sandy Bridge) x86 Haswell Intel Core Processor (Haswell) x86 Opteron_G1 AMD Opteron 240 (Gen 1 Class Opteron) x86 Opteron_G2 AMD Opteron 22xx (Gen 2 Class Opteron) x86 Opteron_G3 AMD Opteron 23xx (Gen 3 Class Opteron) x86 Opteron_G4 AMD Opteron 62xx class CPU x86 Opteron_G5 AMD Opteron 63xx class CPU
Esetemben a Haswell CPU architektra kivlasztsa lett volna clszer, de ebben az esetben az SMAP szolgltats nem volt elrhet legnagyobb meglepetsemre. Az interneten trtn hosszabb kutats sem jrt nagyobb eredmnnyel, mint hogy a Qemu 1.4-tl kezdve tmogatva van az SMAP s egy patch-re bukkantam klnsebb 85
lersok nlkl. Ezt kveten a Qemu forrst vlasztottam dokumentciknt s megkerestem, hogy milyen esetekben mkdhet biztosan az SMAP. Ezt kveten ltrehoztam egy teszt script-et, mivel a fejleszts sorn szmtalanszor kellett hasznlni ezt a programot ltalban azonos belltsokkal.
op@pandora-test git# less smap_test.csh #!/bin/csh set FREEBSD_PREFIX="/usr/home/op/git/" #set QEMU_PREFIX="/usr/home/op/qemu/" set QEMU_PREFIX="/usr/local/" set QEMU="${QEMU_PREFIX}/bin/qemu" set QEMU_X86_64="${QEMU_PREFIX}/bin/qemu-system-x86_64" set QEMU_OPTIONS="-cpu qemu64,enforce,+smap,-hypervisor -m 1024M" set HDD_IMAGE="${FREEBSD_PREFIX}/freebsd-test.raw" $QEMU_X86_64 $QEMU_OPTIONS -hda $HDD_IMAGE
Ahogy a vastagon kiemelt sorban lthat Haswell CPU tpus helyett qemu64-et hasznlok, mely a Qemu sajt metaprocesszora, amit szles krben lehet konfigurlni. Hrom lnyeges opcit kellett megadni a CPU tpusn kvl: enforce +smap -hypervisor
Az enforce nevbl addik, hogy az adott opcikat mindenkpp be akarjuk kapcsolni. A +smap opcival jelezzk, hogy az SMAP szolgltatst be akarjuk kapcsolni. A hypervisor pedig egy FreeBSD specifikus bellts. Kikapcsolja a hypervisor bitet, mivel a Qemu alaprtelmezetten belltja az emullt processzorban. Azonban a FreeBSD s az ltalam ksztett SMAP implementci is kikapcsol bizonyos szolgltatsokat hypervisor-ok alatt, melyet ezen bit segtsgvel rzkel. Erre azrt van szksg, mivel nhny hypervisor ne m szri ki megfelelen a nem tmogatott kiterjesztseket a FreeBSD-ben tallhat komment szerint. Az smap_test.csh script egy virtulis gpet indt el, melyben egy FreeBSD 10CURRENT kapott helyet.
86
Az image frisstse ugyancsak egy script segtsgvel trtnik, melyet az smap_test.csh utn mutatok be. update_freebsd.csh:
#!/bin/csh set set set set set set set set set FREEBSD_PREFIX="/usr/home/op/git/" QEMU_PREFIX="/usr/home/op/qemu/" MDCONFIG="/sbin/mdconfig" QEMU="${QEMU_PREFIX}/bin/qemu" QEMU_IMG="${QEMU_PREFIX}bin/qemu-img" QEMU_X86_64="${QEMU_PREFIX}/bin/qemu-system-x86_64" QEMU_OPTIONS="-cpu Haswell -m 1024M" FSCK="/sbin/fsck_ffs" HDD_IMAGE="${FREEBSD_PREFIX}/freebsd-test.raw"
if (! -e $HDD_IMAGE) then ${FREEBSD_PREFIX}/mkenv_haswell_env.csh endif set MD_DEV=`$MDCONFIG -a -t vnode -f $HDD_IMAGE` if (! -e /dev/$MD_DEV) then echo "mdconfig failed..." exit -1 endif set MD_DEV_ROOT="/dev/${MD_DEV}p2" $FSCK -y $MD_DEV_ROOT setenv DESTDIR ${FREEBSD_PREFIX}/target if (! -e $DESTDIR) then mkdir $DESTDIR endif mount /dev/${MD_DEV}p2 $DESTDIR cd ${FREEBSD_PREFIX}/freebsd-base.git.http #make -j4 buildworld installworld kernel -DNO_CLEAN make -j4 kernel -DNO_CLEAN || make -j4 kernel umount ${FREEBSD_PREFIX}/target $MDCONFIG -d -u $MD_DEV
A script rviden lerva, egy FreeBSD image file-t csatol fel egy specilis alrendszeren keresztl, melynek a neve md. Ezt kveten az image file helyett egy block eszkzt fogunk ltni a /dev knyvtrban, melynek nevvel az mdconfig eszkz visszatr. Utna az ezen az eszkzn tallhat root partcit ellenrizzk, mivel a tesztels alatt kernel panic()-ot kapunk szmtalanszor s ekkor a file rendszer inkonzisztens llapotba kerl. Ha ez lefutott, akkor felcsatoljuk a root file rendszert a target mappba s lebuildeljk az j kernel-t a make kernel parancs segtsgvel. Ha ez lefutott s 87
frisstette a kernel-t, akkor a file rendszert lecsatoljuk, s az mdconfig segtsgvel lecsatoljuk az image-t is az md alrendszerrel. Ezt kveten az elszr bemutatott script segtsgvel mehet a tesztels. A tesztels nem lett automatizlva, mivel kzi beavatkozst s elemzst is szmtalanszor ignyel. Az image-re elhelyeztem a mr korbban emltett smap-tester programokat s kzzel futtattam ket.
A kezdeti szakaszban, amikor a ksp alrendszer fejlesztsvel foglalkoztam, gyorsabbnak lttam kt fizikai FreeBSD gp hasznlatt. Az egyik gp (laptop) volt a debugger gp a msik (desktop) pedig a teszt gp. A kt gp kztt soros kapcsolat volt. Mivel az identcpu s initcpu szakaszban a kernel mg kevsb mkdkpes s USB perifrik nem mkdnek. A kernel viszont nyjt soros terminl szolgltatst, amin keresztl a kernelt DDB-vel egyszeren lehetett debuggolni. Ehhez az albbi sorok bersra volt szksg a /boot/loader.conf file-ba:
boot_multicons="YES" boot_serial="YES" console="vidconsole,comconsole"
88