Читая книгу «Взлом: искусство эксплуатации» Джона Эриксона, я пытаюсь приблизить адрес переменной среды, SHELLCODE
чтобы использовать программу.
Каждый раз, когда я бегу, getenv("SHELLCODE");
чтобы узнать местоположение, результат совершенно другой.
Выписка из моей раковины:
> 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
Я понимаю, что если имя программы изменяется или добавляются новые переменные среды, позиция будет немного отличаться, но почему местоположение так сильно меняется?
getenv
Руководство говорит она возвращает указатель на строку , содержащую значение переменной. Все остальное не определено, поэтому ваше ядро и / или компилятор могут сохранять значение в любом месте, пока это обещание указателя остается верным. Я предполагаю, что точный ответ на это может быть тяжелым волшебством и зависеть от различных деталей реализации отображения памяти и фазы луны. (Я не достаточно волшебник, чтобы дать вам точный ответ.)Ответы:
То, что вы описываете, - это функция защиты от эксплуатации, называемая рандомизацией расположения адресного пространства (ASLR). По сути, ядро помещает самый верхний адрес стека вызовов функций программы в несколько иной («случайный») адрес каждый раз, когда ядро загружает файл ELF программы с диска. Адреса
argv
и переменные среды, одним из которых является ваш шелл-код, заканчиваются по-разному с каждым вызовом программы.Предполагается, что ASLR усложнит использование переполнения буфера и других уязвимостей, связанных со стеком. Эксплуататор должен написать код или сделать что-то, чтобы учесть различные адреса переменных и значений в стеке вызовов функций.
Похоже, вы можете отключить ASLR, выполнив что-то вроде:
как пользователь root. Поскольку вы явно цитируете Ubuntu, приведенная выше команда отличается:
источник