Я установил дистрибутив Linux с именем DVL (чертовски уязвимый Linux) и тренируюсь с эксплойтами переполнения буфера. Я написал две практически идентичные программы, уязвимые для bof:
//bof_n.c
#include <stdio.h>
void bof() {
printf("BOF");
}
void foo(char* argv) {
char buf[10];
strcpy(buf, argv);
prinf("foo");
}
int main(int argc, char* argv[]) {
if (argc >= 1) {
foo(argv[1]);
}
return 0;
}
и
//bof.c
#include <stdio.h>
void bof() {
printf("BOF!\n");//this is the only change
}
void foo(char* argv) {
char buf[10];
strcpy(buf, argv);
prinf("foo");
}
int main(int argc, char* argv[]) {
if (argc >= 1) {
foo(argv[1]);
}
return 0;
}
После этого я их скомпилировал и в обоих случаях получил адрес функции bof() (например, objdump -d bof.o | grep bof). Назовем такой адрес ADDR размером 4 байта.
Я также обнаружил, что если я записываю 32 байта в переменную buf, регистр EIP полностью перезаписывается (я не могу скопировать сюда вывод gdb, так как он находится на виртуальной машине).
Теперь, если я сделаю:
./bof `perl -e 'print "\x90"x28 . "ADDR"'`
Я получил:
fooBOF!
Segmentation fault
Вместо этого, если я попробую тот же подход, но с использованием bof_n, я получу только сообщение «Ошибка сегментации». Поэтому я попытался увеличить количество раз, когда значение ADDR повторяется, и обнаружил, что если оно повторяется не менее 350 раз, я получаю желаемый результат. Но вместо точного вывода выше я получаю длинный список сообщений «BOF» одно за другим. Я пытался получить только одно сообщение "BOF", но, видимо, не могу этого сделать (получил или ноль, или их длинный список). Почему это происходит? Любая идея?
Я использую DVL с gcc 3.4.6.
perl -e 'print "\x90"x28 . "ADDR"'
› размер buf[10]. 30+ › 10. - person someuser   schedule 29.08.2013perl -e 'print "\x90"x28 . "ADDR"'
может быть больше 10. - person someuser   schedule 29.08.2013