Czytając książkę Hacking: The Art of Exploitation autorstwa Jona Ericksona, staram się przybliżyć adres zmiennej środowiskowej, SHELLCODE
aby wykorzystać program.
Za każdym razem, gdy biegnę, getenv("SHELLCODE");
aby uzyskać lokalizację, rezultat jest zupełnie inny.
Wyciąg z mojej skorupy:
> for i in $(seq 10); do ./a.out SHELLCODE; done
SHELLCODE is at 0xff9ab3a3
SHELLCODE is at 0xffcdb3a3
SHELLCODE is at 0xffb9a3a3
SHELLCODE is at 0xffa743a3
SHELLCODE is at 0xffdb43a3
SHELLCODE is at 0xfff683a3
SHELLCODE is at 0xffef03a3
SHELLCODE is at 0xffc1c3a3
SHELLCODE is at 0xff85a3a3
SHELLCODE is at 0xff8e03a3
Rozumiem, że jeśli nazwa programu zostanie zmodyfikowana lub dodane zostaną nowe zmienne środowiskowe, pozycja będzie nieco inna, ale dlaczego lokalizacja tak się różni?
getenv
Instrukcja mówi, że zwraca wskaźnik do łańcucha znaków zawierającego wartość zmiennej. Cała reszta jest nieokreślona, więc twoje jądro i / lub kompilator mogą trzymać wartość tam, gdzie chcą, pod warunkiem, że obietnica wskaźnika pozostanie prawdziwa. Zgaduję, że dokładna odpowiedź na to może być ciężka magia i zależy od różnych szczegółów implementacji mapowania pamięci i fazy księżyca. (Nie jestem wystarczającym czarodziejem, aby dać ci dokładną odpowiedź.)Odpowiedzi:
To, co opisujesz, to funkcja anty-exploitacyjna o nazwie Randomization Layout Space Address (ASLR). Zasadniczo jądro umieszcza najwyższy adres stosu wywołań funkcji programu pod nieco innym („losowym”) adresem za każdym razem, gdy jądro ładuje plik ELF programu z dysku. Adresy
argv
i zmienne środowiskowe, z których jeden jest kodem powłoki, kończą się pod różnym adresem przy każdym wywołaniu programu.ASLR ma utrudniać wykorzystanie przepełnienia bufora i innych luk związanych ze stosem. Eksplorator musi napisać kod lub zrobić coś, aby uwzględnić różne adresy zmiennych i wartości na stosie wywołań funkcji.
Wygląda na to, że możesz wyłączyć ASLR, wykonując coś takiego:
jako użytkownik root. Ponieważ wyraźnie powołujesz się na Ubuntu, powyższe polecenie jest inne:
źródło