Pillantás a sebezhetőségek kihasználására

Mivel várom, hogy folytassam a téma folytatását, hadd mondjak el egy kis történelmet, elméletet és gyakorlatot a sebezhetőségekről. Mindannyian hallottuk már, hogy a biztonsági hibák sokba kerülhetnek, mindannyian tudjuk, hogy szoftverünket naprakészen kell tartanunk, mindannyian tudjuk, hogy sok frissítést biztonsági hibák okoznak. De ma elmondok egy kicsit arról, hogyan találják meg és használják ki ezeket a hibákat 🙂 De előtte tisztázni fogunk néhány részletet a jobb áttekintés érdekében.

Mielőtt elkezdené

Először szeretném elmondani, hogy az első sebezhetőségre fogunk összpontosítani, amelyet megtanultam kihasználni, az ismertre Puffer túlcsordul, ebben a biztonsági résben kihasználjuk a memóriaellenőrzés hiányát, hogy szórakoztató dolgokat végezzünk 🙂 De tisztázzunk még egy kicsit többet róla.

Ez nem valós forgatókönyv lesz

Nem engedhetem meg magamnak, hogy megtanítsam őket megszakítani az általuk nézett programokat - egyrészt azért, mert veszélyes a számítógépükre, másrészt azért, mert ehhez több kellene, mint a szokásos szavakból.

Kirándulunk a 80-as évekbe

Amit megmutatni fogok, azt megtehetem a laptopomon, de ez nem azt jelenti, hogy ezt ma egyszerű módon meg lehet valósítani 🙂 sok ilyen fogalmat már annyiszor kihasználtak, hogy új védelmi módszerek és új módszerek kerülhetők el megjelentek 😛 de ez visszavezet minket ugyanoda, nincs hely mindennek elmondani 🙂

Lehet, hogy nem működik a processzorán

Bár egy nagyon egyszerű példát fogok használni, azt szeretném, ha a kezdetektől fogva teljesen világos lenne, hogy ennek a részletei annyira sokfélék és annyira változatosak, hogy ugyanúgy kijöhet, mint én, ha ki akarja próbálni , a kívánt hatást szintén nem lehet elérni 🙂 De elképzelheti, hogy ezt nem tudom megmagyarázni ezen a téren, főleg, hogy ezzel a bevezetéssel már több mint 300 szót vettem fel, így egyenesen a lényegünkhöz jutunk.

Mi az a Puffer túlcsordulás

Ennek megválaszolásához először meg kell értenünk ennek a kombinációnak az első felét.

Pufferek

Mivel minden a számítógép memóriájáról szól, logikus, hogy léteznie kell valamilyen típusú információtartálynak. Amikor arról beszélünk bemenet kimenetek, közvetlenül a pufferek. Hogy rövid legyen, a ütköző Ez egy meghatározott méretű memóriaterület, amelyben egyszerű mennyiségű információt tárolunk

Túlcsordulások következnek be, ahogy a neve is mutatja, amikor egy puffer több információval tölt fel, mint amennyit képes kezelni. De miért fontos ez?

Stack

Veremként is ismert, absztrakt adattípus, amelyben megtehetjük Kazal információ, fő jellemzőjük, hogy rendelés van LIFO (Last In First Out). Gondoljunk egy pillanatra egy halom tányérra, ezeket egyenként tegyük a tetejére, majd egyenként kivesszük a tetejéről, ez teszi az utolsó tányért, amelyet feltettünk (azt, ami a tetején van) ) az első lemez, amelyet elő fogunk venni, nyilvánvalóan, ha egyszerre csak egy lemezt tudunk elővenni, és úgy döntünk, hogy ebben a sorrendben csináljuk: P.

Most, hogy ismeri ezt a két fogalmat, rendbe kell hoznunk őket. A kötegek azért fontosak, mert minden általunk futtatott programnak megvan a maga végrehajtási verem. De ennek a veremnek van egy sajátos jellemzőjelefelé nő. Az egyetlen dolog, amit tudnia kell erről: az, hogy egy program futása közben egy függvény meghívásakor a verem a memóriában lévő X számtól egy számig (Xn) megy. De a folytatáshoz meg kell értenünk még egy fogalmat.

Mutatók

Ez egy olyan koncepció, amely sok programozót megőrjít, amikor elindulnak a C világában, valójában a C programozás nagy ereje részben a mutatók használatának köszönhető. Az egyszerűség kedvéért mutató memóriacímre mutat. Ez összetettnek hangzik, de nem annyira összetett, mindannyiunkban van RAM a gépeinkben, igaz? Nos, ez meghatározható a blokkok egymást követő elrendezése, ezeket a helyeket általában hexadecimális számokban fejezzük ki (0 és 9, majd A és F között, például 0x0, 0x1, 0x6, 0xA, 0xF, 0x10). Érdekes megjegyzésként itt 0x10 NEM egyenlő 10 😛 -vel, ha decimális sorrendbe konvertáljuk, az ugyanaz lenne, mint a 15. mondás. Ez egy olyan dolog, amely eleinte többet is összekever, de térjünk rá.

Records

A processzorok számos nyilvántartások, amelyek a fizikai memóriából a processzorba továbbítják a helyeket, a 64 bites architektúrák esetében a regiszterek száma nagy és nehéz itt leírni, de az ötlet megalkotása érdekében a regiszterek olyanok, mint a mutatók, többek között jeleznek , egy memóriahely (hely).

Most gyakoroljon

Tudom, hogy sok információ feldolgozása volt eddig, de a valóságban ezek kissé összetett kérdések, amelyeket megpróbálok nagyon egyszerű módon elmagyarázni. Meglátunk egy kis programot, amely puffereket használ, és törd meg, hogy megértsd ezt a túlcsordulásokról, nyilván ez nem az. Ez egy igazi program, és "elkerüljük" a ma alkalmazott ellenintézkedéseket, csak azért, hogy megmutassuk, hogyan tették a dolgokat korábban 🙂, és mert ezek egy része alapelvekre van szükség ahhoz, hogy összetettebb dolgokat tanulhassunk

GDB

Remek program, amelyet kétségtelenül az egyik leggyakrabban használ a C programozó. Számos erénye között megvan az a tény, hogy lehetővé teszi számunkra, hogy lássuk mindazt, amiről eddig beszéltünk, regisztereket, verem, pufferek stb. 🙂 Lássuk azt a programot, amelyet a példánkban használni fogunk.

retinput.c

Saját. Christopher Diaz Riveros

Ez egy meglehetősen egyszerű program, a könyvtárat fogjuk használni stdio.h hogy információkat szerezhessen és megjeleníthessen egy terminálon. Láthatjuk az úgynevezett függvényt return_input amely generálja a ütköző hívott sor, amelynek hossza 30 bájt (a char adattípus 1 bájt hosszú).

A funkció gets(array); információt kérhet konzol és funkció szerint printf() visszaadja a tömb tartalmát és megjeleníti a képernyőn.

Minden C-ben írt program a függvénnyel kezdődik main(), ez csak a return_input meghívásáért felel, most lefordítjuk a programot.

Saját. Christopher Diaz Riveros

Vegyünk egy kicsit abból, amit éppen tettem. Az opció -ggdb azt mondja a gcc-nek, hogy a programot információkkal kell lefordítania ahhoz, hogy a gdb megfelelően hibakereshető legyen. -fno-stack-protector Ez egy olyan opció, amelyet nyilvánvalóan nem használnánk, hanem használni fogunk, mert különben lehetséges lenne a puffer túlcsordulását a veremben létrehozni. Végül kipróbáltam az eredményt. ./a.out csak azt futtatja, amit az imént összeállítottam, információkat kér tőlem és visszaadja. Futás 🙂

Figyelmeztetések

Egy másik megjegyzés itt. Látja a figyelmeztetéseket? egyértelműen ezt figyelembe kell venni, ha kóddal dolgozunk vagy fordítunk, ez egy kicsit nyilvánvaló, és kevés olyan program van, amely ma a funkcióval rendelkezik gets() A kódban. A Gentoo egyik előnye, hogy az egyes programok összeállításával látom, hogy mi lehet a baj, egy "ideális" programnak nem szabadna, de meglepődne, hogy hány nagy programnál vannak ezek a figyelmeztetések, mert csak NAGYON nagyok és veszélyes funkciók, ha egyszerre sok figyelmeztetés van. Most, ha folytatjuk

A program hibakeresése

Saját. Christopher Diaz Riveros

Most ez a rész kissé zavaró lehet, de mivel már elég sokat írtam, nem engedhetem meg magamnak, hogy mindent elmagyarázzak, ezért sajnálom, ha látja, hogy túl gyorsan megyek 🙂

A kód hatástalanítása

Kezdjük azzal, hogy megnézzük az összeállított gépnyelvi programunkat.

Saját. Christopher Diaz Riveros

Ez a fő funkciónk kódja a Assembly, ezt a processzorunk érti, a bal oldali sor a memóriában lévő fizikai cím, a <+ n> úgy is ismert mint eltolt, alapvetően a függvény (main) elejétől az állításig (más néven műveleti kód). Ezután megnézzük az utasítás típusát (push / mov / callq…) és egy vagy több regisztert. Összefoglalva elmondhatjuk, hogy ez a forrás / eredet és a cél utáni jelzés. <return_input> második funkciónkra utal, nézzük meg.

return_input

Saját. Christopher Diaz Riveros

Ez egy kicsit összetettebb, de csak azt akarom, hogy ellenőrizzen pár dolgot, van egy címke <gets@plt> és egy utolsó opcode hívott retq jelezve a funkció végét. Helyezni fogunk néhány töréspontot, egyet a függvénybe gets másik pedig a retq.

Saját. Christopher Diaz Riveros

futás

Most futtatjuk a programot, hogy lássuk, hogyan kezdődik a cselekvés.

Saját. Christopher Diaz Riveros

Láthatjuk, hogy megjelenik egy kis nyíl, amely jelzi az opkódot, ahol vagyunk, szeretném, ha figyelembe vennék az irányt 0x000055555555469b, ez a cím a hívás után return_input funkcióban main , ez fontos, mivel a programnak vissza kell térnie, amikor befejezte a bemenet, térjünk be a függvényre. Most megnézzük a memóriát, mielőtt belépnénk a funkcióba gets.

Saját. Christopher Diaz Riveros

Visszatettem az ön számára a fő funkciót, és kiemeltem a kódot, amelyre utaltam, amint láthatja, a végesség két részre osztották, szeretném, ha figyelembe vennék az irányt 0x7fffffffdbf0 (az első balról a kommandós után x/20x $rsp) mivel ezt a helyet kell használnunk a get eredményeinek ellenőrzéséhez, folytassuk:

A program megtörése

Saját. Christopher Diaz Riveros

Ezeket kiemeltem 0x44444444mert ezek képviselik a Ds-t 🙂 most elkezdtük hozzáadni bemenet a programhoz, és amint láthatja, csak két sorra vagyunk a kívánt címetől, addig fogjuk kitölteni, amíg közvetlenül az előző lépésben kiemelt címek elé nem kerülünk.

A visszatérési útvonal módosítása

Most, hogy sikerült beírnunk a kódnak ezt a részét, ahol ez a függvény visszatérését jelzi, nézzük meg, mi történik, ha megváltoztatjuk a 🙂 címet, ahelyett, hogy az opcode helyére lépnénk, amely követi azt, amelyet egy pillanatra megéltünk, mit gondolsz, ha visszatérünk return_input? Ehhez azonban binárisan kell megírnunk a kívánt címet, ezt a függvénnyel fogjuk megtenni printf bash-ból 🙂

Saját. Christopher Diaz Riveros

Most már kétszer megkaptuk az információkat 😀 biztosan nem erre készült a program, de sikerült megtörnünk a kódot, és megismételnünk valamit, amit nem kellett volna tennie.

Gondolatok

Ez az egyszerű változás a kihasználni nagyon alapvető: sikerült megtörnie a programot, és megtenni valamit, amit szeretnénk.

Ez csak az első lépés a szinte végtelen listában a látnivalókról és a hozzáadható dolgokról, többféleképpen is lehet hozzáadni, mint egyszerűen megismételni a megrendelést, de ezúttal sokat és mindent írtam héjkódolás tárgy, hogy többet írjak, mint cikkeket, komplett könyveket, mondhatnám. Bocsánat, ha nem sikerült egy kicsit többet elmélyülnöm olyan témákban, amelyek tetszettek volna, de biztosan lesz esély 🙂 Üdvözlet és köszönet, hogy ideértem.


Hagyja megjegyzését

E-mail címed nem kerül nyilvánosságra. Kötelező mezők vannak jelölve *

*

*

  1. Az adatokért felelős: Miguel Ángel Gatón
  2. Az adatok célja: A SPAM ellenőrzése, a megjegyzések kezelése.
  3. Legitimáció: Az Ön beleegyezése
  4. Az adatok közlése: Az adatokat csak jogi kötelezettség alapján továbbítjuk harmadik felekkel.
  5. Adattárolás: Az Occentus Networks (EU) által üzemeltetett adatbázis
  6. Jogok: Bármikor korlátozhatja, helyreállíthatja és törölheti adatait.

  1.   2p2 dijo

    Legyen közvetlenebb. Írj kevesebbet, és koncentrálj arra, ami számít

    1.    ChrisADR dijo

      Szia, köszönöm a megjegyzést.

      Az igazat megvallva az ötletek jó részét levágtam, de még így is számomra úgy tűnt, hogy elhagytam a minimumot, hogy valaki, aki nem rendelkezik programozási ismeretekkel, ötletet szerezzen.

      Üdvözlet

      1.    Névtelen dijo

        A probléma az, hogy akik nem rendelkeznek programozási ismeretekkel, nem fognak semmit megtudni, mert túl bonyolult a kezdéshez, de akik tudnak programozni, azok értékelik, hogy közvetlenebbek.

        Feltételezem, hogy nem érhet el mindenkit, választania kell, és ebben az esetben vétett, hogy sokat akar fedezni.

        Egyébként építő kritikaként mondom neked, imádom ezeket a témákat, és szeretném, ha továbbra is cikkeket írnál, gratulálok!

    2.    Névtelen dijo

      Ugyanezt érzem.

      1.    ChrisADR dijo

        Nagyon köszönöm mindkettőnek !! Minden bizonnyal nehéz megérteni, hogyan lehet elérni a célközönséget, ha az az igazság, hogy alacsony a fejlett programozási szinttel rendelkezők száma, akik elolvassák ezeket a cikkeket (legalábbis erre a következtetések alapján lehet következtetni)

        Mindenképpen vétkeztem abból, hogy le akarok egyszerűsíteni valamit, amelynek megértéséhez széles körű tudásbázisra van szükség. Remélem, megértette, hogy mivel most kezdem a blogolást, még nem fedeztem fel azt a pontos pontot, ahol olvasóim tudják és értik, amit mondok. Ez sokkal megkönnyítené az igazmondást 🙂

        Igyekszem rövidebb lenni, amikor megérdemli, anélkül, hogy személyteleníteném a formátumot, mivel az írás és a tartalom elkülönítése kissé bonyolultabb, mint azt elképzelni lehetne, legalábbis eléggé összekapcsoltam őket, de feltételezem, hogy végül képes leszek vonalak hozzáadása a tartalom vágása helyett.

        Üdvözlet

  2.   Mario dijo

    Hol tudhat többet a témáról? Ajánlott könyv?

    1.    ChrisADR dijo

      A példát a The Shellcoder kézikönyvéből Chris Anley, John Heasman, Felix Linder és Gerardo Richarte vette át, de a 64 bites fordítás elvégzéséhez meg kellett tanulnom az architektúrámat, az Intel fejlesztői kézikönyv 2. és 3. kötete egy elég megbízható forrás erre. Jó elolvasni a GDB dokumentációt is, amely az 'info gdb' paranccsal jár együtt. Az Assembly és a C megtanulásához sok nagyon jó könyv létezik, csakhogy az Assembly könyvek egy kicsit régiek, így hiányosságok vannak kitöltéssel típusdokumentáció.

      Maga a héjkód különböző okok miatt manapság már nem olyan hatékony, de mégis érdekes új technikákat elsajátítani.

      Remélem, ez segít egy kicsit 🙂 Üdvözlet

  3.   Franz dijo

    Jó cikk, régi blog desdelinux újjászületett =)
    Amikor azt állítja, hogy a távoli héj nem olyan hatékony, akkor a támadások enyhítésére tervezett ellenintézkedéseket kell értenie, sértő biztonságnak nevezik.
    Üdvözlet, és így tovább

    1.    ChrisADR dijo

      Nagyon köszönöm Franz 🙂 nagyon kedves szavakat, valójában arra gondoltam, hogy a Shellcoding ma sokkal összetettebb, mint amit itt látunk. Rendelkezünk az ASLR (véletlenszerű memóriahely-generátor) veremvédővel, a különféle intézkedésekkel és ellenintézkedésekkel, amelyek korlátozzák a programba befecskendezhető opkódok számát, és ez csak a kezdet.

      Üdvözlettel,

  4.   ingyenes szoftver dijo

    Helló, csinálsz még egy részt a téma kibővítésével? Érdekes

    1.    ChrisADR dijo

      Helló, a téma minden bizonnyal meglehetősen érdekes, de a komplexitás szintje, amelyet elfogadnánk, nagyon magasra emelkedne, valószínűleg sok hozzászólással jár, amelyek elmagyarázzák a másik megértésének különféle előfeltételeit. Valószínűleg írok róla, de nem a következő bejegyzések lesznek, szeretnék írni néhány témát, mielőtt folytatnám ezt.

      Üdvözlet és köszönet a megosztásért

  5.   kaktusz dijo

    Nagyon jó che! Remek bejegyzésekkel járul hozzá! Egy kérdés, hogy ezt az informatikai biztonsági dolgot azzal kezdem, hogy elolvastam egy "Biztonság biztosítása tollteszteléssel" című könyvet. Ajánlott ez a könyv? Hogyan javasolja, hogy kezdjek érdeklődni ezekről a kérdésekről?

    1.    ChrisADR dijo

      Helló kaktusz, egy egész univerzum a sérülékenységekről, és mások, az igazat megvallva, nagyon sok múlik azon, hogy mi vonzza a figyelmedet, és hogy milyen igényeid vannak, az informatikai vezető nem követeli meg ugyanazt, mint a toll-tesztelő, Or egy sebezhetőségi nyomozó vagy igazságügyi elemző, egy katasztrófa utáni helyreállítási csapat nagyon különböző készségekkel rendelkezik. Nyilvánvaló, hogy mindegyiküknek más szintű technikai ismeretekre van szüksége, javasoljuk, hogy kezdje el felfedezni pontosan azt, ami tetszik, és kezdje el felfalni a könyveket, cikkeket és másokat, és ami a legfontosabb, gyakoroljon mindent, amit elolvasott, még akkor is, ha elavult. a végén változást hoz.
      Üdvözlettel,

  6.   Eizen dijo

    Hello.
    Köszönöm szépen, hogy elmagyarázta ezt a témát, valamint megjegyezte, hogy további információkért rendelkezünk a "The Shellcoder kézikönyvével". Már van függőben lévő olvasmányom 😉