PDA

View Full Version : آموزش: BruteForce کردن یک تابع، معرفی روش و توضیح روال مربوطه



یوسف زالی
سه شنبه 29 بهمن 1392, 23:34 عصر
سلام.
همون طور که می دونید، BruteForce روشی هست که تمام حالات ممکن رو برای کلید تست می کنه تا بالاخره کلید مربوطه رو پیدا کنه. پریروز نرم افزار یک بنده خدایی رو کرک کردم (خدا منو ببخشه :لبخند:) و به سرور سایت دسترسی پیدا کردم، بعد به سرم زد که با روش مزبور پسورد sa رو بزنم :لبخند:
نشستم این قطعه برنامه رو نوشتم، بعد از هک صرف نظر کردم (چون خیلی زمان بر بود!)
حالا گذشته از شوخی، دیدم که این روال جنبه آموزشی خوبی می تونه داشته باشه، از طرفی یک روال جنرال هست که به راحتی می شه برای منظورهای خاص استفاده بشه. مثلا با استفاده از همین روال، طی چند دقیقه پسورد ادمین اس کیو ال سیستم لوکالم رو که یادم رفته بود، ولی می دونستم ترکیب چند حرفی از اعداد هست رو پیدا کنم.
مرتبه ی زمانی این تابع همون طور که انتظار می ره توان هایی از طول کلید هست، بنابراین توقع معجزه نداشته باشید، اما با بهینه سازی دیکشنری، شمارش، ارسال کلید و ... می شه به روشهای سریعتری دست پیدا کرد.

اما یونیت مربوطه:


unit BruteForceUnit;

interface

type
TBruteForcableFunc = function (TryThis: string): boolean of object;

function BruteForce(VictimFunc: TBruteForcableFunc; Dictionary: string; MinLength: byte = 0; MaxLength: byte = 0): string;

implementation

uses Math, StrUtils;

function BruteForce(VictimFunc: TBruteForcableFunc; Dictionary: string; MinLength: byte = 0; MaxLength: byte = 0): string;

function GetItemsBy(this, base: cardinal; deep: integer): string;
begin
Result := '';

repeat
Result := Dictionary[(this mod base) +1] + Result;
this := this div base;
until this = 0;

Result := RightStr(DupeString(Dictionary[1], deep) + Result, deep);
end;

var
deep, base: integer;
n: cardinal;
TryThis: string;
begin
Result := '';
base := length(Dictionary);

if not Assigned(VictimFunc) then Exit;
if base = 0 then Exit;
if MinLength < 1 then MinLength := 1;
if MaxLength > base then MaxLength := base;
if MinLength > MaxLength then MaxLength := base;

for deep := MinLength to MaxLength do
begin
for n := 0 to Floor(Power(base, deep)) -1 do
try
TryThis := GetItemsBy(n, base, deep);
if VictimFunc(TryThis) then
begin
Result := TryThis;
Exit;
end;
except
end;
end;
end;

end.


این هم تست:


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
function CheckPassword(Pass: string): boolean;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses BruteForceUnit;

{$R *.dfm}

{ TForm1 }

function TForm1.CheckPassword(Pass: string): boolean;
begin
// Caption := Pass; {this line makes function really slow}

Result := Pass = {091237} '80840';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
ret: string;
begin
ret := BruteForce(CheckPassword, '0123456789');
if ret <> '' then
ShowMessage('HORA! Password is "' + ret + '"')
else
ShowMessage('Not successfull');
end;

end.


برنامه رو هم می تونید از اینجا دانلود کنید:
116848

VictimFunc تابعی هست که یک رشته می گیره و اگر اون رشته مورد نظر ما بود true برمی گردونه. مثلا رشته رو در پایگاه داده چک می کنه، یا هر چیز دیگه. در اینجا فقط برای مثال یک تابع الکی کال شده.

Dictionary هم کاراکترهایی هست که کلید باید از روی اونها ساخته بشه. همون طور که الان دارید فکر می کنید، اگر ترکیب اعداد و حروف بزرگ و کوچک رو در نظر بگیریم، می شه 10 + 26 + 26 یعنی 62 تا. در نظر بگیرید بدونیم طول رشته کلید 5 باشه، 62 به توان 5 حالت باید چک بشه. برای همینه که می گم فکرای بد بد نکنید!

اون دو تا پارامتر دیگه هم که معلومه کارشون چیه. توضیح نمی دم.

روش کار تابع به این صورته که برای هر طول انتخاب شده، در مبنای طول دیکشنری، اعداد رو تبدیل به مبنای مورد نظر می کنیم. شاید یکم سخت به نظر برسه ولی به بررسیش می ارزه. برای مثال می تونید اون قطعه Caption رو از کامنت در بیارید تا ببینید داره چه اتفاقی می افته.
مثلا اگر دیکشنری مون فقط ABC باشه، و طول 2 رو بخواهیم چی می شه؟

از 0 تا 8 می شماریم (3 به توان 2 منهای 1)
نتیجه می شه:
AA
AB
AC
BA
BB
BC
CA
CB
CC
یعنی تمام حالات ممکن.

روش مورد نظر می تونه برای تبدیل مبناها، و البته ساخت فضای نمونه ی تمام حالات و ترکیب های ممکن مثلا در محاسبات آماری هم بکار بره.
به راحتی یک تابع رو بهش می دید و .. :چشمک:

اگر سوالی هم داشتید بگید تا هر جا گنگ بود توضیح بدم.

BORHAN TEC
چهارشنبه 30 بهمن 1392, 01:11 صبح
سلام
به نظرت بهتر نبود اگه این تاپیک رو توی بخش مقالات قرار میدادی؟ :چشمک:

یوسف زالی
چهارشنبه 30 بهمن 1392, 01:26 صبح
لینک در سورس های نمونه آموزشی قرار داده شد. منظورت همون جا بود دیگه؟

Ebrahim_Rayaneh
جمعه 01 اسفند 1393, 02:06 صبح
زبان برنامه پاسکال هست؟
کاشکی به سی شارپ بود!

rahnema1
جمعه 01 اسفند 1393, 22:01 عصر
زبان برنامه پاسکال هست؟
کاشکی به سی شارپ بود!

سلام
با اجازه You-See با کمی تغییر به #C تبدیل کردم
اینم واسه اینکه آرزو به دل نمونید :چشمک:
برنامه اصلی را در لازاروس اجرا کردم نکته جالب اینه که سرعت سی شارپ از برنامه کامپایل شده با لازاروس بیشتر بود