Как использовать переполнение буфера для выполнения инструкций в стеке

#c #buffer-overflow

#c #переполнение буфера

Вопрос:

Я начинаю возиться с переполнением буфера и написал следующую программу:

 #include <unistd.h>

void g() {
  execve("/bin/sh", NULL, NULL);
}

void f() {
  long *return_address;
  char instructions[] = "xb8x01x00x00x00xcdx80"; // exit(1)

  return_address = (long*) (amp;return_address   2);
  *return_address = (long)amp;g; // or (long)instructions
}

int main() {
  f();
}
 

Он делает то, что я ожидаю от него: return_address перезаписывает обратный адрес f с адресом g , который открывает оболочку. Однако, если я установлю адрес возврата instructions равным, я получу ошибку сегментации, и ни одна из инструкций instructions не будет выполнена.

Я компилирую с помощью GCC, используя -fno-stack-protector .

Как я мог предотвратить возникновение этой ошибки сегментации?

Комментарии:

1. Не эксперт, но может быть, instructions это сохраняется в сегменте данных и, следовательно, отключает предотвращение выполнения данных (или его название в Linux), и поэтому программа завершается? Если я правильно понимаю, это не то же самое, что переполнение стека, и оно не отключается -fno-stack-protector . Но я совсем не уверен!

2. @FabioTurati instructions хранится в стеке, я проверил с помощью GDB

Ответ №1:

По крайней мере, одна проблема не связана с переполнением буфера.

 execve("/bin/sh", NULL, NULL);
 

Этот первый NULL становится argv процесса, который вы запускаете. argv должен быть массивом строк, который заканчивается НУЛЕМ. Таким образом, segfault может произойти при /bin/sh запуске, попытке чтения argv[0] и разыменовании NULL.

 void g(void) {
    char *argv[] = { "/bin/sh", NULL };
    execve(argv[0], argv, NULL);
}
 

Вы также можете добавить -z execstack в командную строку gcc, которая сообщит компоновщику разрешить исполняемый стек. Вы также должны убедиться, что имеющиеся у вас инструкции exit(1) соответствуют тем, которые компилируются в вашей системе, если вы получили их из какого-то руководства.