menu

Fork Bomb

Fork Bomb

جمعه 12 شهریور 1395

اگه کاربر لینوکسی هستید، به احتمال 90 درصد با این کد آشنایید!

یا حداقل یه بار ازش استفاده کردید

یکی از کدهاییه که آدم موقعی که حوصله اش سر میره دوست داره بزنه دی:

الان میخوام یکم بیشتر وارد جزئیات این کد بشم!

اول از همه ببینیم این کد چی هست؟

این کد، همون کدی هست که بالای صفحه میبینید (یا اگه با گوشی اومده باشید نمیبینید!)

:(){: | : & }; :

الان موقع اون هست که این کد را بیشتر بررسی کنیم

بزار اول ببینیم که اگه این کد را بزنیم چی میشه!

برای تست، لطفا کد بالا را در ترمینال وارد کرده و سپس اینتر را بزنید

اگر واقعا وارد کردید، و اینتر را زدید، و سیستمتون خیلی خوب کانفیگ نبود، لطفا به من فحش ندید!

خب بریم سراغ بررسی بیشتر

خدمت دوستانی که هنوز این کد را نزدن، باید عرض کنم که با زدن این کد، سیستم شما پس از مدتی کاملا هنگ میکنه و تنها راه ریست کردن سیستمتون هست!

اما واقعا در پشت پرده ی این کد ساده چیه؟ خیلی واضحه

این همه مقدمه چینی نوشتم که بریم سراغ خود کد!

این کد کوچولوی shell در واقع یه تابع خیلی کوچیکه

یه تابع، که موقع اجرا شدن خودش را فرامیخونه و خروجی خودش را دوباره میریزه تو خودش

یعنی در واقع یه تابع که هر دفعه دو تا زیر تابع داره و هر کدوم از اونها یه زیر تابع هست و اونقدر ادامه میدن که منابع سیستمتون تموم شه

نفهمیدین؟

فک کنم این جوری واضح تره!

ساده، و خطرناک!

حالا بیاییم خود کد را بررسی کنیم

:(){: | : & }; :

اولین قسمت کد : هست. این : در اسم تابع ما هست. یعنی ما با استفاده از این : یه تابع میسازیم که به جای اینکه اسمش مثلا noisy باشه، اسمش را میزاریم :

ساختار یه تابع توی bash به این شکله

noisy(){}

حالا اگه ما اسم تابعمون را به جای noisy بزاریم : تابع ما این شکلی میشه

:(){}

که نیمی از کد اصلی fork bomb را تشکیل میده

حالا میرسیم به قسمت داخل آکولاد ها

دقیقا داخل آکولاد، اولین چیز : هست. این یعنی این که ما تابعی را که تعریف کرده ایم، داخل خودش فراخونی میکنیم و اون را داخل خودش اجرا میکنیم

بعد از اون علامت | هست. این علامته پایپه و همونطور که توی اینجا توضیح دادم، خروجی تابع قبل از خودش را به عنوان ورودی تابع بعد از خودش در نظر میگیره

حالا یه نگاه به دو طرف | میندازیم. هر دو طرفش تابع : قرار داره

یعنی ابتدا ما یه تابع : تعریف میکنیم، بعد داخل اون تابع خودش را فراخونی میکنیم، و خروجی خودش را به عنوان ورودی خودش قرار میدیم!

یعنی هر دفعه که تابع اجرا شه، دوبار دیگه خودش را اجرا میکنه

که هر کدوم از اون دوبار ها، دوبار دیگه خودشون را اجرا میکنند و ....

و این دقیقا عاملی هست که باعث میشه بعد از یه مدت، منابع سیستم مخصوصا رم کم بیاد و سیستم کرش کنه

قسمت بعدی داخل آکولاد، علامت & هست. اون را هم همینجا توضیح دادم.

گذاشتن این کد علامت باعث میشه که تمام کد های ما و این فراخوانی های تو در تو، همش در پس زمینه انجام بشه و پردازش ما را یه background proccess میکنه

این کار هم باعث میشه که هر پردازش یه حالت اختصاصی براش ایجاد بشه و در این حالت، اگه parent اون پردازش kill بشه، پردازش های child از بین نمیرن و نابود کردن و متوقف کردن کد را مشکل تر میکنه

بعد از اون هم علامت بسته شدن پرانتز هست که یعنی تابع ما تموم شده

:(){: | : & }

تا اینجای کار ما این بالایی را توضیح دادیم که یه تابع هست. علامت بعد از اون یه ; هست که نشون میده کد ما اینجا تموم شده و میخواهیم یه دستور جدید وارد کنیم. بعد از اون هم دوباره یه : هست که باعث میشه برای اولین بار تابع ما فراخوانی بشه و پراسس های تو در تو ساخته بشن

یه تابع ساده که میتونه باعث مشکلات پیچیده بشه

اما یه سیستم خوب، سیستمی هست که با این کد های ساده از پا در نیاد!

راحت ترین راه برای جلوگیری از این که سیستممون با یه کد به این سادگی از پا در بیاد، اینه که میزان مصرف منابعمون و مخصوصا رم را برای سیستم ها و package ها مختلف مشخص کنیم و یه Max usage بهشون بدیم تا تموم منابع سیستم را به فنا ندن!

که خود این کار ان شاء الله در پستی دیگر

البته اکپگه فکر کردین که این کد مخصوص لینوکسه یا فرض بر این گذاشتین که این یه باگ لینوکسی هست(خیلی از افراد تا چنین چیزی را میبینن میگن : اه اینم از لینوکستون که گند زده. اولا لینوکس من نیس! دوما ...) یا ... باید خدمتتون عرض کنم که خیر

این بیشتر از این که یه کد باشه، یه مفهمومه

مفهومی از تابعی که درون خودش چند بار خودش را صدا بزنه و همینطور ادامه بده تا بی نهایت تا تمامی منابع سیستم را مصرف کنه

حالا این کد میتونه توی لینوکس نوشته بشه

میتونه با زبان هایی مثل پایتون، سی، روبی، پرل یا هر زبانی باشه

میتونه توی ویندوز باشه

حتی میتونه توی وب باشه

یه تکه کد جاوا اسکریپت، که درون خودش، خودش را توی یه new windows باز کنه

با باز کردن صفحه، به صورت fork bomb، پشت سر هم پنجره باز میشه تا سیستم کلاینت و سرور هر دوش نابود شه!

یا با هر ابزار دیگه، میشه این کد را نوشت

مثال های خوبی هم توی ویکی پدیا هست

موفق و موید باشید

مهدی

منتشر شده در:

  • آواتار شهریار

    شهریار

    یکشنبه 28 شهریور 1395

    ارسال پاسخ

    میشه راحت یدونه max child process مشخص کرد و دیگه این مشکل (به این راحتی!) پیش نمیاد. اگه اشتباه نکنم توی centOS و ی سری توزیع های BSD به صورت پیشفرض گذاشتن روی 50 پروسس. پ.ن : ی احساسی بهم میگه این captcha تغییر نمیکنه :/
  • آواتار شهریار

    مهدی علیخاصی

    یکشنبه 28 شهریور 1395

    الان مطمئن نیستم، ولی فک کنم با استفاده از & میشد کاری کرد که همه شون child یه parent نباشن و با این کار، یکم جلوش را گرفتن سخت تر میشه. البته باز هم میتونی این محدودیت را به init بدی. ولی من خودم همیشه واسه ی برطرف کردن این مشکل از تنظیم محدودیت مصرف رم استفاده میکنم! توی اوبونتو، آخرین باری که چک کردم انگار یه Ram limit داشت و باعث نمیشد که سیستم به طور کامل هنگ کنه و میتونستی باز هم kill کنی پراسس را. (دیگه یارو اگه خیلی بخواد چیز بازی در بیاره میتونه بیاد و سیگنال ها را هم عوض کنه! اونطوری دیگه ctrl +C و kill هم کار نمیده) توی فدورا هم آخرین باری که دیدم، مجبور شدم سیستم را ریست کنم! CentOs و اینا باز هم وضعشون بهتره... در مورد کپچا هم تغییر میکنه، ولی نه با رفرش صفحه! با تغییر کاربر و Sessions تغییر میکنه! یعنی برای هر کاربر یه کپچا میسازه و تا وقتی که اون کاربر توی سایت هست، میتونه از همون کپچا استفاده کنه.
ارسال نظر
خوانا نیست؟تعویض کد