تزریق کد به یک برنامه در حال اجرا ( یا Process Injection ) |
|
تعریف:
در ادبیات امنیت نرم افزار ، Process Injection به تزریق کد باینری به فضای آدرسی پروسه های دیگه گفته میشود . سیستمهای عامل مدرنی که از مدل Protected Mode استفاده میکنن ، برای هر پروسه با استفاده از ترکیب حافظه حقیقی و مجازی ، فضای آدرسی مستقلی رو تعریف میکنن که اجزاء یک پروسه ( توابع ، متغیرها ، اشاره گر ها ، رفرنسها ، کتابخانه های اشتراکی و ... ) داخل اون فضا آدرس دهی میشوند . پردازنده ، به نوبت ، کد ماشین رو بصورت جداگانه از هر فضای آدرسی دریافت و پردازش میکنه . اگر شما کد ماشین یا متغیر یا سایر موجودیتهای باینری مورد نظرتان را ، بدون اینکه بطور مستقیم متعلق به یک پروسه باشن ، به فضای آدرسی اون پروسه تزریق کنید ، یک Process Injection انجام داده اید. مثال : شما برنامه A.exe رو نوشته اید . یک برنامه به نام explorer.exe هم روی ویندوز وجود دارد . شما به هر دلیل مایلید یکی از عناصر موجود در فضای آدرسی explorer.exe رو توسط A.exe تغییر بدید . Process Injection یعنی تزریق کد مورد نظر از فضای A.exe به فضای explorer.exe . کاربرد: کاربرد اصلی و عام Process Injection ، توسعهء برنامه های مرتبط با Access Control است . برنامه های مثبت ، با استفاده از این تکنیک و با تزریق یک کد محافظ به فضای آدرس پروسه های سرور یا سرویس های ( inetinfo.exe یا svchost.exe و ... ) سعی میکنن این پروسه ها رو از گزند تلاشهای مخرب و کدهای مخرب ( Exploit ) ایمن نگه دارن . برنامه های منفی با استفاده از Process Injection به مقاصد شومی مثل عبور از فایروالهای شخصی و فریب دادن آنتی ویروسها خواهند رسید . مثال مثبت : زون آلارم(ZoneAlarm) ، با تزریق کد که اجرای کد باینری از طریق بخش Data ی Stack رو ممنوع میکنه ، به داخل فضای پروسه هائی مثل Services.exe از اونها نگهداری میکنه . این یه نمونه کاربرد مثبت Process Injection است . مثال منفی : اغلب فایروالهای شخصی ، Access Control رو مبتنی بر پروسهء فراخوانِ کد انجام میدهند . یعنی اگر فراخوانی کدی از طریق پروسهء قابل اعتماد IExplorer.exe ( مرورگر ویندوز ) انجام شده باشه ، فایروال اجازه ایجاد اتصال شبکه رو میده و اگر نه ، خیر . یک تروجان ، برای اتصال به شبکه ، با وجود یک فایروال شخصی توفیق چندانی نخواهد داشت ، اما با استفاده از یک Process Injection ساده و تزریق کد باینری مورد نظر برای ایجاد اتصال شبکه ای ، به فضای پروسهء IExplorer.exe میتونه فایروال رو دور بزنه . چند نمونه از کاربرد های مختلف آن: ویندوز 2003 سرور به عنوان یکی از معدود سیستمهای عاملی که روی IA32 میتونه تا حدود 4 گیگ آدرس دهی بکنه ، هم از Process Injection برای افزایش کیفیت و کارائی اش استفاده کرده . ویژگی HotPatch موجود در ویندوز 2003 دقیقا" از همین قابلیت استفاده میکنه . با تشکر از این تکنیک ، در صورت کشف یک نقطه ضعف امنیتی روی یک سرویس خاص ( مثلا" IIS 6 ) شما برای نصب Patch اون لازم نیست سرویس رو متوقف کنین . Patch با استفاده از سرویس HotPatch یک نسخه از خودش رو روی Image سرویس در هارد دیسک بازنویسی میکنه و یک نسخه از تصحیحات لازم رو بصورت زنده ( Process Injection ) روی سرویس در حال اجرا و سرویسدهی اعمال میکنه . به این ترتیب دفعه بعدی که سرویس اجرا میشه ، از یک نسخه امن استفاده میکنه مضاف بر اینکه ، همین حالا هم با اعمال زندهء تغییرات روی نسخهء در حال اجرای سرویس در فضای آدرسی مخصوص به خودش ، نقطه ضعف امنیتی بر طرف شده . مایکروسافت برای کسانی که میخوان از این ویژگی بصورت جدی استفاده کنن یک Calss Library مبتنی بر COM به رایگان منتشر کرده که با جستجو روی سایت مایکروسافت پیداش میکنی . ( CPP ) . مثال عملی(دلفی): { Process Injection by Inpy - Soul inprise@gmail-dot-com Greets to soul for giving me the imagebase idea. } program Project1; {$IMAGEBASE $13140000} uses Windows; //Injected entrypoint function Main(dwEntryPoint: Pointer): longword; stdcall; begin {now we are in notepad} LoadLibrary("kernel32.dll"); LoadLibrary("user32.dll"); MessageBox(0, "Hello, now I am in the memory of another process!", "Hijacked Process", 0); MessageBox(0, "Now we can do anything we want. :)", "Hijacked Process", 0); MessageBox(0, "You can even delete the original exe and these message boxes will still be here.", "Hijacked Process", 0); MessageBox(0, "See?", "Hijacked Process", 0); MessageBox(0, "Told you.", "Hijacked Process", 0); MessageBox(0, "Ok, bye.", "Hijacked Process", 0); MessageBox(0, "Hails to Barnamenevis.org fellas ", "Hijacked Process", 0); MessageBox(0, "I""ll close notepad for you ;)", "Hijacked Process", 0); ExitProcess(0); Result := 0; end; //Injection procedure Inject(ProcessHandle: longword; EntryPoint: pointer); var Module, NewModule: Pointer; Size, BytesWritten, TID: longword; begin Module := Pointer(GetModuleHandle(nil)); Size := PImageOptionalHeader(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage; VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE); NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten); CreateRemoteThread(ProcessHandle, nil, 0, EntryPoint, Module, 0, TID); end; var ProcessHandle, PID: longword; StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; begin {lets make a new process} CreateProcess(nil, "notepad", nil, nil, False, 0, nil, nil, StartupInfo, ProcessInfo); {give it some time to wake up} Sleep(500); {and hijack it!} GetWindowThreadProcessId(FindWindow("Notepad", nil), @PID); ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID); Inject(ProcessHandle, @Main); CloseHandle(ProcessHandle); {we have a copy of ourself running in notepad so we can exit} end. //go home kid :-) 1.تابع Main در بدنهء پروسهء قربانی اجرا میشه . نسخه اصلی کد با دریافت نقطه شروع خودش رو تنظیم میکنه لیکن انتشارش لزومی نداشت . بعد از ورود به کانتکست پروسه Notepad چند پیام نمایش داده میشه که نشاندهنده موفقیت آمیز بودن روند تزریق کد است 2. روتین Inject کد مورد نظر رو تزریق میکنه . به عنوان ورودی پروسه مورد نظر رو در نقش قربانی دریافت ، نقطه مناسب برای شروع کد تزریقی رو پیدا و با روشهای گفته شده در صفحه قبل فضای لازم برای ایجاد یک ریسمان راه دور رو به خودش اختصاص میده . 3. بدنهء اصلی برنامه ابتدا یک نسخه از Notepad به عنوان مثال میسازه ، شماره پروسه رو دریافت و به روتین Inject ارسال میکنه . این روتین ، تابع Main رو به فضای آدرسی Notepad کپی میکنه . حالا کد ِ در حال اجرا ارتباطی با برنامه ساخته شده توسط ما نداره و روی حافظه مختص به Notepad اجرا میشه . اگر به توضیحات دقت کنید میبینید که ابتدا هندل پروسه مورد نظرم - اینجا Notepad - رو بدست آوردم بعد فضای مورد نظرم رو اختصاص دادم نهایتا" یک Remote Thread برای اجرای کد مطلوب ایجاد شده است . برای مطالعه بیشتر در مورد جزئیات و الفبای کارکرد عناصر ویندوز خصوصا" با دید توسعه کاربردهای سیستمی و امنیتی کتاب Windows Internals مارک راشنوویچ از MS Press رو بخون . |