حملات و دفاعهایی برای اسیب پذیری دهه اخیر
چکیده سرریزهای بافمتدلترین شکل اسیب امنیتی در طی ده سال گذشته است.
ضمنا، شدن حوزۀ آسیب های نفوذ شبکه از راه دور را شامل می شود در جایی که یک کاربر اینترنت درصدد بدست آوردن کنترل نسبی میزبان است.
اگر آسیب های لبریزی بافر بطور موثر حذف گردد، بخش زیادب از تهدیدهای امنیتی جدی نیز حذف می شود در این مقاله به انواع آسیب های لبریزی بافر و حملات مربوطه اشاره می کنیم و اقدامات دفاعی مختلف را بررسی می کنیم که شامل روش Guard Stack است.
سپس ترکیبات روش هایی را که می توانند مشکل عملکرد سیستم های موجود را حذف کنند بررسی می کنیم در حالیکه عملکرد سیستم های موجود حفظ می گردد.
مقدمه : لبریزی بافر شایع ترین مشکل آسیب امنیتی در ده های اخیر بوده است آسیب های لبریزی بافر در حوزۀ آسیب های نفوذ شبکه از راه دور حکمفرماست در جایی که یک کاربر اینترنت به جستجوی کنترل کامل یا نسبی یک میزبان است چون این نوع حملات هر کسی را قادر می سازد که کنترل کلی یک میزبان را به عهده بگیرد آنها یکی از جدی ترین حملات هرکسی را قادر می سازد که کنترل کلی یک میزبان را به عهده بگیرد آنها یکی از جدی ترین مولود تهدید های امنیتی محسوب می شوند حملات لبریزی بافر یک بخش مهم از حملات امنیتی را تشکیل می دهند زیرا آسیب های لبریزی به آسانی کشف می گردند.
با اینحال آسیب های لبریزی بافر در گروه حملات نفوذ از راه دور قرار می گیرند زیرا یک آسیب پذیری لبریزی بافر مهاجم را با آنچه که نیاز دارد نشان می دهد یعنی توانایی تزریق و اجرای رمز (کد) حمله.
کد حملۀ تزریق شده با برنامۀ آسیب پذیر کار می کند و به مهاجم امکان آن را می دهد که عملکرد لازم دیگر برای کنترل رایانۀ میزبان را در اختیار بگیرد.
مثلا از بین بردن حملات بکار رفته در ارزیابی آشکار سازی تهاجم در ازمایشگاه لینکلن در 1998 سه مورد از نوع حملات مهندسی اجتماعی اساسی بودند که به اعتبارات کاربر حمله کردند و دو مورد از نوع لبریزی های بافر بودند و 9 مورد از 13 مورد مشاوره های CERT از 1948 شامل لبریزی های بافر بود و حداقل نیمی از مشاوره های CERT 1998 شامل اینحال لبریزی های بافر بود بررسی غیر رسمی درباره خدمت آسیب پذیری امنیتی نشان داد که تقریبا 2/3 پاسخ دهندگان عقیده داشتند که لبریزیهای بافر علت اصلی آسیب پذیری امنیتی است.
آسیب پذیری های لبریزی بافر و حملات در یک سری از شکل ها می آید که ما در بخش 2 شرح می دهیم و طبقه بندی می کنیم2) ) دفاع در برابر حملات لبریزی بافر بطور مشابه در یک سری شکل ها ظاهر می شود که در بخش 3 شرح می دهیم که شامل انواع حملات و اسیب پذیری هایی است که این دفاع ها در برابر آنها موثر است پروژه Immunix مکانیزم دفاعی Guard Stack را تو سعه داده است که در دفاع از حملات بدون لطمه به عملکرد یا سازگاری سیستم بسیار موثر بوده است .
بخش 4 به بررسی ترکیبی از دفاع هایی می پردازد که یکدیگر را پوشش می دهند.
بخش 5 نتیجه گیری ها را شامل می گردد.
2 ) آسیب پذیری های لبریزی بافر و حملات
هدف کلی بک حملۀ لبریزی بافر، خنثی کردن عملکرد یک برنامه ممتاز است طوری که مهاجم بتواند کنترل آن برنامه را بعهده بگیرد.
و اگر برنامه بقدر کافی پیشرفته باشد بتواند کنترل میزبان را انجام دهد.
مهاجم به یک برنامه root ریشه حمله می کند و فورا کد مشابه با exec(sh) را اجرا می کند تا به یک لایه root برسد
برای انجام این هدف، مهاجم باید به دو هدف دست یابد:
کد مناسب را آرایش دهد تا در فضای نشانی برنامه باشد 2) از برنامه برای پرش به آن کد استفاده کند و پارامترهای مناسب بداخل حافظه و رجیسترها لود شوند.
کد مناسب را آرایش دهد تا در فضای نشانی برنامه باشد 2) از برنامه برای پرش به آن کد استفاده کند و پارامترهای مناسب بداخل حافظه و رجیسترها لود شوند.
ما حملات لبریزی بافر را بر حسب حصول این اهداف دسته بندی می کنیم بخش 2.1 نحوه قرار گرفتن کد حمله در فضای نشانی برنامه قربانی را شرح می دهد.
بخش 2.2 شرح می دهد که چونه مهاجم یک بافر برنامه را لبریز می کند تا حالت برنامه مجاور را تغییر دهد که جایی است که قسمت لبریزی از آنجا می آید تا باعث شد که برنامه قربانی به کد حمله پرشی نماید بخش 2.3 موضوعات مربوطه را در ترکیب کردن روشهای تزریق کد از بخش 2.1 با روش ها ی وقفۀ جریان کنترل از بخش 2.2 بحث می کند.
2.1 روش های آرایشی کد مناسب برای فضای نشانی برنامه : دو روش برای آرایش کد حمله برای فضای نشانی برنامه قربانی وجود دارد: تزریق یا کاربرد آن چه که قبلاً در آنجا وجود دارد.
تزریق آن: مهاجم یک رشته را بصورت ورودی برای برنامه فراهم می کند که برنامه در یک بافر ذخیره شود.
رشته شامل بایت هایی است که دستورالعمل های CPU برای سکوی مورد حمله می باشند در اینجا حمله کننده از بافر های برنامه قربانی برای ذخیره کردن کد حمله استفاده می کند.
بعضی موارد مربوط به این روش به این شرح است: مهاجم مجبور نیست هر بافری را برای انجام این کار لبریز کند: بارگیری کافی کافی می تواند بداخل بافرهای کاملا سالم تزریق شود بافر می تواند در هر جایی قرار بگیرد.
روی متغیرهای خودکار روی متغیرهایی mallocell در ناحیه ایتای استاتیک (مقدار طی شده اولیه یا نشده) قبلا در آنجا وجود دارد: اغلب کد برای انجام آنچه که مهاجم می خواهد انجام دهد قبلا در فضای نشانی برنامه وجود دارد و مهاجم فقط لازم است که کد را پارامتر بندی کند و سپس باعث پرش برنامه به آن شودمثلا اگر کد حمله لازم باشد تا ("/bin/sh") exel را انجام دهد در جایی که arg یک آرگومان مکان نمایی رشته است آنگاه مهاجم باید یک مکان نما را تغییر دهد تا به ("/bin/sh") اشاره کند و به دستور العمل های مناسب در کتابخانه libe پرش نماید.
2.2 راههایی که برنامه باعث پرش به کد مهاجم می شود: تمام این روشها قصد دارند تا جریان کنترل برنامه را تغییر بدهند طوری که برنامه به کد حمله پرش کند.
روش اصلی عبارت اند از لبریزی یک بافر است که دارای حدود غیر موجود یا ضعیف ای است که ورودی را با هدف از بین بردن یک قسمت مجاور برنامه کنترل می کند مثلا مکان نماهای مجاور و غیره با لبریز کردن بافر، مهاجم می تواند حالت برنامه مجاور را با یک توالی تقریبا اختیاری از بایت ها بازنویسی کند که منجر به یک میان بری اختیاری از سیستم نوع C و منطق برنامه قربانی می شود در اینجا طبقه بندی کردن از نوع حالت برنامه ای است که لبریزی باقر مهاجم قصد دارد تا در ان خرابی بوجود آورد.
در اصل، این حالت می تواند هر نوع حالت ای باشد.
مثلا morris worn از یک لبریزی بافر در مقابل برنامه fingerel استفاده کرد تا نام یک فایل ای را از بین ببرد که fingerd اجرا می نماید.
در عکل اکثر لبریزی های بافر قصد دارند تا مکان نماهای کد را خراب نمایند.
رکوردهای فعالیت: هر بار که یک تابع انحصاری می شود یک رکورد فعالیت روی دسته قرار دارد می وشد که شامل نشانی برگشت ای است که برنامه باید پرش کند وقتی که تابع وجود دارد یعنی به کد تزریق شده در بخش 2.1 اشاره می کند.
حملاتی که رکورد فعالیت را خراب می کنند متغیرهای خودکار جریان لبریزی نشانی ها را تحت تاثیر قرار می دهند یعنی بافرهای مطابق شکل با خراب کردن نشانی در رکورد فعالیت مهاجم باعث می شود که برنامه به کد مهاجم پرش کند وقتی که تابع قربانی نشانی برگشت را برمی گرداند.
این شکل لبریزی یک سری حملات لبریزی بافر را باعث می شوند.
مکان های تابع:(*foo) void متغیر foo را اعلان می کند که از نوع مکان نما برای تابع ای است که viod را بر می گرداند.
مکان نما های تابع می توانند در هر جایی تخصیص داده شوند و بنابراین مهاجم فقط باید یک بافر قابل لبریزی مجاور به یک مکان نمای تابع را در هر کدام از این نواحی پیدا کند و آن را لبریز کند تا مکان نمای تابع را پیدا کند پس از مدتیوقتی برنامه احضاری را از طریق این مکان نمای تابع انجام می دهد به محل مطلوب مهاجم حمله می کند یک مثال از این نوع حمله در مقابل برنامه snperprobe برای لینوکس ظاهر گردید بافرهای پرش بلند: c شامل یک سیستم موسوم set ymp/longsmp است.
اگر مهاجم بتواند حالت بافر را خراب کند آنگاه longJmp(buffer) به کد مهاجم پرش خواهد کرئ مانند مکان نما های تابع بافرهای lingJmp می توانند هر جایی تخصیص داده شوند بنابراین مهاجم فقط باید یک بافر قابل لبریزی را پیدا کند .
یک مثال از این شکل حمله در مقابل perld.003 ظاهر گردیدحنله ابتدا یک بافر LongJmp را خراب کرد برای بازیابی استفاده شد وقتی که لبریزی های بافر آشکار می شوند و سپس شامل مود بازیافت بود که باعث شد که مفسر perl به کد حمله پرش کند.
2.3 ترکیب کردن تزریق کد و روش های خراب کردن و جریان کنترل در اینجا به بررسی موضوعات ترکیب تزریق کد مهاجم و روش های خراب رکدن جریان کنترل می پردازیم.
ساده ترین شکل حمله لبریزی بافر یک روش تزریق را با یک خرابی رکورد فعال سازی در یک رشته واحد ترکیب می کند مهاجم یک متغیر خودکار قابل لبریزی را قرار می دهد و به برنامه یک رشته بلند را تغذیه می کند که بطور همزمان بافر را لبریز می کند تا رکورد فعالیت را تغییر دهد و حاوی کد حمله تزریق شده است.
این سکویی برای یک حمله مطرح شده توسط levey است.
چون اصلاح تخصیص یک بافر محلی کوچک بسیار متداول است یک سری حالت های آسیب پذیری کد برای این شکل حمله وجود دارند .
تزریق و خرابی در یک عمل انجام نمی شود.
مهاجم می تواند کد را به داخل یک بافر بدون لبریز کردن آن تزریق کند و یک بافر متفاوت را برای خراب کردن یک مکان نمای کد لبریز می کند این کار تر انجام می شود اگر بافر قابل لبریزی محدودیت هایی داشته باشد که روی آن کنترل انجام شود بنابراین بافر تا تعداد معینی از بایت ها قابل لبریزی است مهاجم حمله برای قرار دادن کد بافر آسیب پذیر نمی باشد بنابراین کد به سادگی در داخل یک بافر متفاوت با اندازه کافی قرار داده می شود.
اگر مهاجم سعی کند از کد قبلی بجای تزریق آن استفاده کند، آنها لازم است تا کد را پارامتر بندی کنند مثلا قطعه کدهایی در Libe وجود دارند (مرتبط با برنامه C) که something" "exel را انجام می دهند در جایی که "something" یک پارامتر است.مهاجم می تواند از لبریزی های بافر برای خراب کردن آرگومان استفاده کند و لبریزی بافر دیگری برای خراب کردن یک مکان نمای کد بکار می رود تا به libe در قطعه کد مناسب اشاره گردد.
3) دفاع های لبریزی بافر.
چهار روش اصلی برای دفاع در برابر آسیب پذیری های لبریزی بافر و حملات وجود دارد روشی در بخش 3.1 شرح داده شده است روش سیستم های عامل در بخش 3.2 شرح داده می شود که برای نواحی ذخیره برای بافرهای غیر قابل اجرا است و ا زمهاجم از تزریق کد حمله حمله جلوگیری می کند.
این روش بسیاری حملات را متوقف می کند.
روش کامپایلر در بخش 3.3 برای اجرا کنترل یکپارچگی روی مکان نماهای کد قبل از مرجع زدایی آنهااست.
این روش حملات لبریزی بافر را غیر ممکن نمی کند ولی اکثر حملات لبریزی بافر را متوقف می کند و حملاتی که متوقف نمی شوند به سختی ایجاد می شوند و مزایای عملکرد و سازگاری زیادی دارد که در بخش 3.5 شرح داده می شود 3) کد تصحیح نوشتن این اصطلاح در هنگام نوشتن به زبان مثلا c مطرح می شود وبویژه وقتی که نوشتن و اصلاح آن مطرح باشد با وجود سابقه طولانی درک نوشتن برنامه های آسیب پذیری بطور منظم در حال ظاهر شدن هستند بنابراین بعضی ابزارها و روش ها به توسعه دهندگان کمک کرده است که آسیب پذیری های لبریزی بافر را تشخیص دهند.
ساده ترین روش عبارت اند از greb که منبع برای احضارهای کتابخانه ای از قبیل stcpy و sprintf است که طول آرگون های آنها کنترل نمی کند نسخه های کتابخانه استاندارد c توسعه یافته است که برای این منظور بکار