Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #45, АВГУСТ 2004 г.

Защитись и замети!

Коваленко Дмитрий aka Ingrem

Спецвыпуск Xakep, номер #045, стр. 045-068-3


Слово предоставляется канарейке, или Что делать, если ничего не помогло

Но теперь предположим такую ситуацию. Допустим, перед записью в буфер ты почему-то не можешь явно задать или проверить длину данных. Что тогда? Оставить дырку, надеясь, что ее никогда не найдут?

При таком раскладе я могу тебе посоветовать простой способ защиты. Его называют защитой на основе canary word. Суть его вот в чем: еще при объявлении буфера его делают на 4 байта больше. "Лишние" 4 байта в конце буфера используются для контроля его целостности. Перед тем как записывать что-либо в буфер, генерируется случайное двойное слово – так называемое canary word, которое заносится одновременно в глобальную переменную и в последние 4 байта буфера. Теперь, если при записи в буфер произойдет переполнение, canary word в конце буфера будет затерто кодом эксплоита:

Глобальная переменная при этом не пострадает. Так что после записи в буфер достаточно сравнить canary word в глобальной переменной с canary word в буфере. Совпадают – все оk, нет – буфер переполнен, ахтунг!

Теперь возьмем то несчастное приложение, которое мы пытались уберечь от переполнения строкой. Чтобы защитить буфер с помощью canary word, достаточно добавить пару строчек в исходный код уязвимой процедуры:

Листинг

static DWORD CanaryWord;

int overflow_proc(char* big) {

char buff[10+4];

CanaryWord = GetTickCount();

*((DWORD*)&buff[11]) = CanaryWord;

strcpy(buff, big);

if(*((DWORD*)&buff[11])!=CanaryWord) {

MessageBox(0, "Buffer overflow detected!", \

"Warning!", MB_OK+MB_ICONWARNING);

ExitProcess(0);

};

return 0; }

Как видишь, все элементарно. Сначала получаем сanary word. Для этого используем API GetTickCount, которая возвращает количество микросекунд, прошедших с момента включения компьютера. Это значение, конечно, не случайное, но предсказать его заранее абсолютно точно почти нереально. Затем сanary word заносится в глобальную переменную CanaryWord и в последние 4 байта буфера. Производится чтение в буфер. Сразу после чтения, до return, сравнивается CanaryWord и последние 4 байта в буфере. Если результат сравнения положительный – буфер не переполнен. Если отрицательный – выдадим сообщении о возможной атаке и завершим работу программы. Для завершения используем API ExitProcess. Этот и другие исходники к первой части ты можешь найти на диске, прилагающемся к журналу. Вот и все :-).

Немного экзотики: неисполняемый стек

5 правил безопасного программирования

Отпечатать крупными буквами и повесить над монитором!

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

2. Везде, где только можно, пользуйся безопасными функциями для работы со строками.

3. Проверяй или явно указывай длину данных, которые записываешь в буфер.

Назад на стр. 045-068-2  Содержание  Вперед на стр. 045-068-4