در این بخش از دوره آموزشی تست نفوذ سطح متوسط که برگرفته از دوره SEC642 می باشد به ادامه مبحث آشنایی با File Inclusion می پردازیم.
محدودیتهای File Inclusion : مانند Prepend و Append
هنگامی که یک توسعه دهنده از File Inclusion پویا استفاده میکند، ممکن است تمام فایلهایی را که قصد Include نمودن آنها را داد، در یک پوشه و در زیر مجموعه Web Root قرار دهد. هنگام اجرای عملیاتinclusion، توسعه دهنده میتواند محل پوشه را به ورودی ارائهشده توسط کاربر که باید Include شود، الحاق کند.
برای مثال، در یک برنامه کاربردی وبلاگ، تمام پستهای وبلاگ ممکن است در یک دایرکتوری “پست” زیرمجموعه Web Root ذخیره شوند. تکنیک اصلی برای کنار گذاشتن این محدودیت، پیمایش دایرکتوری یا Directory Traversal نامیده میشود. این کار با اضافه کردن یک سری از “../” ها به نام فایل موجود انجام میشود.
درPHP، این فرآیند ممکن است کاملا نامحدود باشد. با این حال ASP و JSP مانع از این نوعTraversal از بالای Web Root می شوند. با این حال، هر فایلی در Web Root هنوز در دسترس است، بنابراین هنوز هم پتانسیل بهرهبرداری در این زبانها وجود دارد.
علاوه بر این، JSP گام پیشگیرانه اضافی را نیز شامل میشود که در آن یک Prepending برای تمام فایلها با مسیر Web Root به طور خودکار ایجاد میگردد. این کار نه تنها مانع از Traversal میشود، بلکه مانع از استفاده هر گونه مسیر مطلق نیز میشود.
لازم به ذکر است یک مسیر مطلق به پروندهای در اینترنت با استفاده از URL کامل آن اشاره دارد، به عنوان مثال:
“www.uvsc.edu/disted/php/webct/itr/index.php”
یک مسیر نسبی فرض میکند که پرونده در سرور فعلی باشد ، به عنوان مثال:
“/webct/test/index. php”:
در مقابل،ASP اجازه فرار از Web Root را از طریق پیمایش نمیدهد اما هنوز هم استفاده از مسیرهای مطلق را ممکن میسازد. یک محدودیت مهم در عملیات include با یک مسیر از پیش تعیینشده (Prepended) این است که تمام اکسپلویتهای Include مبتنی بر URL غیر ممکن خواهند شد.
محدودیت رایج دیگر در بهرهبرداری از File Inclusion زمانی رخ میدهد که توسعه دهنده تصمیم میگیرد تا یک پسوند را به ورودی کاربر اضافه نماید.
در PHP که به زبان C ++ نوشته شده است، تمام ورودیها به صورت رشتههای نوع C پردازش میشوند. در C وC ++ ، بایت null یا%00 نشان دهنده پایان یک رشته است.
بنابراین، با قرار دادن یک بایت تهی Encode شده توسطURL، میتوانیم پردازش مسیر فایل که به تابع Include منتقل میشود را بوسیله بایت Null، اصطلاحات Bypass نموده و با این کار، انتهای رشته را به این تابع اعمال نماییم تا از اضافه نمودن مقادیری تعریف شده توسط توسعه دهنده وب، جلوگیری به عمل آید.
این آسیبپذیری در نسخه PHP ۵.۳.۴ + برطرف شدهاست. Null Byte دیگر بر روی نسخههای اخیر PHP کار نمیکند.
در JSP اضافه نمودن یک علامت سوال به انتهای ورودی، مشابه Null Byte عمل می نماید. البته در ASP چنین معادلی وجود ندارد. اگر عملیات inclusion مبتنی بر URL باشد، یک مهاجم میتواند به انتهای URL یک علامت سوال اضافه نماید و هر چیزی که به انتهای URL اضافه شود به عنوان یک متغیر GET تلقی شده و به طور موثر نادیده گرفته میشود.
پیشگیری از اجرای LFI
مشاهده محتویات سورس فایل ها برای تست نفوذگران مفید میباشد. اگر بتوانیم سورس یک برنامه را مشاهده کنیم، تست نفوذ به یک مرور کد یا Code Review تبدیل میشود. این امر ما را قادر میسازد تا آسیبپذیریهای دیگری را برای بهرهبرداری شناسایی نماییم و همچنین الگوریتم درهم سازی (Hashing) را که یک برنامه ممکن است برای ذخیره گذرواژهها از آن استفاده کند را مشاهده کنیم.
حتی در صورتی که برنامه متن باز هم باشد، فایلهای پیکربندی اغلب به عنوان سورس فایلها ذخیره شده و این فایلها میتوانند شامل اطلاعات ارتباط با دیتابیس و یا اطلاعات ارزشمند دیگری شامل کلیدها یا کلمات عبور باشند.
اگر آسیبپذیری File Inclusion موجود بر روی سرور از نوع اجرای کد باشد، ما نمیتوانیم سورس کد مربوط به هر فایل را به طور مستقیم مشاهده نماییم. این امر به ویژه در زبان PHP به دلیل تمایل توسعه دهنده به ذخیره اطلاعات با ارزش، مانند Credential های مربوط به پایگاهداده در کد، مشکلساز است.
اگر قرار باشد، برای مثال، wp-config.php را Include کنیم، محتویات فایل پیکربندی وردپرس را نخواهیم دید، بلکه تنها یک صفحه خالی را مشاهده خواهیم کرد. کدی که Credential مربوط به پایگاهداده را در یک متغیر PHP ذخیره میکند اجرا شد، اما هیچ چیزی توسط این کد به عنوان خروجی در نظر گرفته نشده است، بنابراین هیچ چیزی در صفحه مشاهده نمیشود.
برای عبور از این حالت، میتوانیم از یک ویژگی PHP استفاده کنیم که هنگام برخورد با یک جریان فایل، به سرور میگوید که قبل از پردازش، یک فایل را از طریق یک فیلتر اجرا کند. اگر ما بتوانیم یک عملیات فیلتر بر روی فایل انجام دهیم که از تفسیر آن به عنوان کد جلوگیری میکند اما هنوز هم به ما اجازه خواندن محتویات پس از فیلتر را میدهد، میتوانیم به طور موثر از اجرا جلوگیری کنیم و همچنان محتوای فایل منبع را بخوانیم.
یکی از این فیلترهایی که در PHP موجود است، Convert.base64-encode است. این فیلتر فایل را به صورت Base64 کدگذاری میکند، در نتیجه هر تگ مربوط به PHP را که به طور معمول کد اجرایی را نشان میدهد به متن ساده تبدیل میکند که سرور آن را تفسیر یا اجرا نمیکند – فقط آن را در صفحه نمایش میدهد.
سپس خروجی که به صورت Base64 میباشد را دیکد نموده تا محتویات فایل گنجانده شده را بازیابی نماییم. نکته کلیدی در اینجا است که فیلترینگ / کدگذاری، قبل از تلاش PHP برای اجرای فایل رخ میدهد. PHP هیچ وقت تگها را که به طور معمول به آن نشان میدهند که کدی برای اجرا وجود دارد، نمیبیند.
برای کدگذاری Base64 فایل با استفاده از عملکرد فیلترPHP، ما از یک پارامتر URL خاص به عنوان مسیر فایل استفاده میکنیم:
php://filter/read=convert.base64‐encode/resource=filename
توجه داشته باشید که چون این یک URL-Style Inclusion میباشد، هر متن از پیش نوشته شده (Prepended) ما را از استفاده از این تکنیک باز میدارد.
مثال مربوط به پیشگیری از اجرا
حالا به یک مثال نگاه کنید که این چگونه کار میکند. صفحه نمونه،fileview.php میباشد که دارای یک آسیبپذیری File Inclusion در هنگام استفاده از پارامتر loc میباشد.
در مرحله اول، ابتدا فایل /etc/passwd را فراخوانی نموده و مشاهده میکنیم که محتوای این فایل در صفحه نمایش داده میشود.
fileview.php?loc=/etc/passwd
در مرحله بعدی ما میدانیم که این برنامه تحت وب دارای یک فایل با نام config.php میباشد که در Web Root قرار گرفته و اطلاعات مربوط به دیتابیس درون آن ذخیره شده است. حالا بدون هیچ فیلتری سعی کنید تا آن را include نمایید.
به دلیل اینکه تمام اطلاعات با ارزش در این فایل، بین تگهای PHP قرار گرفته است، کد اجرا شده و تنها چیزی که شما مشاهده میکنید یک صفحه خالی میباشد:
fileview.php?loc=config.php
حالا فیلتر خود را با استفاده از مسیر زیر اعمال نمایید:
fileview.php?loc=php://filter/read=convert.base64‐encode/resource=config.php
در اینجا شما یک خروجی دارید که قابل مشاهده میباشد. این خروجی به روش Base64 کدگذاری شده است. پس از دیکد نمودن این مقدار، محتویات فایل چیزی شبیه کد زیر خواهد بود: