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


Introduktion och historik

För att kunna uppskatta denna artikel krävs det att man har lite koll på allmänt programmerande, virtuellt minne och hur buffer overflows någorlunda fungerar.

En ganska bra beskrivning av 'buffer overflows' finns här:
LinuxJournal

..men i korthet går det iallafall ut på att när man gör ett anrop eller hoppar till en subrutin så sparas en massa data på stacken tillsammans med anropets inparametrar och returaddressen dit man avser att återgå till när anropet är färdigt.

Om man då, via en bugg eller genom att göra något "oväntat" (som att mata in en 8000 tecken lång URL eller liknade), kan få en sträng eller en buffer att "flöda över" så kommer det extra datat att läcka in i omgivande data och allra helst (ur attackerarens perspektiv) skriva över returaddressen. Kan man skriva över returaddressen så kan man hoppa "vart man vill", lämpligen till kod man själv har kontroll över, men om man inte får det så finns det ofta en massa kod att ta av på andra ställen, t.ex delade bibliotek och liknande. En bra buffer overflow har koden med sig i själva overflowdelen så att samma data som orsakar själva 'kraschen' även innehåller koden man vill få programmet att exekvera.

Så fort det här inträffar så kommer den som sände bufferten till programmet att kunna köra kod som exekveras med samma rättigheter som programmet självt. Är det en mailserver som har rätt att ändra i folks mailkataloger så kan elak kod radera samtliga personers mail. Är det ett program som körs med fulla rättigheter så kan koden göra i princip "allt", från att boota om datorn, mata ut cd-luckan eller formattera om diskarna.

Det är ju en av de stora anledningarna till att MacOS6->9 och Win3/W9x/WinME suger så hårt som server, för oavsett vilken kod/tjänst man lyckas bräcka på en sån dator så äger man hela maskinen. Iden att logga in som icke-administrator på moderna OS är just för att om inte du kan formatera disken så kan inte ett nyss inkommet mailvirus eller en exploit du åkt på göra det heller.

Det elaka i sammanhanget är att det oftast rör sig om storleksordningen 1k, 4k eller 8k för att flöda över en buffer normalt, så det är inga som helst problem att köra en attack från en modemlina eller liknande. Det syns liksom inte om ens maskin tar emot 8k extra när den är kopplad på nätet. Inte ens på modem. Men så fort de är inne så är man rökt, direkt. 1-8k är dessutom gott om utrymme för att kunna få in elak kod. Den senaste vågen som kom av Slammer/Sapphireviruset är ett bra exempel. Där var viruskoden inte mer än 376 bytes lång. Även om dagens system verkar bloatade och programmen hur stora som helst så tar det fortfarande inte många hundra bytes att skriva kod som raderar din hårddisk, ditt registry eller annan liknande vital del. Om den koden råkar skita sig på 99% av systemen spelar ju ingen roll för en angripare, han kommer leta upp nästa måltavla på nätet bara och attackera vidare.

Gamla befintliga metoder att skydda sig med

Ett sätt har varit att se till att minnet där programmets stack lagras har egenskapen "executable" avslagen, eftersom man normalt sett inte ska köra kod i stacken. Stacken är ju en mellanlagringsplats för data (och även kod) men räknas ju inte som en plats dit man skulle hoppa till inifrån programmet, så det är normalt sett en ganska bra metod att exekveringsskydda stacken. Dock finns det ett par kompilatorer och språk som ändå förlitar sig på att stackens utrymme är körbart för att kunna skapa kod on-the-fly, och i dessa fall måste man få till en ändring av dem för att de ska kunna köras alls, vilket är svårt i vissa fall. Det går dessutom att lagra bus-koden i andra utrymmen än stacken, så det är inte ett heltäckande skydd i sig, även om det är vanligt med stack-smash:ande exploits.

Ett annat är ju att se till att de programmen som exponeras mot nätet eller som tar in info på ett okontrollerat sätt (t.ex inmatning från users eller valfria filer) körs med så lite privilegier som det bara går. Även här kan det vara problem att få det att funka i praktiken, eftersom program som t.ex mailservrar faktiskt måste kunna ändra i allt folks mailkataloger om den ska kunna leverera mail till dem.

Ett tredje sätt är att helt enkelt skriva om gammal kod i andra språk som har mer inbyggda kontroller och som inte på samma vis låter sig påverkas av den här typen av attacker. Det brukar ofta innebära en förlust i prestanda, men med dagens maskiner är det kanske inte lika märkbart om man går över till ett språk på högre nivå. Nackdelen med att skriva om saker blir bland annat att man kan introducera en mängd helt nya buggar i ett annars beprövat system.

Dessutom är det ingen garanti för att det nya språkets slutkod är buggfri vad gäller all datahantering. Språk som php, perl, python är ju interpreterande språk vars interpretatorer är skrivna i C/C++, så det finns ju en chans att C-koden som de baseras på innehåller tankefel och missar som ärvs uppåt till högnivåspråket trots att högnivåspråket i sig kanske inte ens kan ha overflowproblem per design. Det är ju skillnad på designen och implementationen i det läget.


  Nästa sida »


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

Utskriftsvänligare versionUtskriftsvänligare version

Diskutera denna artikeln i vårt forum!