Прячем Зло или Чистим АВ-сигнатуры: Второе пришествие
Прячем Зло или Чистим АВ-сигнатуры: Второе пришествие
This is war, ain't no fun and games
Наконец-то я решил написать продолжение мануала по чистке файлов. Суть способа почти не изменилась, поэтому для начала лучше прочитать первую часть (/page/malware-cleanin) - там есть немного информации для старта.
Into The Lungs Of Hell
Для начала, ознакомимся с ключевыми теоретическими моментами, с которыми связана чистка и на которых многие тормозят.
Первый вопрос - что же чистить?
Многие знают, что чистить нужно стаб, но что это такое? Рассмотрим назначение стаба на примере джоинера. Этот тип программ склеивает несколько файлов в один, при запуске которого файла извлекаются и исполняются. Но ведь если просто записать один файл в конец другого - эффекта склейки не выйдет, и, если повезет, запустится только первый файл - к которому дописывали другой файл. Для решения этой проблемы пишут небольшую программу, в конец которой дописывают файлы для склейки (также возможна запись в ресурсы). Она при запуске извлекает и запускает файлы. Именно эту программу и называют стабом.
Другой вариант - если целью чистки является не джоинер или криптор, а обычная программа, которую, антивирусы ошибочно детектируют как вирус, или, например, уже готовый троян, вирус и т.п. - тогда ни о каком стабе не идет речь и нужно чистить сам файл.
Второй вопрос - почему именно стаб нужно чистить?
В виду того, что, например, в джоинере используется всего один стаб, результирующий файл (далее - "контейнер") после склейки любых файлов будет иметь одно общее - стаб. Именно из-за этого антивирусы берут за основу своей сигнатуры именно часть стаба, а не файлов внутри контейнера (так происходит в большинстве случаев).
Третий вопрос - где взять стаб?
Очень логичный вопрос, так как я встречался с разными уникальными персонами, которые прятали стаб как можно глубже.
Самый простой вариант - стаб находится рядом с джоинером - в этом случае нужно просто почистить файл и заменить старый стаб очищенным.
Более сложный вариант - стаб находится в ресурсах программы. Достать его достаточно легко, воспользовавшись программой Restorator:
1) Открываем в Restorator'e наш джоинер.
2) Для хранения стаба в большинстве случаев используется тип ресурса "RCData". Если в дереве ресурсов файла в Restorator'e есть такой формат, значит стаб вероятнее всего там. Другой вариант - стаб находится в ресурсах, но в другом типе. Найти его легко - достаточно пересмотреть все ресурсы файла на предмет сигнатуры PE EXE файла. Т.е. первые 2 байта файла в ресурсах должны быть "M" и "Z" соответственно.
3) Само извлечение показано на скриншоте #1:

4) Чистим стаб и записываем его обратно в ресурсы программы:

Самый изощренный способ - хранение стаба в виде константы. Т.е. стаб находится в секции кода, в секции данных программы или в оверлее. Оверлей - место в PE EXE файле после самого файла, т.е. стаб записан в конец программы. Поиск стаба файла не сложен - достаточно искать его по сигнатуре "MZ". При помощи HEX-редактора нужно извлечь его оттуда, очистить и вставить обратно тем-же HEX-редактором.
Going Under
В первой части статьи суть чистки была вот в чем - меняем каждый байт файла и проверяем антивирусом. Способ действенный, но очень медленный. С момента её выхода в свет я почистил не один десяток файлов и нашел некоторые закономерности, используя которые, процесс чистки ускоряется в десятки раз.
Например, во всех файлах (далее под фразами "всех" и "всегда" я буду иметь в виду "почти всех" и "почти всегда" :) ) сигнатуры находятся в первой секции (чуть реже чем всегда она с кодом, а не с данными), из-за чего процесс чистки одинаков для любых PE-EXE файлов. Это очень существенно ускоряет чистку, ведь ты точнее знаешь местоположение сигнатуры.
Также, для значительного ускорения я переписал в SignDetect одну функцию, а именно - "Bytes to write". Именно она помогает более быстро обнаружить сигнатуру.
Needful Things
Чтобы понять некоторые ключевые моменты, желательно иметь хотя бы поверхностные знания ассемблера и формата файлов PE EXE. Для работы нам понадобится любой HEX-редактор (например WinHex), любой отладчик (я буду использовать OllyDbg), PE Tools, PEiD. Не лишними были бы хоть небольшие навыки работы с этими программами.
Желательно также ознакомиться с туториалами по OllyDbg от Рикардо Нарваха - http://www.wasm.ru/publist.php?list=23#series_17 - как минимум, первых 15-20 глав.
Highway To Hell
Итак, вкратце объясню, как всё будет происходить. Предположим, мы имеем PE EXE, который определяется антивирусом Касперского, и сигнатура находится в секции кода. Казалось бы, что сложного - надо просто найти её и изменить. Изменить так, чтобы файл работал. В этом и кроется вся проблема - на сегодняшний день очень незначительно количество людей может это правильно сделать, так как в большинстве случаев требуется знание ассемблера. Далее я опишу небольшую заготовку на ассемблере, которую можно использовать вслепую, не совсем понимая - что, зачем и как. Но для понимания некоторых примеров все-таки лучше знать назначение некоторых команд.
Сигнатура антивируса Касперского (тогда, когда она находится в секции кода) чаще всего начинается с инструкции длиной в 5 байт и более. Это могут быть уникальные инструкции, например "MOV EAX, DWORD PTR [ECX+ECX*4+17]", которые адекватно изменить с сохранением работоспособности будет непросто. Да, если учесть факт того, что в большинстве случаев длина сигнатуры равна 128 байт, то действительно, для отдельного файла можно найти уютный кусок кода, который можно изменить так, как нам надо. Но такой вариант сложнее - для каждого файла нужно вручную искать инструкцию, подходящую нам. Я молчу о том, что для этого необходимо наличие начальных знаний команд ассемблера. Или, например, сигнатура попадает на строку, которая находится в секции кода (так делает например компилятор от Borland) - без потерь не обойтись. В общем - излишние затраты времени и нейронов.
Теперь о сути способа. Все вышеизложенные проблемы обходятся очень просто. Мы меняем (удаляем или изменяем - без разницы) нашу сигнатуру, предварительно запомнив её. Далее дописываем небольшой участок кода, который бы при запуске восстановит измененный нами кусок кода/данных с сигнатурой. Т.е. файл как бы изменен, но при запуске сам восстанавливает тот участок и работает как и ранее. Для более внятного понимания перечитай.
При этом возникают некоторые непонятные моменты, например как перенаправить выполнение программы на наш участок и куда записать наш код. Первое решается сменой одного поля в структуре PE EXE, а именно "Entry Point". Для решения второго есть два способа - запись в конец секции с кодом или добавление новой секции с нашим кодом. Запись в конец проще и, чаще всего, более удобна. Но я сталкивался с такими файлами, в которых оставалось всего несколько неиспользуемых байт, вместить в которые нужный код не представлялось возможным. В таких случаях ничего не остается, кроме как добавить новую секцию. Громадный минус этого способа - изменение размера файла. Именно из-за этого очищенный стаб может стать нерабочим.
Ниже я буду описывать именно первый вариант, так как он более прост и подходит в большинстве случаев.
Если цель понятна и ты знаешь, как это реализовать - не читай дальше, а иди делай.
I'll get even with you
Примером чистки будет служить уже знакомый тебе SunS Joiner, который можно взять тут - http://rapidshare.com/files/131667281/SunS-joiner2.2.4.rar.html
Извлекай файл стаба как показано на рисунке выше и сохраняй в файл. Выбирай в SignDetect файл стаба и папку для складирования очищенных файлов.
Важная часть настройки чистки - выбор диапазона (Range) и количества байт для записи (Bytes to write - BTW).
Про выбор диапазона я уже писал выше - нам нужна первая секция файла. Жми на кнопку "From sections":

В данном случае первой секцией является "CODE" - дважды кликни на ней для выбора диапазона байт, относящихся к этой секции. Поля диапазона заполнятся смещениями 00000400 и 00003800.
Теперь о "BTW". Просто запомни такое правило - на первом этапе поиска сигнатуры: BTW = ( RangeMax - RangeMin ) / 20 но не менее чем 128 байт. Именно такой выбор позволяет значительно ускорить процесс и увеличить точность поиска сигнатуры.
Жми кнопку "Start" и ожидай завершения обработки файла. Когда SD закончит - закрывай её.
Натравливай антивирус на папку с файлами, которую ты выбирал и в которой SD создала файлы. После проверки папки, в ней осталось всего 2 файла:

Проверка антивирусом у меня длилась всего 12 секунд - несравнимо короткий срок.
Второй этап чистки - уточнение положения сигнатуры в файле. Мы уже узнали, что она лежит в пределах [00003580..00003680]. Нижняя граница - самое меньшее значение среди оставшихся файлов после первого этапа. Второе - это наибольшее значение + выбранное нами значение BTW.
Запоминаем эти два значение и очищаем папку, в которую SD создавала файлы. Опять запускаем её, выбираем наш стаб и папку. Диапазон на второй стадии мы уже нашли - 00003580 и 00003680. В BTW же нужно выставить единицу. Запускаем обработку файлов, которая длится всего несколько секунд и после её завершения закрываем SD, она нам больше не понадобится. Натравливем антивирус и получаем на выходе 128 файлов. А это значит, что мы полностью нашли сигнатуру и править можно любой байт из этого диапазона [000035A0..0000361F].
Angel in our pocket, devil by our side
На этом этап поиска сигнатуры завершен, приступим к корректному изменению кода стаба.
Для начала нужно узнать VA (виртуальный адрес) кода, с которого начинается сигна.
VA = SignOffset - R.Offset + V.Offset + ImageBase
Где SignOffset - начало диапазона сигны, который мы уже нашли (000035A0). Все остальные значение находятся в полях структуры PE EXE нашего стаба и их можно узнать в PEiD'e, они находятся тут:




Подробнее об этих значениях можно узнать в различных туториалах, посвященных формату PE EXE, поэтому я не буду на них останавливаться, для чистки нам это не понадобится.
После этого, формула для нашего стаба приобретает такой вид:
VA = 000035A0 - 00000400 + 00001000 + 00400000 = 004041A0
004041A0 - Это и есть виртуальный адрес, по которому начинается сигнатура.
Далее нам понадобится отладчик - OllyDbg, открывай в нем файл стаба.
Первое, что нужно сделать - запомнить виртуальный адрес точки входа (EP):

Листай вниз, до того момента, когда заканчивается весь код и данные, и начинаются нули. Именно здесь мы будет вписывать наш код, восстанавливающий сигнатуру:

Выбираем для записи место с нулями, например 00404380.
Вот прототип кода, который выполняет свою миссию - восстановление сигны:
mov esi, %VA%
mov edi, esi
mov ecx, %size%
%label1%:
lodsb
xor al, cl
stosb
loop %label1%
jmp %EP%
Где:
%VA% - виртуальный адрес сигнатуры, в нашем случае это 004041A0
%size% - количество байт, которые мы будем менять. Достаточно и одного, но в большинстве случаев лучше выбрать число из диапазона [16..128]. Почему так нужно делать, ведь если изменить 1 байт, то сигнатура все-равно пропадет? Дело в том, что мы чистим от одного антивируса - Касперского, но очень часто встречается, что где-то рядом с сигнатурой Касперского лежит например сигна Доктора Веба - тем самым можно почистить от нескольких антивирусов сразу, как повезет.
%EP% - виртуальный адрес точки входа, который мы запомнили в начале работы с файлом стаба в отладчике.
%label1% - условное обозначение адреса, по которому находится следующая инструкция, т.е. "lodsb" - на картинке с примером будет яснее:

После команды "loop" нужно вводить адрес команды "lodsb", как на картинке.
Выделяй весь введенные код и сохраняй его:
Кликни правой кнопкой мыши на нем -> "Copy to executable" -> "Selection". Появится окно, жми в нем "Copy All", появится еще одно окно, нажимай как на рисунке:

и сохраняй стаб, например под именем "stub_2.exe".
Следующий пункт - работа с PE Tools.
Для чего, ведь код мы уже записали?!
В стабе нам нужно провести еще 2 изменения - изменить точку входа, чтобы сначала исполнился наш код и восстановил сигнатуру, и изменить атрибуты первой секции.
У каждой секции в PE EXE файле есть атрибуты, которые характеризуют её содержимое - например, что в ней хранится только код или только данные. По дефолту, в секции кода не стоит атрибут, позволяющий писать в неё - это мы и исправим, чтобы наш код нормально заработал и не выдал ошибку при записи сигны.
Запускай программу, вызывай PE Editor (Alt+1) и выбирай в нем наш модифицированный стаб "stub_2.exe".
Первым делом сменяем EP - сначала нужно высчитать правильное значение.
NewEP = NewCodeVA - ImageBase
где:
NewCodeVA - тот адрес, по которому мы начали записывать код
ImageBase - уже известно, что это
В нашем случае это приобретает такой вид:
NewEP = 00404380 - 00400000 = 00004380
Редактируй поле с EP подставляя новое значение:


и жми "Ok".
Далее меняем аттрибуты секции, в которую мы дописывали код, а именно - "CODE":




Выставляй галку "Writeable", жми "Ok", "Ok", "Close", "Ok".
Казалось бы - всё готово, ан нет. Код записали, секцию подготовили, но не сделали самого главного - не убрали саму сигнатуру.
Для этого открываем "stub_2.exe" в OllyDbg и оказываемся на точке входа.
В дописаном коде я использовал обратимое изменение данных - т.е. сигнатура меняется и восстанавливается одной и той-же командой, а именно "xor". Т.е. достаточно запустить наш код и данные изменятся так, как нам надо.
Выделяем строку с последней введенной командой "JMP 00404184" и жмем F2 - тем самым ставя брекпойнт на эту команду, т.е. исполнение программы остановится именно на этом джампе. Запускаем стаб на исполнение нажатием F9 - исполнение остановилось и выделилась строка с джампом. Опять жмем F2 чтобы убрать брекпойнт.
Последнее, что нужно сделать - сохранить стаб. Переходи по адресу сигнатуры - 004041A0 и выделяй вниз измененные байты - можно чуть больше, чем мы изменяли (16 байт), делай так:

отвечай в следующем диалоге "Да". Далее появится окно, с выделенным фрагментом сигнатуры, который мы изменили. Жми правой кнопкой на выделенном:

и сохраняй чистый стаб.
Всё! Осталось только записать стаб обратно в джоинер с помощью Restorator'a. Как это сделать было описано в начале.
А теперь самое главное - оценка результата.
До чистки стаб определяло вот так:
20 on 22 http://scanner.novirusthanks.org/analysis/46299cadfe021f2dae5ea043a6869fbc/c3R1Yi5leGU=/
А теперь:
13 on 21 http://scanner.novirusthanks.org/file/05a00a4cb098ac0917140346328dbe47/c3R1Yl8zLmV4ZQ==/
Т.е. мы зацепили сигнатуры не только Касперского, но и еще многих других явно кривых антивирусов.
Shit Happens
Почистил файл, а он снова стал палиться? Достаточно провести аналогичную процедуру, изменив, например, смещение или количество байт для смены (то значение, которое мы ложили в регистр ECX).
The End Of The Line
Была идея писать всё это в стиле старого Хакера, упоминая пиво, порно и сиськи, но я искренне надеюсь, что ты перестал читать откровенно идиотскую хуету.
Я надеюсь, что внятно все описал, но если останутся вопросы - выслушаю их на форуме.
Спасибо за внимание.
Еще записи по теме
- Прячем Зло или Чистим АВ-сигнатуры
- Сжатие данных: проще не бывает
- Wonder.Waffle.9000 - вундер-спрединг через вундер-клипбоард
- Записки рыболова-любителя. Ловим WM-трояна.
- Осмотр Гоги или Анализ тулзы "Goga Hosts"
- Имейте совесть или совесть поимеет вас
- Downloader, или "Трать трафик соседу, пока он не знает"

Комментариев: 19
Оличная статья. +5
Но все картинки битые!
> Но все картинки битые!
Исправил
В IE Каритнки открываются нормуль, форматирование тоже нормуль. Но в Opera и MF часть картинок не открывается, да и форматирование страницы глючит.
Ща вот вроде нормально открылось все в MF. А до этого косяки были. CMS может глючит?
Скорее лаги сервера. Да и после переезда на другой айпи траблы с НСами достают. В общем, со временем пройдет )
thx за эту статью + предыдущую, интересно и доступно пишешь, даже для непосвященных людей.
отдельное спасибо за то, что расписал - что такое стаб_ очень долго хотел узнать что же это)))
Велкам!
Почитал статьи , довольно не плохо пишешь!
У меня тут мысль, почему бы тебе не собрать не большую базу из этих палевных сигнатур, а затем добавить их в твою тулзу, что бы она их сразу искала и переносила???
Ну типо сделать анти-антивирус :):):)
Спасибо за внимание!
Буду следить за твоим сайтом! УСПЕХОВ1
бред
подскажите пожалуйство ввожу "LOOPD SHORT Stub.0040438C" пишит "Unrecognized operand" все делаю так как описано в статье! скажу сразу в ollydbg слабоват!
Нужно вводить "loop 40438C"
Описанный метод без труда обходит эвристический анализ антивирусов. Могу предложить идею для следующей статьи чистки АВ-сигнатуры. Нужно, в начале программы вставить код, который позволял бы переходить на оригинальную точку входа в программу (ЕР), но только чтобы эвристика АВ не смогла понять что к чему. Я не программист, поэтому не знаю как это реализовать.
Антивирь удаляет из папки все файлы, перепробовал разные стабы, эффект тот-же. Не подскажешь почему?
Gloria22MCPHERSON - бот =(
спасибо, все доступно =)
премного благодарен
Хорошая статья, спасибо. Но у меня вопрос в другом, а как чистить к примеру связку и сами эксплоиты?
Vazonez, а чё делать, если сигнатуры лежат в конце файла, и их адрес не попадает в CPU отладчика?
Знаю что к первой части есть видео.А есть видео к этой части??Поделитесь пожалуйста...
А к очистики dll-ок ето тоже подходит?