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

Лопнуть как мыльный пузырь

Vint (vint@glstar.ru)

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


Чтобы не было вопросов, постараюсь объяснить эту схему как можно подробнее, так как именно в ней заключается основная идея атак типа переполнение буфера. Мы видим, что адрес возврата из процедуры, в которой происходит объявление процедуры buff, лежит в одном сегменте с буфером самой переменной buff. Что нам это дает? На первый взгляд, ничего особенного, но если вспомнить, что стек «растет» вниз, то есть имеет идеологию FILO, то становится очевидной потенциальная уязвимость: при попытке записи в переменную buff больше 10 байт произойдет затирание области памяти, никак не относящейся к данной переменной! Сначала будет затерта область служебной информации, а потом, если передать достаточно длинную строку, произойдет перезапись адреса возврата из процедуры. Причем в качестве адреса возврата будут выступать не случайные адреса, а первые несколько байт строки, переполнившей буфер.

А в жизни все бывает так

Отличительной чертой таких атак является то, что они не имеют привязки к какой-либо платформе. Уязвимости этого типа находят и в Виндах, и в Линуксе, и в Фрибсд и многих других. Тебе интересно, как ОС отреагирует на такую ошибку в программе, если она произошла случайно, а не под действием эксплоита? Все очень просто: *nix-системы при возникновении такой критической ситуации выполнят аварийное завершение программы и выдадут на консоль предупреждение, аналогичное "Segmentation fault, core dump" (как говорится, упал в кору). Перевод этого высказывания системы чего-то конкретного не даст: ошибка сегментации, кусок памяти, вызвавший сбой, сохранен на винте. Однако появление такого сообщения вовсе не означает, что произошло именно переполнение буфера, поэтому говорить о стопроцентной ошибке программистов в этих случаях, по меньшей мере, глупо ;-). Очень часто *nix-системы "сбрасывают дамп в кору" при других ошибках, вовсе не связанных с переполнением. Иначе дело обстоит в среде мелкомягких. При переполнении буфера в Windows пользователь получит системное предупреждение и аварийную остановку программ. Но предупреждение ОС в данной системе более информативно: "The instruction at "0x31313131" referenced memory at "0x31313131". The memory could not be read". Как видишь, все достаточно понятно: мы видим попытку глючной программы обратиться к запрещенному адресу памяти. Почему адрес именно 0x31313131? Потому что для вызова переполнения буфера на вход была подана строка из 17 символов "A". Достаточно немного поэкспериментировать с найденным переполнением, и эксплоит будет создан. В процессе изучения такого бага каждый хакер должен определить длину строки, которая способна эффективно переполнить буфер в стеке, а также подобрать такой конец этой строки, чтобы он ссылался на другую процедуру, написанную хакером. Обычно с первым параметром проблем возникает немного: во многих программах используются стандартные значения длин буферов, такие, как 10, 100, 128, 256, 1000, 1024 и 10000. Другие значения – большая редкость, хотя и они встречаются, но программист обязательно уделит немалое внимание защите такого большого буфера, так как в него будет передаваться массив данных, который при неправильном копировании повесит всю программу в один момент. Несколько сложнее дело обстоит с выбором последних байт строки. Они будут представлять собой адрес возврата, и на каждый случай переполнения приходится подбирать новую строку. Перед тем как я объясню, что же это за адрес, ты должен понять, какой "магическую" силу несут эти несколько байт.

Назад на стр. 045-004-1  Содержание  Вперед на стр. 045-004-3