-
پنجشنبه, ۹ مرداد ۱۳۹۹، ۰۳:۵۸ ب.ظ
-
۴۰۳۲
آموزش ساخت ابزار کرکر صفحات لاگین وب در پایتون
درود به همه !
امروز میبینیم چطور میشه یه cracker برای صفحات لاگین که از روش POST برای انتقال اطلاعات استفاده میکنند ساخت .در این آموزش برای ارسال درخواست های POST به سمت سرور از کتابخونه ی requests در پایتون استفاده میکنیم . کتابخونه ی requests دارای تابعی به نام post است که از این تابع برای انجام کارمون استفاده میکنیم .
قبل از اینکه شروع کنیم بزارید یکم در مورد درخواست های HTTP توضیح بدم . وقتی یک کاربر میخواد از طریق صفحه لاگین یک وبسایت وارد اون بشه باید ابتدا از طریق مرورگرش به آدرس صفحه لاگین بره و یوزرنیم و پسووردشو بزنه و مثلا دکمه ی ورود رو بزنه . این کار باعث میشه یه درخواست HTTP از طریق متود POST برای سرور اون سایت ارسال بشه که حاوی یوزرنیم و پسووردی هست که کاربر زده . پس از اینکه سرور این درخواست رو دریافت کرد میبینه آیا یوزرنیم و پسووردی که کاربر زده معتبره یا نه . اگه معتبر باشه بهش اجازه ورود میده و اگه معتبر نباشه بهش اجازه ی ورود نمیده .
کار کرکر ما اینه که یوزرنیم و پسووردای زیادی رو روی صفحه لاگین تست کنه ببینه کدومش درسته . خب پس ما باید اسکریپتی بنویسیم که همون درخواست HTTP که کاربر میفرستاد رو بفرسته ولی با این تفاوت که اینکار رو بارها تکرار کنه و یوزرنیم و پسووردای مختلفی رو تست کنه . هرکدوم از درخواست ها جواب درستی از سمت سرور گرفت یعنی یوزرنیم و پسوورد صحیح همون بوده .
اما اگه بخوایم یکم دقیق تر درخواست HTTP رو برسی کنیم باید پروتکل HTTP رو بدونیم چیه . پروتکل HTTP مخفف Hyper Text Transfer Protocol هستش . کار این پروتکل انتقال اطلاعات بین سرور و کلاینته . روش کار طوریه که هر کلاینت یک درخواست HTTP به یک آدرس وب میفرسته و اون سرور یک جواب HTTP به کلاینت ارسال میکنه . تصویر زیر :
هر درخواست HTTP شامل سه بخش اصلی هستش .
۱ - بخش خط درخواست یا Request Line : این بخش دارای سه قسمت است . قسمت اول متود یا شیوه ی ارتباط را مشخص میکند که میتواند یکی از متود های HTTP مثل GET یا post باشد . قسمت دوم از این بخش آدرس url مقصد ، روی سرور هدف را مشخص میکند برای مثال :
/apps/login.php
قسمت سوم هم مشخص کننده ی ورژن پروتکل HTTP است . برای مثال میتواند متنی شبیه به متن زیر باشد :
HTTP 1/1
بیشتر صفحات لاگین وبسایت هایی که اصولی طراحی شده اند از متود POST برای انتقال استفاده میکنند پس ما هم باید از همین متود برای تست یوزرنیم و پسوودامون استفاده کنیم .
۲ - بخش هدر ها (Headers) : هدر ها درواقع یک سری مقادیر اطلاعاتی در مورد کلاینت هستند که سرور از طریق این هدر ها میتواند با کلاینت ارتباط برقرار کند . برای مثال اطلاعاتی مثل زبان یا نوع مرورگری که کلاینت استفاده میکند را مشخص میکند .
۳ - بخش بدنه اطلاعات یا Message Body : تمام قسمت های قبلی در واقع برای این موضوع بودن که بتونن بخش سوم یعنی اطلاعات رو انتقال بدن . اطلاعات یا message body همون اطلاعاتی هستند که ما میخوایم از طریق این درخواست انتقال بدیم که در مورد پروژه ما در واقع یوزرنیم و پسوورد هستش .
خب اینا یه سری چیزای پایه بودن که باید در مورد این پروژه میدونستیم .
آماده سازی : قبل از اینکه بریم سراغ مرحله ی بعد پیشنهادم اینه یکم در مورد بحثای بالا توی گوگل هم بخونید .
میریم سراغ اسکریپت نویسی . قبلش بگم که من از اپلیکیشن آسیب پذیر dvwa برای تست اسکریت استفاده میکنم . به شما هم پیشنهاد میکنم برای تست اسکریپت یه صفحه لاگین خودتون بنویسید یا از اپلیکیشن های آسیب پذیر مثل dvwa استفاده کنید .
صفحه لاگین اپلیکیشن آسیب پذیر من به آدرس http://192.168.1.105/dvwa/login.php به شکل زیره .
حالا ما نیاز به یه سری اطلاعات داریم .۱ - نیاز به یک متن کلیدی برای شناسایی اینکه لاگین موفقیت آمیز بوده یا نه . برای مثال در این وبسایتی که من تست میکنم اگه پسوورد رو درست بزنم وارد یه صفحه ای میشم که اولش نوشته Welcome . پس بعدا تو اسکریپت میگیم اگه کلمه ی Welcome در متن بازگشتی وجود داشت یعنی اینکه پسوورد و یوزرنیم درست بودن .
مورد بعدی که نیاز داریم همون قسمت سوم درخواست HTTP یعنی MessageBody است . ما نیاز داریم تا متغییر های این قسمت را بدونیم . برای اینکار من ابتدا با مرورگر خودم (فایرفاکس) وارد صفحه لاگین میشم
بعد کلیک راست میکنم وگزینه ی Inspect Element رو انتخاب میکنم .
بعد میرم توی سربرگ Network
حالا یه پسوورد تستی به اشتباه وارد میکنم و اقدام به لاگین میکنم .
همینطور که میبینید پس از وارد کردن یه پسوورد اشتباه سربرگ network تغییراتی پیدا میکند :
حالا میتونیم اون درخواست اصلی که برای ورود به وبسایت است و با متود post است رو انتخاب کنیم :
و نهایتا در سربرگ request من میتونم متغییر ها رو ببینم . همینطور که میبینید اینجا سه تا متغیر دارم . password , username و Login .
این مقادیر را بعدا در سورس کد مقدار دهی میکنیم . کافی است یوزرنیم مورد نظر رو به جای متغییر username و پسوورد موردنظر رو به جای متغییر password بزاریم و Login هم که همیشه ثابته .
برای نوشتن اسکریپت نیاز به دوتا کتابخونه داریم . یکی requests که به صورت پیشفرض نصبه و کتابخونه ی colorama برای نوشتن متن های رنگی که برای نصبش میتونیم از ابزار pip استفاده کنیم.
نصب کتابخونه روی لینوکس :
MrPython@debian:~$ sudo pip3 install colorama
نصب کتابخونه روی ویندوز :
C:\> pip install colorama
میریم برای نوشتن اسکریپت.
سورس اسکریپت :
from requests import post import colorama
colorama.init() ## initialize the colorama
url = "http://192.168.1.105/dvwa/login.php"
usernamefile = input("Username List : ") passwordfile = input("Password List : ")
find = False for username in open(usernamefile): username = username.strip("\n") for password in open(passwordfile): password = password.strip('\n') print (colorama.Fore.RED + "{}:{}".format(username,password)) res = post(url,data = {"username" : username , "password" : password , "Login" : "Login"}) content = res.content content = content.decode() if "Welcome" in content: print("-"*50) print(colorama.Fore.GREEN + "Correct USERNAME / PASSWORD --> {}:{}".format(username,password)) find = True break if find : break
توضیح سورس کد :
در ابتدا کتابخونه های مورد نیاز رو ایمپورت کردیم . سپس با استفاده از colorama.init اومدیم ماژول colorama رو کانفیگ کردیم تا بتونه متنای رنگی برامون تولید کنه (آماده سازی colorama) . پس از اون دوتا ورودی از کاربر گرفتیم یکی usernamelist و دیگری passwordlist که درواقع آدرس فایل های یوزرنیم لیست و پسووردلیست هستند . سپس یه متغییر به نام find تعریف کردیم که فقط در صورتی برابر True میشه که یوزرنیم و پسوورد صحیح رو پیدا کنیم . بعد یه حلقه ی for برای فایل usernamelist نوشتیم که به وسیله ی اون بتونیم به تک تک یوزرنیم های داخل فایل دسترسی داشته باشیم . در اولین خط از کد این حلقه اومدیم عبارت n\ آخر هر یوزرنیم رو حذف کردیم . سپس یک حلقه for دیگر برای فایل پسوورد ها ایجاد کردیم و در اولین کد این حلقه نیز مانند حلقه قبل اومدیم n\ آخر هر پسوورد رو حذف کردیم .بعد از اون اومدیم چاپ کردیم که چه پسوورد و یوزرنیمی رو داریم تست میکنیم . سپس اومدیم با استفاده از متود post یه درخواست http فرستادیم سمت اون آدرس به همراه پارامتر های مورد نیازش که اون بالا گفتیم یکی username بود و دیگری password . همچنین یه Login هم داشتیم که همیشه ثابت بود .
بعد جواب درخواستمون که از سمت سرور میاد رو ریختیم داخل متغییر res . حالا با استفاده از res.content اومدیم محتویات اون صفحه برگشتی رو دیدیم . اگه یادتون باشه وقتی من لاگین صحیح انجام میدادم یکی از کلمه هایی که روی صفحه به ما نشون میداد کلمه ی Welcome بود . پس اینجا گفتم اگه کلمه ی Welcome داخل متن بازگشتی بود یعنی ورود موفقیت آمیز بوده و یوزرنیم و پسوورد درست رو به کاربر نشون بده و نهایتا متغییر find رو برابر True کن و از حلقه ها خارج شو و تمام .
پس از اجرای اسکریپت و دادن فایل های یوزرنیم و پسوورد به برنامه ، با نتیجه ی زیر رو به روز میشیم :
یا حق !
Telegram Channel : @mrpythonblog