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

 

 

Методы исследования

Существует несколько методов восстановления исходного кода программного обеспечения. Для каждого из них характерны свои преимущества, и у каждого есть свои требования относительно ресурсов и времени. В стандартном исследовании ис­пользуется набор методов для декомпиляции и анализа программного обеспечения. Правильное сочетание выбранных методов целиком зависит от конкретной ситуа­ции. Например, сначала можно выполнить быстрое сканирование программного ко­да для определения очевидных уязвимых мест. Затем можно перейти к подробному отслеживанию обработки в программе введенных пользователем данных. Вероятнее всего, не удастся отследить каждый вариант внутреннего маршрута выполнения программы, поэтому разумно воспользоваться точками останова и другими средст­вами для ускорения процесса анализа программы. Рассмотрим несколько основных методов исследования.
Отслеживание обработки входных данных
Отслеживание обработки входных данных является наиболее доскональным мето­дом исследования программы. Прежде всего, нужно определить точки входа. Точки входа — это места, в которых введенные пользователем данные передаются программе. Например, получение сетевого пакета осуществляется с помощью вызова функции WSARecvFrom (). По существу, этот вызов принимает введенные пользователем дан­ные из сети и размещает их в буфер. На точке входа можно установить точку останова и начать пошаговое отслеживание выполнения программы. Конечно, используя набор отладочных средств, не забывайте о простом карандаше и листе бумаги. Следует запи­сывать каждый переход и изменение в процессе выполнения программы. Конечно, это очень утомительный подход, но он позволяет получить максимум информации.
Хотя определение вручную всех точек входа потребует массу времени, исследо­ватель получает возможность обнаружить каждый фрагмент кода, в котором прини­маются решения относительно введенных пользователем данных. Используя этот метод, можно выявить наиболее сложные проблемы.
Одним из языков, который защищен от подобных атак "отслеживания с помощью входных данных" является язык Perl. В Perl предусмотрен специальный режим безопасности, который называется режимом недоверия (taint mode). В режиме недо­верия используются комбинации статических и динамических проверок для контро­ля за всей информацией, которая поступает извне программы (такой как введенные пользователем данные, аргументы функций и переменные окружения) и выдачи

предупреждений при попытке программы сделать что-то потенциально опасное с этими ненадежными данными. Рассмотрим следующий сценарий.
#!/usr/bin/perl -T $username   = <STDIN>; chop $username;
system   ("cat /usr/stats/$username");
При выполнении этой программы Perl-обработчик переходит в режим недоверия, поскольку указан параметр -Тв первой строке вызова. Perl затем осуществляет по­пытку скомпилировать программу. Режим недоверия позволяет обнаружить, что программист не инициализировал явно переменную PATH и, тем не менее, пытается запустить программу с помощью командного интерпретатора, который легко может быть скомпрометирован. Перед прекращением компиляции будет выдано сообщение об ошибке, подобное приведенному ниже.
Insecure   $ENV{PATH}   while   running  with   -T   switch at ./catform.pl  line 4,   <STDIN> chunk 1.
Мы можем отредактировать сценарий, чтобы явно задать какое-то безопасное значение для переменной PATH в нашей программе при запуске.
#!/usr/bin/perl -T use strict;
$ENV{PATH}   w join   '  :  '   => split   ("   ",«   '_EOPATH_') ;
/usr/bin /bin
_EOPATH_
my   $username   = <STDIN>; chop $username;
system     ("cat    /usr/stats/$username") ;
Теперь режим недоверия позволяет определить, что значение переменной $username контролируется извне и ему нельзя доверять. Таким образом удается определить, что поскольку значение переменной $username может оказаться вре­доносным, то вредоносным может оказаться и вызов функции system. Поэтому вы­дается другое сообщение об ошибке.
Insecure dependency in system while  running with -T switch at   ./catform.pl  line  9,   <STDIN> chunk 1.
Даже если мы скопируем значение переменной $username в другую перемен­ную, то режим недоверия все равно позволит выявить проблему.
В предыдущем примере выдается сообщение об ошибке, поскольку переменная может использовать командный интерпретатор, чтобы запустить команду. Однако режим недоверия не способен предотвратить все возможные атаки на уязвимые мес­та, выполняемые с помощью входных данных, поэтому опытный хакер все равно в состоянии добиться успеха.
Для защиты от проведения нашей атаки (или для ее усиления) также пригодится улучшенный анализ потока данных. Средства для проведения статического анализа позволяют аналитику (или хакеру) выявить все точки входа и определить, значения каких переменных могут быть изменены с помощью внешних данных.
Использование отличий в версиях программ
При исследовании системы на предмет выявления уязвимых мест не забывайте, что поставщик программного обеспечения исправляет многие ошибки в каждой сле­дующей версии программы. В некоторых случаях поставщик может предоставлять

"горячее исправление" ("hot fix") или заплату, которые вносят исправления в двоич­ные файлы системы, поэтому очень важно отслеживать отличия между различными версиями программного обеспечения.
Различия между версиями можно использовать как руководство по проведению атак. Если появляется новая версия программного обеспечения или спецификации протокола, значит, скорее всего, в ней были исправлены уязвимые места или ошибки (если они были обнаружены). Даже если список исправлений не опубликован, то можно сравнить двоичные файлы новой версии с двоичными файлами устаревшей версии. Различия обнаруживаются на месте добавления новых функций или ис­правления ошибок. Таким образом, этими отличиями можно смело руководство­ваться для поиска уязвимых мест.
Использование охвата кода
Применение научных методов дает хакеру преимущество при прочих равных ус­ловиях. Научный метод начинается с измерений. Без возможности измерения своей среды исполнения нельзя сделать о ней никаких выводов. Большинство из рассмот­ренных в этой книге методов предназначены для поиска ошибок при программиро­вании. Обычно (хотя и не всегда) эти ошибки относятся к небольшой части про­граммного кода. Вот почему во многих новых средствах разработки программ обес­печивается защита от традиционных атак. В средстве разработки достаточно просто предусмотреть возможность выявления простой ошибки программирования (стати­чески) и устранить эту ошибку при компиляции. Вообще, через несколько лет атаки на переполнение буфера безнадежно устареют.
Мы рассматриваем поведение программы при ее выполнении в определенных ус­ловиях (например, при пиковых нагрузках).,Необычное поведение программы, как правило, означает нестабильность программного кода. А нестабильность программ­ного кода означает высокую вероятность наличия уязвимых мест.
Охват кода (code coverage) представляет собой способ отслеживания выполнения программы и определения того, какие участки задействованы в исходном коде. Для определения охвата кода разработано множество средств. Эти средства не всегда предполагают доступ к исходному коду. С помощью некоторых средств можно под­ключаться к процессу и собирать данные в реальном времени. В качестве примера можно назвать программу dyninstAPI, созданную Джефом Холлингсворсом (Jeff Hollingsworth), которая используется в Мэрилендском университете и которая дос­тупна по адресу http://www.dyninst.org/.
Для хакера охват кода говорит об объеме работы, которую предстоит выполнить при первом осмотре атакуемой программы. Компьютерные программы весьма слож­ны и их взлом — утомительное занятие. Человеку свойственно пропускать фрагмен­ты кода и переходить к главному. Охват кода позволяет определить, не пропустил ли хакер чего-либо важного. Если вы пропустили процедуру, поскольку она показалась вам безвредной, то, возможно, следует подумать еще раз! Охват кода позволяет вер­нуться и повторно проверить проделанную хакером работу.
Пытаясь взломать программное обеспечение, хакеры обычно начинают с точки ввода пользовательских данных. В качестве примера рассмотрим вызов функции

WSARecv()\ Отслеживая обработку данных по методу "снаружи внутрь", можно определить задействованные участки программного кода. Многие решения, как пра­вило, принимаются после приема пользовательских данных. Эти решения реализу­ются, как операторы ветвления, например, условные операторы ветвления JNZ и JE в коде для платформы х86. Охват кода позволяет определить, когда происходит ветвление, и "нарисовать" карту каждого непрерывного блока машинного кода. Для хакера это означает возможность определить, какие участки кода не исполняются при анализе программы.
Использование программ для оценки охвата кода позволяет опытному специали­сту получить "маршрут" выполнения программы. Подобная трассировка позволяет сохранить силы и продолжать исследование, когда в другом случае (без охвата кода) хакер мог бы прекратить усилия по взлому, не проверив все возможности.

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

 

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