PDA

View Full Version : [C/Linux] Le var di ambiente cambiano continuamente indirizzo


Gica78R
20-05-2005, 16:49
Ciao!

Vi risulta per caso che dopo ogni accesso alle variabili d'ambiente (durante una stessa sessione), queste cambino indirizzo di memoria?
Considerate questa porzione di un programma che chiameremo getenvaddr.c:
char *addr;
addr=getenv(argv[1]);
if (addr!=NULL)
printf("Indirizzo di %s: %p\n",argv[1],addr);
dove ovviamente argv[1] contiene il nome della variabile di ambiente.
Invocando il programma ad esempio con
$ ./getenvaddr PATH
si ottiene l'indirizzo di memoria in cui dovrebbe essere memorizzata la variabile d'ambiente PATH; ma rieseguendo il programma subito dopo, tale indirizzo cambia, e cosi' ogni volta che lo si esegue!
Vi sembra normale?
Io sto cercando di realizzare un overflow di puntatore a funzione, in modo tale che il contenuto di un determinato puntatore a funzione (in un programma volutamente vulnerabile) venga sovrascritto con l'indirizzo di una var di ambiente che contiene lo shellcode... ma se ogni volta che tento di ricavare l'indirizzo della variabile poi questo cambia, non riusciro' mai a far assumere al puntatore a funzione l'indirizzo giusto.

Secondo voi dove sta l'inghippo?

ilsensine
20-05-2005, 16:57
Vi sembra normale?

Sì, per molti motivi:
- stai usando uno di quei kernel con alcune patch per la sicurezza, che spostano stack e heap su indirizzi casuali. In questo caso è 100% ripetibile.
- hai ricompilato il programma
- l'ambiente è cambiato (...e di norma cambia: ad es. viene impostato in alcune variabili d'ambiente l'ultimo programma eseguito, l'ultimo return code, e altre cose dinamiche simili)

Gica78R
20-05-2005, 17:06
Boh... escluderei la seconda e la terza ipotesi. Il programma e' sempre quello (getenvaddr), ed eseguendolo 10 volte in sequenza, senza fare nient'altro, l'indirizzo stampato cambia sempre, e apparentemente non c'e' modo di prevedere quale indirizzo stampera' la volta successiva (non c'e' una progressione regolare o roba simile).
Mi sa che ho un kernel come dici tu...
Uffa! Ho un sistema inattaccabile :D Ho provato anche qualche esempio di buffer overflow, ma pure quelli non vanno...

Vabbe', provero' su qualche altro kernel...

Grazie

ilsensine
20-05-2005, 17:53
Interessante, non sapevo che ce ne fossero di simili già in giro. Puoi verificare se con questo programma hai risultati sempre differenti?

#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>

int main(void)
{
long addr;
void *map;
asm(
"movl %%esp, %0"
:"=g"(addr) : );
map = mmap(NULL, getpagesize(),
PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
printf("esp=0x%08lx map=%p\n", addr, map);
return 0;
}

71104
20-05-2005, 17:56
oggi ho imparato che includere assembly in C col gcc è un casino. :mbe:

ilsensine
20-05-2005, 17:58
oggi ho imparato che includere assembly in C col gcc è un casino. :mbe:
Una volta che hai imparato è molto comodo, fidati ;)

cionci
20-05-2005, 19:24
oggi ho imparato che includere assembly in C col gcc è un casino. :mbe:
Fai un modulo esterno...tanto li linki insieme :)

Gica78R
20-05-2005, 20:13
Interessante, non sapevo che ce ne fossero di simili già in giro. Puoi verificare se con questo programma hai risultati sempre differenti?

esp ha sempre risultati differenti, map no...
Cmq sto usando semplicemente il kernel di Fedora Core 3, il 2.6.9-1.667, roba che e' in giro da sei mesi... credo :confused:
Ah, ho fatto un tentativo su una Slackware 9.2 che usa un kernel 2.6.10 compilato da me: l'indirizzo delle var di ambiente non cambia, nel programma vulnerabile riesco a sovrascrivere il puntatore a funzione con l'indirizzo esatto della variabile d'ambiente che contiene lo shellcode, ma all'invocazione della funzione mi da' segmentation fault. Eppure il programma ha il bit suid impostato. :boh:

Gia' che siamo in tema, sapreste consigliarmi un manualetto di assembly x86 per principianti? Magari liberamente scaricabile dalla rete? Intanto cerco qualcosa con Google...

Gica

ilsensine
23-05-2005, 08:30
esp ha sempre risultati differenti, map no...

Ok hanno probabilmente abilitato la casualità della posizione dello stack. Ti fornisce una certa protezione dagli stack overflow, ma sei ancora vulnerabile agli heap overflow.