web-dev-qa-db-ja.com

Macでフォーク爆弾?

fork bomb について学んだところです。興味深いタイプのサービス拒否攻撃です。ウィキペディア(および他のいくつかの場所)は、UNIXマシンで:(){ :|:& };:を使用してプロセスを無限の回数フォークすることを推奨しています。ただし、Mac OS X Lionでは動作しないようです(最も一般的なオペレーティングシステムはこのような直接攻撃に対して脆弱ではないことを読んだことを覚えています)。しかし、私はそのような攻撃がどのように機能する(そして見える)かについて非常に興味があり、私のMacで試してみたいと思います。システムのセーフガードを回避する方法はありますか、それともMacでフォーク爆弾が不可能であるということですか?

8
user13049

フォーク爆弾のしくみ:C(またはCのような)コードでは、fork()という名前の関数が呼び出されます。これにより、linuxまたはUnixまたはUnix-a-likesがまったく新しいプロセスを作成します。このプロセスには、アドレススペース、プロセスID、シグナルマスク、オープンファイル記述子、OSカーネルのいくらか限られたメモリでスペースを占めるあらゆる種類のものが含まれます。新しく作成されたプロセスは、実行するプロセスのカーネルのデータ構造にもスポットを取得します。 fork()を呼び出したプロセスには、何も起こらなかったように見えます。 fork-bombプロセスは、fork()をできるだけ早く、何度も呼び出そうとします。

トリックは、新しく作成されたプロセス同じコードでfork()からも戻ってくることです。フォークの後、2つのプロセスが同じコードを実行しています。新しいfork-bombプロセスはそれぞれ、fork()をできるだけ早く、何度も呼び出そうとします。例として提供したコードは、フォーク爆弾のBashスクリプトバージョンです。

間もなく、OSカーネルのプロセス関連リソースがすべて使い果たされます。プロセステーブルがいっぱいです。プロセスの実行待機リストがいっぱいです。実メモリーがいっぱいであるため、ページングが開始されます。これが十分長く続くと、スワップパーティションがいっぱいになります。

これはユーザーにとってどのように見えるか:すべてが超低速で実行されます。 lsのような簡単なことを試みると、「プロセスを作成できませんでした」などのエラーメッセージが表示されます。 psを試行すると、一時停止が発生し(実行される場合)、プロセスの非常に長いリストが返されます。この状況では、電源コードを介して再起動する必要がある場合があります。

フォーク爆弾はかつて「ウサギ」と呼ばれていました。彼らはとても急速に再現したからです。

ちょうど楽しみのために、私はCでフォーク爆弾プログラムを書きました:

_#include <stdio.h>
#include <unistd.h>
int
main(int ac, char **av)
{
        while (1)
                fork();

        return 0;
}
_

そのプログラムをArch Linuxの下で1つのxtermにコンパイルして実行しました。プロセスリストを取得しようとした別のxterm:

_1004 % ps -fu bediger
zsh: fork failed: resource temporarily unavailable
_

2番目のxtermのZシェルは、1番目のxtermに関連付けられたフォーク爆弾プロセスが、作成および実行中のプロセスに関連するすべてのカーネルリソースを使い果たしたため、fork()を正常に呼び出すことができませんでした。

3
Bruce Ediger

フォーク爆弾が機能しないようにするために導入できる多くの保護手段があります。

最も簡単なのは:

ulimit -u 1024

ユーザープロセスの数を1024に制限します。

システムのセーフガードを回避する限り、確かにそれを実行する方法を見つけることができますが、私はここにいる誰もがそれを行う方法を提供するとは思いませんが、基本的にはシステムがPIDを使い果たし、それ以上スポーンできません爆弾がCPUの100%を占有してそれ自体をさらに生成しようとしている場合、プロセスおよび基本的に完全に停止します。

3
Karlson

フォーク爆弾の動作を確認するために本当に必死になっている場合は、rootとして実行してみてください。 Sudo :(){ :|:& };:ですが、もう一度警告します。 Ubuntuで自分で試してみました。システムはフリーズします!

あなたのための簡単な解剖:

:() { #Define a new Shell function
  :|:& #Pipe function named ':' through itself, creating two copies of itself, and make them run in the background
} #End of function definition block
;: #Call the ':' function. Note how the function is defined with two calls to itself piped through each other. This starts a chain reaction: those two copies will in turn create two more, and so on, as infinitum

そのような危害を加えようとするときは、これに注意してください...

2
realkstrawn93

あなたはこれを行うことができますが、ファイルの名前がfile.pyであることを確認してください

import os 
while True
os.startfile(file.py)
0
aNTHONY