Hogyan vezethet egy puffer alulcsordulás távoli kódfuttatáshoz 64-bites biteken?

A következő összesített álkód van a C89-ben egy ssh kiszolgáló könyvtárból, amely csak olyan dolgokhoz nyújt hozzáférést, mint a git-shell (/bin/bash helyébe a futtatandó program lép, így nem lehet mást tenni) :

struct _raw_uncapped_ssh_string { // no limit on the size of the string; uint32_t len; char non_null_terminated_string[]; // by protocol design it have a minimum length of 1 }; typedef struct _raw_uncapped_ssh_string raw_ssh_string; union buffer { void * uncapped_zlib_decompressed_network_data; // yes, the size is uncapped, so it’s possible to put 4Gb of // data in it that would be copied later into memory. zlib // allow easily to turn some Mb in Gb of data, but it’s not // the point of the question. raw_ssh_string st; }; get_command (compressed_network_data) { size_t len; char * command; buffer string=uncompress_to_buffer(compressed_network_data); len=ntohl(string.st.len)+1; command=malloc(len+1); command[len]=0; // here’s the point, both the string length and content as // well it’s supplied size is controlled by the attacker. memcpy(command,string.st.data,len); return command; } 

Íme a parancs későbbi végrehajtása (a command karakterlánc változatlan a get_command()) után .

const char *args[]={"/bin/bash",command,NULL}; // /bin/bash isn’t the shell, it has been replaced by git‑shell. // redirect the program output to the network. dup2(stdin, 0); dup2(stdout,1); dup2(stdout,2); close(stdin); close(stdout); //if this return execution failed and print an error message return execv(args[0],(char * const *)args); // I don’t know which is the system, so I can’t know about the libc behaviour. 

Nem tudom megtenni memcpy(command,string.st.data,0), mivel a memcpy harmadik tagjának minimális mérete 1, és a kontextusomban a size_t 64 bites egész számot használ, puffertúlcsordulást nem tudok végrehajtani, mivel len.

Csak annyit tehetek, hogy a len értéket nagyobbra állítom, mint a string.st.data számára kiosztott érték. Ez egy olyan puffer alulcsordulás, amely lehetővé teszi a fel nem osztott memória olvasását.
Tudom olvasni a kiszolgáló memóriáját, de nem látom, hogy egy nyilvános ssh-kiszolgáló milyen érzékeny adatokat képes tárolni (esetemben a ssh is public is .

Tehát a memcpy lehetővé teszi a távoli puffer alulfolyását kód végrehajtása?

Megjegyzések

  • Ha a kód valóban command[len] = 0 akkor ez puffertúlcsordulás, mivel a len hosszúságú puffer maximális indexe len-1. Alternatív megoldásként, ha a tényleges kód malloc(len+1) -t hajt végre malloc(len) helyett, akkor hatalmas puffertúlcsordulást hozhat létre a len érték a 0xFFFFFFFF értékre.
  • @ThomasPornin: Nem ez a hiba részemről, valójában több függvényt hív meg ez. Tegyük fel, hogy a maradék igaz.
  • @ThomasPornin: 64 bitről beszélek, mivel a len méret_t, 64 bites egész számot használ. Tehát az egész szám túlcsordulásának nincs módja.
  • @ThomasPornin Kiosztanak len+1, így a 0 értéknek érvényesnek kell lennie.
  • @ RoraΖ: Arról beszélt, hogy a string.st.len -1 értékre állítja.

Válasz

Általában nem, a puffer alulcsordulása nem használható távoli kódfuttatáshoz. Mivel a támadók által vezérelt adatok soha nem hagyják el a számára lefoglalt helyet, soha nem képes átvenni a program végrehajtási folyamatát.

A puffer alulcsordulásának lehetősége van más típusú támadásokra is, mint pl. információ nyilvánosságra hozatala (ha a program számít arra, hogy a puffer eredeti tartalmát eltörlik az új adatok).

Megjegyzések

  • Vagy ahogy én nemrégiben a git-ben látta, később puffertúlcsordulássá alakítja.

Válasz

Amikor ezt a választ eredetileg írtam , úgy tűnik, elsimítottam néhány félreértést, amelyet ön tart. Ezek a félreértések valószínűleg megakadályoznák a válaszom megértését. Az egyértelműség kedvéért ezt a szöveget nagyra fogom emelni, hogy hangsúlyt fektessek, és ne legyek tiszteletlen:

Az Ön által használt kifejezések közül sok nem azt jelenti, amit úgy gondolja, hogy jelent.

Például:

  • “a memcpy harmadik tagja nem létezik, mert a memcpy függvény, nem pedig struct vagy union.
  • “Nem tudok puffertúlcsordulást végrehajtani, mivel van len és nem fogyhat el a benzin, mivel van benzin. Könyörgöm a kérdés? Számomra megfelelő analógia, főleg, hogy elméletileg a kódod puffertúlcsordulást idézhet elő.
  • “Csak annyit tehetek, hogy beállítok len nagyobb értékre, mint az string.st.data. Ez egy puffer alulcsordulás … “ Nem, ez nem a puffer alulcsordulás definíciója. A puffer alulcsordulás akkor következik be, amikor egy tömböt kívülről elérsz egy negatív index, vagy egy olyan index segítségével, amely okozhat pointer aritmetikai csomagolás fordulhat elő. Ez utóbbi bizonyos konfigurációknál lehetséges (még “64 bites rendszereken is, bármit is jelent ez), de kétlem, hogy erre gondolt, amikor ezeket a szavakat írta, mert akkor követte őket a következővel:
  • “… lehetővé téve számomra a fel nem osztott memória elolvasását.” Azt hiszem, talán “inicializálatlan memóriára” gondoltál. Hogy világos legyek, azt hiszem, azt akartad kijelenteni, hogy “ve felosztott egy felesleget, és a felesleget inicializálatlanul hagyta , és talán szeretne tenni valamit ezzel kapcsolatban (lásd: calloc vagy memset).

Vegyük egy pillanatra fontolóra a char *fubar = NULL; … ez a fajta mutató általában nulla érték.A hivatkozások levonása null pointer dereference nak számít, de ha valami hasonlót írunk, mint 0["hello"], akkor ugyanazt kapjuk, mint a "hello"[0] (vagyis "h"). Így a nullpontos eltérés felhasználható a támadásokban, amikor a támadó vezérli a négyzet alakú zárójelek közötti kifejezést (ahogyan az Ön helyzetében is).

Visszatérve a fubar dolog; mondjuk azt, hogy memset(&fubar, UCHAR_MAX, sizeof fubar);, most fubar mind 1 bites, vagyis lehet egy cím ez a legnagyobb cím, amelyet rendszerünk (elméletileg) be tudna fogadni. Mi van, ha hozzáférünk az fubar[1] fájlhoz? Hogyan érheti el a legnagyobb cím után elemet? Ezután a cím visszavonul? Technikailag mindez nem meghatározott viselkedés, de ha ezt megnevezném a közös architektúrán, az a következő lenne:

  1. számtani túlcsordulás egy mutató, amely a következő irányba vezet …
  2. Nulla mutató-eltérés és / vagy potenciálisan puffer alulcsordulás .

egy puffer alulcsordul a memcpy oldalon a távoli kódfuttatáshoz?

puffer az alulcsordulás lehetővé teszi a támadó számára, hogy felülírja a memória régióiban található funkciómutatókat a kérdéses tömb előtt. Ha ezeket a funkciómutatókat shell-re mutatják, akkor akkor kell végrehajtani, amikor később újra meghívják őket.

Ebben a kissé homályos kódrészben a puffer alulcsordulásának kockázata jelenik meg, ha a int szélesebb domain, mint uint32_t, mivel az ntohl(string.st.len)+1 miatt a uint32_t érték int típus. Vegyük például, ha a INT_MIN -4294967296 (ami eggyel kevesebb, mint 0 - UINT32_MAX) és INT_MAX 4294967295 … ez lényegében egy 33 bites int párnázás bájt szélességig; ritka, de lehetséges. Ebben a helyzetben az ntohl(string.st.len)+1 kifejezés nem uint32_t típusú; ez “s int típusú, és ahelyett, hogy visszaforgatna a 0-ra, amikor aláíratlan egész szám túlcsordulás fordul elő, valószínűleg a -4294967296 amikor aláírt egész szám túlcsordulás történik.

Ha garanciát keres a puffer alulcsordulás ra, használja a U egész szó szerinti utótag (azaz ntohl(string.st.len)+1U). Ekkor ebben a helyzetben a kifejezés vagy uint32_t vagy unsigned int lesz (attól függően, hogy melyik típus a legnagyobb domain).

Ha úgy gondolja, hogy a ntohl(string.st.len) eggyel kevesebbet adhat vissza, mint az adott aláíratlan típus maximális értéke (bármi is legyen az), akkor len=ntohl(string.st.len)+1 a maximális értéket eredményezi, a malloc(len+1) aláíratlan csomagolást okoz, így végül a malloc(0) majd a command[len]=0 a tömb végén túl jól és valóban ír. Ezután természetesen “ szintén problémája lesz a memcpy(command,string.st.data,len); vel (ez egy puffertúlcsordulás).

A puffer alulcsordul és a túlcsordulás nem az egyetlen kockázat. Ha nem “t ellenőrzi a malloc és malloc értéke NULL, majd egy null mutató hivatkozás használható tetszőleges kódfuttatásra. Ez azt jelenti, hogy rendelkeznie kell módszerrel a malloc hiba a hívónak. Ez azt is magában foglalja, hogy ugyanazzal a módszerrel ellenőrizheti és közölheti a csomagolási problémát a hívóval.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük