GNU/Linux >> Linux の 問題 >  >> Linux

Linux のサンドボックスで信頼できない C プログラムを実行し、ファイルのオープンやフォークなどを防止しますか?

私は Systrace を使用して、対話モードと自動モードの両方で、信頼できないプログラムをサンドボックス化しました。 ptrace() があります

chroot(1) を使用して、Unix ライクなシステムでサンドボックスを作成することもできます。 、それはそれほど簡単でも安全でもありません。 Linux コンテナーと FreeBSD の監獄は、chroot のより優れた代替手段です。 Linux でのもう 1 つの代替手段は、SELinux や AppArmor などのセキュリティ フレームワークを使用することです。これは、私が実稼働システムに提案するものです。

あなたが何をしたいのかを具体的に教えていただければ、もっとお手伝いできます.

編集:

あなたのケースでは Systrace が有効ですが、ディストリビューションによっては、AppArmor や SELinux などの Linux セキュリティ モデルに基づくものがより標準的であり、したがって推奨される代替手段であると思います。

編集 2:

chroot(1) の間 ほとんどの (すべて?) Unix ライクなシステムで利用できますが、かなりの問題があります:

  • それは壊れることができます。システムで信頼できない C プログラムを実際にコンパイルまたは実行する場合は、この問題に対して特に脆弱です。そして、あなたの生徒が私のような人なら、誰かが刑務所から脱出しようとするでしょう.

  • タスクに必要なすべてのものを備えた、完全に独立したファイルシステム階層を作成する必要があります。 chroot にコンパイラを含める必要はありませんが、コンパイルされたプログラムを実行するために必要なものはすべて含める必要があります。これを支援するユーティリティはありますが、それでも簡単ではありません。

  • chroot を維持する必要があります。独立しているため、ディストリビューションと共に chroot ファイルが更新されることはありません。 chroot を定期的に再作成するか、chroot に必要な更新ツールを含める必要があります。これには、本格的な Linux ディストリビューションであることが基本的に必要です。また、システムとユーザー データ (パスワード、入力ファイルなど) をホスト システムと同期させる必要があります。

  • chroot() ファイルシステムのみを保護します。悪意のあるプログラムがネットワーク ソケットを開いたり、不適切なプログラムが利用可能なすべてのリソースを使い果たしたりするのを防ぐことはできません。

リソース使用の問題は、すべての代替案に共通しています。ファイルシステム クォータは、プログラムがディスクをいっぱいにするのを防ぎます。適切な ulimit (setrlimit() C) 設定は、メモリの過剰使用やフォーク爆弾から保護し、CPU の浪費を止めることができます。 nice(1) これらのプログラムの優先度を下げて、より重要と見なされるタスクにコンピュータを問題なく使用できるようにすることができます。


最近、Linux でのサンドボックス化手法の概要を書きました。この環境ではあまり問題にならない fork などを気にしないのであれば、Linux コンテナー (lxc) を使用するのが最も簡単な方法だと思います。プロセスに読み取り専用のルート ファイル システム、分離されたループバック ネットワーク接続を与えることができますが、それでも簡単に強制終了し、メモリ制限などを設定することができます。

コードはメモリを割り当てることさえできないため、seccomp は少し難しくなります。

Selinux はもう 1 つのオプションですが、コンテナよりも手間がかかると思います。


Qemu を使用すると、割り当てをすばやくテストできます。以下の手順は、5 年前のラップトップで 5 秒もかかりません。

学生が、「-1」の行が到着するまで、それぞれの行に unsigned int を取るプログラムを開発しなければならないと仮定しましょう。次に、プログラムはすべての int を平均し、"Average:%f" を出力する必要があります。プログラムを完全に分離してテストする方法は次のとおりです:

<オール>
  • まず、root.bin を取得します Jslinux から、それをユーザーランドとして使用します (tcc C コンパイラーがあります):

    wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin

  • 生徒の提出物を root.bin に入れたい 、ループデバイスをセットアップします:

    sudo losetup /dev/loop0 root.bin

    (これにも fuseext2 を使用できますが、あまり安定していません。安定すれば、root は必要ありません)

  • 空のディレクトリを作成:

    mkdir mountpoint

  • root.bin をマウント :

    sudo mount /dev/loop0 mountpoint

  • マウントされたファイルシステムを入力してください:

    cd mountpoint .

  • 修正権:

    sudo chown -R `whoami` .

  • mkdir -p etc/init.d
  • vi etc/init.d :

    #!/bin/sh
    cd /root
    echo READY 2>&1 > /dev/ttyS0
    tcc assignment.c 2>&1 > /dev/ttyS0
    ./a.out 2>&1 > /dev/ttyS0
    
  • chmod +x etc/init.d/rcS

  • 提出物を VM にコピーします:

    cp ~/student_assignment.c root/assignment.c

  • VM のルート FS を終了します:

    cd ..

  • sudo umount mountpoint
  • イメージの準備ができたので、実行するだけです。起動後に提出物をコンパイルして実行します。
  • mkfifo /tmp/guest_output
  • 別のターミナルを開き、ゲスト出力のリッスンを開始します:

    dd if=/tmp/guest_output bs=1

  • 別の端末で:

    qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput (ここでは Ubuntu カーネルを使用しましたが、多くのカーネルが動作します)

  • ゲストの出力に「READY」と表示されたら、qemu プロンプトからキーを VM に送信できます。たとえば、この割り当てをテストするには、次のようにします。

    (qemu) sendkey 1
    (qemu) sendkey 4
    (qemu) sendkey ret
    (qemu) sendkey 1
    (qemu) sendkey 0
    (qemu) sendkey ret
    (qemu) sendkey minus
    (qemu) sendkey 1
    (qemu) sendkey ret
    
  • 現在 Average = 12.000000 ゲスト出力パイプに表示されるはずです。そうでない場合、学生は不合格です。

  • qemu を終了:quit
  • テストに合格したプログラムはこちら:https://stackoverflow.com/a/14424295/309483. tcclib.h を使用するだけです stdio.h の代わりに .


    Linux
    1. LinuxでPDFファイルからビデオを作成する方法

    2. Linux – Linuxからブートローダーを実行する方法は?

    3. コマンドラインからのLinuxサーバーの移行

    1. Linux –オンラインで投稿した場合、ログファイルやエラーメッセージなどからどのデータを除外する必要がありますか?

    2. Linux シェルから、現在とは異なる作業ディレクトリでプログラムを実行するにはどうすればよいですか?

    3. Linux .dts デバイス ツリー ファイルをプログラムする方法は?

    1. Linux端末からファイルを印刷する

    2. Linuxコマンドラインからハードウェアをプログラムする

    3. Linux での有害な可能性があるプログラムの実行