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

Зоопарк переполняющихся буферов 

Крис Касперски aka мыщъх

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


Лучше брать какой-нибудь малоизвестный клон UNIX'а или почтовый сервер, писанный дядей Ваней на коленках, – он вообще никем протестирован не был. Таких значительно больше, чем специалистов! Ну и что с того, что они установлены на сотне-другой машин во всем мире? Вполне хватит пространства, чтобы похакерствовать.

Собственно говоря, методик поиска переполняющихся буферов всего две, и обе они порочны и неправильны. Одна из них, простая и не слишком умная, – методично скармливать исследуемому сервису текстовые строки различной длины и смотреть, как он на них отреагирует. Упадет – значит переполняющийся буфер обнаружен. Разумеется, эта технология не всегда дает ожидаемый результат: можно пройти от здоровенной дыры в двух шагах и ничего не заметить. Допустим, сервер ожидает урл. Он наивно полагает, что имя протокола (ну там http или ftp) не может состоять больше чем из четырех букв; чтобы переполнить буфер, достаточно будет послать ему нечто вроде httttttttp://fuckyour.com. Обратите внимание: http://fuuuuuuuuuuuuuuckyour.com уже не сработает! А откуда мы заранее может знать, что именно забыл проконтролировать программист? Может, он понадеялся, что слэшей никогда не бывает больше двух? Или что двоеточие может быть только одно? Перебирая все варианты вслепую, мы взломаем сервер не раньше, чем наступит конец света, когда это уже будет неактуально. А ведь большинство "серьезных" запросов состоит из сотен сложно взаимодействующих друг с другом полей, и метод перебора здесь становится бессилен! Вот тогда-то на помощь и придет систематический анализ.

Теоретически для гарантированного обнаружения всех переполняющихся буферов достаточно просто построчно вычитать весь сырец программы (дизассемблерный листинг) на предмет пропущенных проверок. Практически же все упирается в чудовищный объем кода, который читать – не перечитать. К тому же, не всякая отсутствующая проверка – уже дыра. Рассмотрим следующий код:

Код #8

f(char *src)

{

char buf[0x10];

strcpy(buf, src);

...

}

Если длина строки src превысит 0x10 символов, буфер проломит стену и затрет адрес возврата. Весь вопрос в том, проверяет ли материнская функция длину строки src перед ее передачей или нет. Даже если явных проверок нет, но строка формируется таким образом, что она гарантированно не превысит отведенной ей величины (а формироваться она может и в праматеринской функции), то никакого переполнения буфера не произойдет и усилия на анализ будут потрачены впустую.

Короче говоря, предстоит много кропотливого труда. Кое-какую информацию на этот счет можно почерпнуть из моих "Записок исследователя компьютерных вирусов", но мало. Поиск переполняющихся буферов очень трудно формализовать и практически невозможно автоматизировать. Microsoft вкладывает в технологии совершенствования анализа миллиарды долларов, но взамен получает фигу. Что же тогда вы от бедного (во всех отношения) мыщъх’а хотите?

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