آسیب‌پذیری‌های آپلود فایل

آسیب‌پذیری‌های آپلود فایل
دسته بندی: مقالات برچسب ها :

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

امنیت در آپلود فایل

منظور از آسیب‌پذیری‌های آپلود فایل چیست؟

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

در برخی موارد، صرفاً آپلود فایل به‌خودی‌خود برای آسیب‌رسانی کفایت می‌کند. در سایر حملات ممکن است فرد مهاجم ملزم به ارسال درخواست HTTP دیگری تحت عنوان درخواست پسایند برای فایل آپلود‌شده باشد که معمولاً باهدف اجرای از راه دور فایل مخرب توسط سرور ارسال می‌شود.

اثرات و عواقب آسیب‌پذیری‌های آپلود فایل چیستند؟

به‌طورکلی، تأثیر آسیب‌پذیری‌های آپلود فایل به دو عامل کلیدی بستگی دارد:

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

در بدترین حالت، نوع فایل به‌درستی و به حد کافی اعتبارسنجی نمی‌شود و نحوه‌ی پیکربندی و تنظیمات سرور این اجازه را می‌دهد تا انواع خاصی از فایل‌ها با پسوندهای به‌طوربالقوه مضر (مانند php. و .jsp.) به‌عنوان کد زبان‌های برنامه‌نویسی در سمت سرور تفسیر و اجرا شوند. در این حالت، فرد مهاجم با آپلود فایل حاوی کد مخرب که در سمت سرور اجرا می‌شود و در قالب پوسته‌ی وب عمل می‌کند، عملاً می‌تواند کنترل کامل سرور را به دست آورد.

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

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

آسیب‌پذیری‌های آپلود فایل چگونه ایجاد می‌شوند؟

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

در نهایت باید گفت که حتی معیارهای اعتبارسنجی قدرتمند هم ممکن است به شکلی ناهماهنگ در کل شبکه‌ی حاوی میزبان‌ها و دایرکتوری‌های تشکیل‌دهنده‌ی وب‌سایت به کار گرفته شوندکه این امر منجر به مغایرت‌هایی می‌شود که احتمال بهره‌برداری از آن‌ها وجود دارد.

در ادامه‌ی این مبحث، نحوه‌ی بهره‌برداری از برخی از این نقص‌ها (آسیب‌پذیری‌ها) جهت آپلود یک پوسته‌ی وب برای اجرای کد از راه دور را به شما آموزش خواهیم داد. ما حتی تعدادی آزمایشگاه تعاملی و عمداً آسیب‌پذیر طراحی و ایجاد کرده‌ایم تا بتوانید آموخته‌های خود را در برابر سیستم‌ها یا محیط‌های شبیه‌سازی‌شده بر مبنای دنیای واقعی تمرین کنید.

نحوه‌ی مدیریت درخواست‌های مربوط به فایلهای ثابت توسط وب‌سِرورها

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

در روزهای اولیه‌ی اینترنت، بیشتر وب‌سایت‌ها صرفاً مجموعه‌ای از فایل‌های ثابت مانند صفحات HTML، تصاویر و فایل‌های CSS بودند. این فایل‌ها در فایل‌سیستم سرور ذخیره می‌شدند و زمانی‌که کاربر صفحه‌ای را درخواست می‌کرد، سرور به‌سادگی فایل مربوطه را ارائه می‌کرد. در نتیجه، این امکان وجود داشت که مسیر هر درخواست مانند /index.html، مستقیماً و به‌صورت 1:1 به سلسله‌مراتبی از فایل‌ها و دایرکتوری‌های حاوی آن صفحه در فایل‌سیستم سرور، مانند /var/www/html/index.html پیوند داده شود. اما در سال‌های اخیر، وب‌سایت‌ها به شکلی فزاینده پویا شده‌اند و اغلب اوقات مسیر درخواست هیچ رابطه‌ی مستقیمی با فایل‌سیستم ندارد. بااین‌وجود، وب‌سرورها هنوز هم با درخواست‌هایی برای فایل‌های ثابتی همچون شیوه‌نامه‌ها (فایل‌های CSS)، تصاویر و غیره سروکار دارند که پویا نیستند.

فرایند مدیریت فایل‌های ثابت در وب‌سرورها، حتی با وجود حرکت به‌سوی وب‌سایت‌های پویاتر، به شکل قابل‌توجهی ثابت و بدون تغییر باقی‌مانده است. در برخی مواقع، وب‌سرور برای شناسایی پسوند فایل، مسیر یا URL درخواستی کاربر را تجزیه‌وتحلیل می‌کند. سپس باتکیه‌بر نتیجه‌ی این تجزیه‌وتحلیل، نوع فایل درخواستی را تعیین می‌کند که این فرایند معمولاً با مقایسه‌ی پسوند فایل با فهرستی از نگاشت‌های از پیش تنظیم‌شده بین پسوندها و انواع MIME انجام می‌شود. رخداد بعدی بستگی به نوع فایل و پیکربندی سرور دارد.

  • اگر نوع فایل غیراجرایی باشد، مانند تصویر یا صفحه‌ی HTML ایستا، سرور به‌سادگی محتویات فایل را در قالب پاسخ HTTP برای کلاینت ارسال می‌کند. این بدان معناست که کلاینت قادر خواهد بود فایل را در مرورگر خود مشاهده کند.
  • اگر نوع فایل مانند فایل PHP اجرایی باشد و سرور را برای اجرای چنین فایل‌هایی پیکربندی کرده باشیم، ابتدا سرور بر اساس هدرها و پارامترهای موجود در درخواست HTTP متغیرهایی را به فایل اختصاص می‌دهد و آن را پردازش می‌کند. در مرحله‌ی بعد این متغیرها می‌توانند توسط اسکریپت PHP هنگام اجرا استفاده شوند و در این مرحله خروجی حاصل از اسکریپت را می‌توان در قالب پاسخ HTTP برای کلاینت ارسال کرد.
  • اگر نوع فایل اجرایی باشد، اما سرور را برای اجرای فایل‌هایی ازاین‌قبیل پیکربندی نکرده باشیم، به‌طورکلی سرور با پیام خطا پاسخ می‌دهد. بااین‌حال، در برخی موارد، همچنان ممکن است محتویات فایل در قالب متن ساده به کلاینت ارائه شود. گاهی اوقات می‌توان به‌منظور افشای کد منبع و سایر اطلاعات حساس از پیکربندی‌های مشکل‌دار این‌چنینی بهره‌برداری کرد. در مطالب آموزشی مربوط به افشای اطلاعات ما، نمونه‌ای از این سناریو آورده شده است.

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

بهره‌برداری از آپلود نامحدود فایل برای استقرار پوسته‌ی وب

از دید امنیتی، بدترین حالت ممکن زمانی‌است که وب‌سایت به کاربر (فرد مهاجم بالقوه) اجازه دهد تا کدهای اسکریپت سمت سرور همچون فایل‌های رایجی PHP، Java و Python را آپلود کند و علاوه‌براین طوری پیکربندی شده باشد که این فایل‌ها را در قالب کد اجرا نماید. این امر فرایند ساخت اسکریپت مخرب پوسته‌ی وب بر روی سرور را برای فرد مهاجم بالقوه آسان می‌سازد.

پوسته‌ی وب

پوسته‌ی وب نوعی کد مخرب است که فرد مهاجم را قادر می‌سازد تا با ارسال درخواست‌های HTTP به نقطه‌ی خاصی از سرور موردنظر به‌سادگی دستورات دلخواه خود را از راه دور بر روی وب‌سرور اجرا کند.

اگر بتوانیم پوسته‌ی وبی را با موفقیت بر روی وب‌سرور آپلود کنیم، عملاً کنترل کاملی بر آن خواهیم داشت. این بدان معنی است که می‌توانیم هر فایلی را به‌دلخواه بخوانیم و بنویسیم، به داده‌های حساس دسترسی پیدا کنیم و آن‌ها را تغییر دهیم یا استخراج (دزدیدن) نماییم، حتی می‌توانیم از وب‌سرور به‌عنوان محور حملات خود به زیرساخت‌های داخل شبکه و سایر سرورهای خارج از شبکه استفاده کنیم. برای مثال، به‌منظور خواندن فایل‌های دلخواه از روی فایل‌سیستم سرور می‌توان از کد یک خطی PHP زیر (قطعه‌ای کوتاه از کد PHP) استفاده کرد:


php echo file_get_contents('/path/to/target/file');

به‌محض آپلود موفقیت‌آمیز فایل مخرب بر روی سرور، درخواستی (معمولاً درخواست HTTP) برای تعامل با این فایل مخرب ارسال می‌شود. سپس وب‌سرور این درخواست را پردازش می‌کند و در آخر محتویات فایل موردنظر (هدف) را در پاسخ بازمی‌گرداند.

پوسته‌ی وبی با سطح عملکرد پیشرفته‌تر در مقایسه با پوسته‌های استاندارد ممکن است به این شکل باشد:


php echo system($_GET['command']);

با استفاده از این اسکریپت می‌توان به‌دلخواه هر نوع دستور معتبر سیستمی را در پارامترهای پرس‌وجو گنجاند و عبور داد:


GET /example/exploit.php?command=id HTTP/1.1

بهره‌برداری از اعتبارسنجی معیوب آپلود فایل

همان‌طور که در آزمایشگاه قبلی مشاهده کردیم، در سناریوهای دنیای واقعی بعید است با وب‌سایتی مواجه شویم که به طور کامل فاقد هرگونه مکانیزم محافظتی در برابر حملات آپلود فایل باشد. اما با وجود اجرای تدابیر دفاعی یا امنیتی برای مقابله با حملات آپلود فایل در وب‌سایت، تضمینی برای قدرتمندی یا قابلیت‌اعتماد (اثربخشی حتمی) این تدابیر نیست. در این بخش، ما به برخی از اقدامات امنیتی صورت‌گرفته از سوی وب‌سرورها برای اعتبارسنجی و عاری‌سازی آپلودها خواهیم پرداخت و همچنین چگونگی بهره‌برداری از عیوب این مکانیزم‌ها باهدف دستیابی به پوسته‌ی وب برای اجرای کد از راه دور را بررسی خواهیم کرد.

اعتبارسنجی معیوب نوع فایل

مرورگر معمولاً هنگام ارسال فرم‌های HTML، داده‌های ارائه‌شده را در قالب درخواست POST همراه با هدر نوع محتوای application/x-www-form-url-encoded ارسال می‌کند. این هدر برای ارسال متون ساده‌ای مانند نام، آدرس و غیره مناسب است، اما برای ارسال مقادیر زیادی از داده‌های باینری، همچون فایل عکس یا سند PDF مناسب نیست. روش ترجیحی هنگام برخورد با داده‌های حجیم باینری، استفاده از نوع محتوای دیگری به نام «multipart/form-data» است.

فرمی را تصور کنید که حاوی فیلدهایی برای آپلود تصویر، ارائه‌ی توضیحاتی در مورد آن و واردکردن نام کاربری است. درخواستی که از ارسال چنین فرمی حاصل می‌شود، شبیه این است:


POST /images HTTP/1.1
Host: normal-website.com
Content-Length: 12345
Content-Type: multipart/form-data; boundary=---------------------------012345678901234567890123456
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="image"; filename="example.jpg"
Content-Type: image/jpeg
[...binary content of example.jpg...]
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="description"
This is an interesting description of my image.
---------------------------012345678901234567890123456
Content-Disposition: form-data; name="username"
wiener
---------------------------012345678901234567890123456--

 

همان‌طور که مشاهده می‌کنید، بدنه‌ی پیام درخواست HTTP به بخش‌های مجزا تقسیم شده‌اند که هر بخش مربوط به یکی از فیلدهای ورودی فرم است. هر بخش از بدنه‌ی پیام حاوی هدری موسوم به ساختار محتوا است که این هدر با فیلد ورودی خاصی اتصال دارد و اطلاعات اولیه‌ای در مورد آن فیلد ورودی ارائه می‌دهد. هر یک از بخش‌های مجزای فرم می‌توانند هدر نوع محتوای مختص به خود را داشته باشند که وظیفه‌ی این هدر اعلام نوع MIME دیتای ارسال‌شده از طریق فیلد ورودی مرتبط با آن بخش به سرور است.

یکی از روش‌هایی که وب‌سایت‌ها ممکن است برای اعتبارسنجی آپلود فایل‌ها انجام دهند، بررسی مطابقت یا عدم مطابقت هدر نوع محتوای مختص به ورودی مذکور با نوع MIME مورد انتظار است. برای مثال، اگر سرور صرفاً در انتظار آپلود فایل‌های تصویری باشد، ممکن است فقط فایل‌هایی با هدر نوع محتوای مثلاً image/jpeg و image/png را مجاز اعلام کند. مشکل از جایی ممکن است آغاز شود که سرور بی‌چون‌وچرا به ارزش این هدر اعتماد کرده باشد. اگر برای بررسی تطابق یا عدم تطابق محتویات فایل با نوع MIME مورد انتظار هیچ‌گونه اعتبارسنجی دیگری صورت نگیرد، این مکانیزم دفاعی با استفاده از ابزارهایی مانند Burp Repeater به‌راحتی قابل دورزدن خواهد بود.

جلوگیری از اجرای فایل در دایرکتوری‌های قابل‌دسترس برای کاربر

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

برای احتیاط و امنیت بیشتر، عموماً سرورها فقط اسکریپت‌هایی را اجرا می‌کنند که نوع MIME آن‌ها به‌صراحت بر روی سرور پیکربندی شده باشد. هنگامی که سرور با اسکریپتی با نوع MIME پیکربندی‌نشده یا غیرمجاز روبرو می‌شود، به‌جای اجرای اسکریپت، یکی از این دو احتمال را دنبال می‌کند: یا با ایجاد پیام خطا و بازگردانی آن نشان می‌دهد که اجرای اسکریپت مجاز نیست، یا در سناریوهای خاص، ممکن است محتویات فایل را به‌عنوان متن ساده ارائه دهد.


GET /static/exploit.php?command=id HTTP/1.1
Host: normal-website.com
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 39
php echo system($_GET['command']);

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

این نوع پیکربندی اغلب بین دایرکتوری‌هایی با قوانین مختلف متفاوت است. دایرکتوری‌هایی که به طور خاص برای فایل‌های آپلودشده‌ی کاربران تعیین شده‌اند، معمولاً در مقایسه با نقاط دیگر فایل‌سیستم که تصور می‌شود برای کاربران عادی غیرقابل‌دسترس هستند، اقدامات امنیتی سخت‌گیرانه‌تری دارند. اگر فرد مهاجم موفق شود اسکریپتی را در دایرکتوری دیگری که قرار نیست حاوی فایل‌های آپلودشده‌ی کاربر باشد (جایی که معمولاً کنترل‌های سخت‌گیرانه‌ی کمتری اعمال می‌شود) آپلود کند، این احتمال وجود دارد که سرور فایل آپلودشده را اجرا کند.

علی‌رغم اینکه ما همه‌ی درخواست‌های خود را به‌سوی نام دامنه‌ای واحد (یک سرور) ارسال می‌کنیم، اغلب اوقات در میانه‌ی راه، نوعی پروکسی‌سرور معکوس مانند متعادل‌گر بار وجود دارد و ممکن است با چندین سرور در پشت‌صحنه سروکار داشته باشیم. درخواست‌های کاربر یا کلاینت معمولاً توسط سرورهای دیگری در پشت‌صحنه پردازش می‌شوند که برای کاربر مستقیماً قابل‌مشاهده یا قابل‌دسترسی نیستند و ممکن است پیکربندی متفاوتی نیز داشته باشند.

ایجاد لیست سیاه ناکافی برای انواع فایل‌های خطرناک

یکی از بدیهی‌ترین روش‌های جلوگیری از آپلود اسکریپت‌های مخرب توسط کاربران، ایجاد لیست سیاه از پسوند فایل‌هایی است که به‌طوربالقوه خطرناک در نظر گرفته می‌شوند، مانند پسوند .php که معمولاً با اسکریپت‌های PHP مرتبط است. (هدف جلوگیری از آپلود فایل‌هایی با پسوندهای لیست سیاه است.) فهرست‌کردن و مسدودسازی دقیق هر پسوند فایل قابل‌تصور که به‌طوربالقوه می‌تواند برای اجرای کد مورداستفاده قرار گیرد، چالش‌برانگیز و دشوار است، ازاین‌رو، استفاده از لیست سیاه اصلاً به‌تنهایی کافی نیست. گاهی اوقات می‌توان با استفاده از پسوندهای کمترشناخته‌شده و جایگزین مانند .php5، .shtml و غیره که عملکرد مشابهی دارند و همچنان می‌توانند کد را اجرا کنند، چنین لیست‌های سیاهی را دور زد.

لغو تنظیمات پیکربندی کل سرور

همان‌طور که در بخش قبلی گفته شد، سرورها معمولاً به طور پیش‌فرض فایل‌ها را فقط در صورتی اجرا می‌کنند که برای این کار پیکربندی شده باشند. برای مثال، سرور آپاچی قبل از اینکه فایل‌های PHP درخواستی توسط کلاینت را اجرا کند، توسعه‌دهندگان شاید مجبور باشند دستورالعمل‌های زیر را به فایلی با نام /etc/apache2/apache2.conf اضافه کنند تا اجرای فایل‌های PHP ممکن شود:


LoadModule php_module /usr/lib/apache2/modules/libphp.so
AddType application/x-httpd-php .php

بسیاری از سرورها به توسعه‌دهندگان این اجازه را می‌دهند تا برای لغو یا بسط تنظیمات کلی سرور در دایرکتوری‌های مجزا فایل‌های پیکربندی اختصاصی ایجاد کنند. برای مثال، سرورهای آپاچی، تنظیمات اختصاصی دایرکتوری را (در صورت وجود) از فایلی به نام .htaccess دریافت می‌کنند.

مشابه سرورهای آپاچی که برای تنظیمات اختصاصی از فایل‌های .htaccess بهره می‌برند، توسعه‌دهندگانی که با سرورهای IIS سروکار دارند می‌توانند با استفاده از فایلی به نام web.config پیکربندی‌های اختصاصی دایرکتوری ایجاد کنند.

فایل web.config ممکن است حاوی دستورالعمل‌ها یا تنظیمات پیکربندی خاص دایرکتوری مانند زیر باشد. این دستورالعمل نشان می‌دهد سرور به‌گونه‌ای پیکربندی شده است که به درخواست‌های کاربران برای فایل‌های JSON در آن دایرکتوری بخصوص رسیدگی کند و این فایل‌ها را به‌عنوان پاسخ به مرورگرهای کاربران یا برنامه‌های کلاینت ارائه دهد:


staticContent
mimeMap fileExtension=".json" mimeType="application/json"
staticContent

سرورهای وب از این نوع فایل‌های پیکربندی در صورت وجود استفاده می‌کنند، اما کاربران معمولاً مجاز به دسترسی مستقیم به آن‌ها با استفاده از درخواست‌های معمول HTTP نیستند. بااین‌حال، گاهی اوقات ممکن است سرورهایی یافت شوند که به دلیل ضعف‌های امنیتی یا پیکربندی نامناسب نتوانند فرد مهاجم را از آپلود فایل پیکربندی مخرب باز دارند. در این‌گونه موارد، حتی با وجود قرارداشتن پسوند فایل مخرب در لیست سیاه، ممکن است فرد مهاجم با فریب سرور بتواند پسوند فایلی دلخواه و سفارشی (که در لیست سیاه قرار ندارد) را به‌نوعی MIME اجرایی نگاشت کند.

مبهم‌سازی پسوندهای فایل

حتی جامع‌ترین لیست‌های سیاه را می‌توان با استفاده از تکنیک‌های مبهم‌سازی سنتی دور زد. فرض را بر این می‌گیریم که کد اعتبارسنجی مسئول بررسی پسوند فایل‌ها به حروف کوچک و بزرگ حساس است و نمی‌تواند تشخیص دهد که exploit.pHp در واقع یک فایل .php است؛ به این معنی که کد اعتبارسنجی به‌اشتباه آن را به‌عنوان فایلی با پسوند ناشناخته در نظر می‌گیرد. اگر در مرحله‌ی بعد کد مسئول نگاشت پسوندهای فایل به انواع MIME مربوطه، به حروف کوچک و بزرگ حساس نباشد، این ناهماهنگی در حساسیت به حروف فرد مهاجم را قادر می‌سازد تا فایل‌های مخرب PHP را به طور نامحسوس از گیت اعتبارسنجی عبور دهد که این امر در نهایت منجر به اجرای فایل‌ها از سوی سرور خواهد شد.

همچنین می‌توانید با استفاده از تکنیک‌های زیر به نتایج مشابهی دست یابید:

  • پسوندهای متعددی ایجاد کنید. بسته به الگوریتم مورداستفاده در تجزیه‌وتحلیل نام فایل، فایل زیر ممکن است به‌عنوان فایل PHP یا تصویر JPG تفسیر شود:

exploit.php.jpg

  • به انتهای نام فایل کاراکترهای پسایند (اضافی) مانند فضای خالی یا نقطه اضافه کنید (مثلاً php.). البته برخی از مؤلفه‌ها ممکن است این کاراکترهای پسایند را حذف کنند یا اینکه نادیده بگیرند.
  • سعی کنید برای کاراکترهای «.»، «/» و «\» از رمزنگاری URL (یا رمزنگاری دوگانه‌ی URL) استفاده نمایید. اگر فرایند اعتبارسنجی موفق به رمزگشایی ارزش این کاراکترها نشود و بعداً در طول پردازش در سمت سرور رمزگشایی شوند، می‌توان فایل‌های مخربی که در غیر این صورت مسدود می‌شدند را نیز آپلود کرد: exploit%2Ephp.
  • قبل از پسوند فایل، «;» یا کاراکترهای بایت تهی (کاراکترها یا رشته‌های تهی) کدشده با URL وارد کنید (به‌عنوان‌مثال، asp;.jpg یا exploit.asp%00.jpg). اگر اعتبارسنجی با زبان سطح بالایی مانند PHP یا جاوا نوشته شده باشد، اما سرور این فایل را با استفاده از توابع سطح پایین نوشته‌شده در زبان‌هایی مانند C/C++ پردازش کند، ممکن است در نحوه‌ی تفسیر انتهای نام فایل ناهماهنگی ایجاد شود. درواقع با افزودن کاراکتر تهی قبل از پسوند فایل، مانند «exploit.asp%00.jpg»، فرد مهاجم اساساً کاراکتر نشان‌دهنده‌ی پایان رشته را به سرور پردازشگر فایل تزریق می‌کند:

exploit.asp;.jpg یا exploit.asp%00.jpg

  • از کاراکترهای یونی‌کد چندبایتی استفاده کنید که پس از تبدیل به کاراکترهای اسکی یا فرایند عادی‌سازی یونی‌کد ممکن است به بایت‌های تهی و نقطه تبدیل شوند. اگر نام فایل ابتدا به‌صورت کاراکترهای یونی‌کد یا رشته‌ی UTF-8 تجزیه‌وتحلیل شود و قبل از استفاده در مسیر فایل، به کاراکترهای اسکی تبدیل شود، آنگاه توالی کاراکترهای چندبایتی مانند «xC0 x2E, xC4 xA» یا «xC0 xAE» ممکن است به‌صورت کاراکتر اسکی نقطه (x2E) ترجمه شوند. به عبارت ساده‌تر، اگر مسیر فایل به کاراکترهای اسکی تبدیل شود، کاراکترهای یونی‌کد چندبایتی در نام فایل ممکن است به بایت‌های تهی یا نقطه تبدیل شوند که این امر می‌تواند مشکلاتی از قبیل عدم دسترسی به فایل یا خرابی نام فایل را ایجاد کند.

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

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

اعتبارسنجی معیوب محتویات فایل

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

برای مثال، اگر فرد مهاجم سعی بر آپلود اسکریپت PHP داشته باشد، چون این اسکریپت اصلاً ابعادی ندارد، سرور می‌تواند نتیجه بگیرد که فایل آپلودشده احتمالاً تصویر نیست و براین‌اساس مانع از آپلود آن شود؛ زیرا انتظار دارد فایل‌هایی با پسوند تصویر دارای ابعاد مرتبط باشند.

به همین ترتیب، برخی از انواع فایل‌ها ممکن است همیشه در هدر یا فوتر خود دارای توالی یا سلسله‌ی خاص و متمایزی از بایت‌ها باشند. این سلسله بایت‌ها مانند اثر انگشت یا امضایی منحصربه‌فرد برای مطابقت‌دهی محتویات فایل با نوع مورد انتظار استفاده می‌شوند. برای مثال، فایل‌های JPEG همیشه با سلسله بایت‌های ثابت هگزادسیمال «FF D8 FF» شروع می‌شوند.

این روش در مقایسه با سایر روش‌های اعتبارسنجی نوع فایل بسیار قوی‌تر و قابل‌اعتمادتر عمل می‌کند، اما حتی این روش نیز خطاناپذير نیست. با استفاده از ابزارهای تخصصی مانند ExifTool، ایجاد فایل JPEG چندفرمتی در ظاهر معتبر اما حاوی کدهای مخرب (پنهان در متادیتای آن) می‌تواند آسان باشد.

بهره‌برداری از آسیب‌پذیری شرایط مسابقه (زمان‌بندی) در فرایند آپلود فایل

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

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

برای مثال، برخی وب‌سایت‌ها فایل را مستقیماً در فایل‌سیستم اصلی خود (سیستم ذخیره‌سازی اصلی سرور وب‌سایت) آپلود کرده و در صورت عدم موفقیت فایل در اعتبارسنجی، دوباره آن را حذف می‌کنند. این نوع رفتار (آپلود و حذف فایل بر اساس نتایج اعتبارسنجی) در وب‌سایت‌هایی که برای بررسی و شناسایی بدافزارها به نرم‌افزار ضدویروس و موارد مشابه متکی هستند، معمول است. اگرچه فرایند آپلود و حذف ممکن است خیلی سریع اتفاق بیفتد (در عرض چند میلی‌ثانیه)، اما در همین مدت کوتاهی که فایل قبل از حذف بر روی سرور قرار دارد، فرد مهاجم کماکان می‌تواند آن را اجرا کند.

این آسیب‌پذیری‌ها اغلب بسیار نامحسوس هستند و به دلیل همین ماهیت ظریف، شناسایی آن‌ها در حین آزمایش جعبه‌ی سیاه دشوار است و تنها در صورتی می‌توان آن‌ها را شناسایی کرد که به «کد منبع مرتبط» سیستم مورد آزمایش دسترسی پیدا کنیم.

آسیب‌پذیری شرایط مسابقه در آپلود فایلهای مبتنی بر آدرس URL

در مؤلفه‌هایی که به شما اجازه می‌دهند فایلی را با ارائه‌ی URL آپلود کنید، شرایط مسابقه‌ی مشابهی می‌تواند رخ دهد. در این فرایند که هنگام آپلود فایل با استفاده از آدرس URL اتفاق می‌افتد، سرور به‌جای دریافت مستقیم فایل از کاربر، باید آن را از آدرسی مشخص‌شده (URL) از طریق اینترنت بازآوری (دانلود) کند. سرور پس از بازآوری فایل، قبل از انجام هرگونه فرایند اعتبارسنجی کپی محلی از فایل ایجاد می‌کند.

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

برای مثال، اگر فایل در یک دایرکتوری موقت با نامی تصادفی دانلود شود، از لحاظ تئوری، برای فرد مهاجم غیرممکن است که از هرگونه شرایط مسابقه‌ای بهره‌برداری کند. فرد مهاجم اگر نام دایرکتوری را نداند، قادر به درخواست فایل باهدف اجرای آن نخواهد بود. از سوی دیگر، اگر نام تصادفی دایرکتوری با استفاده از مولفه‌های شبه‌تصادفی مانند uniqid() در زبان PHP تولید شده باشد، به‌طوربالقوه ممکن است تحت حمله‌ی brute-force قرار گیرد.

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

بهره‌برداری از آسیب‌پذیری‌های آپلود فایل بدون نیاز به اجرای کد از راه دور

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

آپلود اسکریپت‌های مخرب در سمت سرویس‌گیرنده

اگرچه شاید نتوان اسکریپت‌ها را بر روی سرور اجرا کرد، اما همچنان می‌توان اسکریپت‌هایی را برای انجام حملات در سمت سرویس‌گیرنده آپلود نمود. برای مثال، اگر بتوان فایل‌های HTML یا تصاویر SVG را آپلود کرد، به‌طوربالقوه می‌توان برای ایجاد بارهای ذخیره‌شده‌ی XSS (کدهای مخرب) از تگ‌های <script>  استفاده نمود که به‌محض باز شدن فایل اجرا می‌شوند.

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

بهره‌برداری از آسیب‌پذیری‌های موجود در نحوه‌ی تجزیه‌وتحلیل فایل‌های آپلودشده

اگر فایل آپلودشده از نظر ظاهری به شکلی ایمن ذخیره و سرویس‌دهی شده باشد، تنها گزینه‌ی باقی‌مانده برای مهاجم بهره‌برداری از آسیب‌پذیری‌هایی است که مختص به نحوه‌ی تجزیه‌وتحلیل یا پردازش قالب‌های مختلف فایل توسط سرور هستند. برای مثال، همان‌طور که می‌دانید، سرور فایل‌های مبتنی بر XML مانند فایل‌های مایکروسافت آفیس با پسوندهای .doc یا .xls را تجزیه‌وتحلیل می‌کند که این امر می‌تواند مسیری بالقوه برای حملات تزریق XXE باشد.

آپلود فایل‌ها با استفاده از روش PUT

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


PUT /images/exploit.php HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-httpd-php
Content-Length: 49
php echo file_get_contents('/path/to/file');

نکات

با ارسال درخواست‌های OPTIONS به نقاط پایانی مختلف، می‌توان پشتیبانی یا عدم پشتیبانی این نقاط پایانی از روش PUT را آزمایش کرد.

نحوه‌ی جلوگیری از آسیب‌پذیری‌های آپلود فایل

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

  • به‌جای استفاده از لیست سیاه پسوندهای ممنوعه، پسوند فایل را با استفاده از لیست سفید پسوندهای مجاز بررسی کنید. حدس‌زدن اینکه خواهان مجاز کردن کدام پسوندها هستیم، بسیار آسان‌تر از حدس‌زدن همه‌ی پسوندهایی‌است که فرد مهاجم ممکن است آپلود کند.
  • برای جلوگیری از حملات بالقوه‌ی پیمایش دایرکتوری، اطمینان حاصل کنید که نام فایل حاوی هیچ‌گونه زیررشته‌ای مانند (../) نباشد که احیاناً به‌عنوان دایرکتوری یا توالی پیمایش تفسیر شود.
  • برای جلوگیری از تلاقی‌هایی که ممکن است باعث بازنویسی نام فایل‌های موجود شوند، نام فایل‌های آپلودشده را تغییر دهید.
  • فایل‌ها را تا زمان گذر از اعتبارسنجی کامل، در فایل‌سیستم دائمی سرور آپلود نکنید.

تا جایی که ممکن است از تلاش برای نوشتن مکانیزم‌های اعتبارسنجی شخصی دست بردارید و برای پیش‌پردازش آپلود فایل از چهارچوب‌های آماده استفاده کنید.