Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Non-executable stack iz user-modea

[es] :: Security Coding :: Non-executable stack iz user-modea

[ Pregleda: 2847 | Odgovora: 2 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

zvrba
The Lord of Chaos

Član broj: 31716
Poruke: 105
*.fina.hr



Profil

icon Non-executable stack iz user-modea10.08.2004. u 09:49 - pre 239 meseci
Na linuxu i FreeBSD-u (i ostalima koji podrzavaju modify_ldt syscall na x86 arhitekturi) je moguce ostvariti non-executable stack iskljucivo iz user-modea jednostavnim smanjivanjem velicine code segmenta. Treba samo staviti da code segment zavrsi tamo gdje pocinje stack (obicno na 3GB - 8MB). Ako se pokusa izvrsavati kod sa stacka, adresa izlazi izvan dozvoljene granice code segmenta i procesorov segmentacijski mehanizam dize general protection fault - program dobije SIGSEGV.

Za dodatnu sigurnost treba postaviti "osiguranim" procesima stack limit na 8 MB (ili koliko vec treba - tada se treba prilagoditi i granica code segmenta). Jer inace program moze zauzeti dovoljno stacka i tako ga prosiriti u code segment.

Evo primjer koda za linux:

Code:

#include <stdio.h>
#include <string.h>
#include <asm/ldt.h>
#include <linux/unistd.h>

void test()
{
    int ret = 0xC3C3C3C3;  /* C3 je kod za RET instrukciju */
    void (*fn)(void) = &ret;
    printf("trying stack call...");
    fflush(stdout);
    fn();
    printf("done!!\n");
}

int main()
{
    struct modify_ldt_ldt_s ldt;

    printf("Before modify_ldt: "); test();

    ldt.entry_number = 1;
    ldt.base_addr = 0;
    ldt.limit = 0xBF800;    /* 3GB - 8MB */
    ldt.seg_32bit = 1;
    ldt.contents = 2;    /* execute/read */
    ldt.read_exec_only = 0;    /* allow read in exec segments */
    ldt.limit_in_pages = 1;
    ldt.seg_not_present = 0;
    ldt.useable = 0;

    if(modify_ldt(1, &ldt, sizeof(ldt)) < 0) {
        perror("modify_ldt");
        exit(1);
    }

    /* Nema instrukcija tipa movw %ax,%cs. Mora se izvesti FAR JUMP. */
    printf("After modify_ldt: ");
    asm("ljmp $0x0F, $0f; 0: nop");
    test();

    return 0;
}
 
Odgovor na temu

DownBload

Član broj: 1333
Poruke: 310
*.net.htnet.hr



Profil

icon Re: Non-executable stack iz user-modea15.08.2004. u 15:00 - pre 238 meseci
Zanimljiva forica, ali ne kuzim zasto to radi. Stack memorija inace ne spada pod code segment, pa kako to funkcionira?
Btw: Inace, jako kul ideja. Mislim da to jos nisam nigdje vidio.


Leon Juranic
 
Odgovor na temu

zvrba
The Lord of Chaos

Član broj: 31716
Poruke: 105
*.fina.hr



Profil

icon Re: Non-executable stack iz user-modea16.08.2004. u 07:45 - pre 238 meseci
Citat:
DownBload: Zanimljiva forica, ali ne kuzim zasto to radi. Stack memorija inace ne spada pod code segment, pa kako to funkcionira?
Btw: Inace, jako kul ideja. Mislim da to jos nisam nigdje vidio.


Svi moderni OS-ovi (pa i Linux) imaju flat adresiranje memorije unutar procesa. Sto znaci da se sa jednim pointerom adresira i data i code i stack. Svi ti segmenti se medusobno preklapaju, i stovise, identicni su -- bazna adresa im je 0, a limit je 3GB.

A radi zato sto smanjis za 8MB limit code segmenta. To onemogucuje izvrsavanje sa stacka. Code i data rastu "prema gore", od adrese 0 (mada je donjih 64kB ili nesto vise rezervirano za NULL pointer protection) prema 3GB, a pocetna adresa stacka je 3GB i raste prema "dolje", tj. nizim adresama. Default velicina stacka je 8MB i kad stavis limit code segmenta na 3GB-8MB, efektivno onemogucavas izvrsavanje koda sa stacka.

Nazalost, ta fora vise ne radi na AMD-ovoj x86-64 arhitekturi koja ima iskljucivo flat address space u 64-bitnom modu. Ne provjeravaju se limiti segmenta. Ali oni zato imaju podrsku za NX (non-execute) bit u page-tableovima.

Napisao sam nedavno detaljno o mehanizmu paginga i segmentacije na:
http://www.elitesecurity.org/tema/38600
 
Odgovor na temu

[es] :: Security Coding :: Non-executable stack iz user-modea

[ Pregleda: 2847 | Odgovora: 2 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.