Реверс «пасхального» трояна
Всех поздравляю со светлым праздником Пасхи! Сегодня мы будем заниматься разбором интересного пасхального трояна, имя которому Backdoor.Win32.Torr.ihd MD5: 6107A446E5310E03BFAECC20D1603F1D. Данный индивид представляет из себя исполняемый файл PE с расширением scr, также он очень похож на папку в windows xp, так как имеет соответствующую иконку. Назывался бинарник «Со светлым праздником Пасхи.scr». Если у юзверя стоит xp и до сих порт стоит галочка в настройках скрывать расширения, то тут уже очень большая вероятность, что данный сэмпл будет запущен. После запуска открываются фотографии, которые вы видели в галерее к данной статье. Но, всё же, давайте просмотрим, для чего он на самом деле предназначается.
Статический анализ дроппера трояна
Сперва, откроем образец в каком-нибудь PE просмотрщике, я юзаю CFF explorer. Убеждаемся, что это действительно, исполняемый PE файл и сразу смотрим импорты и ресурсы. В ресурсах замечаем интересную картину:
Тут настораживает следующая ситуация, в ресурсах находится исполняемый файл, так как первый байты начинаются с 0x4d,0x5A (MZ). Это говорит о том, что, с большой долей вероятности, данный исполняемый файл будет извлечён и запущен, что уже сейчас хочется сделать вывод, что мы ковыряем дроппер. В ресурсах далее хранятся jpg изображения. Надо сказать, что малварщики, видимо, очень торопились, когда писали вредоносик, обычно ресурсы хранятся в закриптованном виде, чтобы так уж сильно не бросалась вся эта картина в глаза. Давайте откроем в иде данный бинарник и посмотрим что же всё-таки на самом деле происходит. Но перед этим, сохраните ресурс 219 с помощью PE просмотрщика, мы будем его ревёрсить немного погодя. Кстати говоря, неплохо бы убедиться в том, что дроппер не запакован ничем, а, и заодно, посмотреть строки. Строки — эта такая ерунда, по которой можно сразу догадаться, к какому типу данный зловред относится. Так что открываем его в HIEW, далее Enter->Alt+F6 и мы видим вот что:
Тут видно, что используются ключ в реестре SOFTWARE\Microsoft\Windows\Current Version\Shell Folders\ Common Startup. Для тех, кто не знает, данное место в реестре определяет папку-автозагрузку. Что в этой папке будет, то и будет запускаться при старте системы. Таких мест можно сделать сколь угодно.
Откроем образец в Ida и на точке входа (Ctrl+E), мы видим, что это стандартная обёртка компилятора:
По адресу 00401CC2 находится настоящая точка входа в программу. Смотрим, что в ней творится:
Тут мы видим AfxWinMain. Это означает, что запрогали зловред на студии и юзали формочки. На самом деле это не круто. Круто, когда пишут на чистом WinApi. Для нас это будет означать, что на оконную процедуру мы так сразу и не выйдем. Поэтому, чтобы посмотреть, что творится в AfxWinMain, мы поставим точку останова и, затем, зайдём в неё! Тыкаем F2, F9, а на адресе 00401DB4 жмём F7, F8 и мы на месте). Но давайте вспомним, что у нас сэмпл не запакованный и не будем тратить лишнее время, так как нас интересует лишь установить факт вредоносности. Поэтому поступим следующим образом: откроем импорты, найдём нам интересные функции, по кросс ссылкам перейдём в места, которые их используют и проанализируем код. Вот, что показала IDA мне в импортах:
На скрине подсвечены наиболее подозрительные функции. Проанализировав код, можно понять, что цепочка основных действий делается в процедурине по адресу 00401330. Начало Sub_401330 довольно интересное:
Первым делом получается текущая директория (0040136A), вызовом GetCurrentDirectoryW, далее, может показаться, что конструируется строка CurDir\RECYCLER\temp.tmp, где CurDir — текущая директория, но присмотритесь внимательно:
От полученной текущей директории требуются только первые 3 символа. Таким образом получается текущий диск. Метод довольно интересный, обычно в таком случае используется функция splitpath. В общем по адресу 00401389 функция wcscat конструирует строку: «C:\RECYCLER\temp.tmp». Далее снова вызывается GetCurrentDirectoryW, после чего полученная строка преобразуется в строку типа CString. Уже в ней вызывается метод Right(1), который возвращает подстроку справа. В данном случае — последнюю букву в строке текущей директории. Всё-таки интересно наблюдать за стилем программирования у разных людей. Обычно, чтобы получить последний символ, используют смещение на strlen-1. Тогда бы не потребовалось создавать новый объект CString. Далее идёт проверка на то, стоит ли в конце символ «\» или нет. Хз, зачем так делать, ведь и так ясно, что GetCurrentDirectoryW возвращает строку без слеша. Если слеша нет, то он прибавляется. Далее продолжается конструирование строки.
Добавляется туда строка по адресу 403198. Если посмотреть её, то увидим вот что:
Попытка преобразовать её в Unicode не заканчивается успехом. Но, если попробовать снова, но с другой кодировкой? Жмём Alt+A, в появившемся окне внизу жмём кнопку Change encoding и у нас появляется небольшой выбор.
Выбираем UTF-16LE, жмём «Ок», в первом окне жмём кнопку «Unicode» и:
Видим, что непонятная строка преобразовалась в абсолютно читабельный вид — в поздравление с Пасхой! В общем, далее в листинге видно, что получается строка вида «CurDir\Со светлым праздником Пасхи». Затем создаётся соответствующая папка, далее добавляется подстрока «explorer /e, »
После идёт вызов ShellExecute(NULL, «explorer»,»CurDir\Со светлым праздником Пасхи»,0,0,5). Это запустит нам проводник с новосозданной папкой. Далее идёт получение темповской папки, и создание в ней новой, с именем «Update». После чего, вызывается sub_4018A0.
sub_4018A0 принимает один параметр. Суть её в следующем: Записать в реестр «HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\User Shell Folders\Common Startup» строку «%Temp%\Update». Таким образом превратить папку Update в папку — автозагрузку. Тут интересно то, что чуваки опять запутались в лишних слешах) Ну да, у них проблема с этим :-).
Далее конструируется строка «%Temp%\Update\temp.exe» и строки «CurDir\Со светлым праздником Пасхи\Со светлым праздником Пасхи №1.jpg»,»CurDir\Со светлым праздником Пасхи\Со светлым праздником Пасхи №2.jpg»,»CurDir\Со светлым праздником Пасхи\Со светлым праздником Пасхи №3.jpg»,»CurDir\Со светлым праздником Пасхи\Со светлым праздником Пасхи №4.jpg». Бросается в глаза нелепый код. ну зачем хранить строку «Со светлым праздником Пасхи №N.jpg» n раз, когда можно было бы в цикле подставить нужную циферку?! Дальше больше!
Тут идёт извлечение ресурсов, сначала в папку Update, извлекается ресурс с номером 219, помните его? Затем, четыре картинки в «CurDir\Со светлым праздником Пасхи», после чего дроппер самоудаляется. На этом и завершается данная процедура, а с ней и функционал нашего дроппера. Далее нам предстоит разобраться с извлечённым файлом temp.exe.
Итог: образец MD5: 6107A446E5310E03BFAECC20D1603F1D можно к отнести к классу вредоносных программ типа «дроппер». Его задачей является установка в системе исполняемого файла, который находится в ресурсах. Установка заключается в том, что извлекаемый ресурс прописывается в автозапуск и дропается в тепмовскую папку. Для отвода глаз, также дропаются в текущую папку 4 jpg файла. Работать «начинка» будет только после следующей загрузки системы.
Анализ начинки трояна — дроппера
Начинка дроппера: temp.exe MD5: 5BB8BE2718AD17D371A142298E6A99DB, является исполняемым файлом. Так же смотрим ресурсы:
Тут вырисовывается интересная картина: ресурс с номером 101 так же является исполняемым файлом. Так что придётся его выдернуть и разревёрсить, но, сначала, займёмся собственно самим сэмплом. Открываем его в IDA.
Мы тут видим, что авторы зловреда отошли от школьного метода использования формочек и написали вредоносик без них! Вот молодцы-то! Нам же легче будет анализировать. Кстати, листинг очень приятный и чистый. Интересно, что по адресу 00402326 вызывается GetInputState, которая в eax возвратит 1, если в очереди сообщений есть сообщения, связанные с мышкой или клавой. Но её результат нигде не сохраняется, а следующий вызов GetModuleHandleA затрёт его. В общем, быдлокод какой-то :-). Далее всё банально, получаются адреса нужных функций, после чего запускается процедура ThreadProc в отдельном потоке. Далее ожидается завершение потока в течении 500 мл секунд. Давайте посмотрим, что в потоке творится.
А в потоке у нас следующее: первым делом проверяется дескриптор окна на валидность. Если он — 0, значит окно ещё не создалось. В этом случае сразу поток завершается. Если дескриптор окна не 0, то, по адресу 00401760 вызывается функция, от результата которой зависит, будет ли поток дальше выполняться или отправит своему окну сообщение с номером 2 и завершится. Эту функцию я назвал Init. Если всё ок, то конструируется строка: «X:\Windows\System32\360SoftMgr.cpl», где X — буква диска, на котором установлена текущая ось. После чего вызывается GetFileAttributesA с данной строкой. Данная функция возвратит -1, в случае отсутствия директории или файла, что и проверяется по адресу 004017D9.
Если существует файл 360SoftMgr.cpl в системной папке, то отправляется себе сообщение с кодом 0x804. Иначе, код сообщения будет равен 0x807 соответственно. Осталось рассмотреть процедуру Init, которая вызывается в данном потоке.
Обратите внимание на функцию sub_4024B0, которая несколько раз вызывается и принимает в качестве параметров — адрес загруженного модуля и имя какой-нибудь функции. После чего в переменную записывается результат работы sub_4024B0. Не трудно догадаться, что работа sub_4024B0 — получить адрес нужной функции! Давайте убедимся в этом, откроем её.
Ну, тут сразу видно, что дальше идёт получение адреса функции путём ручного парсинга таблицы экспорта. Сначала определяется смещение до NT заголовка. Его адрес находится по смещению 0x3C. Далее … короче говоря, тут всё ясно. В Init определяются адреса следующих функций: RtlUnicodeStringToAnsiString, RtlInitUnicodeString, RtlAnsiStringToUnicodeString, RtlInitAnsiString, DeleteIPAddress, AddIPAddress, GetInterfaceInfo. Функции принадлежат либо ntdll.dl, либо iphlpapi.dll. Если у нас определились все библиотеки, то функция вернёт 1, то есть true. Итак, в одтельном потоке идёт определение адресов нужных нам функций и проверка на существование файла 360SoftMgr.cpl в системной папке.
После этого, по листингу видно, что создаётся скрытое окно с именем класса «Setup» и программа зацикливается в цикле оконных сообщений. В общем всё, как и должно быть. Нас интересует только оконная процедура. Рассмотрим её. Оконная процедура, на нашу радость, не большая. Обрабатывает она 5 сообщений с номерами: 2, 0x804, 0x805, 0x806, 0x807.
Если сообщение равно 2, то зловредик завершается. Если вы помните, то данное сообщение посылается в случае, если функция Init не определила адреса всех нужных функций. В случае, если сообщение равно 0x804 (существует файл 360SoftMgr.cpl), то в отдельном потоке выполняется sub_401860. Её задача в следующем: если в текущем пути файла есть подстрока — services.exe, то отправляется сообщение с кодом 0x806. Иначе — в sub_402AE0 текущий путь конвертируется в Unicode строку. Причём делается это довольно интересным способом — через вызов последовательности двух функций: RtlInitAnsiString и RtlAnsiStringToUnicodeString. Первая — инициализирует ansi строку из массива символов, вторая — конвертирует полученную строку в Unicode. Лично для меня такой способ был новый. Обычно, для такой цели используется WideCharToMultiByte. Далее в реестре HKCU\Console создаётся ключ «MoZhe» в который пишется текущий путь в формате Unicode. После этого текущее окно становится видимым и вызывается sub_401647, после которой идёт запрос на завершение текущего процесса. sub_401647 представляет дня нас интерес.
Обработка сообщения 0x807
Считываются ресурсы 513 и 514 из InFormation каталога, далее в 514 ресурсе ищется сигнатура «()», если она существует, то обрезается нулём. Дальше идёт работа с начала и до этого нуля.
После этого, данный промежуток копируется в другое место и в нём ищется разделитель «|». Если он найден, то вместо него ставится 0, и теперешний участок расшифровывается функцией
Строка «SINmbHl2hH04ZX18gXk4R31mgXmEOGJthXZ9ZjhHfWZqgXd9GA==» преобразуется в «Portable Media Serial Number Service». Тоже самое делается со строкой «Rn1sZoF9an1nOGyAfThnfWaBeYQ4gm2Fdn1mOIN6OHmCcThog2ZseXaEfTiFfXyBeThohHlxfWY4d4OCgn13bH18OGyDOGyAgWc4d4OFaG1sfWZCOGF6OGyAgWc4Z31maoF3fTiBZzhnbINoaH18RDhoZoNsfXdsfXw4d4OCbH2CbDiFgXuAbDiCg2w4dn04fINrgjiEg3l8fXw4bIM4bIB9OHx9aoF3fUIY». Она преобразуется в «Retrieves the serial number of any portable media player connecte d to this computer. If this service is stopped, protected content might not be down loaded to the device.». Сразу после этого строки преобразуются в Unicode строки с аналогичным содержимым. После этого, в sub_401E30 создаётся сервис с этими параметрами. В данной процедуре создаётся ключ HKLM\SYSTEM\CurrentControlSet\Services\WmdmPmSN. Для нормальной работы сервиса, требуется там создать ещё один подраздел — Parameters. Тут же сперва создаётся ключ с описанием новой службы. Далее конструируется строка такого вида: «X:\Windows\system32\WmdmPmSN.dll».WmdmPmSN.dll — имя dll, в которой будет находиться рабочий код службы. После этого, собственно, и создаётся подраздел Parameters. Дальше производится попытка удалить файл c:\reg.tmp. Это делается для того, чтобы извлечь на это место ресурс «HACKFANS» с номером 103. Дальше скрывается окно, которое было показано. После идёт попытка повысить привилегии до того, чтобы экспортнуть содержимое c:\reg.tmp в реестр. Для этого делается следующее:
Тоже самое, что получить привилегии отладчика, только не его :-). После этого, по адресу 004020E4 идёт вызов функции RegRestoreKeyW, которая импортирует в реестр настройки из «c:\reg.tmp». Далее, идёт попытка удалить данный файл и на место него извлечь новый, из ресурсов с номером 104.
После извлечения ресурса 104, проверяется существование «c:\windows\system32\WmdmPmSN.CMD». Снова стоит отметить быдлокодерство малварщиков, так как какого фига вшивать в программный код пути? А если система установлена не на диск C?! Ну так вот, если данный файл есть, то трой создаёт файл по адресу c:\ntldr.sys. Дальше:
идёт переименование файла из «c:\windows\system32\WmdmPmSN.dll» в «c:\windows\system32\WmdmPmSN.bak». Так же регистрируется запрос на переименовывание данного файла после перезагрузки. После чего, наконец-то, извлекается и сама библиотека, которая понадобится для работы службы — «C:\Windows\system32\WmdmPmSN.dll» из «HACKFANS» с номером 101. После извлечения, удаляется c:\ntldr.sys. Честно говоря, не понятные эти телодвижения с данным файлом. Они вызывают лишь улыбку. После всего этого, пытается стартануть готовый к этому сервис. Делает это процедура sub_402A70. Далее, удаляется файл c:\reg.tmp, и ключ в реестре: HKCU\Console\MoZhe. На этом и заканчивается обработка этого сообщения. Разве что ещё проверяется существование файла по «X:\windows\system32\360SoftMgr.cpl». Если он есть, то он удаляется. Далее посылается сообщение, инициирующее завершение своего процесса.
Обработчик сообщения 0x805
Ахха, тут видно, что посылается запрос на вызов обработчика сообщения 0x807, а, затем, в бесконечном цикле программа пытается обнаружить окно с текстом «Windows 文件保护», что переводится c китайского, как «Защита файлов Windows». Если окно обнаружено, то оно скрывается.
Анализ сервиса
MD5: 2B42C5F64AA3C0BAA0ED69E8FB0A8090. Теперь мы знаем, что основой боевой нагрузкой будет служба, рабочий код который находится в динамической библиотеки, извлекаемой из файла temp.exe. Она находится в ресурсе «HACKFANS» с номером 101. Изучим её, открыв в иде. Если опустить все моменты, нужные для инициализации службы и попробовать найти самую «вкусную» процедуру, то, несомненно, ей будет являться Sub_1000CAA0.
Бросается в глаза то, что все строки находятся в перевёрнутом виде, видимо, для того, чтобы сбить сигнатурку. Честно говоря, факт вредоносности уже доказан, поэтому интерес к данному сэмплу начинает постепенно пропадать. Дальше всё идёт как и у обычных бэкдорчиков. Среди основного функционала — скачивание произвольных файлов, связь с админкой, передача подробной информации о машину, клавиатурный шпион. Логи не передаются в открытом виде, а в заксоренном на 0x90.
Также есть возможность подглядывать через web камеру. На этой позитивной ноте, хотелось бы завершить обзор данного зловредика.
If you found an error, highlight it and press Shift + Enter or click here to inform us.
Специально зарегался, чтобы выразить почтение. Респект! Сколько сотен сэмплов нужно отреверсить, чтобы так влегкую потрошить троянцев?
Большое спасибо! Насчёт количества сэмплов, думаю, это чисто индивидуальная величина для каждого. Самое главное — качественно отревёрсить сэмпл. Потом выработается определённая схема, а понимать, что делают некоторые куски кода уже можно будет не вникая в них.