На главную | Содержание | Назад | Вперёд
Наши друзья

 

 

Ознакомление с технологией взлома

Что происходит при атаке на программное обеспечение? В целях изучения меха­низма взлома программного обеспечения воспользуемся простой аналогией с жилым домом. "Комнаты" в нашей атакуемой программе соответствуют блокам кода в про­граммном обеспечении, выполняющем определенную функцию. Следует изучить "комнаты", чтобы смело перемещаться по всему "дому".
Каждый блок кода служит для выполнения уникальной функции в программе. Некоторые блоки кода применяются для чтения данных из сети. Представим блоки кода в виде комнат дома, а также представим, что злоумышленник стоит перед вхо­дом этого дома на крыльце. Тогда вполне логично представить программный код по взаимодействию с сетью как фойе. Этот код для работы в сети должен проверяться в первую очередь, ведь он принимает входные данные, поступающие от удаленного хакера. В большинстве случаев программный код для работы в сети просто прини­мает входные данные и "упаковывает" их в поток данных. Этот поток данных затем передается дальше в "дом" для обработки более сложными фрагментами кода. Таким образом, "фойе" (код для работы в сети) связано внутренними дверями со смежными "комнатами". Злоумышленнику не интересно проводить атаку в "фойе", но зато он может перейти в "кухню", где находится множество ценных вещей. Например, на "кухне" можно открывать файлы и выполнять запросы к базам данных. Цель зло­умышленника — найти проход из "фойе" на "кухню".
Точка зрения хакера
Атака начинается с нарушения установленных правил и проверки предположе­ний. Одним из первых действий хакера является проверка предположения "безу­словного доверия". Хакеры точно обойдут любое правило, в котором использованы предположения относительно того, "когда, где и что" разрешено принимать в каче­стве входных данных. По той же причине, по которой редко составляются схемы разрабатываемой программы, эти программы также редко проходят интенсивное "тестирование при критических нагрузках", и особенно такое тестирование, при ко­тором используются специально подготовленные вредоносные входные данные. В ре­зультате для всех пользователей по умолчанию устанавливаются доверительные от­ношения. При этом предполагается, что пользователь, с которым установлены без­условные доверительные отношения, будет вводить только корректно сформирован­ные данные, соответствующие установленным правилам, т.е. по отношению к этим данным тоже демонстрируется полное доверие.
Чтобы было понятнее, мы повторим то же самое другими словами. Ключевым яв­ляется предположение, что пользователи, с которыми установлены доверительные отношения, не предоставлюет "некорректных"или "вредоносных" данных. В одном из видов этих доверительных отношений используется клиентское программное обеспечение. Если клиентская программа создана в целях отправки только опреде­ленных команд, то разработчики часто предполагают, что разумный пользователь

будет использовать клиентскую программу только для доступа к серверу. Незаме­ченной часто остается проблема, что хакеры сами пишут программы. Опытный хакер может написать свою собственную клиентскую программу или взломать сущест­вующую. При этом созданное злоумышленником клиентское приложение может (и будет) специально предоставлять вредоносные входные данные и точно в нужное время.
Почему нельзя доверять пользователям
Рассмотрим простой пример, демонстрирующий ошибочность безусловного до­верия к данным, вводимым пользователями. В нашем примере используется атрибут maxsize HTML-формы. Формы представляют собой стандартный элемент для за­проса пользователей Web-сайта о необходимости ввода данных. Они широко ис­пользуются практически во всех Web-транзакциях. К сожалению, для большинства Web-форм сделаны предположения о вводе только корректных данных.
Разработчик формы может задать максимальное количество символов, которые разрешено вводить пользователю. Например, в следующем фрагменте кода размер поля "username" ограничивается десятью символами.
<form action="login.cgi" method=GET>
<input   maxlength=10   type="input" name="username">Username</input> </form>
Дизайнер, который плохо разбирается в базовой технологии, может предполо­жить, что удаленному пользователю теперь можно будет вводить не более десяти символов в поле имени. При этом они могут не понимать, что ограничение происхо­дит на компьютере удаленного пользователя, в его Web-браузере! Но ведь удален­ный пользователь может применять Web-браузер, который не учитывает ограниче­ние по размеру поля. Или же удаленный пользователь может создать собственный браузер с такой возможностью. Или же удаленный пользователь вообще не будет использовать Web-браузер. Он может просто вручную ответить на запрос формы с помощью специального адреса URL.
http://victim/login.cgi?username=billthecat
В любом случае, не следует безоговорочно доверять данным удаленного пользо­вателя и никогда не надеяться на его программное обеспечение. Ничего не мешает удаленному пользователю предоставить в ответ на запрос следующий URL-адрес.
http://victim/login.cgi?username=THIS_IS_WAY_TOO_LONG_FOR_A_USERNAME
Предположения, основанные на доверии, наподобие приведенных выше, создают потайные ходы между "комнатами" в нашем воображаемом доме. Опытный хакер может использовать лазейку "безусловных доверительных отношений", чтобы про­никнуть из "фойе" в "кухню".
Отмычка для замка
Злоумышленник способен тщательно подобрать входные данные и предусмот­реть "правильный" порядок их поступления. При атаке каждый бит данных напоми­нает ключ, который открывает путь к нужному коду. Полную атаку можно предста­вить "связкой ключей", которая позволяет последовательно "открыть все пути" в программе. Обратите внимание, что эти "ключи" должны использоваться в опреде­ленном порядке. После того как "ключ" использован, он должен быть отложен в сто­

рону. Другими словами, проведение атаки предусматривает ввод абсолютно точных данных в абсолютно точном порядке.
Программное обеспечение представляет собой матрицу решений. Решения транс­формируются в ветви, которые соединяют блоки кода друг с другом. Представим эти ветви в виде проходов, которые соединяют комнаты. "Двери" будут открыты, если хакер введет нужные данные ("ключ") в нужном порядке. В некоторых фрагментах кода программы происходит выбор ветви в зависимости от введенных пользовате­лем данных. Вот здесь и происходит "подбор ключей". Хотя на определение этих мест в программном коде требуется огромное количество времени, в некоторых слу­чаях этот процесс можно автоматизировать. На 2 показана структура дерева кода стандартного FTP-сервера. На рисунке указано, какие ветви выбираются в за­висимости от введенных пользователем данных.
Подобные схемы являются мощным средством при восстановлении исходного кода и структуры программы!. Однако иногда требуются гораздо более сложные дан­ные. На 3 показана более сложная трехмерная схема, которая также отобража­ет внутреннюю структуру программы.
Внутри отдельных "комнат" нашей программы обрабатываются различные час­ти пользовательского запроса. На 4 показан результат дисассемблирования отдельного фрагмента кода из атакуемой программы. Следуя нашей аналогии, этот код содержится в одной из "комнат" нашего "дома" (один из блоков, показанных на приведенных выше рисунках). Злоумышленник может использовать эту информа­цию для планирования атаки в каждой из "комнат".
Простой пример
Рассмотрим программу атаки, при которой злоумышленник запускает команду ко­мандного интерпретатора на атакуемой системе. Ошибка в программном коде, которая приводит к появлению уязвимого места, может выглядеть следующим образом.
$username = ARGV;   #user-supplied data system("cat  /logs/$username"   . ".log");
Обратите внимание, что при вызове функции system () ей передается параметр, значение которого не проходит никаких проверок. Предположим, например, что значение параметра,шегпате поступает из HTTP-cookie. HTTP-cookie представ­ляет собой небольшой файл данных, который полностью составляется удаленным пользователем (и, как правило, хранится в Web-браузере). Опытные разработчики программного обеспечения знают, что данным файлов cookie доверять нельзя нико­гда (за исключением криптографически защищенных файлов, которые прошли про­верку).
Используемое в нашем примере уязвимое место возникло вследствие того, что ненадежные данные файла cookie принимаются в системе и используется в команде командного интерпретатора. В большинстве систем для командного интерпретатора предоставляется доступ на уровне системы, и при "правильном" подборе символов в качестве значения username, хакер может отправлять команды, которые будут управлять удаленной системой.
Давайте рассмотрим этот пример немного подробнее. Если удаленный пользова­тель в строку для имени введет значение bracken, то конечная команда нашего ко­да, выполняемая с помощью вызова system (), будет такой, как показано ниже.
cat /logs/bracken.log
Эта команда отображает содержимое файла bracken.log из каталога logs в окне Web-браузера. Если удаленный пользователь введет другое имя, например nosuchuser, то команда будет иметь следующий вид.
cat /logs/nosuchuser.log

Если файла не существует, то происходит ошибка, о которой выдается уведомле­ние, а именно: не отображается никаких данных. С точки зрения злоумышленника вызвать такую ошибку не очень интересно, но зато есть "пища для размышлений". Поскольку мы контролируем значение переменной username, то мы можем ввести любые символы в качестве имени пользователя. Теперь воспользуемся преимущест­вами такого положения.
Давайте посмотрим, что произойдет, если мы введем "нужные символы в нужном порядке". Используем в качестве имени пользователя строку ". . /etc/passwd." и в результате получим следующую команду.
cat /logs/../etc/passwd.log
В данном случае мы использовали типичную хитрость перехода в корневой ката­лог для отображения содержимого файла /etc/passwd. log. Удалось это благода­ря тому, что мы имели полный контроль над именем файла, которое передается ко­манде cat. Жаль, что файл /etc/passwd. log отсутствует на большинстве UNIX-систем.
Наша программа атаки довольно проста и не приведет к серьезным негативным последствиям. Но в результате даже небольших умственных усилий можно добавить еще несколько команд, чтобы они были выполнены на атакуемом компьютере. А по­скольку уже вполне реально контролировать содержимое строки после команды cat, то столь же реально добавить еще несколько команд.
Далее введем вредоносное имя пользователя, например "bracken; rm -rf /; cat blah.", которое приведет к последовательному запуску трех команд. В качест­ве разделителя команд используется символ точки с запятой.
cat /logs/bracken;   rm -rf  /;   cat blah.log
В этой простой атаке несколько команд используются для удаления всех файлов из корневого каталога. После такой атаки на взломанной системе останется только корневой каталог и, возможно, каталог lost-and-found. Вот к каким серьезным по­следствиям для всей системы может привести лишь одно "простое" уязвимое место в строке кода для ввода имени пользователя на Web-сайте.
Важно отметить, что здесь тщательно было подобрано значение для имени поль­зователя в конце собственной строки. Таким образом, конечная командная строка будет иметь правильный формат, что позволит выполнить встроенные вредоносные команды. Поскольку для разделения команд используется символ точки с запятой, в нашем примере выполняются три команды. Но эту атаку нельзя назвать полностью разумной! Последняя команда cat blah, log не будет выполнена, ведь уже были удалены все файлы!
В конечном счете эта простая атака основана на управлении строками данных и использовании синтаксиса языка на уровне системы.
Безусловно, наш пример атаки является тривиальным, но он демонстрирует, что может произойти, когда программное обеспечение удаленной цели может запускать команды, данные для которых поступают из непроверенных источников. Возвраща­ясь к нашей аналогии с домом, можно сказать, что в данном случае была оставлена открытой "дверь", позволившая хакеру управлять тем, какие команды должны вы­полняться программой.
В этой атаке мы только воспользовались уже существующими свойствами ата­куемой программы. Как увидим далее, существуют и значительно более мощные

атаки, которые позволяют полностью обойти свойства атакуемого программного обеспечения с помощью встроенного кода (и иногда даже вирусов). В качестве при­мера можно назвать атаки на переполнение буфера, которые "прорубают новую дверь" в "доме" программного обеспечения, разрушая "стены" управления потоком данных. Это доказывает, что подобные атаки нацелены на структуру программ и иногда в этих атаках используются чрезвычайно глубокие знания о "правилах по­стройки домов". Иногда это предполагает умение писать на машинном языке и вла­дение предметом схемотехники. Безусловно, такие атаки намного сложнее, чем рас­смотренная выше атака.

 

На главную | Содержание | Назад | Вперёд
 
Яндекс.Метрика