Visszatérő programozás

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2015. július 28-án felülvizsgált verziótól ; az ellenőrzések 7 szerkesztést igényelnek .

A Return oriented Programming ( ROP ) a szoftver sérülékenységeinek kihasználására szolgáló  módszer , amellyel a támadó végrehajthatja a számára szükséges kódot, ha a rendszerben védelmi technológiák vannak, például olyan technológia, amely megtiltja bizonyos memóriaoldalakról származó kód futtatását [ 1] . A módszer abban rejlik, hogy a támadó átveheti az irányítást a hívási verem felett , megtalálhatja a kódban a szükséges műveleteket végrehajtó utasításokat , amelyeket "gadgeteknek" neveznek, és végrehajthatja a "gadgeteket" a kívánt sorrendben [2]. A "gadget" általában egy visszatérési utasítással végződik, és a meglévő kódban (programkódban vagy megosztott könyvtárkódban ) a fő memóriában található . A támadó a modulok szekvenciális végrehajtását valósítja meg a visszatérési utasítások segítségével, és úgy rendezi el a modulok sorozatát, hogy végrehajtsa a kívánt műveleteket. A támadás még olyan rendszereken is megvalósítható, amelyek rendelkeznek az egyszerűbb támadások megelőzésére szolgáló mechanizmusokkal.

Történelem

Puffer túlcsordulási támadás

A Return Oriented Programming a puffertúlcsordulási támadás továbbfejlesztett változata . Ebben a támadásban a támadó egy hibát használ a programban, amikor a függvény nem ellenőrzi (vagy hibásan ellenőrzi) a határokat, amikor a felhasználótól kapott adatok pufferébe ír. Ha a felhasználó a pufferméretnél több adatot küld, akkor a többlet adat a többi helyi változónak szánt memóriaterületbe kerül, és felülírhatja a visszatérési címet is. Ha a visszatérési címet felülírják, akkor a függvény visszatérésekor a vezérlés átkerül az újonnan írt címre.

A puffertúlcsordulási támadás legegyszerűbb változatában a támadó kódot ("payload") tol a verembe, majd felülírja a visszatérési címet az éppen írt utasítások címével. Az 1990-es évek végéig a legtöbb operációs rendszer nem nyújtott védelmet ezekkel a támadásokkal szemben. A Windows rendszerek 2004-ig nem rendelkeztek védelemmel a puffertúlcsordulási támadások ellen. [3] Végül az operációs rendszerek elkezdtek foglalkozni a puffertúlcsordulási sérülékenységek kihasználásával a memória bizonyos oldalainak nem végrehajthatóként való megjelölésével (ez az úgynevezett "adatvégrehajtás-megelőzés"). Ha az adatvégrehajtás megakadályozása engedélyezve van, a gép megtagadja a kód végrehajtását a "csak adatok" jelzésű memóriaoldalakon, beleértve a köteget tartalmazó oldalakat is. Ez megakadályozza, hogy a hasznos terhet a veremre tolja, majd ráugorjon, felülírva a visszatérési címet. Később úgy tűnt, hogy az adatvégrehajtás-megelőzés hardveres támogatása fokozza a védelmet.

Library return attack

Az adatvégrehajtás megakadályozása a fent leírt módszerrel megakadályozza a támadást. A támadó a megtámadott programban és a megosztott könyvtárakban már található kódra korlátozódik. A megosztott könyvtárak, például a libc azonban gyakran tartalmaznak rendszerhívásokat indító funkciókat és egyéb hasznos funkciókat a támadók számára, amelyek lehetővé teszik ezeknek a funkcióknak a támadások során történő használatát.

A könyvtár visszatérési támadása a puffer túlcsordulást is kihasználja. A visszatérési címet felülírja a kívánt könyvtári függvény belépési pontja. A visszatérési cím feletti cellák is felülírásra kerülnek, hogy paramétereket adjanak át a függvénynek vagy a többszörös lánchívásoknak. Ezt a technikát először Alexander Peslyak (Solar Designer néven ismert) vezette be 1997-ben, [4] és azóta kibővítették, hogy lehetővé tegye a függvényhívások korlátlan láncát. [5]

Kódrészletek kölcsönzése

A 64 bites hardverek és operációs rendszerek elterjedésével egyre nehezebbé vált a könyvtári visszatérési támadás végrehajtása: a 64 bites rendszerekben alkalmazott hívási konvenciókban az első paraméterek nem a veremben, hanem a függvénynek adódnak át. regisztereket. Ez megnehezíti a támadás során meghívandó paraméterek előkészítését. Ezenkívül a megosztott könyvtárak fejlesztői elkezdték eltávolítani vagy korlátozni a "veszélyes" funkciókat, például a rendszerhívás-burkolókat a könyvtárakból.

A támadás következő fejlesztési köre a könyvtári funkciók részeinek felhasználása volt a teljes funkciók helyett. [6] Ez a technika a függvények azon részeit keresi, amelyek az adatokat a veremből a regiszterekbe tolják. Ezen részek gondos kiválasztása lehetővé teszi a szükséges paraméterek elkészítését a regiszterekben a függvény hívásához az új konvenció szerint. Továbbá a támadást ugyanúgy hajtják végre, mint a könyvtári visszaküldést.

Támadás visszatérés-orientált programozással

A Return-Oriented Programming kiterjeszti a kódkölcsönzési megközelítést azáltal, hogy a támadónak Turing-teljes funkcionalitást biztosít, beleértve a ciklusokat és elágazásokat . [7] Más szóval, a visszatérés-orientált programozás lehetőséget biztosít a támadónak bármilyen művelet végrehajtására. Hovav Shaham 2007-ben publikálta a módszer leírását [8] , és egy olyan programon demonstrálta, amely a szabványos C könyvtárat használja, és puffertúlcsordulási sebezhetőséget tartalmaz. A megtérülés-orientált programozás mind kifejezőerőben, mind védekező intézkedésekkel szembeni ellenállásában felülmúlja a fent leírt egyéb támadástípusokat. A támadások elleni küzdelem fenti módszerei egyike sem, beleértve a veszélyes funkciók eltávolítását a megosztott könyvtárakból, nem hatékony a visszatérés-orientált programozás ellen.

Ellentétben a visszatérő könyvtárba támadással, amely teljes függvényeket használ, a visszatérés-orientált programozás kis utasítássorozatokat használ, amelyek visszatérési utasítással végződnek, az úgynevezett "gadgeteket". A minialkalmazások például meglévő függvények végződései. Egyes platformokon azonban, különösen az x86 -on , a kütyük előfordulhatnak "a sorok között", vagyis amikor egy meglévő utasítás közepétől dekódolnak. Például a következő utasítássorozat: [8]

teszt edi , 7 ; f7 c7 07 00 00 00 setnz bájt [ ebp -61 ] ; 0f 95 45 c3

amikor a dekódolás egy bájttal később kezdődik, ad

mov dword [ edi ], 0 f000000h ; c7 07 00 00 00 0f xchg ebp , eax ; 95 inc ebp ; 45 ret ; c3

Ezenkívül a modulok lehetnek az adatokban, valamilyen okból a kód részben. Ennek az az oka, hogy az x86 utasításkészlet meglehetősen sűrű, ami azt jelenti, hogy jó eséllyel egy tetszőleges bájtfolyamot tényleges utasítások folyamaként értelmezünk. Másrészt a MIPS architektúrában minden utasítás 4 bájt hosszú, és csak a 4 bájt többszörösének megfelelő címekhez igazított utasítások hajthatók végre. Ezért nincs mód arra, hogy "sorok közötti olvasással" új sorozatot kapjunk.

A támadás a puffertúlcsordulási sebezhetőséget használja ki. Az aktuális függvény visszatérési címe felülíródik az első modul címével. A verem következő pozíciói a következő modulok címeit és a modulok által használt adatokat tartalmazzák.

Példák

Kiterjesztések

Az x86-os platform eredeti verziójában a kütyük ugrások nélkül egymás után elrendezett utasítások láncai, amelyek egy közeli visszatérési utasítással végződnek. A támadás kiterjesztett változataiban a láncutasítások nem feltétlenül szekvenciálisak, hanem közvetlen ugrási utasításokkal kapcsolódnak össze. Valamint a végső utasítás szerepét egy másik visszatérési utasítás is betöltheti (x86-ban van távoli visszatérési utasítás, közeli és távoli visszatérési utasítások veremtörléssel), indirekt ugrási utasítás, vagy akár indirekt hívási utasítás is. Ez megnehezíti a támadási módszer elleni küzdelmet.

Automatikus generálás

Vannak eszközök a kütyük automatikus megtalálására és a támadások tervezésére. Ilyen eszköz például a ROPgadget. [9]

Védelem a visszatérés-orientált programozás ellen

Számos módszer létezik a visszatérés-orientált programozás elleni védekezésre. [10] A legtöbb a programkód és a könyvtárak viszonylag tetszőleges címen való elhelyezkedésére támaszkodik, így a támadó nem tudja pontosan megjósolni a kütyükben esetleg hasznos utasítások helyét, és ezért nem tud felépíteni egy modulláncot a támadáshoz. A módszer egyik megvalósítása, az ASLR , a program minden egyes futtatásakor más címen tölti be a megosztott könyvtárakat. Bár ezt a technológiát széles körben használják a modern operációs rendszerekben, sebezhető az információszivárgási támadásokkal és más olyan támadásokkal szemben, amelyek lehetővé teszik egy ismert könyvtári funkció helyzetének meghatározását. Ha egy támadó meg tudja határozni egy funkció helyét, meg tudja határozni az összes utasítás helyét a könyvtárban, és visszatérés-orientált programozási támadást hajthat végre.

Nemcsak a teljes könyvtárakat, hanem a programok és könyvtárak egyes utasításait is átrendezheti. [11] Ehhez azonban kiterjedt futásidejű támogatásra van szükség, például dinamikus fordításra, hogy a permutált utasításokat a megfelelő végrehajtási sorrendbe állítsa vissza. Ez a módszer megnehezíti a kütyük megtalálását és használatát, de magas költségekkel jár.

A kBouncer [12] megközelítése annak ellenőrzése, hogy a return utasítás átadja-e a vezérlést közvetlenül a hívási utasítást követő utasításnak. Ez nagymértékben csökkenti a lehetséges kütyük számát, ugyanakkor jelentős teljesítménycsökkenést is okoz. [12] Ráadásul a visszatérés-orientált programozás kiterjesztett változatában a kütyük nem csak visszatérési utasítással, hanem indirekt ugrás- vagy hívásutasítással is összekapcsolhatók. Egy ilyen kiterjedt támadás ellen a kBouncer hatástalan lesz.

Jegyzetek

  1. Shacham, Hovav; Buchanan, Eric; Romer, Ryan; Savage, Stefan Return-Oriented Programing: Exploits Without Code Injection . Letöltve: 2009. augusztus 12. Az eredetiből archiválva : 2010. június 1.
  2. Erik Buchanan, Ryan Roemer, Hovav Shacham és Stefan Savage; Amikor a jó utasítások megromlanak: A Return-Oriented Programming to RISC archiválása : 2017. augusztus 11., a Wayback Machine , Proceedings of CCS 2008 , ACM Press, 2008. október.
  3. Microsoft Windows XP SP2 adatvégrehajtás megelőzése . Letöltve: 2014. április 10. Az eredetiből archiválva : 2018. április 14..
  4. Solar Designer, Return-into-lib(c) exploits Archiválva : 2018. február 23., a Wayback Machine , Bugtraq
  5. Nergal, Phrack 58 4. cikk, return-into-lib(c) exploits Archivált 2013. április 25. a Wayback Machine -nél
  6. Sebastian Krahmer, x86-64 puffer túlcsordulás exploit és a kölcsönzött kóddarabok kihasználási technika Archivált : 2018. december 22., a Wayback Machine , 2005. szeptember 28.
  7. Martín Abadi, Mihai Budiu, Úlfar Erlingsson és Jay Ligatti. Control-Flow integritás: alapelvek, megvalósítások és alkalmazások . In Catherine Meadows és Ari Juels, szerkesztők, Proceedings of CCS 2005 . ACM. 2005. október
  8. 1 2 Hovav Shacham. Az ártatlan hús geometriája a csonton: visszatérés a libc-be függvényhívások nélkül (x86-on) . In Proceedings of the 14th ACM Conference on Computer and Communications Security (CCS '07) . ACM 2007
  9. Jonathan Salwan és Allan Wirth, ROPgadget – Gadgets kereső és auto-roper Archiválva : 2014. április 18. a Wayback Machine -nél
  10. Richard Skowyra, Kelly Casteel, Hamed Okhravi és William Streilein; A megtérülés-orientált programozás elleni védekezés szisztematikus elemzése archiválva : 2014. február 22., a Wayback Machine , In Proceedings of RAID 2013 , Lecture Notes in Computer Science (LNCS), Vol. 8145, pp. 2013., 82-102.
  11. Jason Hiser, Anh Nguyen-Tuong, Michele Co, Matthew Hall, JackW. Davidson, ILR: Hová tűntek a kütyüim? Proceedings of the IEEE Symposium on Security and Privacy, 2012. május, San Francisco, CA
  12. 1 2 Vasilis Pappas. kBouncer: Efficient and Transparent ROP Mitigation Archivált : 2017. augusztus 30. a Wayback Machine -nál . 2012. április.