کشف آسیب‌پذیری CSRF

متخصصین امنیتی ما یک آسیب‌پذیری CSRF کشف کردند. این مورد یک نوع حمله امنیتی می‌باشد که می‌تواند باعث تغییر یا حذف اطلاعات در وب‌سایت‌ها شود.
تصویر شاخص مقاله آسیب‌پذیری CSRF

در این مقاله می‌خوانیم

آسیب‌پذیری CSRF چیست؟

آسیب‌پذیری از نوع Cross-Site Request Forgery (CSRF)، یک نوع حمله امنیتی می‌باشد که می‌تواند باعث تغییر یا حذف اطلاعات در یک وب‌سایت شود. این حمله به صورتی انجام می‌شود که یک هکر با استفاده از یک کاربر غیر هویت‌دار، با فرستادن یک درخواست غیر مجاز به سرور، تغییرات را در اطلاعات وب‌سایت ایجاد می‌کند.

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

روش‌های جلوگیری از آسیب‌پذیری CSRF

  • استفاده از Tokenهای مخصوص برای هر درخواست که از سایت ارسال می‌شود. این Tokenها باید فقط در پاسخ به درخواست‌های معتبر استفاده شود و نباید در سایت دیگری قابل نمایش باشند.
  • استفاده از HTTP Referrer Headerها برای بررسی اینکه آیا درخواست از سایت معتبر یا غیر معتبر ارسال شده است.
  • استفاده از پروتکل HTTPS به جای HTTP برای ارسال درخواست‌ها.
  • استفاده از مهارت‌های مرتبط با سیزینگ (Session Management) برای مدیریت نشست‌های کاربران.

روش‌های ارتقا آسیب‌پذیری CSRF به RCE

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

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

پس از بسته‌شدن آسیب‌پذیری CSRF، می‌توانید آسیب‌پذیری RCE را به صورت خطی یا غیرخطی شناسایی کنید. می‌توانید از ابزارهای مختلف مانند Burp Suite یا از طریق اجرای دستورات خاص در ترمینال نیز استفاده کنید.

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

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

مقاله مهم پیشنهادی برای مطالعه

آسیب‌پذیری ESXiargs چیست؟

مشخصات آسیب‌پذیری

نمای کلی از آسیب‌پذیری CSRF
نمای کلی آسیب‌پذیری
عنوان آسیب‌پذیریCSRF to RCE
نامWP Customer Area
نسخه8.1.3
کد آسیب‌پذیریSubmission #7953
درجه اهمیتCritical
جدول مشخصات آسیب‌پذیری
ساختار کد آسیب‌پذیر
ساختار کد آسیب‌پذیر

مسیر فایل:

wp-admin/options-qeneral.php

محتویات:

switch ($action) {
            case 'chmod':
                if (empty($extra)) {
                    wp_send_json_error(__('Missing parameters', 'cuar'));
                }

                $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
                foreach ($iterator as $item) {
                    if (false === chmod($item, octdec($extra))) {
                        wp_send_json_error(__('Error while changing permissions. PHP probably does not have the required permissions. Please do it manually using FTP or SSH.',
                            'cuar'));
                    }
                }

                $current_perms = @fileperms($path) & 0777;
                if ($current_perms !== octdec($extra)) {
                    wp_send_json_error(__('Permissions could not be changed. PHP probably does not have the required permissions. Please do it manually using FTP or SSH.',
                        'cuar'));
                }
                break;

            case 'mkdir':
                if (empty($extra)) $extra = 0700;
                if ( !is_int($extra)) $extra = octdec($extra);
                @mkdir($path, $extra, true);
                if ( !file_exists($path)) {
                    wp_send_json_error(__('Folder could not be created', 'cuar'));
                }
                break;

            case 'secure-htaccess':
                $htaccess_template_path = trailingslashit(CUAR_PLUGIN_DIR) . 'extras/protect-folder.htaccess';
                $dest_htaccess_path = trailingslashit($path) . '.htaccess';

                @copy($htaccess_template_path, $dest_htaccess_path);
                if ( !file_exists($dest_htaccess_path)) {
                    wp_send_json_error(__('htaccess file could not be copied. Please do it manually using FTP or SSH.', 'cuar'));
                }

                break;
        }

در این کد، یک شی از نوع RecursiveDirectoryIterator با نام $iterator برای مورد دروغ ورودی به عنوان پارامتر به تابع RecursiveIteratorIterator ایجاد می‌شود. این شی به صورت خودکار پیمایش تمام پوشه‌ها و فایل‌های موجود در داخل پوشه مورد نظر انجام می‌دهد. سپس از بلوک کد foreach استفاده می‌شود تا برای هر فایل یا پوشهی که پیدا می‌شود، تابع chmod را برای تغییر دسترسی به فایل یا پوشه صدا زده و یا خطایی را که در حین این عملیات رخ می‌دهد، به عنوان نتیجه خطایی که در تابع wp_send_json_error قرار دارد، ارسال می‌کند.

در این قسمت کد، یک تابع با نام “mkdir” پیاده سازی شده است که هدف ایجاد یک پوشه جدید در مسیر تعیین شده است. ابتدا این تابع بررسی می‌کند که آیا متغیر $extra خالی است یا خیر. اگر خالی بود، مقدار پیش فرض 0700 به آن متغیر می‌دهد. سپس، این تابع بررسی می‌کند که آیا متغیر $extra یک عدد صحیح است یا خیر. اگر نبود، متغیر $extra را به یک عدد ده دهی از نوع octal تبدیل می‌کند.

در صورتی که پوشه مورد نظر توسط تابع mkdir ایجاد شد، پوشه به صورت موفقیت آمیز ایجاد می‌شود. ولی اگر پوشه مورد نظر ایجاد نشد، پیام خطای “Folder could not be created” را به عنوان نتیجه خطایی که در عنوان تابع wp_send_json_error قرار دارد، ارسال می‌شود.

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

case 'mkdir':
                if (empty($extra)) $extra = 0700;
                if ( !is_int($extra)) $extra = octdec($extra);
                @mkdir($path, $extra, true);
                if ( !file_exists($path)) {
                    wp_send_json_error(__('Folder could not be created', 'cuar'));
                }
                break;

درخواست مربوطه:

action=cuar_folder_action&folder_action=mkdir&path=
%2Fvar%2Fwww%2Fhtml%2Fwp-content%2Ftmpp&extra=0770

پارامتر folder_action و پارامتر path آسیب‌پذیر می‌باشد.

نتایج فاز ورودی در آسیب‌پذیری CSRF
نتایج فاز ورودی

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

تست نفوذ چگونه در یافتن نقاط آسیب‌پذیری به ما کمک می‌کند؟

ابتدا درخواست مربوطه را برای فاز نمودن مقادیر مجاز path بررسی نماییم.

مسیر  etc

etc

برای اشاره به مسیر root مسیر مربوط به را url encode وارد نماییم.

%2Fetc

پوشه در مسیر دلخواه و همچنین مجوز دلخواه ایجاد می‌گردد.

روش‌های جلوگیری از آسیب‌پذیری CSRF

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

نمونه کد پچ شده

case 'mkdir':
                // بررسی بیشتری از اطلاعات وارد شده توسط کاربر
                $extra = filter_var($extra, FILTER_VALIDATE_INT);
                if ($extra === false) {
                    wp_send_json_error(__('Invalid permissions value', 'cuar'));
                }
                // بیشتری از بررسی های اختیاری
                if (empty($extra)) $extra = 0700;
                if (strlen($path) > 250) {
                    wp_send_json_error(__('Invalid path length', 'cuar'));
                }
                // ایجاد پوشه
                @mkdir($path, $extra, true);
                if ( !file_exists($path)) {
                    wp_send_json_error(__('Folder could not be created', 'cuar'));
                }
                break;

در این نمونه کد، ابتدا اطلاعات وارد شده توسط کاربر از نوع عدد صحیح با استفاده از تابع filter_var فیلتر می‌شود. اگر مقدار وارد شده نامعتبر بود، پیام خطای “Invalid permissions value” ارسال می‌شود. سپس، موارد بیشتری از بررسی‌های اختیاری انجام می‌شود، مانند بررسی اینکه آیا مقدار وارد شده خالی است یا خیر و تعیین مقدار پیش‌فرض، یا بررسی طول مسیر وارد شده. در صورتی که این بررسی‌های اختیاری نیز موفق باشد.

پیمایش به بالا