چکیده
نشان میدهیم که نوشتن از راه دور برای سرریز بافر بدون داشتن یک کپی از هدف باینری یا کد منبع، در برابر خدماتی که پس از شکست مجدد راهاندازی میشوند ممکن است. این مسئله امکان هک خدمات اختصاصی باینری، یا سرورهای منبع باز گردآوری شده بهصورت دستی و نصب از منبع را فراهم میکند. تکنیک سنتی معمولا در یک فایل باینری خاص و توزیعشده، بهصورت یکسان عمل میکند که در آن هکر، محل ابزار مفید برای برنامهنویسی بازگشتگرا (ROP) را میداند. ROP کورکورانه (BROP)که در این مقاله ارائه شده است به جای حمله از راه دور، ابزارهای ROP کافی برای انجام یک سیستم فراخوانی Write و انتقال آسیبپذیر باینری بر روی شبکه را مییابد و پس از بهرهبرداری، میتواند با استفاده از تکنیک شناخته شدهای تکمیل شود. بنابراین با نفوذ در اطلاعات یک بیت براساس اینکه آیا یک فرایند شکست خورده است یا نه، عملیات را شروع میکند. BROP نیاز به آسیبپذیری پشته و یک سرویس دارد که پس از شکست شروع به اجرا کند. در این مقاله Braille پیادهسازی شده است، بهرهبرداری کاملا خودکار، که کمتر از 4000 درخواست (20 دقیقه) در برابر آسیبپذیری در nginx، yaSSL + MySQL و سرور اختصاصی را متحمل است. حمله در لینوکس 64 بیتی با فضای آدرسدهی تصادفی (ASLR)، بدون محفاظت از اجرای صفحه (NX) و پشته صورت میگیرد.
مقدمه
مهاجمان در سوءاستفاده بر روی هدف، با درجهای از اطلاعات مختلف بسیار موفق عمل کردهاند. نرمافزار متن باز دردسترس است زیرا مهاجمان میتوانند کد را برای یافتن آسیبپذیری پویش کنند. نرمافزار منبع بسته هک ممکن است برای ایجاد انگیزه در مهاجمان از طریق استفاده از تست fuzz و مهندسی معکوس به کار گرفته شود. تلاش برای درک محدودیتهای مهاجم، این سؤال را مطرح میکند که: آیا مهاجمان ممکن است تلاش خود برای رسیدن به هدف و سوء استفاده از خدمات اختصاصی را نه تنها برای منبع بلکه برای کد باینری گسترش دهند؟ در نگاه اول، ممکن است چنین به نظر برسد که دست نیافتنی است زیرا سوء استفاده به داشتن یک کپی از هدف دودویی برای استفاده در برنامهنویسی بازگشتگرا (ROP) نیاز دارد [1]. ROP لازم است، زیرا در سیستمهای مدرن، حفاظت غیراجرایی (NX) از حافظه تا حد زیادی مانع از تزریق کد حملات میشود. برای پاسخ به این سوال، با سادهترین آسیبپذیری ممکن شروع میکنیم: پشته سرریز میشود. متاسفانه این مسئله هنوز هم در نرمافزارهای محبوب (بهعنوان مثال، در nginx CVE-2013- 2028 [2]) قابل اعمال است. بنابراین تنها میتوان چنین حدس زد که باگها از نرمافزار اختصاصی دور بماند، که در آن منبع (و دودویی) تحت بررسی عمومی و دقیق متخصصان امنیت نیست. بااینحال، این امکان برای یک مهاجم فراهم است که از تست fuzz برای یافتن باگها از طریق رابطهای سرویس شناخته شده یا طراحی معکوس استفاده کند. در روش دیگر، مهاجمان میتوانند آسیبپذیریهای شناخته شده در کتابخانههای محبوب را (بهعنوان مثال، SSL یا تجزیهکننده PNG) مورد هدف قرار دهند که ممکن است در خدمات اختصاصی مورد استفاده قرار گیرند. مهمترین چالش این مسئله، توسعهی یک روش برای بهرهبرداری از این آسیبپذیریها است زمانیکه اطلاعات در مورد هدف دودویی محدود است.
یکی از مزیتهایی که اغلب حملات دارند این است که بسیاری از سرورها فرآیندهای خود را پس از یک شکست در جهت موفقیت دوباره مجددا راهاندازی میکنند. نمونههای قابل توجه عبارتند از، آپاچی، وب سرور nginx، سامبا و OpenSSH. اسکریپت Wrapper مانند mysqld_safe.sh یا daemon ها مانند systemd، این قابلیت را دارند. متعادلکنندههای بار بهطور فزایندهای شایع هستند و اغلب اتصالات را به تعداد زیادی از میزبانهابا پیکربندیهای یکسان برای اجرای فایلهای باینری برنامه توزیع میکنند. بدین ترتیب، موقعیتهای بسیاری وجود دارد که در آن یک مهاجم بهطور بالقوه برای ایجاد بهرهبرداری (تا تشخیص) بینهایت تلاش میکند.
تاریخچه مختصری از سرریزهای بافر
سرریزهای بافر یک آسیبپذیری کلاسیک با تاریخچه طولانی در سوء استفادهها هستند [4]. از لحاظ مفهومی، حمله به آنها نسبتا آسان است. بهعنوانمثال، یک برنامه آسیبپذیر ممکن است دادهها را از شبکه خوانده و در یک بافر جای دهد. سپس، با فرض اینکه برنامه فاقد مرزهای بررسی کافی برای محدود کردن اندازه ورودی داده است، مهاجم میتواند در پایان بافر حافظه را مجددا بازنویسی کند. در نتیجه، حالت بحرانی جریان کنترل، مانند بازگشت آدرس یا اشارهگر تابع، میتواند دستکاری کرد. سرریزهای پشته بافر تمایل ویژهای به بازگشت آدرسها به طور ضمنی در نزدیکی حافظه بهدلیل عملکرد فراخوانی دارند. با اینحال، حملاتی که بافر را مورد هدف قرار میدهند عملی میباشند [5].
آموزش ROP
قبل از بحث در مورد روش کورکورانه ROP، ابتدا با ROP آشنا میشویم. سوء استفاده مدرن به شدت به ROPمتکی است. هدف از ROP ساخت یک توالی است که معمولا براساس کد موجود عمل میکند. هنگامی که یک پوسته اجرا میشود، مهاجم میتواند دستورات بیشتری را برای ادامه حمله اجرا کند. شکل 1 shellcode معمولی را نشان میدهد که سوکت مهاجم را به ورودی استاندارد، خروجی، خطا و اجرای یک shell خط لوله میکند.
سرریزهای بافر
در اکثر سیستم عاملهای جدید، که در آنها NX و ASLR شایع هستند، یک مهاجم باید حداقل دو نیازمندی بهمنظور بهدست آوردن کنترل کامل برنامه برای اجرای از راه دور را انجام دهد:
1) برای شکست NX، مهاجم باید بدانید که ابزار در داخل برنامه اجرایی کجا قرار دارد.
2) برای شکست ASLR، مهاجم باید مکانی را که بخش متن اجرایی در ان واقع است در حافظه لود کند.
این الزامات بهراحتی در سیستم 32 بیتی [9]، [14] از طریق حدس زدن ساده عملی هستند. این مورد برای سیستمهای 64 بیتی عملی نیست. در واقع، بسیاری از سوء استفادههای عمومی سیستمهای 32 بیتی را مورد هدف قرار میدهند. هدف از حمله BROP
دور زدن این شرایط در سیستمهای 64 بیتی است. از این رو، بقیه این بحث منحصرا به حملات 64 بیتی اختصاص مییابد.
محیط BROP
حمله برنامهنویسی از راه دور کورکورانه (BROP) از مفروضات زیر پیروی میکند و به محیط زیر نیاز دارد:
• آسیبپذیری پشته و دانش کنترل و راهاندازی آن.
• برنامه سرویسدهنده یا سرور که پس از شکست مجدد شروع به کار میکند.
مدل تهدید برای حمله BROP، یک مهاجم است که رشته ورودی را با توجه به شکست سرور و اشکال در سرریز میداند. مهاجم باید قادر به بازنویسی بایتهای یک متغیر از جمله اشارهگر دستور بازگشت باشد. مهاجم نیاز به دانستن منبع یا دودویی سرور ندارد. مهاجم باید قادر به شکست چندین باره سرور به هنگام انجام حمله باشد و سرور باید مجدد راهاندازی شود.
طرح کلی حمله
حمله BROP شامل مراحل زیر است:
1) خواندن از پشته: خواندن از پشته برای نشت canaries و برگرداندن آدرس برای شکست ASLR.
2) ROP کورکورانه: یافتن ابزار کافی برای فراخوانی write و کنترل آرگومانهای آن.
3) ایجاد بهرهبرداری: هدر رفت کافی باینری برای یافتن ابزار کافی جهت ایجاد یک کد و راهاندازی نهایی بهرهبرداری.
مرحله اول، همانند آدرس نقطه شروع برای اسکن ابزارهای پیدا شده ضروری است. سپس ابزار برای دستور write پیدا میشوند. پس از آن، باینری بر روی شبکهای از حافظه منتقل میشود و قادر به اعمال تکنیکهای شناخته شده جهت بهرهبرداری نهایی است.
خواندن از پشته: تصادفیسازی مجدد ASLR
سوء استفاده باید براساس یک روش شکست ASLR برای تنظیمات بنا شده باشد که در آن PIEاستفاده شده است. در حال حاضر ما یک روش جدید خواندن از پشته ارائه میکنیم که تعمیم یافته یک تکنیک شناخته شده مورد استفاده برای نشت canaries است. این روش در مواردی که باینری شناخته شده است و حمله کامل BROP الزامی نیست بسیار مفید است. ایده اصلی در canaries سرریز یک بایت، بازنویسی بایت canaries با مقدار x است. اگر xدرست بود، سرور شکست نمیخورد. این الگوریتم برای 256 مقدار بایت (به طور متوسط128) امکانپذیر است. حمله برای بایت بعدی تا زمانی که همه 8 بایت (در 64 بیتی) به بیرون درز کنند ادامه مییابد. شکل 5 حمله را نشان میدهد. پس از canary، عموما اشارهگر فریم ذخیره میشود و پس از آن آدرس بازگشت ذخیره میشود، بهطوریکه سه کلمه باید خوانده شوند. شکل 6 طرح پشته را نشان میدهد.
حمله BROP
حمله BROP اجازهی نوشتن بهمنظور سوء استفاده و بدون داشتن هدف باینری را میدهد. این روش تکنیکهایی برای یافتن ابزار از راه دور ROP و بهینهسازی برای حمله کاربردی را معرفی میکند.
قطعاتی از پازل
هدف، یافتن ابزار کافی با استناد به write است. بعد از این، باینری را میتوان از حافظه به شبکه برای یافتن ابزارهای بیشتر انتقال داد. سیستم فراخوانی write سه آرگومان را در پی دارد: سوکت، بافر و طول. آرگومانها از رجیسترهای RDI، RSI و RDX عبور میکنند و تعداد پاسخ سیستم در ثبات RAX ذخیره میشود.
پیادهسازی
ما حملات BROP را در یک ابزار به نام "Braille" که بهطور خودکار ناشی از یک شکست از راه دور است اجرا میکنیم. این برنامه در 2000 خط کد روبی نوشته شده است. Braille اساسا بهرهبرداری است که منجر به شکست سرور و تمام اطلاعات مورد نیاز برای بهرهبرداری میشود.
ارزیابی
ما حمله BROP را در سه سناریو مورد آزمایش قرار میدهیم:
1) یک کتابخانه باز SSL با آسیبپذیری شناخته شده پشته (yaSSL). این سناریو،حمله به یک سرویس اختصاصی است که اعتقاد بر استفاده از یک منبع باز آسیبپذیر دارد. بهعنوان یک هدف نمونه، ما از نسخه قدیمی MySQL که از yaSSL استفاده میکند کمک میگیرد.
2) یک نرمافزار منبع باز با یک پشته آسیبپذیر شناخته شده (در nginx)، بهصورت دستی از منبع شروع به اجرا میکند. در این سناریوی مهاجم منبع کل سرور را میداند، اما باینری را نگه نمیدارد.
3) یک سرویس باینری با یک پشته آسیبپذیر. که توسط یکی از همکاران نوشته شده بود و هر دو منبع باینری و منبع بهصورت مخفی نگه داشته شده است. در حالت ایدهآل این مورد را در برابر دنیای واقعی مورد آزمایش قرار میدهیم اما از نظر قانونی بسیار دشوار است.
عملکرد
جدول 2 تعداد تجمعی درخواست مورد نیاز را برای هر فاز حمله نشان میدهد. این حمله میتواند در کمتر از 4000 درخواست، و یا 20 دقیقه تکمیل شود. بنابراین با توجه به اینکه در حملات گذشته در ASLR 32 بیتی به طور متوسط 32768 درخواست مورد نیاز بود قابل قبول است [9]. در تمام موارد، در 1500 مورد درخواست حمله قادر به شکست دادن canary، ASLR و پیدا کردن یک ابزار توقف است. چه مدت طول میکشد تا از دانش صفر به اجرای یک قطعه کد مفید برسد. پس از آن، پیدا کردن ابزار BROP ، بسته به محبوبیت خود، میتواند بین 27-467 درخواست قبول کند.
محدودیت ها
حمله BROP محدودیتهای خاص خود را دارد. ما آن را تنها به سرریز ساده پشته اعمال میکنیم. درحالیکه آن یک نقطه شروع خوب در بسیاری از آسیبپذیریهای پیچیده و مبتنی بر heap است.
خواندن از پشته فرض میکند که مهاجم میتواند در یک بایت سرریز کند و آخرین بایت سرریز شده را کنترل کند (بهعنوان مثال، یک صفر توسط سرور اضافه نشده است).
حمله فرض میکند که دستگاه و روند یکسانی بعد از هر تلاش میتواند اتفاق بیافتد. توازن بار میتواند باعث شکست حمله گردد به خصوص زمانی که PIEاستفاده شده است و canary نمیتواند برخورد کند.
بحث
BROP در سیستم عاملهای مختلف
ویندوز فاقد یک API شبیه fork (تنها CreateProcess) است بنابراین canary و بخش متنی آدرس پایه برای تصادفیسازی پس از شکست تضمین شدهاند، بنابراین ساخت سیستم قوی در برابر حملاتی مانندBROP بسیار ضروری به نظر میرسد. ویندوز ABI آرگومانها را در ابتدای رجیستر (بهعنوان مثال، RCX، RDX) برای ساختن ابزار و وسایل pop عبور میدهد. این ابزارها بسیار کمیاب هستند چرا که در طول فراخوانی تابع حفظ نمیشوند، بنابراین کامپایلر نیازی به ذخیره آنها در پشته ندارد. این ابزارها به احتمال زیاد وجود دارند ولی از آنها کمتر استفاده میشود.
پیشگیری BROP
در زیر در مورد مکانیسمهای دفاعی بحث شده است که حمله BROP نیز جزء آنها است، برای مثال دو اقدام احتیاطی برای استفادهی توسعهدهندگان سرور پیشنهاد شده است. بسیاری از تحقیقات گذشته در مورد مکانیسمهای دفاعی حمله ROPاست و بسیاری از این تکنیکها قابل اجرا در برابر BROP هستند. بنابراین، این لیست به هیچ وجه جامع نیست.
تصادفی سازی
حفاظت اساسی در برابر حمله BROP تصادفیسازی canary و ASLR بهعنوان امکان پذیر است. این مکانیسمهای حافظت موثر هستند، اما توسعهدهندگان سرور آنها را با عدم تصادفیسازی تضعیف میکنند. سادهترین روش فرآیند fork و exec در یک شکست است، که canary و ASLR را تصادفیسازی میکند. بنابراین مهم است که هر پروسهی فرزند بهطور مستقل تصادفی شود بهطوریکه هر گونه اطلاعات به دست آمده از فرزند نتواند در برابر دیگری مورد استفاده قرار گیرد. تحقیقات زیادی در زمینه تصادفیسازی باینری در زمان اجرا وجود دارد. یکی از روشهایی که توسط Giuffrida و همکارانش بیان شده، استفاده از یک کامپایلر اصلاح شده برای انتقال حالت اجرا بین دو نمونه (با روش تصادفیساز مختلف ی ASLR) است [19]. همچنین نمونهسازی مجدد یک تکنیک برای انتقال بخش متن باینری به یک مکان جدید با استفاده از mmap / munmap در این مقاله اعمال شده است که از یک کنترلر خطای صفحه برای تعیین اینکه آیا اشارهگر باید به عنوان خطا بازنویسی شود، استفاده میکند.
کارهای مرتبط
کارهای مرتبط زیادی برای اسکن یک ابزار ROPوجود دارد. حملهی نیم کور Goodspeed علیه میکروکنترلرها [31] متکی بر دانش (عمومی) کد bootloader است و یک ابزار را در یک بخش ناشناخته از حافظه برای ایجاد حمله مورد استفاده برای استخراج سیستم عامل مهیا میکند. حمله BROP کلیتر است زیرا بهطورکامل کور است و تکنیکهایی برای پیدا کردن و زنجیروارد کردن ابزار مختلف ارائه میدهد.
نتیجه گیری
ما نشان دادیم که، تحت شرایط مناسبی، نوشتن سوء استفاده بدون هیچ گونه دانش باینری و یا کد منبعی ممکن است. این روش برای آسیبپذیریهای پشته که در آن فرآیند سرور پس از شکست مجدد راهاندازی میشود بهرت عمل میکند. حمله ارائه دهش در این مقاله قادر به شکست ASLR، NX و پشته canary در سرور مدرن لینوکس 64 بیتی است. در این مقاله دو روش جدید ارائه شده است: خواندن از پشته تعمیمیافته، که موجب شکست کاملASLR بر روی سیستمهای 64 بیتی میشود و حمله BROP، که قادر به یافتن از راه دور ابزارهای ROPاست. ابزار کاملا خودکار ارائه شده در این مقاله، Braille، میتواند 4000 درخواست را در کمتر از 20 دقیقه، در برابر نسخههای واقعی yaSSL + MySQL و nginx با آسیبپذیریهای شناخته شده و ابزار خدمات اختصاصی در حال اجرای یک باینری ناشناخته، مورد آزمایش قرار دهد.
ما نشان دادیم که الگوهای طراحی مانند fork سرور با فرآیندهای متعدد کارگر میتواند در تقابل با ASLR باشد و ASLR فقط هنگامی مؤثر است که همه کد به بخش باینری (از جمله PIE) اعمال شود. علاوهبراین، امنیت از طریق ابهام، که در آن باینری ناشناخته و یا تصادفی است، تنها میتواند کاهش سرعت گردد اما از حملات سرریز بافر جلوگیری نمیکند. برای دفاع در برابر حمله ما، پیشنهاد میکنیم که سیستمها باید ASLR و canary را بعد از هر شکست تصادفیسازی کنند و هیچ کتابخانه یا قابلیت اجرایی نباید از ASLR معاف باشد.
این مقاله در سال 2014 در نشریه آی تریپل ای و در سمپوزیوم امنیت و حریم خصوصی، توسط دانشگاه استنفورد منتشر شده و در سایت ای ترجمه جهت دانلود ارائه شده است. در صورت نیاز به دانلود رایگان اصل مقاله انگلیسی و ترجمه آن می توانید به پست دانلود ترجمه مقاله هک کورکورانه در سایت ای ترجمه مراجعه نمایید.