1. مهمان گرامی، جهت ارسال پست، دانلود و سایر امکانات ویژه کاربران عضو، ثبت نام کنید.
    بستن اطلاعیه

تزریق کد به یک برنامه در حال اجرا ( یا Process Injection )

شروع موضوع توسط hector2141 ‏15/7/13 در انجمن مهندسی کامپیوتر

  1. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo

    تعریف:

    در ادبيات امنيت نرم افزار ، 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), [MENTION=84229]pid[/MENTION]);
    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 رو بخون .



    منبع :برنامه نویس و آرتیکل