2014-01-16 2 views
2

вызывая переполнение буфера, мы можем перезаписать память, где значение флага 0 сохраняется, так что даже неправильный пароль будет взломать код ..Что касается недостатка безопасности в STRCPY

Как это будет происходить внутри? Может ли кто-то объяснить это подробно. Как это будет происходить в памяти практически?

#include<stdio.h> 

int main(int argc, char *argv[]) 
{ 
int flag = 0; 
char passwd[10]; 

memset(passwd,0,sizeof(passwd)); 

strcpy(passwd, argv[1]); 

if(0 == strcmp("LinuxGeek", passwd)) 
{ 
    flag = 1; 
} 

if(flag) 
{ 
    printf("\n Password cracked \n"); 
} 
else 
{ 
    printf("\n Incorrect passwd \n"); 

} 
return 0; 

}

+0

Не так релевантно: вам не нужно memset до нуля перед strcpy(). – moeCake

ответ

6

Имейте в виду, что с теоретической точки зрения, если строка хранится в passwd переполняется, он вызывает неопределенное поведение и результат непредсказуем.

Практически, на многих современных платформах, где локальные переменные хранятся в стеке, если ваш компилятор помещает flag выше passwd буфера, он может быть переполнен в strcpy вызова.

I.e. ваш стек может выглядеть следующим образом:

| ...  | 
+------------+ 
| flag  |/\ 
+------------+ | 
| passwd[10] | | increasing addresses 
| ...  | 

Если вы пишете более 10 байт passwd, strcpy просто пишет через flag.

Обратите внимание, что поведение зависит от компилятора и от платформы к платформе. Это объяснение охватывает то, что происходит в общих системах, но известно, что теоретически возможно иметь платформу, которая не использует стек, поэтому это объяснение не будет применяться.

+0

Итак, ответ: .. это может или не может быть. Кроме того, хранение локальной переменной в компиляторе зависит. Я думал, что они сохранены как объявлено. –

+0

Да, это зависит от компилятора, чтобы выбрать, где они размещены , – tangrs

3

Локальные переменные в C обычно выделяются в стеке. Стеки, как правило, растут вниз в памяти, поэтому хранилище для «флага» будет сразу после хранения, выделенного для «passwd».

strcpy не проверяет, что количество копируемых данных не переполняет буфер, в который копируются данные. Итак, представьте, что ARGV [1] 11 символов точно, это то, что будет происходить:

  • первые 10 символов будут идти в PASSWD
  • символ 11 будет идти в первый байт памяти для флага
  • завершающий нулевой символ перейдет во второй байт хранения для флага

Следовательно, флаг будет отличным от нуля.

Точный behaivour будет отличаться от компилятора к компилятору, но это типичный сценарий.

Используйте strncpy, чтобы этого избежать.

Смежные вопросы