Innehåll

Hackskydd i OpenBSD 3.3

Introduktion och historik
OpenBSDs skydd
Andra metoder

OpenBSD 3.3 - This you can trust


16/06-03 | IcePic | icepic@64bits.se

Utskriftsvänligare versionUtskriftsvänligare version


Andra metoder

Bortsett från de råa tekniska sätten att krångla med koden i minnet för att minska chansen att lyckas rent statistiskt, så jobbas det parallellt med nåt som heter "Priviledge Separation". Som jag nämnde i den historiska sektionen om att ha så lite privilegier som möjligt så är det inte helt enkelt att bara ta bort dem och köra som "nobody", eftersom många demoner behöver eleverade privilegier.

Ett par av anledningarna är t.ex sshd, dvs demonen som svarar på ssh-protokollet. När man loggar in via ssh så ska man efter att ha angivit rätt lösenord "bli" sin user på datorn och med fulla rättigheter för "mig". Det innebär ju att sshd måste köras med så mycket rättigheter att den får bli "mig" om jag anger rätt lösen, eller får bli "dig" om du anger rätt lösen. Det visar sig rätt fort att den måste ha i princip summan av alla personers rättigheter under stor del av tiden. Dock inte hela tiden, vilket är det PrivSep går ut på.

Tidigare har man ojat sig lite och sedan försökt hålla demoner av sshd's typ så buggfria som möjligt. Med PrivSep så ser man till att hålla så lite kod som möjligt under högsta nivån och sedan sänka sig till en lägre nivå direkt. Det innebär att maildemoner är root under en kort stund medans den binder till port 25, och sedan går ner till usern "smmsp" (i OpenBSD's fall) vilket i sin tur är en user som inte har ett hemkonto, inte kan logga in, men som får addera till folks maillådor och skriva/radera filer i spool-arean för mail. Enbart.

Det gör att under tiden den är root, vilket är ett par tiotal rader kanske, så är chansen för att den blir exploaterad väldigt liten eftersom enbart ett fåtal saker ska göras där och inget av det kräver att man tolkar user-input eller saker från nätet och det är mycket lättare att verifiera att den koden gör exakt det den ska och inget annat och sedan droppar man sina privilegier till en mail-user. Visserligen kan denne mail-user ställa till det på mailsidan, men den är åtminstone inte root, vilket är ett stort steg.

I den andan har OpenBSD skapat en massa nya users (en per tjänst), och sedan flyttat om all kod som kräver root-privilegier till början av programmet, kollat en extra gång och sedan går den ner till sin per-tjänst-user för att minimera den skada som ev. kan ske om någon tar full kontroll över demonen via nån sorts bugg under drift.

Man använder också anropet chroot() i samband med PrivSep (och i andra sammanhang med) som är ett komplement till att byta användare. Att byta användare ser ju till att man enbart kan skada de delar av systemet som tillhör den nya användaren, men med chroot() kan man minska även på det. chroot() gör så att ett program får en virtuell vy av filsystemet som inte längre täcker hela filsystemet utan enbart en del av det.

Man tar en katalog, gör chroot() dit och vips så tror programmet att filsystemet enbart består av de filer och kataloger som existerar under den katalogen. Alla andra processer och users kan (om rättigheterna är så satta) läsa och skriva normalt till den katalogen, men den process som är chroot:ad till katalogen kan inte se några som helst filer utanför katalogen. Det finns inget sätt (utom extrema buggar då) för en process att avsluta chroot(), så det är en oåterkallelig begränsning som inte går att ta sig runt.

Så länge man har lagt dit de filer som programmet nånsin kan tänkas behöva så klarar det sig alldeles utmärkt. Man kan även ha det på ett eget filsystem och de det filsystemet lämpliga icke-rättigheter som att "i detta filsystem får inga devicefiler existera, inga exekverbara program kan startas från det" alternativt: "Eventuella suid:ade program får suid-biten borttagen innan start" (nodev, noexec och nosuid respektive) för att förhindra att en buse som tagit kontroll över demonen placerar en massa binärer från nätet där för att kunna återkomma senare eller för att försöka skapa devicefiler som skulle kunna ge åtkomst till hårdvaran på maskinen om busen har tur.

I extrema fall kan det filsystemet vara monterat read-only och filerna ägs av någon annan och saknar writepermissions för servern, varpå det blir omöjligt på flera plan samtidigt för busen att kunna ändra på datat som ligger där.

Det innebär att t.ex webservern eller namnservern kan ha en katalog någonstans dit den (efter att ha bundit sin nätverksport) självmant låter sig chroot:as och sedan är den fast under den katalogen tills den dör. Är man rädd om sitt data så ser man till att inte lägga originalen på sin website eller sin dns-info där under utan kopierar ner det dit innan man startar sin server, och sen startar man upp tjänsten.

På så vis kan inte ens busen ändra i ditt original, utan bara i den temporära kopian om han får full kontroll över www/namnservern. Servern kör dessutom som en egen user som inte någon annan server delar, så trots att man har full kontroll så kan man inte göra mycket annat än att öda lite disk och cpu på servern, eller radera de temporära kopiorna. Punkt.

Dock är det inte sista ordet sagt om OpenBSDs säkerhet där. De har ytterligare en metod, som kom med OpenBSD 3.2 som kallas Systrace. Systrace kom till efter att man insett att program som går med höga privilegienivåer borde hindras att göra vissa saker som de aldrig ska kunna göra överhuvudtaget. Ett bra exempel är "ping". Den bakar sina egna paket och måste enligt gammal unixtradition köras med eleverade privilegier. Dock måste ping endast ha privilegierna för att sända egenhändigt bakade paket och inget annat. Inte för filåtkomster eller för att läsa andra personers lösenord i konsolen. Men om nu koden i ping har nån sorts bugg så att den som pingar min onda maskin får ett svar som i sin tur får nån buffert att flöda över och jag kan ta kontroll över din process så har jag helt plötsligt fått fulla rättigheter på ditt system och kan läsa alla dina filer osv.

Det man gjorde var en variant på runtime-debug-programmen strace/truss/ktrace som används för att lista vilka OS-anrop ett program gör under sin gång. Genom att modifiera anropen kunde man istället för att bara logga dem istället utsätta dem för en policy. Man kunde alltså skapa en policyfil som säger att "ping får använda OSanropet sendto() som root". Allt som inte passar i policyn kan antingen stoppa programmet, skapa en varning eller helt enkelt bara ignoreras. Man kan även se till att parametrarna till anropen är på ett visst sätt. T.ex att programmet Foo får öppna filen "foo.log" för skrivning, och enbart i katalogen "Foo/logs", eller att mailsändande program enbart får koppla sig över nätet till andra maskiner på port 25 (som mail använder) och jobbets browsers enbart får gå mot företagets proxy på datorn x.y.z.w på port 80.

På det viset kan program som "ping" hindras från att läsa filer eller formattera din hårddisk om man låter den köras inom ramen för systrace med en lagom policy trots att den körs med eleverade privilegier. Att testa policyn mot anropen var dessutom inte mycket dyrare än de tester som redan görs.

Men det fina med systrace är att den kan jobba åt två håll. Att hindra ping från att göra annat än nätverkshantering medans den har eleverade privilegier är ju en sorts "privilege degradation", dvs man har många rättigheter men kan inte bruka dem ohejdat. Ping har ju en flagga satt på sin binär som heter "setuid", dvs att när man kör ping så körs den som ägaren till filen, i unixens fall som root. Detta är just för att enbart root får sända konstiga hemsnickrade paket. Men med hjälp av systrace kan man vända på hela steken och istället göra "privilege escalation".

Istället för att ping (i sin helhet eller delvis via PrivSep) körs som root för att setuid-flaggan säger det, och sedan hindra alla anrop som inte är nätverksrelaterade så låter man systrace skapa en omvänd policy som säger: "När ping vill sända ett egensnickrat paket så anse att den är root". Då kan man ta bort setuid-biten på binären och all kod i ping körs som om det var min user precis som vanligt, men just enbart för ett anrop så är ping "root" och får sända sitt paket, och klarar då att komma förbi anropets kontroll att man är root. Under all annan tid är programmet helt opriviligierat.

Tycker man att det låter krångligt att skriva systrace-policies så finns det självklart hjälp att få. Det går att köra ett program som ännu inte har en policy, och logga alla anrop under en normal körning, och sen sätta det som policy efteråt. På så vis vet man till 99% vad som programmet kräver under normal drift och kan enkelt anpassa policyn senare vid behov. Samtidigt har man fått ett grymt bra skydd mot allehanda typer av oväntade problem. Det finns även grafiska frontends som låter dig välja Stora Gröna eller Stora Röda Knappen(tm) för varje anrop och därefter skapa en sån policy för programmet. Eller helt enkelt bara köra sina program med en lagom policy och sen när nåt oväntat händer som inte finns med i policyn så poppar gui:t upp och låter dig ange om du vill tillåta det eller inte, lite som ZoneAlarm gör med utgående paket på Windows. Givetvis finns det siter på nätet med färdiga policies för diverse program som man kan ladda ner om man vill.

Sammantaget gör alla sådana knep, metoder och system att man får en plattform som är extremt svår att få kontroll över som buse. Det har länge varit OpenBSDs policy att inte låta nätverksstacken bete sig på ett sätt som gör det onödigt svårt att veta vilket OS som körs på datorn. Det finns ju program som pratar över nätet med din maskin och beroende på hur den beter sig om det kommer konstiga paket så kan man göra en hyffsad gissning av vilket OS du kör. Vart 3:e månad poppar den frågan upp på OpenBSDs maillistor: "hur döljer jag vilket OS jag kör?", men hittils har det oftast mötts av stort motstånd. Dels är det ju inget skydd i sig att ens OS inte syns, har man en mailserver med ett gapande stort hål i så har man, vare sig busen kan läsa av ditt OS eller inte och dels så kan det faktiskt vara ett "skydd" att visa att man kör det "säkraste" OS:et. Precis som man sätter klisterlappar och dioder för att visa att man har ett dugligt larm på sin bil så kan det vara lika avhållande att faktiskt flagga tydligt vilket OS man kör.

Det sista kapitlet är ju knappast helt unikt för OpenBSD, men de har tagit det här ett steg seriösare än andra. Det innebär att det är lite lurigare för de som vill att alla users enkelt ska kunna ha hemsidor i sin hemkatalog under public_html/ eller liknande samtidigt som webservern inte kan komma ur sin chroot() till en katalog på en annan plats i filsystemet, men den typen av metoder ökar säkerheten och minskar exponeringen så mycket att det får vara värt det. OpenBSD skryter med "Endast ett fjärrexploaterbart hål i grundinstallationen på sju år" och det är med all rätt tycker jag. Att hålla sig så ren och samtidigt så buggfri att den som installerar det kan lita på att utvecklarna verkligen gjort sitt yttersta för att göra det säkert är nåt att sträva efter. Inget system är någonsin perfekt, men det betyder inte att man inte ska sträva efter det målet.




« Föregående  


16/06-03 | IcePic | icepic@64bits.se

Utskriftsvänligare versionUtskriftsvänligare version

Diskutera denna artikeln i vårt forum!