تعریف:
در ادبيات امنيت نرم افزار ، 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 رو بخون .
