Для переполнения буфера, какой адрес стека при использовании pthreads? - PullRequest
4 голосов
/ 08 марта 2010

Я учусь на уроке по компьютерной безопасности, и есть дополнительное кредитное назначение для вставки исполняемого кода в переполнение буфера. У меня есть исходный код c для целевой программы, которой я пытаюсь манипулировать, и я дошел до того, что смог успешно перезаписать eip для текущего фрейма стека функций. Однако я всегда получаю ошибку сегментации, потому что адрес, который я предоставляю, всегда неверен. Проблема в том, что текущая функция находится внутри pthread, и, следовательно, адрес стека, кажется, всегда меняется между различными запусками программы. Есть ли какой-либо метод для поиска адреса стека в pthread (или для оценки адреса стека в pthread)? (примечание: 2-й аргумент pthread_create равен нулю, поэтому мы не назначаем адрес стека вручную)

Ответы [ 3 ]

7 голосов
/ 08 марта 2010

Предлагаю прочитать отличную (если немного устаревшую) статью / руководство по использованию уязвимостей, связанных с переполнением буфера Уничтожение стека для удовольствия и прибыли .

Вот краткая выдержка:

Проблема в том, что мы не знаем, где в области памяти Программа, которую мы пытаемся использовать код (и строка, которая следует это) будет размещено. Одним из способов обойти это является использование JMP и CALL инструкция. Инструкции JMP и CALL могут использовать относительную IP-адресацию, это означает, что мы можем перейти к смещению от текущего IP без необходимости чтобы узнать точный адрес, где в памяти мы хотим перейти.


Вы можете получить текущее значение указателя стека с помощью небольшого количества встроенных сборок. Все примеры в Сокрушение стека для удовольствия и прибыли переполняют буфер в main, но вы можете так же легко использовать те же методы для переполнения буфера в функции, вызываемой из нить Приведенный ниже код построен на примере из статьи ( overflow1.c ), чтобы показать, что те же методы будут работать с использованием pthreads. Фактическая техника, которую вы будете использовать, будет зависеть от целевой программы, которую вы пытаетесь использовать.


/* get value of sp off the stack - not essential to example */
unsigned long get_sp()
{
   __asm__("movl %esp,%eax"); /* equiv. of 'return esp;' in C */
}

int foo()
{
   char buffer[96];

   /* overflow buffer to overwrite return address */
   /* and place code to be executed into buffer. */
   ...

   return 0;
}

void *thread(void *arg)
{
   printf("thread stack 0x%x\n", get_sp()); 

   foo();   

   return NULL;
}

int main(int argc, char **argv) 
{
   printf("main stack 0x%x\n", get_sp());   

   pthread_t t;
   pthread_create(&t, NULL, thread, NULL);
   pthread_join(t, NULL);

   return 0;
}
0 голосов
/ 09 марта 2010

В дополнение к моему предыдущему ответу вы также можете прочитать следующее:

В следующей статье больше внимания уделяется переполнению кучи:

0 голосов
/ 08 марта 2010

Не зная больше о приложении, это немного сложно понять, но первое, что приходит на ум, это распыление кучи .

...