02 September 2010 @ 10:31 am
Удалил все, что нагадили тут боты - по от ста до 700 записей в день, всего более чем 1400.

Удалил ботов из сообчества. Если вас удалили и вы - не бот, пишите.
 
 
10 September 2008 @ 01:01 am
Доброго дня всем.
В сегодняшнем выпуске много технических подробностей. Так что уж извините, если их слишком много :)

Письмо


Итак, начинаем. На входе у нас письмо с текстом "Journalist shot in Georgia! See attached video. Password is 123" и с приложенным файлом "Georgia.zip".

Для более или менее полного анализа нам понадобятся:
- Самый Лучший дизассемблер в мире IDA
- Неплохой Отладчик Windbg
- python 2.5 (строго говоря, подойдет любой, просто у меня 2.5)
- Visual Studio какая-нибудь и Microsoft SDK, чтобы собрать небольшую программу на с++.
- упаковщик программ upx
- ну и чего-то еще по мелочи.

Распаковываем присланный нам файл, и видим, что наши подозрения оправданы: видео там и рядом не ночевало.
joined.exe (md5:607af96b03addadf28cf9280701df191)
Dr.Web: Trojan.Packed.151
Kaspersky: Trojan-Downloader.Win32.Agent.abqe

Read more... )

Итого


"Большой" троянский конь внутри себя как ресурс содержит "маленького" троянского жеребенка. Этот вирус, всего в полтора килобайта размером (это две страницы текста у меня в редакторе), умеет скачивать и запускать на выполнение другой, более опасный вирус. Сделан он в стиле шелкода, прямо "по учебнику". Большая часть используемых техник подробно рассмотрена в статье Evolving Shell Code. Троян делает небольшой финт ушами, и вместо реализации сетевых соединений, http протокола, и проч., просто использует сервис windows под названием Background intelligent transfer service (именно это позволяет уменьшить размер кода). Системные функции вызываются не по прямым адресам, а функции, которые используются для работы с файлами, типа CreateFile, не вызываются вообще. Есть большое сомнение, что какой-либо из существующих антивирусов способен опознать такую зловредную функциональность одним только эвристическим анализом. Скачивает эта крошка файл с грациозным названем filebyaka.exe, что говорит о сам знаете каких корнях.

Файлы, использованные при анализе, можно найти по этому адресу

На этой оптимистичной ноте прощаюсь с вами. Не запускайте незнакомые файлы. Берегите себя!
 
 
05 June 2008 @ 02:04 am
Нудные технические подробности, без которых никак не обойтись, выделены знаком параграфа: ¶. Надеюсь, их можно пропускать без потери смысла изложения.

Часть первая. Высадка


Как это случается часто, в последнее время, новые вирусы приходят прямиком в почту, - быстро, удобно и совсем не надо напрягаться. Последний вирус прислал себя вот в таком вот письме:
From: "Shauna Hoover" olwen.davie@mairie-paris.fr
To: xxx@xxx.xx
Subject: Paris Hilton

Good afternoon, buddy.

I found nude Angelina Jolie!
See in attachment!
Bye.

Поначалу сбивает, конечно, с толку, почему тема письма про П. Хилтон, а внутри - про А. Джоли, но.. войдем все-же в положение сетевых злодеев! Работа у них нервная, бывает и ошибаются. Хорошо, что хоть вообще письма до адресатов доходят, постарались.

Присоединенный файл назвается xjolie.scr.zip, и внутри содержит "как бы" скринсейвер xjolie.scr. Файл подозрительный: кода мало, всего три функции, данных тоже почти нет. На скринсейвер не тянет, и для вируса маловато. Онлайн сканнер касперского обозначает файл, как зараженный вирусом "Trojan.Win32.Pakes.cyu".

¶ В самом начале выполнения натыкаемся на сюрприз: программа вызывает функцию NtDeleteValueKey (используя KiFastCallEntry, который, по сути есть инструкция sysenter), причем передает ей в качестве аргументов неинициализированные локальные переменные, в которых лежит всякий мусор. Поэтому NtDeleteValueKey в 99.9 процентах случаев должна возвращать STATUS_INVALID_HANDLE. Это значение (0xC0000008) используется как стартовое, из которого путем долгих вычислений (многочисленные "мусорные" арифметические операции), программа получает некий нужный ей адрес. Задача системного вызова здесь, видимо, - обмануть автоматические анализаторы и прочие антивирусы.

Кстати, работающий в тот момент симантек даже и не пикнул, и упорно твердил "Clean"; так что в очередной раз уверяюсь, что надеяться на эвристический анализ в ближайшие лет двенадцать не стоит.

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

После того, как программа расшифровала себя, делаем дамп:
.writemem unpacked0.dmp 00402088 L00009400
, записывая расшифрованный файл на диск.


Этот блок данных на самом деле также является полноценным исполняемым файлом, который мы будем называть unpacked0. Вот эта программа уже и есть настоящий дроппер, целью которого является установка вредоносного ПО на ЭВМ жертвы.

Структура кода дроппера довольно понятна и проста, написан, по-видимому, на "С". Файл внутри содержит строку "d:\programs\siberia\install\objfre_wxp_x86\i386\Install.pdb". Вряд ли это досадное упущение. Может быть, автор пытается таким образом сообщить антивирусным компаниям, "рекомендованное производителем" официальное название вируса?



Инсталляция


Проверка версии ОС. Если честно, то удивил меня этот кусок кода.
¶ В псевдокоде это выглядит так:

if Version.Major = 5
  if Version.Minor = 0
    is_win2k = 1
  else
    is_win2k = 0
else
  is_win2k = 0
is_win2k_temp = is_win2k

После чего идет еще три блока один в один: для XP и 2003 server. Зачем столько переменных и сколько сравнений? Короче, я эти танцы с бубном не понял.

Программа проверяет текущую версию ОС, и заканчивает свою работу, если это не Windows 2000, XP или 2003 server.

Базовый адрес. unpacked0, как и полагается правильному дестантнику, выясняет, где же он, в конце концов очутился. Для этого используется один самых простых методов поиска, основанный на том, что начало загруженного образа совпадает с началом страницы памяти. Ее размер умолчанию на наших обычных x86 компьютерах равна четырем килобайтам. Берется текущее место в коде, из него переходим на начало текущей страницы, ищем в начале сигнатуру MZ, если не найдено, переходим на предыдущую страницу.

Таблица импорта. Так как unpacked0 не может опираться на фиксированный базовый адрес, заданный при компиляции, то и таблица импорта должна быть обновлена. Для этого программа разбирает свой собственный заголовок (который находится в самом начале загруженного образа, а адрес его был найден на прошлом шаге), таким же способом разбирает заголовок библиотеки kernel32, находит ее таблцу экспорта, и методом простого сравнивания строк находит две основные функции: LoadLibraryA и GetProcAddress, используя их, загружает все остальные необходимые для его черного дела функции.

Извлечение драйвера. Да, черт возьми, опять драйвер. Вирусы без драйвера, похоже, уже только лохи пишут. Как некоторые уже догадались, тело драйвера содержится в ресурсах у unpacked0. Кстати, файл с драйвером содержит строку "d:\programs\siberia\protect\objfre_wxp_x86\i386\protect.pdb". Тенденция однако...



Тело драйвера копируется в динамически выделенную область памяти, после чего проверяется его контрольная сумма.

Извлечение winnt32.dll. А теперь, - внимание, - финт ушами. Из только что извлеченного драйвера извлекается еще один компонент. Из ресурсов, а как же. Теперь число компонент нашего вируса стало равно четырем: начальный файл xjolie, распакованный инстолер (unpacked0), драйвер и библиотека со скромным названием winnt32.dll.
Общая схема распаковка приведена на рисунке (синий цвет - код, коричневый - ресурсы).
Последовательная распаковка программ

Название "winnt32.dll" не случайно выбрано из "страшных", даже продвинутые пользователи вряд ли решатся удалить такой файл.
¶ 
kernel32!CreateFileA:
7c801a24 8bff            mov     edi,edi
0:000> da poi(esp+4)
0012feac  "C:\WINDOWS\System32\WinNt32.dll"


Если по каким-то причинам, создать такой файл не получается, то дроппер добавляет в конце имени подчеркивание. Этот файл с подчеркиваением будет переименован в нужный после перезагрузки - для этого вызывается функция MoveFileEx с флагом MOVEFILE_DELAY_UNTIL_REBOOT. Это будет сделано опять же под системным аккаунтом и вероятность успеха очень велика.

Настройка winnt32.dll. Собственно, использование библиотеки как основного файла троянца - ход интересный. Антивирусы и пользователи практически не обращают внимания на них, и в принципе, обоснованно: ведь не исполняемый файл, чего там. Но все-таки есть способы заставить систему загрузить библиотку и передать на нее управление. Способ, применяемый данным трояном, довольно оригинален: он использует механизм нотификаций процесса winlogon.

Для того, чтобы включить этот механизм, дроппер добавляет в раздел HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify реестра следующие значения
DLLName: winnt32.dll
StartShell: WLEventStartShell
Impersonate: 0
Asynchronous: 0

(Список возможных параметров с описанием приводится здесь: http://msdn.microsoft.com/en-us/library/aa379402.aspx)

Это вкратце означает, что Winlogon при логине пользователя обязан загрузить winnt32.dll, вызвать у нее функцию WLEventStartShell, синхронно, не используя имперсонализацию - под тем же аккаунтом, под которым работает сам winlogon, то есть SYSTEM. Для пользователя, который будет логиниться, это означает Страшные Вещи.

На этом установка winnt32.dll закончена, и дроппер возвращается обратно к драйверу.

Установка драйвера. Перво-наперво, дроппер пробует подключиться к уже установленному драйверу, используя имя устройства ""\\.\Prot2". Если подключиться не получилось, то сохраняет тело драйвера в файл со случайным именем вида %SystemRoot%\System32\drivers\Wwwdd.sys, где W - заглавная, w - строчные буквы, d - цифры.
kernel32!CreateFileA:
7c801a24 8bff mov edi,edi
0:000> da poi(esp+4)
0012fc94 "C:\WINDOWS\System32\drivers\Hwo84.sys"


После этого драйвер регистрируется и запускается функциями API CreateService-StartService. Также дроппер добавляет нужные строки реестра в разделы
SYSTEM\CurrentControlSet\Control\SafeBoot\Network\
SYSTEM\CurrentControlSet\Control\SafeBoot\Minimal\
SYSTEM\ControlSet002\Services\
SYSTEM\ControlSet001\Services\

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

После чего вызывает cmd.exe с командной строкой /c del FILENAME >> NULL, удаляя себя с компьютера пользователя.


Вывод


Под личиной голой дивы скрывается не просто троян. Это целый программный комплекс из трех программ - инстраллятора, руткит-драйвера и динамической библиотеки режима пользователя. Техники, используемые для внедрения вредоносного кода, просты, действенны и не лишены оригинальности. Но, как всегда, замечу, что при запрещенной записи в %SYSTEMROOT%\system32, инсталлятор обламывается по полной.

Во второй части рассмотрим вредоносный функционал десантированной библиотеки winnt32.dll и ее темного драйвера-защитника.
 
 
16 May 2008 @ 02:17 am

Поделка на коленке

В то время, как я медленно заходил в тупик с желатином, мне пришло письмо примерно следующего содержания:

Уважаемый Х. Ваша кандидатура очень нас заинтересовала, поэтому мы бы не прочь познакомиться поближе. Предварительно вам нужно скачать наш фирменный бланк резюме resume.exe, заполнить его, и отослать нам обратно. С уважением, сетевые злодеи.

Что характерно, линк на резюме был именно так и написан. <a href="resume.exe">resume.exe</a> Они вообще, что ли?

Скачиваем, смотрим. Файл размером 159744 байтов, на первый взгляд запакован. Касперскому программа знакома под именем "Trojan.Win32.Srizbi.a".

Read more... )

Вывод

Srizbi - никакой не троян, а переносчик настоящей вредоносной программы. Его цель - максимально быстро (хоть и получается медленно) выгрузить из своего тела настоящий вирус, запустить его на выполнение, после чего исчезнуть, оставив минимум следов. Код его несложный и необъемный, и даже таким начинающим, как я, довольно просто в нем разобраться. Из-за дурацкой ошибки, вся работа Srizbi идет на смарку: он не проверяет версию операционной системы на соответствие содержащемуся в нем драйверу. В результате система просто отказывается грузить драйвер. Заглянуть в драйвер полезно, там руткит, который прячет файлы, ключи реестра, сетевые соединения и прослушиваемые порты.
 
 
08 May 2008 @ 12:06 am
Итак, желатин. Хм. Снова.

Первое, с чем я столкнулся - отсутствие какой-либо технической информации о желатине. Гугл, естественно, посылает прямиком в википедию [WIKI]. Здесь мы узнаем немногое.

1. Вирус включает зараженные машины в ботнет [WIKI1];
2. Сеть желатина представляет собой модификацию сети Overnet.

Немного истории желатина на русском также содержится в [KASP].

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

Пройдя путь в несколько ссылок, я нашел некое описание сети желатина.[PPT]. Попытки найти готовые реализации клиентов Overnet также увенчались успехом [KADC]. Одного взгляда на библиотеку KadC было достаточно, чтобы узнать смутные черты дизассемблированного кода валентинистого зловреда. Пусть даже и с некоторыми изменениями, но код KadC вполе может являться базой для желатина. Только этой причиной можно объяснить совершенно наглое высказывание специалистов компании McAffee:
"Bot technology is rapidly evolving, often aided and
abetted, unfortunately, by the open-source movement".

[MCAF], также обсуждается в [CNET1] и [ASHIMMY]. Очень хотелось бы обратить внимание товарищей из McAffee, что неплохо бы им расширить свой взгляд на мир, включив в обвинение бравых ученых из MIT, разработавших Kademlia.


Кстати, одним из самых ценных ресурсов оказался [REC]. Там можно взять оригинальную версию одного из самых первых желатинов. Тогда он представлял собой практически обычный :) зашифрованный исполняемый файл, следы деятельности которого тщательно конспирировались руткитовым драйвером. Преимущество первых версий в том, что они не ксорили сообщения, а значит и wireshark сумеет декодировать их в формате edonkey.

Кстати, об "обксореном" трафике. Дело в том, что предпоследний вид желатина (а последний, как мы знаем, распространялся первого апреля), создает обычные сообщения, которые понятны и прошлым модификациям, и клиентам Overnet, кстати. Но перед отправкой он проходится по нему ксором, используя хардкоданную таблицу. Тот факт, что только представители только "валентинистого штамма" способны обработать трафик своих "братьев", свидетельствует об уменьшении размеров ботнета, который строится на данной модификации [HAC]. Были и другие, более ранние данные о том, что бонет разделился на несколько небольших [ZD].

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

Желатин использует сеть Overnet [WIKI2], которая является реализацией идеи Kademlia [WIKI3], модели распределенной хэш-таблицы, разработанной в MIT, это вам не хухры-мухры. Основной боевой единицей сети является узел, peer. Первоочередная задача любого сознательного узла - прежде всего войти в сеть. Для этого у желатина есть список узлов, к которым он пробует подключиться в первую очередь. В первых версиях этот список был захардкодан прямо в теле вируса, в последних - тоже захардкодан в теле, но извлекался и сохранялся в ini файле. Без него, - без файла, - кстати, валентиновый желатин работать отказывается. Адреса узлов "первого круга" записаны примерно а таком виде:

00003D6C8F338A3FDD3DF3648666F55C=BE56062A5DC600
0100A634122F3553A046EC451061927C=4B6EB028151500
02007E238D780D25FD5511285E2E596E=58E941B3100A00


где число до знака разно - это OvernetID (oid), или хэш узла, 128-битовое число, которое генерируется вроде как случайным образом.Про него подробно мы позднее поговорим. После знака идут IP-адрес (BE56062A = BE.56.06.2A = 190.86.5.42), порт (5DC6 = 24006) и последний байт - тип узла.

Первым (и самым часто используемым) сообщением, которое новый узел посылает другим узлам, является "PUBLICIZE". Это своеобразный пинг, с помощью которого стороны удостоверяются в доступности друг друга. Это сообщение в некоторых источниках прочно называют "HELLO". Внутри него посылается oid узла-отправителя, его IP адрес, порт и тип. Вобщем, такие же данные, как и в ini файле.

После того, как новенький узел удостоверился в том, что адресат доступен и ответил (сообщение "PUBLICIZE_ACK", длиной два байта - заголовок и код сообщения), он посылает запрос на CONNECT. По структуре сообщение идентично сообщению "PUBLICIZE". В ответ на это сообщение принимающая сторона

1. Отправляет список узлов, известных ему и
2. добавляет отправителя в этот список (и, соответственно, будет посылать адрес "новенького" в ответ на новые "CONNECT").

Новый узел добавляет адреса, которые он получил, в список своих хостов. Если посчитать на пальцах, то diperto.ini в составе валентинистого желатина содержал адреса 823 узлов. И если хотя бы половина ответила двадцатью адресами, то... К счастью, желатин написан "правильно". Размер списка известных узлов ограничен 1024-мя элементами.

Следующим шагом выясняется, под каким адресом наш узел выглядит для узла назначения. Для этого желатин открывает tcp порт и начинает его слушать. Помер порта он передает в сообщении IP_REQ, на что получивший это сообщение отвечает сообщением IP_REQ_RES с адресом, от которого он это сообщение получил. Сделано это для обхода ограничений NAT и фаерволов.

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

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

Итак, последовал обмен сообщениями вида (Z - Желатин, H - хост):
Z → PUBLICIZE → H
Z ← PUBLISIZE_ASK ← H
Z → CONNECT → H
Z ← CONNECT_RES ← H
Z → IP_REQ → H
Z ← IP_REQ_RES ← H

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

Хост, которому нужно опубликовать некие данные, вычисляет MD4-хэш содержимого файла (или ключевых слов, в зависимости от того, какая информация публикуется), затем ищет узел, OID которого наиболее близок к этому хэшу. (Степень близости определяется результатом операции XOR, которая, как мы знаем, возвращает ноль для одинаковых битов. То есть для абсолютно одинаковых хэшей мы получим ноль). Для этого публикующий посылает всем хостам из своего списка сообщение SEARCH, в котором содержится нужный хэш. Получившие такое сообщение узлы находят несколько(?) адресов из своих списков, в порядке убывания близости и отсылают обратно этот список с сообщением SEARCH_NEXT. Поиск заканчивается, если узел отправляет внутри SEARCH_NEXT свой собственный адрес. Отдельно публикуются мета-данные и данные об узле, с которого можно скачать этот файл.

Точно таким же образом, но в другую сторону, происходит и поиск. Вычисляется определенным образом хэш, и затем обмен SEARCH-SEARCH_NEXT, после чего выясняются параметры подключения по TCP, после чего файл скачивается.

В простейшем варианте желатин находит нужный хост, скачивает с него список емейлов и начинает не по-дестки спамить.

Про то, что конкретно и как ищет желатин в сети, поговорим в следующий раз.

Литературка.

ASHIMMY. McAfee's open source statements are fighting words to Matt Asay. http://www.stillsecureafteralltheseyears.com/ashimmy/open_source/index.html
CNET1. McAfee's libel against open source. http://www.cnet.com/8301-13505_1-9917989-16.html
HAC. Ботнеты становятся меньше. http://www.xakep.ru/post/40401/default.asp
KADC. KadC library. http://kadc.sourceforge.net/
KASP. Современные информационные угрозы, I квартал 2008//Шторм продолжается. http://www.viruslist.com/ru/analysis?pubid=204007605
MCAF. Killing Botnets. http://www.mcafee.com/us/local_content/white_papers/wp_botnet.pdf
PPT. Brandon Enright. http://noh.ucsd.edu/~bmenrigh/exposing_storm.ppt
REC. Peacomm.C - Cracking the nutshell. http://www.reconstructer.org/papers/Peacomm.C%20-%20Cracking%20the%20nutshell.zip
SCH. The Storm Worm. http://www.schneier.com/blog/archives/2007/10/the_storm_worm.html
WIKI. Storm Worm. vhttp://en.wikipedia.org/wiki/Storm_Worm
WIKI1. Storm botnet. http://en.wikipedia.org/wiki/Storm_botnet
WIKI2. Overnet. http://en.wikipedia.org/wiki/Overnet
WIKI3. Kademlia. http://en.wikipedia.org/wiki/Kademlia
ZD. Storm Worm botnet partitions for sale. http://blogs.zdnet.com/security/?p=592&tag=nl.e539
 
 

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

В моем случае было нечно вроде

<meta http-equiv="refresh" content="1;url='valentine.exe'">
...
<a href="valentine.exe">blah-blah</a>

Неприкрытое приглашение стать новым пользователем вируса. Также аккуратно скачав valentine.exe, и переменовав его в .txt, чтобы ненароком не запустить, можно поковырять его изнутри.

Онлайн файл-сканнер Касперского определяет этот файл как зараженный вирусом "Email-Worm.Win32.Zhelatin.vg".

Общая схема работы вируса такова:
1. Оригинальный "valentine.exe" извлекает из своего тела кусок кода, который сначала расшифровывается, а затем распаковывается с помощью функции RtlUncompressBuffer. Этот код сохраняется в файле %SYSTEMROOT%/system32/diperto$p-$t.sys, где $p и $t - идентификаторы процесса и потока (в шестнадцатеричном формате) "valentine.exe", записывающего файл. Также создается файл  %SYSTEMROOT%/system32/diperto.ini:
[config]
[local]
uport=1211
[peers]

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

2. "valentine.exe" загружает драйвет "diperto.sys", используя функции Windows API, после чего прекращает свою работу.

3. "diperto.sys" создает устройство под названием "DRV_MODULE_MYDR", а также эвент под именем "Ir<fk^7k". Все это можно увидеть с помощью WinObj.exe

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

5. Затем находит процесс под названием "services.exe" - котнролер служб Windows, подсоединяется к нему, выделяет в адресном пространстве процесса новый блок памяти, куда записывает расшифрованный кусок кода.

6. Для передачи управления вредоносному коду, драйвер использует APC - asynchronous procedure call. Используя функцию KeInsertQueueApc он ставит в очередь на исполнение асинхронный вызов, который будет "доставлен" после любого следующего системного вызова из процесса-жертвы. После этого драйвер прекращает свою работу.

7. Вкратце все это выглядит так:
valentive --> расшифровывает кусок себя --> diperto.sys -->  расшифровывает кусок себя --> services.exe.

На данном этапе возникает два вопроса: а) к чему все эти манипуляции? б) как нам защититься это этого зверя?

Ответ на второй вопрос, в общем-то очевиден. Достаточно закрыть доступ на запись %SYSTEMROOT%/system32, в результате самый первый шаг обламывается и вирус идет лесом. Но, представим на минуту, что он мутировал, и умеет записывать файл в любое другое место. Тогда единственное, что может нас спасти - отобрать у себя право на регистрацию и загрузку драйверов (что, по сути, аналогично праву записи в раздел реестра "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services").

По умолчанию, такие права есть только у группы Adminisrtrators.

Ну и теперь самый интересный вопрос - зачем столько телодвижений? А вот зачем. Обычно подобная операция внедрения кода и запуска его на выполнение производится с помощью связки "OpenProceess - VirtualAllocEx - WriteProcessMemory - CreateRemoteThread", на которую антивирусы обращают пристальное внимание. В нашем случае цепочка выглядит так: "KeAttachProcess - ZwAllocateVirtualMemory - rep movds - KeInsertQueueApc". "rep movsd" означает, что вредоносный код копируется напрямую в пространство жертвы, не используя никакие функции вообще. На сегодняшний день выявить такого рода проникновение антивирусы не в состоянии.



Немного статистики:
- размер оригинального файла: 117 248 байтов.
- размер файла драйвера: 129 920 байтов.
- оригинальный файл скопилирован MINGW GCC. Который, кстати, помогает выворачивать мозг наизнанку, когда пытаешься отследить вызовы функций в незнакомом стиле
mov [esp], a
mov [esp+4], b
mov [esp+8], c
call F                  ; calls F(a, b, c);

- оригинальный файл нашпигован ложными вызовами вроде CreateWaitableTimer(0, 0, 0); или IsBadHugeReadPtr(0, 0); или DeleteAtom(0). Не совсем понятно, кого они призваны сбить с толку - антивирусы или человека.

Во второй части рассмотрим собственно то, как работает вирус, внедренный в процесс serives.exe.

 
 
...также известное как System.CodeDom.

Штука забористая, и поначалу выворачивает мозг наизнанку. Взять хотя бы пример из МСДН:
// Declares and initializes an integer variable named testInt.
CodeVariableDeclarationStatement testInt = new CodeVariableDeclarationStatement(typeof(int), "testInt", new CodePrimitiveExpression(0) );

// Creates a for loop that sets testInt to 0 and continues incrementing testInt by 1 each loop until testInt is not less than 10.
CodeIterationStatement forLoop = new CodeIterationStatement(
    // initStatement parameter for pre-loop initialization.
    new CodeAssignStatement( new CodeVariableReferenceExpression("testInt"), new CodePrimitiveExpression(1) ),
    // testExpression parameter to test for continuation condition.
    new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("testInt"), 
        CodeBinaryOperatorType.LessThan, new CodePrimitiveExpression(10) ),
    // incrementStatement parameter indicates statement to execute after each iteration.
    new CodeAssignStatement( new CodeVariableReferenceExpression("testInt"), new CodeBinaryOperatorExpression( 
        new CodeVariableReferenceExpression("testInt"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1) )),
    // statements parameter contains the statements to execute during each interation of the loop.
    // Each loop iteration the value of the integer is output using the Console.WriteLine method.
    new CodeStatement[] { new CodeExpressionStatement( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( 
        new CodeTypeReferenceExpression("Console"), "WriteLine" ), new CodeMethodInvokeExpression( 
        new CodeVariableReferenceExpression("testInt"), "ToString" ) ) ) } );


Компилируется этот ктулхёнок в три строки:
// A C# code generator produces the following source code for the preceeding example code:
//     int testInt = 0;
//     for (testInt = 1; (testInt < 10); testInt = (testInt + 1)) {
//        Console.WriteLine(testInt.ToString());


Нас, непрограммистов на лиспе, пять скобок в конце предложения, честно говоря, пугают.

CodeDom не поддерживает свойство readonly для филдов. Что, впрочем запросто обходится с помощью такой дурацкой конструкции:

CodeMemberField fld = new CodeMemberField("readonly string", "_name");

где "readonly" мы внесли в название типа. Получаем:
private readonly string _name;


Выходит, что кодедом нихрена особо не проверяет, а работает просто как StringBuilder.

Также в кодедом есть какой-то странный глюк со скобками. Вот, например:
for (int i = 0; (i < Count); i = (i + 1))

Или вот:
if ((MD.Ord == null))


А вот чего действительно не хватает, так это генератора для блока lock. Что тоже обходится, правда не так запросто:
try
{
    System.Threading.Monitor.Enter(_sync);
    //...
}
finally
{
    System.Threading.Monitor.Exit(_sync);
}
Tags: ,
 
 
13 November 2007 @ 10:48 am
Сейчас мы будем делать так, чтобы вместо Интернет Эксплорера у нас вегда запускался Firefox:

Делай раз: Открываем regedit, находим в нем секцию HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\.
Делай два: Создаем ключ "iexplore.exe" (если его еще нет).
Делай три: Создаем новую строку здесь (string value) под названием "Debugger". Указываем значение: "d:\ff.bat". Закрываем regedit.
Делай четыре: создаем файл d:\ff.bat со следующим содержанием:
---
@echo off
start "dummy" /b "D:\Program Files\Mozilla Firefox\firefox.exe" %2 %3 %4
@echo on
---

("---" - границы содержания, их в файле быть не должно, вместо D:\Program Files\Mozilla Firefox\firefox.exe пишем путь к фаерфоксу).

Делай пять: кликаем по иконке эксплорера и видим Firefox.
Можно оправиться и закурить.
Tags:
 
 
08 November 2007 @ 11:51 pm
Циклы в .net сделаны по следующей схеме:
initialize, goto check
start:
  cycle body
  index op //i.e., i++
check:
  if index is in bounds, goto start

На обычный цикл это отображается так:
for(int i = 0; i < array.Length; i++)
  Console.WriteLine("{0}", array[i]);
//initialization ($len - временная переменная).
  $len = array.Length; 
  int i = 0;
  goto check;
start:
  $item = array[i];
  Console.WriteLine("{0}", $item);
  i++;
check:
  if (i < $len)
    goto start;

Отличие foreach от for в том, что для типов, наследованных от IEnumerable, операция check вместо приращения и проверки переменной использует IEnumerator.MoveNext(), а start вместо получения элемента по индексу - IEnumerator.Current.
А теперь -слайды )
Tags:
 
 
08 November 2007 @ 02:08 am


Испытательный стенд:
- .net framework 2.0.
- cl 14.00.50727.42.
- набор из семи функций, содержащих различные примитивные операции.
- дизассемблер.
- дебаггер.

С# программа компилировалась как csc /debug- /o+;
C - cl /Oity /Gs /Wall /Gz (от /Ox пришлось отказаться, так как все функции в результате отпимизации оказывались встраиваемыми).

Результаты )

Вывод:

Трудно сделать какой-то общий вывод на таком небольшом наборе операций (мы проделаем еще несколько тестов). Частный вывод на данном этапе таков. В .net по умолчанию используется аналог сишного __fastcall, что снижает затраты на работу с аргументами функций. Зато cl оптимизирует лучше. Jitted код в итоге получается мало отличающийся от сишного, так что на C# можно даже попробовать сделать графическую или криптографическую библиотеку. Самая первая функция (if0) выглядит неоправданно большой - обращение к библиотечной функции Console.WriteLine тянет за собой некоторые артефакты. Есть подозрения, что с более интенсивным использованием библиотечных функций сложность и объем кода будут возрастать - это планируется проверить позже. Следующим этапом надо будет сравнить а) работу с объектами; б) исключения; в) ...
Tags: