ویرگول
ورودثبت نام
سید عمید قائم مقامی
سید عمید قائم مقامیبرنامه نویسی سیستم ویندوز و مهندسی معکوس و علاقه مند به آموزش.
سید عمید قائم مقامی
سید عمید قائم مقامی
خواندن ۱۶ دقیقه·۲۱ روز پیش

آنتی ویروس قسمت سوم:

رویکردهای تحقیق در آنتی‌ویروس

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

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

در این فصل، به موضوعات زیر پرداخته خواهد شد:

• درک رویکردهای مختلف در تحقیق آنتی‌ویروس

• معرفی سیستم‌عامل ویندوز و آشنایی با مفهوم حلقه‌های حفاظتی

• حلقه‌های حفاظتی در سیستم‌عامل ویندوز

• لیست کنترل دسترسی (ACL) در ویندوز

• مشکلات مربوط به سطح دسترسی در نرم‌افزارهای آنتی‌ویروس

• مسیر سرویس بدون کوتیشن (Unquoted Service Path)

• ربایش DLL (DLL Hijacking)

• سرریز بافر (Buffer Overflow)

درک رویکردهای تحقیق در آنتی‌ویروس

دو رویکرد اصلی برای تحقیق روی آنتی‌ویروس‌ها وجود دارد. هر دوی این رویکردها در نهایت باید به یک نتیجه واحد منجر شوند و آن نتیجه همواره دور زدن نرم‌افزار آنتی‌ویروس و اجرای کد مخرب روی سیستم کاربر (Endpoint) است.

این دو رویکرد تحقیق در آنتی‌ویروس عبارت‌اند از:

• پیدا کردن یک آسیب‌پذیری در نرم‌افزار آنتی‌ویروس

• استفاده از روش‌های بایپس تشخیص (Detection Bypass)

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

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

نکته مهم

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

معرفی سیستم‌عامل ویندوز

از آن‌جایی که در این کتاب درباره دور زدن آنتی‌ویروس‌های مبتنی بر ویندوز صحبت می‌کنیم، ابتدا به بررسی سیستم‌عامل ویندوز و سازوکارهای امنیتی و حفاظتی آن می‌پردازیم. نخستین نسخه‌های سیستم‌عامل ویندوز برای پردازنده‌ها و مشخصات سخت‌افزاری خاصی توسعه داده شده بودند. با معرفی Windows NT، نسل جدیدی از ویندوز ارائه شد؛ یک سیستم‌عامل مستقل از پردازش (Process-Independent) که از پردازش چندگانه (Multiprocessing)، محیط چندکاربره (Multi-User) پشتیبانی می‌کرد و نسخه‌های جداگانه‌ای برای ایستگاه‌های کاری (Workstation) و سرورها ارائه می‌داد.

در ابتدا، Windows NT برای پردازنده‌های ۳۲ بیتی نوشته شده بود، اما بعدها دامنه پشتیبانی آن به معماری‌های گسترده‌تری گسترش یافت؛ از جمله IA-32، ‏MIPS، ‏Itanium، ‏ARM و موارد دیگر. همچنین مایکروسافت پشتیبانی از معماری‌های ۶۴ بیتی را به همراه ویژگی‌های مهم و جدیدی اضافه کرد؛ از جمله Windows API و Native API، اکتیو دایرکتوری (Active Directory)، سیستم فایل NTFS، لایه انتزاع سخت‌افزار (HAL)، بهبودهای امنیتی و بسیاری قابلیت‌های دیگر.

در طول سال‌ها، گروه‌ها و افراد زیادی از مایکروسافت به دلیل توجه ناکافی به امنیت اطلاعات در سیستم‌عامل‌های ویندوز انتقاد کرده‌اند. برای مثال، در تصویر زیر مشاهده می‌کنیم که حتی نویسندگان بدافزار Blaster نیز نسبت به سطح امنیت سیستم‌عامل ویندوز اعتراض و انتقاد داشته‌اند.

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

• ASLR (تصادفی‌سازی چیدمان فضای آدرس)

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

• DEP (جلوگیری از اجرای داده‌ها)

قابلیتی که مانع اجرای کد در بخش‌هایی از حافظه می‌شود که صرفاً برای نگهداری داده در نظر گرفته شده‌اند و نه برای اجرای کد.

• SEHOP (محافظت در برابر بازنویسی Structured Exception Handling)

مکانیزمی برای جلوگیری از سوءاستفاده از آسیب‌پذیری‌هایی که با بازنویسی ساختارهای مدیریت استثنا (SEH) انجام می‌شوند.

مکانیزم امنیتی ASLR از سوءاستفاده بدافزارها از آسیب‌پذیری‌های امنیتی‌ای که بر پایه آدرس‌های قابل پیش‌بینی حافظه در سیستم‌عامل هستند جلوگیری می‌کند. ASLR این کار را با تصادفی‌سازی فضای آدرس حافظه انجام می‌دهد و کتابخانه‌های حیاتی (DLLها) را در آدرس‌هایی از حافظه بارگذاری می‌کند که در زمان راه‌اندازی سیستم (Boot) به‌صورت تصادفی تعیین شده‌اند.

در تصویر قبلی مشاهده می‌کنید که فایل‌های DLL در زمان راه‌اندازی سیستم (Boot) در آدرس‌های حافظه‌ای بارگذاری می‌شوند که توسط ASLR به‌صورت تصادفی تعیین شده‌اند.

مکانیزم امنیتی حافظه DEP از اجرای کد در نواحی خاصی از حافظه که به‌عنوان صفحات غیرقابل اجرا (Non-Executable) علامت‌گذاری شده‌اند جلوگیری می‌کند. این موضوع باعث می‌شود تلاش برای بهره‌برداری از آسیب‌پذیری‌های سرریز بافر (Buffer Overflow) یا کاملاً متوقف شود یا دست‌کم به‌مراتب دشوارتر گردد.

مکانیزم امنیتی زمان اجرا SEHOP از تلاش‌های بهره‌برداری کدهای مخرب که با سوءاستفاده از ساختار SEH سیستم‌عامل و از طریق تکنیک بازنویسی SEH (SEH Overwrite) انجام می‌شوند جلوگیری می‌کند. این مکانیزم امنیتی همچنین می‌تواند از طریق تنظیمات Group Policy و گزینه‌های Process Mitigation Options فعال و اعمال شود.

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

درک مفهوم حلقه‌های حفاظتی (Protection Rings)

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

اصطلاح «حلقه حفاظتی» به یک مکانیزم سلسله‌مراتبی اشاره دارد که در پردازنده‌ها پیاده‌سازی شده و توسط سیستم‌عامل‌هایی مانند ویندوز مورد استفاده قرار می‌گیرد. هدف این مکانیزم، حفاظت از سیستم از طریق ایجاد تحمل‌پذیری در برابر خطا (Fault Tolerance) و همچنین افزایش امنیت در برابر فعالیت‌ها و رفتارهای مخرب است. هر حلقه در این ساختار نقش مشخص و منحصربه‌فردی در عملکرد کلی سیستم‌عامل دارد؛ همان‌طور که در تصویر زیر مشاهده می‌شود.

هرچه عدد حلقه (Ring) کمتر باشد، آن حلقه به سخت‌افزار نزدیک‌تر است و در نتیجه سطح دسترسی و امتیاز (Privilege) بالاتری دارد. همان‌طور که در تصویر مشاهده می‌کنید، Ring 0 هسته (Kernel) سیستم‌عامل است که دسترسی مستقیم و دوطرفه («back-to-back») به سخت‌افزار را برای حلقه‌های بالاتر فراهم می‌کند و برعکس.

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

حلقه‌های حفاظتی در سیستم‌عامل ویندوز

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

• Ring 3 – این حلقه با نام‌های «حالت کاربر» (User Mode)، «یوزرلند» (Userland) یا «یوزر‌اسپیس» (Userspace) نیز شناخته می‌شود. همان‌طور که از نامش پیداست، این حلقه جایی است که کاربر با سیستم‌عامل تعامل دارد؛ عمدتاً از طریق رابط کاربری گرافیکی (GUI) یا خط فرمان.

هر عملی که توسط یک برنامه یا پردازش در سیستم‌عامل انجام می‌شود، در نهایت به حلقه‌های پایین‌تر منتقل می‌گردد. برای مثال، زمانی که کاربر یک فایل متنی را ذخیره می‌کند، سیستم‌عامل این کار را با فراخوانی یک تابع از Windows API مانند ‎CreateFile()‎ انجام می‌دهد. این فراخوانی به نوبه خود کنترل را به هسته سیستم‌عامل (Ring 0) منتقل می‌کند. سپس کرنل عملیات را مدیریت کرده و دستورالعمل‌های منطقی را به بیت‌های نهایی تبدیل می‌کند؛ بیت‌هایی که در نهایت در یک سکتور از هارد دیسک رایانه نوشته می‌شوند.

• Ring 2 و Ring 1 – این دو حلقه عموماً برای درایورهای سخت‌افزاری طراحی شده‌اند. در سیستم‌عامل‌های مدرن، این حلقه‌ها اغلب مورد استفاده قرار نمی‌گیرند یا نقش بسیار محدودی دارند.

• Ring 0 – حلقه صفر یا کرنل (Kernel) پایین‌ترین حلقه در سیستم‌عامل است و به همین دلیل بیشترین سطح دسترسی و امتیاز را دارد. برای نویسندگان بدافزار، دسترسی به این لایه عمیق از سیستم‌عامل یک رؤیای بزرگ محسوب می‌شود، زیرا بیشترین میزان دید و کنترل را روی کل سیستم فراهم می‌کند و امکان دستیابی به داده‌های حساس، حیاتی و ارزشمندتری را از سیستم قربانی می‌دهد.

هدف اصلی کرنل این است که اعمال و درخواست‌هایی را که به‌صورت «دوطرفه» (back-to-back) از حلقه‌های بالاتر صادر می‌شوند، به سطح سخت‌افزار ترجمه کند و همچنین پاسخ سخت‌افزار را به حلقه‌های بالاتر بازگرداند. برای مثال، عملی که توسط کاربر انجام می‌شود—مانند مشاهده یک تصویر یا اجرای یک برنامه—در نهایت به کرنل می‌رسد تا در سطح پایین سیستم پردازش شود.

نمودار زیر، جریان اجرای Windows API را از فضای کاربر (User Space) به فضای کرنل (Kernel Space) نشان می‌دهد:

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

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

با این حال، هر نرم‌افزار آنتی‌ویروس دارای مؤلفه‌هایی در Ring 3 است؛ به‌ویژه مؤلفه‌های مربوط به تشخیص (Detection Components). این مؤلفه‌ها در صورتی که به‌درستی پیکربندی نشده باشند، ممکن است به یک کاربر عادی (غیرادمین) اجازه دهند آسیب‌پذیری‌های مبتنی بر سطح دسترسی (Permission-Based Vulnerabilities) را شناسایی و حتی از آن‌ها سوءاستفاده کند.

جدول زیر سطوح مجوز سیستم عامل ویندوز را نشان می دهد

فهرست کنترل دسترسی اختیاری (DACL):

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

لیست کنترل دسترسی در ویندوز (Windows Access Control List)

هر فایل در سیستم‌عامل—از جمله فایل‌های اجرایی، DLLها، درایورها و سایر اشیای سیستمی—دارای مجوزهایی است که بر اساس لیست کنترل دسترسی یا ACL پیکربندی شده‌اند.

در سیستم‌عامل ویندوز، ACL با نام DACL شناخته می‌شود و از دو بخش اصلی تشکیل شده است:

• بخش اول: موجودیت امنیتی (Security Principal) که مجوزهای مربوطه به آن اختصاص داده می‌شود؛ مانند کاربر، گروه یا سرویس.

• بخش دوم: مجوزهایی که شیء دریافت می‌کند، به‌علاوه مجوزهایی که به‌صورت موروثی (Inherited Permissions) از سطوح بالاتر به آن منتقل شده‌اند.

هر یک از این اشیا در لیست کنترل دسترسی (ACL) به‌عنوان یک مخفف تعریف‌شده (Defined Acronym) در نظر گرفته می‌شوند. در تصویر زیر می‌توانید یک نمونه از چنین ACL را مشاهده کنید:

در تصویر قبلی، می‌توانیم موجودیت‌ها (Entities) یا اشیای اصلی امنیتی (Security Principal Objects) را ببینیم که مجوزهای مربوطه به آن‌ها اختصاص داده می‌شود.

مشکل‌های دسترسی در نرم‌افزارهای آنتی‌ویروس

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

دسترسی ناکافی به فایل امضای ایستا

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

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

دسترسی‌های نادرست

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

پس از یک فرآیند ساده جمع‌آوری اطلاعات اولیه، نام فرآیندهای راهکار DLP و مسیر کامل این فرآیندهای بارگذاری‌شده در سیستم فایل همراه با سطح دسترسی آن‌ها به دست آمد. ما کشف کردیم که عامل DLP شرکت Symantec با دسترسی‌های نادرست پیاده‌سازی شده بود. این یعنی کاربری (معمولاً با دسترسی مدیریتی) که دسترسی ارتقا یافته به NT AUTHORITY\SYSTEM داشت، می‌توانست از این آسیب‌پذیری استفاده کرده و تمام فایل‌های داخل پوشه DLP را حذف کند.

در این حالت، پس از اینکه سطح دسترسی خود را از Administrator به SYSTEM ارتقا دادیم (با استفاده از ابزار Sysinternals-PSexec) و پس از اینکه اطلاعات کافی درباره مسیر کامل پوشه DLP جمع‌آوری کردیم (با استفاده از ابزار Sysinternals-Process Explorer)، محتوای پوشه را حذف کرده و سیستم را ریستارت کردیم. با انجام این کار، توانستیم داده‌ها را از سیستم سازمان استخراج کنیم و به‌طور کامل هدف این راهکار DLP پرهزینه و پیچیده را ناکام بگذاریم.

ما این آسیب‌پذیری را به Symantec اطلاع دادیم و آن‌ها نسخه جدیدتری منتشر کردند که این مشکل در آن رفع شده بود.

مشکلات دسترسی همچنین می‌تواند به شکل آسیب‌پذیری مسیر سرویس بدون کوتیشن (Unquoted Service Path) نیز ظاهر شود.

مسیر سرویس بدون کوتیشن (Unquoted Service Path)

وقتی در سیستم‌عامل ویندوز سرویسی ایجاد می‌شود که مسیر فایل اجرایی آن شامل فاصله (Space) است و این مسیر داخل علامت نقل‌قول (Quotation Marks) قرار نگرفته باشد، آن سرویس در معرض آسیب‌پذیری «مسیر سرویس بدون کوتیشن» قرار می‌گیرد.

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

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

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

یک آسیب‌پذیری دیگر که می‌تواند به ما کمک کند نرم‌افزارهای آنتی‌ویروس را دور بزنیم، پیش‌بارگذاری یا ربایش DLL (DLL Preloading/Hijacking) است.

ربایش DLL (DLL Hijacking)

این آسیب‌پذیری از مکانیزم ناامن بارگذاری DLL در سیستم‌عامل ویندوز سوءاستفاده می‌کند.

وقتی یک نرم‌افزار می‌خواهد یک DLL خاص را بارگذاری کند، از فراخوانی API ویندوزی LoadLibrary() استفاده می‌کند. این تابع به‌عنوان پارامتر، نام DLL موردنظر برای بارگذاری را دریافت می‌کند. استفاده از تابع LoadLibrary() توصیه نمی‌شود، زیرا این امکان وجود دارد که DLL اصلی با DLL دیگری که همان نام را دارد جایگزین شود و به این ترتیب، برنامه به‌جای DLL اصلی موردنظر، DLL ما را اجرا کند.

در نرم‌افزارهای غیرآنتی‌ویروس، این آسیب‌پذیری می‌تواند شدت پایین تا متوسطی داشته باشد، اما در زمینه نرم‌افزارهای آنتی‌ویروس، این آسیب‌پذیری می‌تواند به سطح بحرانی (Critical) برسد؛ زیرا در این حالت می‌توانیم باعث شویم آنتی‌ویروس یک DLL مخرب را بارگذاری و اجرا کند. در برخی موارد، این DLL حتی می‌تواند خود آنتی‌ویروس را غیرفعال کند یا به دور زدن مکانیزم‌های لیست سفید (Whitelist) کمک نماید.

نکته مهم

برای سوءاستفاده از یک آسیب‌پذیری ربایش DLL در نرم‌افزارهای آنتی‌ویروس، در بسیاری از مواقع لازم است قبل از انجام اکسپلویت، به سطح دسترسی‌های بالا (High Privileges) دست پیدا کنید.

در سال‌های اخیر، آسیب‌پذیری‌های متعددی از این نوع در آنتی‌ویروس‌های شرکت‌های مطرح شناسایی شده‌اند؛ از جمله AVG و Avast با شناسه CVE-2019-17093، Avira با CVE-2019-17449، McAfee با CVE-2019-3648، Quick Heal با CVE-2018-8090 و موارد دیگر.

یک آسیب‌پذیری دیگر که می‌تواند به ما در دور زدن نرم‌افزارهای آنتی‌ویروس کمک کند، سرریز بافر (Buffer Overflow) است.

سرریز بافر (Buffer Overflow)

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

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

دو نوع آسیب‌پذیری سرریز بافر وجود دارد که می‌توان از آن‌ها سوءاستفاده کرد:

سرریز بافر مبتنی بر پشته (Stack-based Buffer Overflow)

سرریز بافر مبتنی بر هیپ (Heap-based Buffer Overflow)

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

دو رویکرد برای یافتن آسیب‌پذیری‌های سرریز بافر (چه مبتنی بر پشته و چه مبتنی بر هیپ) وجود دارد: دستی و خودکار.

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

رویکرد خودکار شامل استفاده از ابزارهایی به نام فازر (Fuzzer) است که فرایند یافتن ورودی‌های کاربر و در برخی موارد، کشف آسیب‌پذیری‌ها در مکانیزم‌ها و قابلیت‌های پشت کد را به‌صورت خودکار انجام می‌دهند. این فعالیت با نام فازینگ (Fuzzing) یا تست فاز (Fuzz Testing) شناخته می‌شود. چندین نوع فازر برای این کار وجود دارد:

مبتنی بر جهش (Mutation-based)

ساده یا کور (Dumb)

هوشمند (Smart)

آگاه از ساختار (Structure-aware)

سرریز بافر مبتنی بر پشته (Stack-based Buffer Overflow)

این آسیب‌پذیری زمانی قابل سوءاستفاده است که اعتبارسنجی مناسب روی حدود ورودی انجام نشود. مثال کلاسیک آن استفاده از توابعی مانند strcat() و strcpy() است که طول ورودی را بررسی نمی‌کنند. این توابع را می‌توان به‌صورت پویا با استفاده از فازرها آزمایش کرد یا حتی به‌صورت دستی با ابزارهایی مانند دیس‌اسمبلرهایی نظیر IDA Pro و دیباگرهایی مانند x64dbg بررسی نمود.

مراحل کلی برای بهره‌برداری از این نوع آسیب‌پذیری به شرح زیر است:

۱. ایجاد کرش در برنامه برای درک محل وقوع آسیب‌پذیری.

۲. یافتن تعداد دقیق بایت‌هایی که باید سرریز شوند تا به آدرس شروع رجیستر EIP/RIP (اشاره‌گر دستورالعمل) برسیم.

۳. بازنویسی رجیستر EIP/RIP به‌گونه‌ای که به آدرس موردنظر شل‌کد تزریق‌شده اشاره کند.

۴. تزریق شل‌کد به آدرس قابل‌کنترل موردنظر.

۵. در صورت نیاز، تزریق اسلِدهای NOP (دستور بدون عملیات).

۶. پرش به آدرس payload تزریق‌شده برای اجرای آن.

راه‌های متعددی برای رسیدن به این هدف وجود دارد؛ از جمله استفاده از ترکیبی از دستورالعمل‌های leave و ret، تسهیل زنجیره‌های برنامه‌نویسی بازگشت‌محور (ROP) و روش‌های دیگر.

سرریز بافر – رویکرد دور زدن آنتی‌ویروس

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

خلاصه

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

در سه فصل بعدی، رویکرد دوم را بررسی خواهیم کرد و با جزئیات وارد آن می‌شویم؛ با استفاده از روش‌های متعدد دور زدن، همراه با ۱۰ مثال عملی.

Telegram: @CaKeegan
Gmail : amidgm2020@gmail.com

آنتی ویروسویندوزwindows
۰
۰
سید عمید قائم مقامی
سید عمید قائم مقامی
برنامه نویسی سیستم ویندوز و مهندسی معکوس و علاقه مند به آموزش.
شاید از این پست‌ها خوشتان بیاید