دوره تست نفوذ وب سطح متوسط – بخش نوزدهم

در این بخش از دوره آموزشی تست نفوذ سطح متوسط که برگرفته از دوره SEC642 می باشد به ادامه آشنایی با Web Design Patterns می پردازیم.

Understanding Design Choices

شما باید چندین معماری نرم‌افزار، الگوهای پیاده‌سازی و استانداردها را برای آزمایش نفوذ برنامه‌های کاربردی وب مدرن درک کنید. آگاهی از وجود آن‌ها می‌تواند به شما کمک کند تا آسیب‌پذیری‌های نرم‌افزاری مخفی شده را شناسایی نموده و به طور بالقوه شما را به سمت بهره‌برداری موفق یا بیشتر از یک سیستم سوق دهد. یکی از معماری‌های نرم افزاری، معماری MVC می باشد که امروزه تقریبا برای هر زبانی وجود دارند و یکی از محبوب‌ترین آن‌ها روبی روی ریلز است.

ایجاد، خواندن، به روز رسانی، حذف چهار عملکردی هستند که معمولا در هنگام کار با Backend Storage مانند پایگاه‌داده‌ها یا گاهی سیستم فایل‌ها یافت و استفاده می‌شوند. پایگاه‌های داده رابطه‌ای از این چهار کارکرد اصلی برای انجام اکثر کارهای خود استفاده می‌کنند. Create می‌تواند در SQL با استفاده از عبارت Insert انجام شود، در حالی که Create می‌تواند در لایه وب به عنوان یک فرمان POST نیز یافت شود. هر یک از این دستورها می‌توانند عملکرد مبهم داشته باشند و به این ترتیب باید در طول آزمایش در نظر گرفته شوند.

REST مخفف REpresentational State Transfer است. گاهی اوقات از آن به نام RESTful، یاد می‌شود. REST یک لایه انتزاعی دیگر، مانند MVC است. REST یک استاندارد نیست و بیشتر یک معماری است تا یک چارچوب.

شما باید رابطه های موجود در اپلیکیشن را درک کنید: REST یک عمل است؛ شما می‌خواهید کاری را برای Application State انجام دهید و CRUD عمل واقعی چیزی است که در برنامه کاربردی اتفاق می‌افتد. به عنوان مثال، فراخوانی /add/user/1 ممکن است به یک اپلیکیشن بگوید که یک عملیات Create در یک پایگاه‌داده برای کاربر با شناسه یک ایجاد کند.

MVC چگونگی تعامل با برنامه تحت وب است در حالی که RESTful، متد استفاده شده و CRUD نیز کاری است که با برنامه انجام می دهید.

Model – View – Controller

اکثر چارچوب‌های وب (‏به خصوص در Backend) ‏از معماری MVC استفاده می‌کنند. این امر یک برنامه را به سه مولفه عملکردی تقسیم می‌کند: Model، Viewer و Controller.
چارچوب‌های MVC اغلب شامل یک ویژگی URL Mapping هستند که می‌توان آن را Routing نیز نامید. بسیاری از چارچوب‌های جدید سمت مشتری به MVC مهاجرت کرده‌اند تا منطقی که توسعه دهندگان به کلاینت Push می‌کنند را ساده کنند.

Model، اشیا داده‌ای ذخیره‌شده در محل ذخیره داده‌ها را حفظ می‌کند و Application State ای که کاربر در آن است را حفظ می‌کند. این کار می‌تواند در حافظه، پایگاه‌های داده محلی یا انواع دیگر پایگاه‌های داده انجام شود.

Viewer، نگاه و احساس سایت مانند ایجاد یک دسکتاپ و یک نسخه سیار براساس همان Model/Controller را کنترل می‌کند. Viewer ها اغلب از موتورهای قالب یا حتی چارچوب Frontend دیگر برای انجام رندر نهایی استفاده می‌کنند.

Controller، ورودی‌های منتقل‌شده توسط کاربر را کنترل می‌کند و منطق کسب‌وکار اصلی را در مورد چگونگی رسیدگی به آن داده و اینکه چه داده‌هایی باید به عقب فرستاده شوند فراهم می‌کند.

MVC Process Flow

تصویر زیر مفهوم عملکرد MVC در برنامه را نشان می‌دهد. معمولا سه یا چند مولفه وجود دارد؛ در این مورد، چهار مورد وجود دارد: یک موتور مسیریابی (URL Map) یک Controller، یک Model، و یک View Area.

روتر (URL Map) به درخواست نگاه می‌کند و این درخواست را به Controller مناسبی که VERB را کنترل می‌کند، منتقل می‌نماید.

Controller، ورودی‌های منتقل‌شده توسط کاربر را کنترل می‌کند و منطق کسب‌وکار اصلی را در مورد چگونگی رسیدگی به آن داده و اینکه چه داده‌هایی باید به عقب فرستاده شوند فراهم می‌کند.

Model، اشیا داده‌ای ذخیره‌شده در محل ذخیره داده‌ها را حفظ می‌کند و Application State ای که کاربر در آن است را حفظ می‌کند. این کار می‌تواند در حافظه، پایگاه‌های داده محلی یا انواع دیگر پایگاه‌های داده انجام شود.

Viewer، نگاه و احساس سایت مانند ایجاد یک دسکتاپ و یک نسخه سیار براساس همان Model/Controller را کنترل می‌کند. Viewer ها اغلب از موتورهای قالب یا حتی چارچوب Frontend دیگر برای انجام رندر نهایی استفاده می‌کنند.

MVC Process Flow

در این مثال، کاربر یک درخواست GET به domain/app/user/id/100 ارسال می‌کند. URL Map، در اینجا نگاهی به VERB GET انداخته و درخواست کاربر را بررسی نموده و این موضوع را به User Controller انتقال می‌دهد که به طور معمول درخواست‌های USER مبتنی بر GET را کنترل می‌کند. با توجه به درخواست مذکور، ID و ۱۰۰ به عنوان مقدار به سمت Backend عبور داده می‌شود. این مهم است زیرا این چیزی است که ما می‌خواهیم به طور بالقوه به آن حمله کنیم.

کنترل‌کننده به احتمال زیاد دارای یک متد FIND است که می‌تواند مقدار ۱۰۰ را برای ID بگیرد و آن را به مدل منتقل کند. این مدل با محل ذخیره تعامل می‌کند تا داده‌های مناسب را بازیابی نموده و سپس آن را به View مشخص‌شده منتقل ‌کند؛ معمولا این کار از طریق اشیا انجام می‌شود.

Objectارسال شده، شی ID با مقدار 100 است که datastore (معمولاً یک پایگاه داده) اطلاعات را با شناسه 100 اصطلاحا Pull Back می کند. View در واقع صفحه HTML مناسب را می‌سازد که نشان دهنده داده‌ها و انتقال آن‌ها به کاربر است.

Github Mass Attribute Assignment Attack in Action

Pseudo Code for Github

شما باید بدانید که در اینجا چه چیزی در حال وقوع است، چرا که با وجود اینکه در ابتدا Mass Attribute در مقابل Rails3 بود، تقریبا تمام چارچوب‌ها نسبت به این نقص نیز حساس بودند. در این مثال، ما یک مدل ساده داریم که در آن کلاس پیش‌فرض ActiveRecord را در کلاس کاربر به ارث می‌بریم. علاوه بر این، ما مثالی از آنچه که یک مدل Rails3 سنتی می‌توانست به نظر برسد را داریم. آنچه در اینجا مهم است درک منطق update call است.

آنچه که در اینجا اتفاق می‌افتد را در نظر بگیرید:

ما یک کنترلر به نام SSHController داریم که فرض می‌کنیم تخصیص کلیدهای SSH به ID های کاربر را کنترل می‌کند. before_filter بررسی می‌کند که کاربر مجاز است، اما مگر این که سیستم یک ساختار مجوز پیچیده داشته باشد، که به طور بالقوه تمام آن چیزی بود که بررسی شد.

اگر حمله را در نظر بگیریم، می‌توانیم فرض کنیم که تابع به روز رسانی کنترلر گیت‌هاب به احتمال زیاد از الگوی طراحی پیروی می‌کند که اجازه می‌دهد کلید توسط ID پیدا شود که براساس URI است و سپس با یک کلید جدید به روز رسانی می‌شود.

Github Good Request Example

در اینجا، ما یک درخواست معتبر را شرح می‌دهیم که به مثال قبلی ما مربوط می‌شود:

تصور کنید که شما یک برنامه Rails استاندارد دارید که در آن یک راه‌اندازی MVC کلاسیک ساده در Rails وجود دارد.

حال تصور کنید که درخواست برنامه دارای یک پست بود که در آن کاربر repo (‏۱۲۳۴)‏ را با یک کلید عمومی Valid SSH به روز رسانی می‌کرد:

اگر کنسول Rails را اجرا می‌کنید، می توانید با انجام user.update (به روز رسانی شی کاربر) با شناسه 1234 و کلید AAAAB3NzaC1yc2EAAAADAQABAAABAQDQ این کار را شبیه سازی کنید.

ID و Key Object ها عبور داده شده‌اند که احتمالا این کار بدون فیلتر کردن منطقی یا پاک‌سازی مستقیم به پایگاه‌داده انجام می شود. همچنین احتمالا هیچ بررسی مجوزی در مورد اینکه آیا درخواست این درخواست‌کننده به این هدف دسترسی دارد یا خیر، وجود ندارد.

Github Attack Step by Step

مهاجم به چند قطعه اطلاعات نیاز دارد.

  1. repo idمربوط به قربانی (‏یا target repository)‏، در مورد گیت‌هاب. اگر کسی به غیر از گیت‌هاب، به شناسه شی قابل اصلاح نیاز داشته باشد.
  2. Rails Developer ID، در مورد گیت‌هاب. برای شخص دیگری، این موضوعی است که آن‌ها باید از یک هدف مجاز برای ضمیمه کردن بخش‌های داده استفاده کنند. در اینجا، این ID توسعه دهنده بود زیرا آن‌ها به بروز رسانی مخزن Rails دسترسی داشتند.
  3. مهاجم با استفاده از ID توسعه دهنده سیستم، کلید خود را به Rails repo اضافه می‌کند و این کلید را به کلید توسعه دهنده Append می‌نماید.

موارد مهم دیگری نیز در اینجا وجود دارند که باید به آن‌ها توجه کنید. درک درستی از نحوه عملکرد برنامه Github وجود داشت؛ که مهاجم می‌خواست کلید SSH خود را برای به روز رسانی مخازن Git که از طریق برنامه استاندارد به آن دسترسی نداشت، اضافه کند. همچنین یک درک از نحوه کار برنامه با تجزیه و تحلیل الگوهای رایج توسعه دهنده (common developer patterns) وجود داشت. اینها همه مجموعه مهارت‌هایی هستند که ما انتظار داریم یک آزمونگر پیشرفته آن‌ها را داشته باشد.

درباره نویسنده: احسان نیک آور

ممکن است دوست داشته باشید