Научная статья на тему 'Метод динамического анализа защиты программного обеспечения для os X'

Метод динамического анализа защиты программного обеспечения для os X Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
296
51
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ / ЗАЩИТА / ДИНАМИЧЕСКИЙ АНАЛИЗ / СТАТИЧЕСКИЙ АНАЛИЗ

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Чепцов В.Ю., Черкасова Н.И.

Современное программное обеспечение на этапе создания подвергается различным модификациям, затрудняющим анализ и обратную разработку. В случае с легальным программным обеспечением это оправдано защитой от нелегального использования, однако в случае с вредоносным ПО цель авторов обойти эвристические анализаторы антивирусных движков или максимально увеличить время анализа файла. В условиях использования схожих подходов в защите программ сложно отличить легальное ПО от вредоносного. Более того, для устранения последствий вируса или для получения информации об авторах, необходимо производить обход подобных защит. В работе рассмотрены вопросы методов динамического анализа защищённой программы под OS X и предложен подход анализа процесса изнутри.

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Текст научной работы на тему «Метод динамического анализа защиты программного обеспечения для os X»

УДК 004.4.056.5

Чепцов В.Ю., Черкасова Н.И.

Московский государственный технический университет гражданской авиации (МГТУ ГА), Москва, Россия

МЕТОД ДИНАМИЧЕСКОГО АНАЛИЗА ЗАЩИТЫ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ДЛЯ ОБ X

Современное программное обеспечение на этапе создания подвергается различным модификациям, затрудняющим анализ и обратную разработку. В случае с легальным программным обеспечением это оправдано защитой от нелегального использования, однако в случае с вредоносным ПО цель авторов — обойти эвристические анализаторы антивирусных движков или максимально увеличить время анализа файла. В условиях использования схожих подходов в защите программ сложно отличить легальное ПО от вредоносного. Более того, для устранения последствий вируса или для получения информации об авторах, необходимо производить обход подобных защит. В работе рассмотрены вопросы методов динамического анализа защищённой программы под 08X и предложен подход анализа процесса изнутри.

Ключевые слова:

программное обеспечение, защита, динамический анализ, статический анализ

Детальный анализ поведения некоторой программы с закрытым исходным кодом может быть проведён двумя способами: динамический анализ и статический анализ. Под статическим анализом подразумевается разбор исполняемого кода программы без загрузки в оперативную память, под динамическим — анализ алгоритмов работы программы. К методам анализа первого типа обычно относят обратную разработку, в случае со вторым типом — отладку процесса.

К преимуществам статического анализа можно отнести обилие и широкие возможности инструментов, эффективных на простых примерах. Однако многие программы плохо поддаются статическому анализу из-за обильной виртуализации вызовов, навесных защит и высокой степени обфускации, как одного из методов защиты кода.

В таких случаях может быть использован динамический анализ — программа запускается в режиме отладки и часть исполняемого кода пропускается с анализом результата и внешних изменений. При этом также возможно повторное использование статического анализа после проведения динамического, включавшего, например, снятие навесной защиты в виде упаковщика (протектора).

Особенности работы отладчиков

Отладчики можно условно разделить на два типа: уровня ядра и пользовательского уровня, а именно:

Отладчики уровня ядра в основном предназначены для отлаживания операционной системы и драйверов, они имеют полные привилегии в системе и потому обладают широкими возможностями.

Отладчики пользовательского уровня запрашивают у системы определённые привилегии, при этом остаются работать на том же уровне, что и отлаживаемый процесс.

К современным базовым функциям отладчика машинного уровня можно отнести: дизассемблер; условные точки останова; трейсинг программы; чтение и изменение значений регистров и памяти; анализ стека для построения иерархии вызовов.

Следует отметить, что отладчик — это программа, которая вмешивается извне в некоторый процесс, соответственно замедляя при этом его работу и изменяя некоторые условия среды. Отсюда возникает риск обнаружения отладчика и возможные способы противодействия — антиотладочные механизмы.

Поэтому, несмотря на широкий спектр возможностей (к примеру, некоторые отладчики имеют встроенные скриптовые языки программирования или плагины к уже существующим, позволяющие уменьшить ручное взаимодействие аналитика с процессом), использование такого средства не бесплатно.

Антиотладочные методы

Так как современные версии OS X работают на х8 6-совместимых процессорах Intel, то используемые в программах средства антиотладки могут и должны поддерживать специфику процессоров этого типа.

Остановимся на некоторых из них:

1. rdtsc — ассемблерная мнемоника получения значения счётчика TSC с момента последнего сброса процессора. 64-битное количество тактов возвращается в регистрах edx:eax. В режиме х86-64 старшие биты rdx и rax заполняются нулями.

Принцип метода сводится к временной задержке. При использовании пошаговой отладки разница в количестве пройденных тактов между соседними командами по результату rdtsc будет очень велика, что с высокой вероятностью просигнализирует о присутствии отладчика.

Для осложнения обнаружения подобной инструкции могут использоваться методы скрытия опкодов в других опкодах:

B8 0F31EB02 mov eax, 0x2eb310f

EBFA jmp -4

В данном случае 0x2eb310f раскрывается как:

0F31 rdtsc

EB02 jmp +2

2. sysctl — среди системных вызов есть вызов, позволяющий получить флаги процесса. Если среди возвращаемых флагов есть флаг P TRACED, то процесс запущен из-под отладчика. Простейший пример реализации:

static bool debuggerPresent() { int mib[4]; kinfo proc info; size t size = sizeof(info); info.kp proc.p flag = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = getpid();

sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);

return (info.kp_proc.p_flag & P_TRACED)

!= 0;

}

По схожему принципу можно использовать функцию ptrace.

3. По факту регистрации обработчика исключений (по аналогии с созданием дампа и отчёта об ошибке при падении программы). Отладчик по умолчанию регистрирует подобные для отлова нарушений прав доступа к памяти, нахождения некорректных инструкций, установки точек останова и т. п. Список исключений легко получить с помощью функции task_get_exception_ports, указав соответствующую маску, например, EXC BREAKPOINT | EXC BAD ACCESS. Если среди возвращённых функцией портов есть валидный, то используется отладчик.

4. Проверка смещения ASLR.

Функция dyld get image vmaddr slide принимает в качестве параметра номер загруженного образа и возвращает ASLR смещение (произвольное смещение адреса загрузки образа в виртуальной памяти). Отладчики плохо работают при включённом ASLR, потому практически всегда его отключают. Это приводит к возможности обнаружения отладчика по состоянию ASLR.

Есть и другие методы, но принцип остаётся схожим. Отладчик по своей структуре оставляет множество способов, позволяющих легко его обнаружить, чем охотно пользуются авторы вредоносного ПО на Windows уже сейчас и только начинают использовать разработчики для OS X.

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

Нахождение подобных мест особенно в многопоточной программе часто затруднено, а логика проверки может не быть примитивной. При наличии отладчика уровня ядра можно было бы сбрасывать значения регистра TSC, однако существующий отладчик lldb в таком режиме недостаточно приспособлен для отладки пользовательских приложений. Метод динамического анализа

Исходя из выше изложенного, вполне обоснована возможность использования полноценного отладчика как инструмента. Однако использование внешней программы для анализа текущей, подключает дополнительное звено в вертикальную модель, что не является нормой для обычного запуска. Таким образом, можно использовать некоторый внешний элемент одного уровня с программой в рамках этого же процесса.

При запуске исполняемого файла Mach 1.0 в OS X, по аналогии с другими системами, происходит загрузка и отображение в виртуальную память образов различных модулей и самой программы. Упрощённо этот процесс можно представить в порядке выполнения функций ядра:

Вызов execve инициирует запуск процесса; exec activate image производит активацию образа в системе с указанными параметрами, настраивая виртуальную память и считывая файл;

exec mach imgact запускает динамический компоновщик (dyld) для последующей начальной загрузки файла;

load machfile производит считывание и вали-дацию заголовка mach;

parse machfile итерирует по командам загрузки и отображает сегменты в память;

load dylinker уведомляет dyld о точке входа; Процесс зацикливается, пока все необходимые образы не будут загружены.

Графический листинг данного процесса представлен ниже:

execve()

exec activate image() Чтение файла . —> exec mach imgact( dyld ^ получение точки входа

| load machfile() | parse machfile() команды загрузки в память]

| load dylinker() точку входа dyld]

выполнение

[ отображает [передаёт

Наличие внешних модулей, часть из которых принадлежит системе, гарантирует возможность помещения сторонних элементов в памяти. Так как порядок инициализации обратный, т. е. зависимости (например, libSystem, 1^оЬ]с, CoreFounda-^оп и пр.) выполняют загрузочный код ранее самой программы, что естественно, то при загрузке некоторой библиотеки в память возможно производить динамическую модификацию программы. Возможности данного подхода куда менее обширны по сравнению с полноценным отладчиком, однако при условии грамотного подхода в добавлении тела модуля его достаточно сложно обнаружить.

К другим преимуществам данного подхода можно отнести: Отсутствие влияния на скорость исполнения программы; Отсутствие необходимости манипуляций с ASLR и трансляцией адресов; Неограниченные возможности в программной модификации процесса, включая разработку сторонних расширений и модификацию модулей.

Реализацию добавления стороннего модуля можно осуществить как со стороны иэегэрасе (пользовательского уровня), так и со стороны кегпе1эрасе

(уровня ядра). В случае с userspace можно модифицировать сам dyld или какую-либо из системных библиотек, что эффективно, но может быть затруднено, например, в случае задержек публикации исходного кода этих компонентов или из-за необходимости сертификата цифровой подписи со специальными разрешениями. В случае с kernelspace возможности ещё более разнообразны, но могут потребовать базового понимания принципов работы подсистем ядра. Такой вариант обладает значительной устойчивостью к изменениям в операционной системе, так как не вмешивается в процесс верификации цифровой подписи и прав доступа программного обеспечения, не влияет на работу песочницы (среды безопасного исполнения программ), а также позволяет избежать конфликта настроек безопасности системы, находясь на более высоком уровне.

Особенности метода для OS X

Динамическое дизассемблирование

Ограничений на чтение собственной памяти у процессов OS X нет, поэтому в случае с дизассем-блированием принципиальных отличий не возникает. Существует множество встраиваемых дизассемблеров, например, capstone, distorm и др., способных работать в таких условиях. Процесс трансляции адресов может осуществляться прозрачно с использованием метода dyld get image vmaddr slide, а получение адресов функций доступно через dlsym. Практически возможно написать обработчик, который на определённом этапе произведёт дизассемблирование запущенной программы, синхронизировав данные в сторонней IDE для обратной разработки, позволив заниматься дальнейшим статическим анализом программы на определённом этапе.

Замена breakpoint (trap)

В случае с точками останова разные ситуации могут потребовать определённых методов. Ввиду возможности записи в собственную исполняемую память (в отличие от iOS в OS X не предусмотрено принудительного W^X, т. е. исполняемые страницы не могут быть записываемыми и наоборот, и соответственно можно изменить данные кодового сегмента), классический подход программных точек останова вполне реализуем. В месте точки останова прописывается обработчик, сохраняющий состояние процесса и передающий управление на время анализа. Стоит отметить, что в отличие от классического отладчика при таком подходе сторонние потоки не будут остановлены и продолжат работу.

Подход эмуляции точек останова или использования исключительно DR регистров в определённом смысле убивает преимущество работы в том же адресном пространстве. Если задуматься, то благодаря общепринятым соглашениям о вызове процедур возможно манипулировать целыми функциями, заменяя их, изменяя переданные аргументы или порядок вызовов. Такой подход может быть эффективен при работе с некоторыми упаковщиками или для маскировки окружения. В OS X это является особым преимуществом из-за особенностей языков Objective-C и Swift, имеющих нестрогую частично динамическую типизацию и возможности подмены функций и классов во время исполнения программы, на которых написано большинство программного обеспечения. Предложенный в данной работе подход анализа процесса защищённой программы под OS X изнутри может быть использован и в обратном направлении, как метод защиты программного обеспечения.

ЛИТЕРАТУРА

1. Charlie Miller. The Mac Hacker's Handbook / Charlie Miller., Dino Dai Zov / Wiley Publishing, Inc., Indianapolis, 2009 - p 370

2. Amit Singh. Mac OS X Internals: A Systems Approach / Amit Singh / Addison-Wesley Professional,

2006 - p 1680

3. Levin. Jonathan. Mac OS X and IOS Internals: To the Apple's Core. / Levin. Jonathan / John Wrox Press, 2012 - p 800

4. Надейкина Л.А. Проблема отказа доступа к сетевым сервисам. / Надейкина Л.А., Черкасова Н.И./ Труды Международного симпозиума Надежность и качество. -2015.-Т .1. - С.258-261.

i Надоели баннеры? Вы всегда можете отключить рекламу.