آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

پرسش و پاسخ شماره ۵۹

پرسش و پاسخ شماره ۵۹

من این دستور را در جایی دیدم: ‎:(){ :|:& }‎ (بمب خوشه‌ای). این چطور کار می‌کند؟

این به طور بالقوه یک فرمان خطرناک است. آن را اجرا نکنید! راه‌اندازی از پرسش فوق حذف می‌شود، تنها آن قسمتی که تابع را تنظیم می‌کند باقی می‌ماند.

بمب خوشه‌ای یک شکل ساده تکذیب سرویس(یا حمله DoS) است که بر مبنای نام فراخوان سیستم یونیکسیِ ‎fork(2)‎ نام گذاری گردیده است. برنامه‌ای است که توسط انشعاب کپی‌های خودش به طور مکرر، که فرزندان نیز به طور بازگشتی همان کار را می‌کنند، به سرعت منابع سیستم را تحلیل می‌برد. در بسیاری از سیستم‌هایِ بدون محدودیت صحیحِ منابع، این مورد ممکن است شما را در یک وضعیت اصلاح ناپذیر غیرپاسخگو رها کند.

این تعریف ویژه از بمب fork در Bash بنا به دلایلی چنان مشهور است که گاهی اوقات بمب خوشه‌ای نامیده می‌شود.

در اینجا رایج‌ترین شکل مورد پسند عامه کد آن آمده است:

:(){ :|:& };:

و از طرف دیگر، با قواعد مناسب برای خوانایی به این صورت:

#!/usr/bin/env bash
:() { 
    : | : &
}

:

این کد تابعی به نام : تعریف می‌کند. بدنه تابع یک لوله را تنظیم می‌کند، که در Bash متشکل از دو پوسته فرعی می‌باشد، خروجی استاندارد اولی توسط یک لوله به ورودی استاندارد دومی متصل گردیده است. تابع (پوسته والد لوله) لوله را پس‌زمینه‌ای می‌سازد، تابع باز می‌گردد و پوسته با رها نمودن job در پس زمینه، خاتمه می‌یابد. نتیجه نهایی دو پردازش جدید است که هر کدام پردازش : را برای تکرار فرآیند، فراخوانی می‌کنند.

: در واقع در اکثر شرایط ( پایین تشریح شده) یک نام غیر مجاز تابع می‌باشد. اینجا، bomb به جای : استفاده می‌شود، که هم قابل حمل است و هم خوانایی بهتری دارد.

bomb() {
    bomb | bomb &
}

bomb

به طور نظری، هر شخصی که در کامپیوتر شما به پوسته دسترسی دارد، می‌تواند از چنین تکنیکی برای نابود کردن منابعی که به آن دسترسی دارد استفاده کند. در اینجا یک ‎chroot(2)‎ کمک نخواهد بود. اگر منابع کاربر نامحدود باشد، آنوقت در چند ثانیه‌ای تمام منابع سیستم شما(پردازش‌ها، حافظه مجازی، فایلهای باز، وغیره.) استفاده خواهد شد و احتمالاً خودش دچار وقفه می‌شود. هر کوشش به عمل آمده توسط کرنل برای آزاد‌سازی منابع بیشتر فقط اجازه می‌دهد نمونه‌های بیشتری از تابع ایجاد بشود.

در نتیجه، تنها راه محافظت از خودتان در برابر چنین سوءاستفاده‌ای، محدودیتِ حداکثرِ مجازِ استفاده از منابع برای کاربرانتان می‌باشد. چنین منابعی به وسیله فراخوان سیستمی ‎setrlimit(2)‎ مقرر می‌شود. واسط این قابلیت در Bash و پوسته Korn فرمان ‎ulimit‎ است. همچنین ممکن است سیستم عامل شما فایلهای پیکربندی ویژه‌ای برای کمک به مدیریت این منابع داشته باشد( برای مثال، فایل ‎/etc/security/limits.conf‎ در دبیان، یا ‎/etc/login.conf‎ در OpenBSD). برای جزئیات، مستندات سیستم خود را کنکاش نمایید.

چرا ‎'':(){ :|:& };:''‎ روش نامساعدی برای تعریف یک بمب خوشه‌ای است

این تعریف عامه پسند به علت یک ترکیب غیرعادی جزئیات (در پوسته‌هایی که من با آنها تست کرده‌ام) که فقط در Bash غیر POSIX و Zsh(تمام حالت‌های شبیه‌سازی) پیش می‌آید، کار می‌کند.

  1. پوسته باید تعریف نامهای تابع، ماورای آنها که به واسطه یک ‎POSIX "Name"‎ مجاز هستند را اجازه بدهد. این مطلب بلافاصله ksh93 و Bash در وضعیت POSIX و Dash و Posh ( Posh یک شاخه قدیمی pdksh است که دیگر پشتیبانی نمی‌شود)، و ‎Busybox sh‎ را رد می‌کند.

  2. یا باید پوسته:
    • به طور نادرست توابعی مقرر کند که داخلی‌های ویژه را پیش از داخلی خودش بارگذاری می‌کند. جستجو و اجرای فرمان را ببینید. mksh در این مرحله(به طور صحیح) ناموفق می‌شود، واقعاً دستور : داخلی را اجرا می‌کند. حتی اگر شما تابع را به طور موفقیت آمیز تعریف کنید، فراخوانی تابع غیر ممکن است. Bash در وضعیت غیرPOSIX و Zsh (حتی شبیه‌ساز POSIX)مطابق این ضوابط هستند.

    • یا فراهم نمودن وسیله غیر فعال‌سازی فرمان داخلی. Bash و Ksh93 انجام می‌دهند. که Bash ناموفق است (درست مطابق مستنداتش). Ksh93 موفق می‌شود( به طور نادرست بر اساس مستنداتش).
          $ bash -c 'enable -d :; type -p :'
          bash: line 0: enable: :: not dynamically loaded
          $ ksh -c 'builtin -d :; whence -v :'
          ksh: whence: :: not found
      احتمالاً یک باگ:
        -d    **.هر داخلی تعریف شده را حذف می‌کند. **داخلی ویژه نمی‌تواند حذف بشود‎
      در هر صورت، نامربوط است زیرا ksh93 قبلاً در مرحله اول ناموفق شده است. اکنون شما فقط یک داخلی غیرقابل دسترس دارید.

بنابراین به طور خلاصه، این forkbomb خیلی جالب نیست. اساساً تعریف متعارفی است که به طور مبتذل توسط تخصیص یک نام ناشناس که تقریباً در هر جایی ناموفق است، گیج کننده گردیده است. بنا به ادعای فرضی کنایه‌دار نویسنده اصلی، شخص می‌تواند در هر ترمینال یونیکس تایپ کند:

 :(){ :|:& };: 
  • -- حتماً، گمان ‌کنم می‌توانید آن را تایپ کنید.

پرسش و پاسخ 59 (آخرین ویرایش ‎2013-01-08 18:58:36‎ توسط GreyCat)