Переполнение буфера в стеке. Часть 1

kas1e

Xakep, номер #050, стр. 050-062-1


Эта статья открывает цикл статей, которые, я надеюсь, помогут многим уяснить для себя современные и не очень (но по-прежнему актуальные) способы использования уязвимостей в различном программном обеспечении, ошибках проектирования некоторых платформ, реализации компиляторов и так далее. Для полного понимания того, о чем мы будем говорить, очень желательно, чтобы ты знал/понимал ассемблер, немного С, устройство юниксоподобных систем (т.к. ориентировка будет именно на них) и вообще устройство процессоров на уровне low level. Я же постараюсь по возможности упростить подачу материала, чтобы ты, даже не зная ничего из перечисленного, мог понять, о чем идет речь.

Первая статья посвящена проблеме, называемой "переполнение стека", и в связи с большим объемом информации разделена на две части. Первую часть ты читаешь сейчас, вторая появится в следующем номере.

Для начала совершим небольшой экскурс в историю и вспомним "громогласного" червя Морриса. Червь этот имеет непосредственное отношение к нашей теме, так как одним из трех способов его проникновения было использование уязвимости в fingerd демоне, тип которой (уязвимости) впоследствии назвали переполнением стека. Кстати, так же часто встречается термин "переполнение буфера", что, в общем, тоже правильно, но слегка не точно, так как это те буфера, которые находятся именно в стеке. Но обо всем по порядку.

Ноябрь. 1988 год. Паника, все как в современных фильмах про ужасных хакеров - ничего не работает, все виснет, никто не понимает, в чем дело. Спустя некоторое время становится ясно, что проблема в неком программном коде, распространяющемся по сети, забивающем каналы и использующем для заражения компьютеров 3 способа. Первый способ простецкий - в sendmail разработчиками был оставлен отладочный режим, позволяющий подключившемуся пользователю работать с машиной, на которой запущен этот демон. В первых репортах именно на sendmail была повешена участь программы, содержащей в себе переполнение стека, что неверно (см. сорцы червя). Второй способ заключался в тупом подборе логинов к rsh/rexec, а ведь в то время больше чем у половины юзеров логин соответствовал паролю (вот весело было злодеям). А третьим способом было не что иное, как наше переполнение стека в демоне fingerd. Примечательно, что реализация этой техники работала только на VAX компьютерах (возможно, что Моррис - просто ленивый гад и не захотел отлаживать под SunOS, хотя в исходниках видно, что на SunOS рассчитывалось тоже).

В оригинальных репортах (например, из департамента компьютерных наук - University of Lowell) это звучало примерно так: атака на fingerd демон позволяет червю проникать в компьютерные системы, используя ошибку в этом демоне. После соединения fingerd демон принимает от пользователя данные, не ограничивая и не считая их количество и размер. Если читается буфер больше, чем 512 байт, то остальное записывается в критичные участки памяти.

Это был 1988 год, и первое публичное заявление о такого рода уязвимости появилось именно тогда. Моррис ли это придумал, или еще кто - точно уже не скажешь, история помнит лишь студента Морриса. Впрочем, какая теперь разница, мы лучше попробуем понять, что же это за уязвимость.

Содержание  Вперед на стр. 050-062-2