In che modo ASLR protegge i punti di ingresso di libc?

2

ASLR randomizza gli indirizzi del codice eseguibile del processo, stack, heap e librerie. Ciò serve a rendere difficile la vita di un utente malintenzionato poiché non è possibile codificare gli indirizzi nel codice attraverso più istanze.

Ma come può essere d'aiuto con le librerie di sistema? Non vengono mai scaricati. Ogni processo usa libc, per esempio, e quindi l'indirizzo di prinf non cambia mai. Come può essere d'aiuto se sto codificando l'indirizzo di printf? Questo non cambia a meno che la macchina non si riavvii.

Ho ASLR abilitato -

# cat /proc/sys/kernel/randomize_va_space 
2

Ecco alcuni esempi di codice -

unsigned long getEBP ( void )
{
    asm("movl %ebp, %eax");
}

int main(void)
{
    int (*p)(const char*, ...) = &printf;
    printf("printf address = %p \n", p);
    (*p)("printf address = %p\n", &printf);
    printf ("EBP:%x\n" ,getEBP ());
}

E l'output su più esecuzioni -

# ./a.out 
  printf address = 0x4003c0 
  printf address = 0x4003c0 
  EBP:6a71d300

# ./a.out 
  printf address = 0x4003c0 
  printf address = 0x4003c0 
  EBP:93e5c100

Vedi l'EBP sta cambiando come dovrebbe ma non l'indirizzo di printf.

Cosa mi manca?

EDIT: la compilazione con -fPIC non ha aiutato la mia macchina virtuale RHEL.

# ./a.out 
  printf address = 0x3047a4f0f0 
  printf address = 0x3047a4f0f0 
  EBP:7aaac900

# ./a.out 
  printf address = 0x3047a4f0f0 
  printf address = 0x3047a4f0f0
  EBP:632eca20

Se le chiamate alla libc sono di fatto randomizzate come la risposta dice sotto, come viene implementata? la stessa libc non viene ricaricata, quindi l'indirizzo effettivo di printf non cambia, come può essere randomizzato?

    
posta stflow 02.01.2018 - 20:01
fonte

2 risposte

1

Aggiornamento:

vedi link

Compilare il binario usando -fPIE o -fPIC -pie -fPIE :

link

Binario compilato con flag di default:

user01@user01 ~/test $ ./test_ASLR 
printf address = 0x400420 
printf address = 0x400420
EBP:9af703c0
user01@user01 ~/test $ ./test_ASLR 
printf address = 0x400420 
printf address = 0x400420
EBP:8411e900
user01@user01 ~/test $ ./test_ASLR 
printf address = 0x400420 
printf address = 0x400420
EBP:28f8e50

Binario compilato con -pie -fPIE flags:

user01@user01 ~/test $ ./test_ASLR 
printf address = 0x7f8227963340 
printf address = 0x7f8227963340
EBP:19e01ad0
user01@user01 ~/test $ ./test_ASLR 
printf address = 0x7fecb2baa340 
printf address = 0x7fecb2baa340
EBP:9c8148e0
user01@user01 ~/test $ ./test_ASLR 
printf address = 0x7f5d00edb340 
printf address = 0x7f5d00edb340
EBP:32b3c6d0
    
risposta data 02.01.2018 - 20:30
fonte
0

Quando si compilano i flag predefiniti, la maggior parte delle volte il segmento .text rimane su un indirizzo costante e GOT viene riempito con un elenco di puntatori per le funzioni utilizzate nel programma che vengono risolte man mano che vengono rilevate. Ora dal momento che in questo caso GOT era in una posizione costante, viene inserito direttamente in call dal compilatore. Un esempio:

0x8048446 <main+35>    call   printf@plt                    <0x80482f0>

Questo non significa che la posizione effettiva di printf non sia stata randomizzata. Se questa è stata la prima chiamata a printf nel programma _dl_runtime_resolve riempirà i valori appropriati. Altrimenti dovrebbe assomigliare a questo

pwndbg> x/xi 0x80482f0
0x80482f0 <printf@plt>: jmp    DWORD PTR ds:0x804a00c
pwndbg> telescope 0x804a00c
00:0000│   0x804a00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0xf7e38670 (printf) ◂— call   0xf7f0eb09

Questa è la posizione effettiva di printf in libc. In casi normali &printf punta in realtà a printf@plt che è solo un jumptable per%% effettivo di% in libc.

Ora per printf il -pie -fPIE punta alla stampa effettiva in libc. Questo flag aggiunge solo ASLR alle sezioni che erano costanti in precedenza. Le biblioteche erano caricato con offset casuali in entrambi i casi.

    
risposta data 03.01.2018 - 09:22
fonte

Leggi altre domande sui tag