Введение
Что по своей сути плугин? Это некий код, который вирус выкачивает и подсоединяет к себе, вроде так да? Давайте посмотрим на этот код ближе, мы видим call [x], проверка чего-то, потом либо call [y] либо call [z], и снова проверки, и т.д. А все эти call'ы в конечном счете приводят к вызову API функций. Получается, что львиную долю работы делают именно апишные функции, а остальной код составляет логику их связывания, т.е. все, что делает плугин это просто добавление новой логики в готовый вирус, бывают и исключения, скажем сложные алгоритмы шифрования или пермутации делают апишные вызовы только в начале и в конце своей работы. Юзерская тачка напичкана готовыми функциями, которые только и ждут, чтобы их вызвали, нам остается только вызывать их в нужной последовательности, некоторые из этих последовательностей называются прикладными программами, а другие вирусами. Таким образом, вирус отличается от обычной программы своей логикой, а не своим бинарным кодом, удивительно :) Если антивирус (эвристик) усматривает какую-то нездоровую последовательность действий программы он приходит к выводу, что это вирус. Плугинная технология предлагает частую смену логики, вирус постоянно обновляет себя расширяя и замещая свою функциональность, аверы, просто, не успевают находить новые сигнатуры, засовывать их в новые базы, а юзеры эти новые базы скачивать. Все это будет работать до тех пор, пока не появятся эвристики способные на нетривиальную тотальную эмуляцию кода. Зачем аверу париться искать сигнатуру, если можно выловить из кода всего на всего одно действие - запись в экзешник и сразу ясно, что это вирус. Я не буду затрагивать проблемы резидентных мониторов, которым и анализировать ни чего не надо, вызовы к ним сами в лапы идут. Из выше сказанного получаем следующее: вирус не должен обладать вирусной логикой. Парадокс. Если у вируса нет соответствующей логики, то, как он будет функционировать? Можно эту логику хитро прятать (полиморфики) или сложным образом изменять инструкции ее образующие (пермутация), а можно взять и отказаться от ее хранения. Нет логики - нет вируса. VRPC VRPC позволяет вызывать любые функции, хранящиеся в библиотеках удаленного компьютера. Делается это практически также просто, как и вызов функции из локальной библиотеки, даже немного проще - не нужно соблюдать обратный порядок запушивания параметров в стек при вызовах в формате stdcall, и очищать стек при cdecl (в стеке все равно ни чего полезного оказаться не может). Происходит это следующим образом: настраиваем поля структуры описывающей удаленный хост и библиотеку, в ESI заносим указатель на имя функции, в ECX количество ее параметров, пушим параметры в стек и делаем вызов, естественно, что на хосте должен работать наш сервер. Результат работы функции как обычно возвращается EAX, но следует учесть, что все возвращаемые адреса указывают в адресное пространство удаленного процесса. Например: ; структура вызова vrpc mov EDI, offset vrpc_cs ; порт сервера mov [EDI.vrpc_call_addr.sin_port], VRPC_SERV_PORT ; адресс сервера 127.0.0.1 mov [EDI.vrpc_call_addr.sin_addr], 0100007Fh ; имя нужной библиотека mov [EDI.vrpc_call_lib], offset kern32 ; формат передачи параметров на сервере: mov [EDI.vrpc_call_cnv], 0 ; тип функции: mov [EDI.vrpc_call_kind], 0 ; бипкнем mov ESI, offset fBeep mov ECX, 2 push 1000 push 200 call vrpc_call Все удаленные функции поделены на три типа:
Поддерживаются три формата передачи параметров:
Что позволяет вызывать любые функции, в том числе написанные на Delphi с их стандартным соглашением передачи параметров register (немного в регистры, немного в стек:). Существуют также две функции, отвечающие за передачу данных:
Думаю у троянистов уже загорелись глаза и мышь выпадает из рук. ;) Как использовать?
Происходит обмен данными между машинами, следовательно нужен протокол обмена данными, вот я его и опишу. Сервер постоянно ожидает подключения от клиента, как только оно произошло он ожидает пакет, котороый описывает функцию для выполнения, после чего происходит отконнекчивание и сервер переходит в состояние ожидания следующего подключения. Можно было реализовать и постоянное соеденение, но в таком случае сервер на долгое время становится недоступен для других клиентов, т.к. наш сервер однопоточный, т.е. одновременно может обрабатываться только одно соединение, такой же механизм используется большинством серверов HTTP. Это дает возможность выделять под серевер неособо мощные тачки. После оработки пакета чтения сервер отсылает клиенту запрошенные данные, а после обработки пакета выполнения сервер отсылает клиенту результат работы функции, который она возвращает в EAX. Формат пакета такой: write 0: byte, команда записи addr: dword, адрес буфера или 0 для записи во внутренний буфер len: dword, длинна данных data: byte[len], данные read 1: byte, команда чтения addr: dword, адрес буфера или 0 для чтения из внутреннего буфера len: dword, сколько читать exec 2: byte, команда исполнения kind: byte, тип функции: 0 - внешняя 1 - внутренняя 2 - адрес conv: byte, конвенция вызова: 0 - stdcall, WINAPI 1 - cdecl 2 - register, fastcall fn: dword, kind=0, длинна имени функции kind=1, идентификатор внутренней функции kind=2, адрес функции pcnt: byte, кол-во параметров prms: dword[pcnt], параметры fnn: byte[fn], kind=0, имя функции kind=1,2, отсутствует libl: byte, kind=0, длинна имени библиотеки kind=1,2, отсутствует libn: byte[libl], kind=0, имя библиотеки kind=1,2, отсутствует Как только закончится конкурс на тему поиска апишных функций без использования API, формат пакета будет усоершенствован для поддержки вызова функции по хешу имени. Все что должен делать клиент это посылать пакеты в правильном формате, что бы серевер мог правильно их интерпретировать и правильно выполнять те действия которые они описывают. А зачем это ВеРеПеЦе вообще нужно? Продемонстрирую на наглядном примере. Даете вы дискету с сервером VRPC своему недругу или, быть может, другу, а может и никому не даете (все зависит от типа личности). Идете в интернет клуб, ждете пока жертва объявиться в инете, затем исполняете такую последовательность вызовов функций, которая приводит к заражению всех экзешников кодом сервера на его тачке. Через некоторое время жертва вкупается, что чего-то с его софтом не так и отсылает неработающую копию своей любимой игры, весом 500 мегатонн, на мыло аверам, те долго капаются во внутренностях игрушки и не находят там ни какого кода, который мог бы хоть чего-то заразить. А юзер в своем письме накатал, что мол прям все позаражалось у него и комп постоянно только и делает, что винтом трещит выискивая новую жертву. Тут у аверов и приключится приступ неверия в реальность всего происходящего и ощутят оные, что разум их подвешен в пустоте. :) Вы залегаете на недельку на дно, затем опять идете в клуб, сканите IP-шники местных провайдеров и замечаете что ваш сервак уже на 10-ти тачках. Заключение Все это конечно далеко от реальности, ведь по сути код сервера тоже имеет сигнатуру и так же может быть обнаружен, но и цель достигнута - возможно создать вирус не хранящий собственную логику, который совершенно чист с эвристической точки зрения. Ни что не мешает при заражении отпермутировать и стать чистым и с сигнатурной точки зрения, а ежели еще прибавить UEP и перемешивание с жертвой... 15.08.02 |