سوءاستفاده از آسیب‎پذیری سرریز بافر به اندازه‎ی ۱-بایت

چند وقت پیش در خصوص یک آسیب‎پذیری سریز بافر در لینوکس صحبت شد. در راه‎حل ارائه‎شده، اشاره شد که چگونه یک آسیب‎پذیری سرریز بافر می‎تواند جریان اجرای برنامه‎ی آسیب‎پذیر را از طریق بازنویسی اشاره‎گر به دستورالعمل بعدی منتقل کند. امروز بحث اصلی در مورد آسیب‎پذیری کلاسیک دیگری از نوع سرریز بافر است که در نتیجه‎ی آن ثبّات ebp به‎گونه‎ای تغییر داده می‎شود که هر کد دلخواهی را اجرا کند.
۱
به کد بالا نگاه کنید، حداقل دو خطای برنامه‎‎نویسی در آن وجود دارد. اول اینکه در حلقه‎ی کپی، همواره مقادیر یکسانی از بایت‎ها، صرفنظر از این‎که طول زنجیره کپی چقدر است، در بافر نوشته می‌شود. دومین مسئله‎ای که وجود دارد و خیلی مهم‎تر است، بخش مقایسه در طول حلقه است. اندازه‎ی بافر ۲۵۶ است که از اندیس ۰ تا ۲۵۵ را شامل می‎شود ولی در حلقه تا اندیس ۲۵۶ جلو رفته است. این موضوع موجب می‎شود که حداقل یک بایت بطور اضافی در حافظه نوشته شود (جایی که مقدار ثبّات ebp ذخیره شده است.)

۲
همانطور که در دیاگرام شکل بالا ملاحظه می‎کنید، آدرس بازگشت پس از ثبّات ebp قرار گرفته است. ایده‎ی اصلی سوءاستفاده از این آسیب‎پذیری به این شکل است که تغییراتی در ebp ایجاد شود تا به نقطه‎ای در داخل بافر اشاره کند که آدرس بازگشت بتواند از آن نقطه بخواند و همزمان به بار داده در همان بافر اشاره کند.
۳
در تصویر بالا که کد disassemble شده است، مشاهده می‎کنید که پس از اتمام حلقه‎ی کپی، دو دستور دیگر leave و ret اجرا شده است. دستور leave پشته‎ی مربوط به تابع اصلی Main را بازسازی می‎کند. این دستور معادل اجرای دستورات
mov %ebp,%esp
pop %ebp
و مخالف دستورات اجرا شده در ابتدای تابع است. پس از اینکه مقدار ثبّات EBP تغییر یافت، دستور ret مقدار ثبّات eip را از مکان دیگری می‎خواند که یک آدرس واقعی در پشته نیست.
حال اگر برنامه را با ورودی ۲۵۶ کاراکتر A تست کنیم، مقدار ebp برابر با Null خواهد شد چرا که انتهای آرگومان ورودی یعنی بایت ۲۵۷ با Null تمام می‎شود. بعبارتی آدرس بازگشت در داخل بافری پر از A خواهد بود که در نتیجه روند اجرا با خطا مواجه می‎شود که آدرسی برابر با ۰x۴۱۴۱۴۱۴۱ وجود ندارد. ( حرف A معادل ۰x۴۱ است)
۴
اگر یک Breakpoint بعد از مقدار اصلی ebp قرار دهیم، ملاحظه خواهیم کرد که مقدار واقعی برابر با ۰xbffff۳f۸ است. همچنین آدرس بازگشت به تابع اصلی در ادامه در حافظه قابل مشاهده است که برابر با ۰x۰۸۰۴۸۲۶۱ است. همچنین می‎توان یک Breakpoint قبل از اجرای دستور leave قرار داد و مشاهده کرد که مقدار ذخیره شده در ebp برابر با ۰xbffff۳۰۰ است.
نکته‌ی قابل توجه اینجاست که آدرس بافر مابین ۰xbffff۲ec و ۰xbffff۳ec است و تغییر در مقدار ebp مفید خواهد بود بخاطر اینکه در بازه‌ی آدرس داخل بافر قرار خواهد گرفت. پس از اجرای دستور leave می‎توان دید که مقدار ebp آدرس موردنظر در داخل بافر است:
۵
برای ساخت Shellcode کارهای زیر را انجام خواهیم داد:
•در آدرس ۰x۲ec تا ۰x۳۰۰ بطور مثال به اندازه‎ی ۲۰ بایت مقدار به درد نخور قرار می‎دهیم. مثلا این ۲۰ بایت را با NOP (۰x۹۰) پر می‎کنیم.
•در آدرس ۰x۳۰۰ که آدرس ebp مورد هدف است، مجدد ۴ بایت به در نخور می‎نویسیم.
•در آدرس ۰xbffff۳۰۴ می‎توانیم آدرس shellcode خود را که در داخل بافر قرار دارد، بنویسیم مثلاً آدرس ۰xbffff۳۰۸
•در آدرس ۰xbffff۳۰۸ shellcode شروع می‎شود.
•سپس ۲۵۶ بیت باقی‎مانده پر می‎شود.
۶
پس از اجرا مشاهده می‌کنیم که shell در داخل gdb باز شده است.

۷

منبع: asis

درباره نماد امنیت وب

“نماد امنیت وب” به عنوان یکی از شرکت های پیشتاز در زمینه امنیت نرم افزار و سرویس های تحت وب، با ارائه سرویس های امنیتی برای تمامی کسب و کار ها و دارای نمایندگی شرکت Acunetix (اکوانتیکس) بعنوان محبوب ترین اسکنر امنیتی black box در دنیا، ایمنی وب سایت شما را در مقابل حمله هکر ها تضمین می کند.