سلسله آموزش های تست نفوذ Web Application - قسمت اول: آشنایی با مبانی وب اپ


تست نفوذ Web Application - قسمت اول: آشنایی با مبانی وب اپ

در اولین قسمت از مجموعه آموزش های تست نفوذ وب، با موارد زیر آَشنایی مختصری خواهیم یافت:

  1. مبانی پروتکل های HTTP و HTTPS
  2. کدگذاری (Encoding)
  3. مفهوم Same Origin
  4. کوکی ها
  5. نشست ها (Sessions)
  6. پراکسی های اپلیکیشن های وب

که در ادامه به ترتیب به آنها خواهیم پرداخت.

1. مبانی HTTP

پروتکلی است برای انتقال داده های اپلیکیشن های وب و صفحات وب. این پروتکل معماری کلاینت/سرور دارد یعنی یک کلاینت درخواست خود را به سرور مربوطه فرستاده و پاسخ را از سرور دریافت می نماید. در تصویر زیر نمونه ای از درخواست کلاینت HTTP (که معمولا یک مرورگر اینترنت است) برای گرفتن صفحه اصلی www.google.com  و پاسخ سرور را مشاهده می کنیم:

rnpg-client-request

پارامترهای HTTP

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

Header-Name:Header-Value

که در آن Get، متد پیشفرض یا verb درخواست است. سایر افعال یا verb های HTTP عبارتند از:

POST, PUT, DELETE, OPTIONS, TRACE, …

نشانگر / بیان کننده آدرس منبع درخواستی است که در اینجا ROOT یا همان صفحه اصلی می باشد. Host مشخص کننده اطلاعات مربوط به میزبانی است که منبع مورد نظر از او درخواست شده است. UserAgent نشان دهنده مرورگر سمت کاربر است. Accept بیانگر نوع داده ای است که کلاینت در پاسخ انتظار دریافت آن را دارد. Accept-Encoding مشخص کننده نوع کدگذاری هایی است که کلاینت در پاسخ می تواند بپذیرد. و نهایتا Connection با مقدار Keep-alive بدان معنا است که فرستادن درخواست های بعدی از سوی کلاینت به سرور نیازمند برقراری اتصال جدید به سرور نیست.

پاسخ سرور را در تصویر زیر مشاهده می کنیم:

rnpg-server-response

در پاسخ سرور، اولین خط نشان دهنده وضعیت پاسخ است و اصطلاحا Status-Line نام دارد. در اینجا 200 کد پاسخ و OK شرح مختصری از وضعیت است. بطور کلی، پاسخ های رایج سرور عبارتند از:

  • 200 OK
  • 301 Moved Permanently
  • 302 Found
  • 403 Forbidden
  • 404 Not Found
  • 500 Internal Server Error

متغیر Date، زمان پاسخ را نشان می دهد. Cache Control نشان می دهد که فرایند ذخیره سازی محلی محتوایی که تغییر نکرده و نیاز به دریافت جدید آن نیست به چه صورت می باشد. Content-Type نوع پاسخ از سوی سرور را نشان می دهد و همچنین مجموعه کاراکتر مورد استفاده در پاسخ را نشان می دهد. Content-Encoding نشان دهنده نوع کدگذری ای است که سرور از بین متدهای قابل پشتیبانی توسط کلاینت برگزیده است. Server، نوع وب سرور را نشان می دهد. در اینجا gws مخفف Google Web Server می باشد. در نهایت Content Length طول پاسخ سرور (مثلا اندازه صفحه اصلی گوگل) را نشان می دهد.

نکته حائز اهمیت در ارتباط با HTTP، نقل و انتقال آن به شکل متن آشکار می باشد. به عبارت دیگر، هر کسی (از جمله یک مهاجم) می تواند درخواست ها و پاسخ های HTTP رد و بدل شده را مشاهده نموده، آنها را کپچر کند و مقادیر موردنظر خود را در سرآیند این پیام ها قرار دهد. در نتیجه ضرورت استفاده از نسخه ای رمزگذاری شده و ایمن از HTTP سبب بوجود آمدن پروتکل HTTP Secure یا HTTPS شد. HTTPS با برقراری یک نشست رمزگذاری شده بین کلاینت و سرور بر روی پروتکل رمزنگاشتی SSL/TLS، از رد و بدل کردن داده به صورت آشکار اجتناب می کند و سبب تضمین محرمانگی، جامعیت و اصالت پیام های رد و بدل شده می شود.

rnpg-http-over-tls

نکته بسیار مهم آن است که استفاده از HTTPS مشکلات و آسیب پذیری های اپلیکیشن های وب را به هیچ عنوان برطرف نمی کند و فقط به ایمن سازی ارتباط و داده های در حال انتقال بین کلاینت و سرور می پردازد.

2. انکدینگ یا کدگذاری

کدگذاری در اصل فرایندی است که در آن طی یک فرایند برگشت پذیر داده ای به داده ای دیگر نگاشت و تبدیل می شود.

امروزه مهمترین متدهای انکدینگ مورد استفاده عبارتند از:

  1. ASCII: مجموعه کاراکترهایی فقط برای زبان انگلیسی و برخی علائم و نشانه ها
  2. Unicode: مجموعه کاراکترهای استاندارد جهانی

rnpg-ascii-example

لیست کامل در:

انکدینگ کاراکترها

در اینجا مبحثی به نام Character Encoding پیش می آید. بر این مبنا، هر نمایش هر کاراکتر به صورت دنباله ای از بایت ها (یا به عبارتی نگاشت کاراکتر به بایت) را انکدینگ یا کدگذاری کاراکتر میگویند. Unicode سه متد اصلی کدگذاری دارد:

  1. UTF-8
  2. UTF-16
  3. UTF-32

که در آنها اعداد 8، 16 و 32 نشان دهنده تعداد بیت هایی است که برای نمایش کدها بکار می روند. مثال:

rnpg-unicode-example

برای انتقال داده ها نیز می توان از اندکینگ استفاده کرد. مثال از HTTP (سرآیند Content-Type) که پیشتر به آن اشاره شد:

rnpg-coding-info-in-header

موجودیت های HTML

یکی ازموارد مهم در کدگذاری، مبحث Entityهای HTML است. موجودیت های HTML کاراکترهایی هستند که نشان دهنده آغاز و پایان یک رشته می باشند و نباید توسط مفسرها تفسیر و پردازش شوند. این موجودیت ها با & یا &# شروع شده و با ; خاتمه می یابند. در اینجا برای آنکه این اصطلاحا Reference Characterها (یا کاراکترهای مرجع) با بقیه کاراکترها دچار اختلاط نشوند، می توان از روش های مختلفی برای نمایش آنها استفاده نمود. از جمله:

rnpg-representation-of-reference-characters

کدگذاری درصدی (URL Encoding)

مفهوم حائز اهمیت دیگر در حوزه کدگذاری، کدگذاری درصدی یا کدگذاری URLها است. در این روش کاراکترهای مورد استفاده در آدرس ها و URLها نیز کدگذاری می شوند. در این روش تعدادی کاراکتر رزرو نشده داریم که می توانند در آدرس دهی بکار روند:

حروف از a-zA-z، اعداد از 0 تا 9، -، .، _ و ~؛

و کاراکترهای رزرو شده:

:/?#[]@!$&”()*+,;=%

سایر کاراکترها نیز با کمک %  و دو کاراکتر هگزادسیمال کدگذاری می شوند. همچنین کاراکترهای رزروشده نیز بایستی در زمانی که نقش خاصی در URL ندارند کدگذاری شوند. در تصویر زیر لیستی از کاراکترهای رایج کدگذاری شده را مشاهده می کنید:

rnpg-common-encoded-chars

وقتی سایتی را مشاهده می کنیم، URL-Encoding بطور خودکار توسط مرورگر انجام می شود. عمل دیکد کردن یا کدگشایی نیز در سمت سرور صورت می پذیرد. در تصویر زیر نمونه ای از درخواست های سمت کاربر که توسط مرورگرهای مختلف کدگذاری درصدی می شود را ملاحظه می نمایید:

rnpg-url-encoding-in-browsers

کدینگ B64

کدگذاری Base64، نوع دیگری از کدگذاری های مهم و مورد استفاده است. Base64 یک الگوی کدگذاری binary-to-text است که فایل های دودویی را تبدیل کرده و آنها را بر روی اینترنت منتقل می کند. الفبای Base64 از حروف بزرگ و کوچک انگلیسی به همراه اعداد 0 تا 9 و دو کاراکتر / و + تشکیل می شود. از = نیز برای پدکردن استفاده می شود. بعنوان نمونه، کد زیر نشان دهنده تصویری است که در یک داکیومنت وب قرار دارد و سرور می تواند با ارسال Base64 آن، نیاز به خواندن این تصویر از روی سیستم فایل خود را از بین ببرد:

rnpg-b64-encoding-of-an-image

3. مفهوم Same Origin

یکی از مهمترین مفاهیم در حوزه تامین امنیت وب اپلیکیشن ها، استفاده از پالیسی Same Origin است. این پالیسی از گرفتن یا تنظیم کردن مشخصات (Properties) یک اسکریپت یا داکیومنت توسط داکیومنت یا اسکریپت دیگری که منشا و مبدا متفاوتی با داکیومنت اولیه دارد، جلوگیری بعمل می آورد. بعنوان نمونه، CSS stylesheetها، تصاویر و اسکریپت ها بدون استفاده از این پالیسی در مرورگرها بارگذاری می شوند. Same Origin Policy یا SOP زمانی طرف مشورت قرار می گیرد که درخواستی به شکل Cross-site HTTP از طریق اسکریپتی در سمت کلاینت (مثل جاوا اسکریپت یا Ajax) اجرا شود.

مولفه های Origin

به طور کلی، مبدا یا origin با سه مولفه مشخص می شود:

rnpg-same-origin-components

بعنوان نمونه، مثال زیر را در نظر بگیرید:

http://www.rnpg.ir

در این مثال، مولفه پروتکل، http است. مولفه host، عبارتست از www.rnpg.ir//: و مولفه port نیز زمانی که ذکر نشود بصورت پیشفرض درنظر گرفته می شود (برای پروتکل HTTP، پورت 80). همچنین سلسله مراتب دامنه ها از چپ به راست خوانده می شود. در مثال فوق، .ir دامنه سطح بالا (TLD)، rnpg دامنه سطح دوم (SLD) و www دامنه سطح سوم است و الی آخر. هر گاه این سه مولفه (پروتکل، میزبان، پورت) در دو مبدا یکسان باشند، آنگاه آن دو مبدا یکسان هستند. در صورت استفاده از SOP، بسیاری از Getting و Settingها فقط توسط منشاهایی شدنی است که با هم Same Origin باشند. مثال:

rnpg-sop-assess

نکته مهم: Internet Explorer مایکروسافت استثناهایی برای SOP قائل می شود:

  1. پارامتر پورت را در بررسی SOP لحاظ نمی کند.
  2. SOP را در دامنه های شناخته شده (مثلا شرکت ها و دانشگاه ها و ...) اعمال نمی نماید.

بطور کلی، SOP از اجرای جاوا اسکریپت بر روی یک داکیومنت از یک مبدا مشخص از سوی داکیومنتی از مبدایی دیگر جلوگیری بعمل می آورد. هدف اصلی SOP نیز محدودسازی و ایزوله کردن درخواست هایی است که از Different Originها می آیند. قانون اصلی SOP می گوید:

"یک داکیومنت تنها در صورتی می تواند به مشخصات و Propertyهای یک داکیومنت دیگر دسترسی داشته باشد که آن دو داکیومنت مبدایی یکسان داشته باشند."

به عبارت دقیقتر، مرورگر همیشه درخواست را به طور موفق اجرا می نماید اما پاسخ را در صورتی به کاربر برمیگرداند که SOP رعایت شده باشد. عبارت داکیومنت که دائما به آن اشاره می کنیم، می تواند یک صفحه HTML، یک iframe در صفحه اصلی یا پاسخی به یک درخواست Ajax باشد. همانگونه که پیشتر اشاره شد، *.css و *.jsها از SOP مستثنی هستند و فارغ از مبدا، و بدون مشورت با SOP در مرورگر بارگذاری و اجرا می شوند.

مثال 1: فرض می کنیم index.html روی دامنه a.elswapt.site (که به آن origin1: http://a.elswapt.site می گوییم) می خواهد از طریق یک درخواست Ajax (xhr) به صفحه home.html در دامنه b.elswapt.site (که به آن origin 2: http://b.elswapt.site می گوییم) دسترسی داشته باشد.

سوال: آیا می تواند؟

پاسخ: خیر! زیرا این دو در یک دامنه قرار ندارند و SOP نقض شده است.

rnpg-sop-example1

مثال 2: دو داکیومنت داریم: داکیومنت اصلی در http://www.elswapt.site/index.html و یک داکیومنت iframe در http://www.elswapt.site/iframe.html؛

rnpg-sop-example2

از آنجا که این دو داکیومنت مبدا یکسانی دارند، هر داکیومنت می تواند به دیگری از طریق جاوا اسکریپت دسترسی داشته باشد. بنابراین درون داکیومنت اصلی، اجرای دستور جاوا اسکریپت زیر موفقیت آمیز خواهد بود:

rnpg-sop-js-execution

به همین صورت می توان درون iframe نیز دستور جاوا اسکریپت زیر را با موفقیت اجرا نمود:

rnpg-sop-js-execution2

استثناهای SOP

محدودیت های SOP در چهار مورد استثنا دارند:

Window.location: هر داکیومنتی همواره می تواند ویژگی location هر داکیومنت دیگری را بنویسد. آبجکت Window.location می تواند برای گرفتن آدرس فعلی پیج و ریدایرکت مرورگر به صفحه ای جدید مورد استفاده قرار گیرد. این بدان معنا است که ویژگی location همواره می تواند تغییر نماید. همچنین هر داکیومنتی می تواند این ویژگی را آپدیت کند.

بعنوان نمونه، داکیومنت زیر را در نظر بگیرید:

rnpg-sop-exception-example1

          درون این داکیومنت، کد جاوا اسکریپت زیر می تواند با موفقیت اجرا شود:

rnpg-sop-exception-example2

Document.domain: این ویژگی قسمت دامنه مبدا داکیومنت فعلی را نشان می دهد. مثلا در http://jobs.rnp.ir/index.html، ویژگی document.domain برابر است با jobs.rnpg.ir. این مشخصه را می توان تغییر داد. هر داکیومنت می تواند document.domain خود را به دامنه ای بالاتر در سلسله مراتب (به جز TLD) تغییر دهد. دامنه سطح دوم (مثلا domain.com) را نمی توان تغییر داد. با تغییر مشخصه document.domain، در اصل داکیومنت مبدا خود را تغییر می دهد. مثلا دو داکیومنت زیر را در نظر بگیرید:

که از طریق iframe، داکیومنتی از مبدایی دیگر را در خود دارد: