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

 

 

Восстановление кода анализатора

Программа синтаксического анализа, или просто анализатор (parser), разбивает строку байтов на отдельные слова и операторы. Это действие называют синтаксическим анализом (parsing). При обычном анализе обычно требуются символы "пунктуации", которые часто называют метасимволами, поскольку они имеют особое значение. Во многих случаях атакуемое программное обеспечение выполняет анализ входных строк в поисках этих специальных символов.
Метасимволы довольно часто представляют особый интерес для хакеров. Нередко важные решения в программе зависят непосредственно от наличия этих специальных символов. Фильтры тоже используют метасимволы для выполнения необходимых действий.
Опознать метасимволы в дизассемблированном программном коде сравнительно просто. Выделить их настолько же просто, насколько найти код, который сравнивает значение байта со стандартным значением жестко закодированного символа. Используйте таблицу ASCII-символов для определения шестнадцатеричн^гх значений конкретных символов.
На 9 показано окно программы IDA, на котором мы видим, как данные сравниваются с шестнадцатеричными значениями символов косой черты (/) и обратной косой черты (\) — 2F и 5С соответственно. Подобные сравнения часто осуществляются фильтрами файловой системы, что делает эту задачу весьма перспективной для создания атак.
Преобразование символов
Преобразование символов иногда происходит как следствие подготовки системы к вызову функции API. Например, в системном вызове могут приниматься имена файлов, в которых присутствуют символы косой черты, а в программе могут для этой же цели равнозначно использоваться как символы косой черты, так и символы обратной косой черты. Таким образом, перед вызовом функции выполняется преобразование символов косой черты в символы обратной косой черты, т.е. безразлично, какие символы косой черты были предоставлены программе, системным вызовом они будут обработаны как символы обратной косой черты.
Что же в этом интересного? Представьте, что произойдет, если программист захочет проверить, что пользователь не использовал символы косой черты в имени файла. Цель подобной проверки может заключаться в предотвращении возможности ошибки для атак с переходом по файловой системе, например. Программист может установить фильтр для блокирования символов косой черты и успокоиться, решив, что проблема решена. Но если злоумышленник сможет внедрить символ обратной косой черты, то проблема останется нерешенной. Используя преобразование символов, возникает прекрасная возможность обойти простые фильтры и системы обнаружения вторжений. На 10 показан программный код, который преобразовывает символы обратной косой черты в символы косой черты.
Байтовые операции
Встроенные в большинство программ анализаторы работают с отдельными символами. Один символ обычно кодируется одним байтом (очевидное исключение представляют собой многобайтовые символы Unicode). Поскольку символы обычно представляются байтами, разумно выявить однобайтовые операции в дизассембли-рованном коде. Найти эти операции достаточно просто, поскольку они обозначаются как "al", "Ы" и т.д. Большинство современных регистров являются 32-битовыми. Такая запись означает, что операция осуществляется над младшими восемью битами регистра, т.е. одним байтом.
При отладке запущенной программы нужно помнить о крайне важном аспекте. Помните, что только один байт используется при обозначениях типа al и Ы, независимо от того, какие данные хранятся в оставшейся части регистра. Если значение регистра равно 0x0011222F и используется обозначение для побайтовой операции, то в действительности обрабатывается только значение 0x2F, т.е. младшие 8 бит.
Операции для работы с указателями
Строки часто имеют слишком большой размер, чтобы их можно было сохранить в регистре. Поэтому обычно в регистре хранится только адрес ячейки памяти, в которой хранится строка. Этот адрес называют указателем (pointer). Обратите внимание, что указатели являются адресами, которые могут указывать практически на все, а не только на место хранения строки. Одна из удачных хитростей заключается в определении указателя, который инкрементно увеличивает значение на один байт, или операции, в которых используется указатель для загрузки одного байта.
Выявить побайтовые операции с указателями достаточно просто. Для них используется формат записи [ххх], например [eax], [ebx] и т.д. совместно с обозначениями al, bl, cl и т.д.
Арифметические операции с указателями имеют следующий вид.
[еах + 1], [ebx + 1] и т.д.
Операция перемещения байтов в памяти выглядит примерно следующим образом. mov dl, [eax+1]
В некоторых случаях выполняется непосредственная модификация регистра, в котором хранится указатель. inc еах
Символы завершения строки NULL
Поскольку строки обычно завершаются с помощью символа NULL (особенно в коде на языке С), то может пригодится поиск кода нулевого байта. Шаблоны для поиска символа NULL могут выглядеть примерно следующим образом.
test al, al test cl, cl
На 12 показано несколько побайтовых операций с такими данными:
Наличие этих операций может указать на то, что в этой программе выполняется анализ или обработка входных данных.
Как и для большей части серверного программного обеспечения в сервере I-Planet 6.0 от компании Sun Microsystems, для обеспечения безопасности используется метод выявления недопустимых данных, или т.н. "черный список". Как мы уже рассказывали, подобную защиту не так сложно обойти. Используя отслеживание вызовов функций и программу GDB (как описано в главе 4, "Взлом серверных при­ложений"), мы находим несколько вызовов функций, предназначенных для фильтрации пользовательских данных. Вместо простого отбрасывания вредоносных данных, сервер I-Planet пытается "исправить" вредоносные строки данных, удаляя "некорректные" части.
В данном конкретном случае для нахождения этих функций лучше всего установить точки останова и действовать по методу "снаружи внутрь". Напоминаем, что метод "снаружи внутрь" заключается в том, чтобы начинать трассировку с момента поступления входных данных пользователя и отслеживать эти данные в коде программы.
Действуя по этому методу, мы обнаружили, что достаточно часто вызывается функция
_OfJCHttpUtilTCanonicalizeURIPathPCciRPcRiT
Очевидно, что название функции искажено, но зато мы видим, что она используется для канонизации (или приведения в стандартную форму) предоставленных пользователем строк UNI. Как мы уже указывали, эта функция предназначена для обнаружения некорректных строк входных данных. Воспользовавшись программой GDB для установки точки останова в начало этой функции, мы можем исследовать предоставленные данные.
(gdb) break_OfJCHttpUtilTCanonicalizeURIPathPCciRPcRiT
Breakpoint 6 at 0xff22073c
(gdb) cont Continuing..
Теперь точка останова установлена, но нам нужно отправить запрос, чтобы определить, какие данные передаются нашей функции. Мы отправляем Web-запрос к исследуемой программе, и благодаря точке останова немедленно получаем нужные сведения. Затем с помощью команды info red исследуем данные регистров с целью узнать данные, предоставленные функции.
Затем мы исследуем данные каждого регистра с помощью команды х. Лучше использовать обозначение "х/" для получения данных дампа памяти из близлежащих ячеек по отношению к запрошенному адресу. Например, с помощью команды x/8s $g3, мы получаем дамп восьми строк после адреса памяти, указанного в регистре g3.
(gdb) x/8s $g3 0x987ab0:
0x987ad3: "unch.hl.ml"
0x987add:
0x987ade:
0x987adf:
0x987ae0 :
0x987ael:
0x987ae2:
Предоставленный нами URI-адрес хранится в области памяти, указатель на которую хранится в регистре g3. Теперь мы можем приступить к пошаговому исследованию и делать комментарии в программе IDA.
Этот метод "снаружи внутрь" особенно хорошо подходит для выявления деталей синтаксического анализа. Как правило, входные данные принимаются программой и модифицируются до того момента, когда они достигают важных системных вызовов. Начиная снаружи, мы можем определить, что делает анализатор с данными. Например, из имени файла могут удаляться дополнительные символы косой черты. При наличии определенных символов (например строк для перехода вверх по дереву каталогов % . / . .") в запросе этот запрос может вообще не пройти.

На 13 изображено окно программы IDA с добавленными замечаниями для любопытных областей кода. Результат работы программы GDB можно непосредственно вставить в дисассемблированный код IDA. С помощью символа точки с запятой в IDA можно вводить многострочные комментарии. Отслеживая вызов, мы обнаружили, что многие символы запроса удаляются и таким образом "очищается" имя файла.
Углубившись в программу, мы нашли еще одну функцию, которая используется для проверки формата "очищенного" запроса. Кроме очевидной глупости самой идеи поиска вредоносных данных (а не разрешения прохождения нормальных данных), эта функция к тому же называется INTutil_uri_is_evil_internal (забавно!). Эта дополнительная функция предназначена для выявления хакеров, которые атакуют систему. В зависимости от того, определяется ли URI-адрес как "вредоносный", функция возвращает значения TRUE или FALSE. Давайте выполним восстановление кода для этого вызова функции. Очевидно, что при любой реальной атаке нам нужно пройти "через" этот вызов. Дизассемблированный с помощью IDA код этой функции будет выглядеть примерно следующим образом.
В этом примере точка останова срабатывает, после предоставления программе следующего URL-адреса.
http://172.16.10.10/test_string.greg/%2F//.
В этой точке мы видим, что шестнадцатеричные символы в URI уже были преобразованы до момента достижения этой точки. Сделав еще несколько попыток, мы заметили, что проверка на "вредоносность" данных никогда не осуществляется для следующего URL-адреса.
http://172.16.10.10/../../../../../../etc/passwd
Это означает, что, когда мы пытаемся получить непосредственный доступ к файлу паролей, в программе выполняется какая-то другая проверка, до проверки вредоносного URL. Нам никогда не добраться до проверки на "вредоносность"! Очевидно, что в программе есть несколько точек, в которых осуществляется проверка безопасности входных данных.
Интересно, что если добавить в запрос имя подкаталога, то мы достигнем нашей проверки на "вредоносность".
http://172.16.10.10/sassy/../../../../../../etc/passwd
При этом вовсе необязательно наличие подкаталога sassy. Важнейший вывод заключается в том, что нам удалось обмануть логику программы. Добавив в имя файла название несуществующего каталога, мы добились того, что выполнение программы пошло иным путем, чем при непосредственном запросе файла паролей.
Таким образом нам удалось обойти первую проверку для наших входных данных. Выявление подобных множественных отдельных проверок и ветвления программы на основе их результатов, свидетельствует о том, что в такую программу можно проникнуть. В более грамотно спроектированных программах используется одна точка для проведения одной или более проверок (обратите внимание, что в некоторых случаях проверки вообще не нужны, поскольку атакуемая программа работает в замкнутом пространстве chroot или в ней используются другие методы обеспечения безопасности).

 

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