پیدا کردن دایرکتوری های مخفی یک سایت با پاورشل

یکی از روشهایی که توی باگ بانتی و البته تست نفوذ وب اپلیکیشن ها مورد استفاده قرار میگیره پیدا کردن دایرکتوریها و فایلهایی هست که بی صاحاب تو هاست موندن.این موارد میتونه مثلا وجود یک فایل بک آپ قدیمی یا یه دایرکتوری با پرمیشن بالا باشه و یا فایل کانفیگ و … باشه .

برای این منظور ابزارهای مختلفی وجود داره مانند dirb یا dirsearch و البته برپ (ع) هم میشه استفاده کرد. اما این ابزارها چطوری کار میکنند ؟!

این ابزارها اغلب از حملات دیکشنری و درخواست و پاسخ http استفاده می کنند. یعنی یه لیست از کلمات رایج رو میگیرن مثلا config, setting.cfg و با ارسال اون به سایت مورد نظر و پاسخی که دریافت میکنن میتونن بفهمن که وب اپلیکیشن حاوی اون ادرس هست یا نه .

در ادامه می خواهیم یک برنامه تو پاورشل بنویسیم که اینکار رو برای ما بصورت اتوماتیک انجام بده.

اولش برای راحتتر شدن مطلب کارهایی که اسکریپت ما میخواد انجام بده رو به قسمتهای کوچیک تقسیم کنیم.کارهایی که اسکریپت پاورشل ما انجام میده :

1- یک آدرس سایت و یک ادرس فایل حاوی کلمات رو بگیره.

2- این کلمات رو به انتهای آدرس بچسبونه.

3- یک درخواست http ارسال کنه.

4- براساس پاسخ دریافتی نتایج رو برامون لیست کنه.

قبل از اینکه وارد کدنویسی هر بخش بشیم ،کدنویسی رو تو برنامه Windows Powershell ISE انجام میدیم که نیازی به دانلودش نیست و تو خود ویندوز قرار داره و کافیه تو منوی استارت powershell تایپ کنید و رویت کنید :

بعد از اجرای اون صفحه زیر رو میبینید:

خب یکمی محیط برای کار شلوغه برای آروم کردن! محیط اون نوار سمت راست commands رو ضربدر بکنید بره و از قسمت راست بالا فلش script بزنید تا محیط اسکریپت نویسی براتون ظاهر بشه.در کل محیط کدنویسی با اعمال تغییرات این شکلی میشه :

خب محیط آماده است فقط شما میتونید افقی یا عمودی بودن رو دکمه هایی که رنگ زرد مشخص شده تغییر بدید .

احتمالا تو کدنویسی دچار مشکلاتی بشید و نیاز باشه که دیباگ کنید که از دیباگ با قرار دادن بریک پوینت مشکلات سورس کدتون حل کنید.

کار تمومه و بریم سراغ کدنویسی:

قدم اول: گرفتن آدرس سایت و فایل بعنوان پارامتر:

تو پاورشل برای اینکه بتونیم پارامترهای ورودی رو به برنامه بدیم میتونید از $args استفاده کنیم.با توجه به اینکه من اسم اسکریپتم رو گذاشتم powersd برای اینکه بتونم ازش استفاده کنم قالب دستورم اینجوریه :

powersd -u google.com -i list.txt -o list.html

که از u برای گرفتن url

از i برای گرفتن محل فایل ورودی

از o هم برای گرفتن مسیر خروجی.

اگه تعداد آرگومانها رو بشماریم عدد 6 هست و برای اینکه همین اول از ورود صحیح آرگومانها مطمئن بشیم می تونیم در اولین مرحله تعداد آرگومانها رو بشماریم و اگه شش بود بریم ادامه کدمون.

1if ($args.Count -eq 6){
1    getarg $args
1    getinputfile $args[1] $args[3] $args[5]
1}else{
1    Write-Host "
1        your arguments is not valid.please use this statement:
1            powersd -u yoururl -i inputfile -o outputfile
1        "
1}

کد بالا تعداد آرگومانها رو بررسی میکنه و اگر تعدادش دقیقا 6 باشه تابع getarg با پارمتر $args اجرا میکنه در غیر اینصورت یه پیام خطا میده که سینتکس صحیح دستور به چه شکل هست .

با فرض اینکه آرگومانهای ورودی تعدادشون 6 تاست میریم سراغ تابع getarg :

1function getarg($myargs) {
1    $url=$myargs[1]
1    $inputfile=$myargs[3]
1    $outputfile=$myargs[5]
1    Write-Host "*************************************"
1    Write-Host "your URL is: $url"
1    Write-Host "your input file is: $inputfile"
1    Write-Host "your output file is: $outputfile"
1    Write-Host "*************************************"
1    Write-Host "Attacking..."
1}

در پاورشل برای ایجاد یک تابع از کلمه کلیدی function استفاده میکنیم و بعد یک اسم دلخواه (البته نباید جزء کلمات کلیدی باشه ) انتخاب می کنیم و اگر تابع پارامتر ورودی داشته باشه داخل یک پارانتز باز و بسته و با جداکننده کاما معرفی میکنیم .

خب کاریکه تابع بالا انجام میده پارامترهای دریافتی رو داخل متغییرهایی قرار میده و اونارو به کاربر نشون میده .برای تعریف متغیر باید به اول اسم یک علامت دلار $ اضافه کنیم و برای چاپ هم از write-host استفاده کنیم. برای داشتن هر آرگومان ورودی هم از ایندکس اون که داخل براکت هست استفاده میکنیم.

بعد از اینکه ورودی هامون رو نمایش دادیم میریم قدم بعدی …

برای شما

در ادامه تابع getinputfile رو با آرگومانهای سایت و نام فایل ورودی و نام خروجی اجرا میکنیم:

1getinputfile $args[1] $args[3] $args[5]

و کد تابعمون هم به این شکل :

1function getinputfile($myurl,$myfile,$myoutfile){
1    $i=1
1    foreach($line in Get-Content $myfile) {
1        $mylink="$myurl/$line"
1        $mystatus=checkurl($mylink)
1        $result="$i : $mylink ===>($mystatus)"
1        Write-Host $result 
1        $total="$total </br> <a href=""http://$mylink"" target=""_blank""> $mylink</a> ===>($mystatus)"
1        $i++
1    }
1    outputfile $myoutfile $total
1}

با دستور get-content میتونیم محتوای یک فایل بخونیم و برای اینکه خط ب خط این فایل بخونیم از foreach استفاده میکنیم. در حقیقت با این دستور خط ب خط فایل میخونیم و هر خط تو متغیر $line میریزیم.

از $mylink برای لینک سازی استفاده کنیم.(نمایش بهتر).یعنی سایت بعلاوه خط خونده شده از فایل.

از $mystatus هم برای بررسی وضعیت آدرس (404 – 200 و … ) که تابع checkurl رو اجرا میکنه.

از $result هم برای نمایش کارهایی که میکنیم. یعنی شماره سطر + آدرس سایت در حال بررسی و وضعیت اون.

من چون میخوام خروجیم بصورت یک فایل html باشه و نتایج بصورت لینکی ثبت شده باشند که با کلیک روشون بشه به لینک برم از $total استفاده کردم که ساختار یک لینک در زبان html ایجاد میکنه

و در آخر هم که تابع outputfile رو اجرا میکنه که مسئول تولید فایل خروجی هست.

اینجا ابتدا تابع checkurl رو بررسی کنیم و بعدش outputfile .

1function checkurl($mylink){
1    try
1    {
1        $Response = Invoke-WebRequest -Uri $mylink -ErrorAction Stop
1        $StatusCode = $Response.StatusCode
1    }
1    catch
1    {
1        $StatusCode = $_.Exception.Response.StatusCode.value__
1    }
1    $StatusCode   
1}

برای اینکه بتونیم خطاهای احتمالی رو مدیریت کنیم از ساختار try-catch استفاده میکنیم.

توی پاورشل میتونیم به روش های مختلفی درخواست وب ایجاد کنیم .برای راحتی کار من از Invoke-WebRequest استفاده کردم که یک آدرس میگیره و فرایند درخواست و پاسخ برای ما انجام میده.چون تو این پروژه احتمال اینکه یک لینکی وجود نداشته باشه و این تابع یک خطایی رو نمایش بده از -ErrorAction Stop استفاده کردیم که نمایش خطا نده و ادامه بده.

چون برای ما فقط وضعیت لینکمون مهم برای همین از

1$StatusCode = $Response.StatusCode

استفاده کردیم.(میشه سورس و … هم خوند ) و برای اینکه اگه خطایی رخ داد برنامه متوقف نشه از :

1$StatusCode = $_.Exception.Response.StatusCode.value__

تا اینجای کار ، کار تمومه و ما فقط باید فایل خروجیمونو ایجاد کنیم :

1function outputfile($myoutputfile,$mydata){
1    $mydata | out-file -FilePath $myoutputfile
1}

با تابع out-file و دادن مسیر میتونیم یک فایل ایجاد کنیم.

خب بریم برنامه رو تست کنیم . من یک فایل ورودی دارم بدین شکل (list.txt)

و برای تست هم یک سایتی با دایرکتوریهای زیر رو دارم :

ما فقط سایت اصلی که index.html هست میبینیم و از بقیه خبر نداریم .

خب طبق تصویر بالا اونایی که 200 دارند یعنی موجود و اونایی که 404 هم که تکلیفشون مشخصه.

فایل خروجی هم بدین شکله :

این برنامه بصورت مبتدی نوشته شده و فقط برای ارایه اصول اولیه هستش. شما میتونید بسته به نیازتون اونو ارتقا بدید و یک برنامه مختص خودتون بسازید.

دانلود کل پروژه از اینجا

نویسنده مطلب: Seyyid

منبع مطلب

به فکر سرمایه‌گذاری هستی؟

با هر سطحی از دانش در سریع‌ترین زمان با آموزش گام به گام، سرمایه گذاری را تجربه کن. همین الان میتونی با لینک زیر ثبت نام کنی و ۱۰ درصد تخفیف در کارمزد معاملاتی داشته باشی

ثبت نام و دریافت جایزه
ممکن است شما بپسندید
نظر شما درباره این مطلب

آدرس ایمیل شما منتشر نخواهد شد.